Merge branch 'dev' into lockzins
This commit is contained in:
@@ -13,6 +13,7 @@ evil organizations.
|
|||||||
# Hush 3.10.4 ""
|
# Hush 3.10.4 ""
|
||||||
* Updated seed node list
|
* Updated seed node list
|
||||||
* New CLI option -clearnet=0 which disables clearnet networking, i.e. only Tor or i2p are allowed
|
* New CLI option -clearnet=0 which disables clearnet networking, i.e. only Tor or i2p are allowed
|
||||||
|
* Note that at least one of a Tor or i2p daemon are needed for -clearnet=0, both are not needed but supported
|
||||||
* -clearnet=0 is equivalent to the following CLI params:
|
* -clearnet=0 is equivalent to the following CLI params:
|
||||||
```
|
```
|
||||||
-disableipv4=1
|
-disableipv4=1
|
||||||
@@ -25,7 +26,6 @@ evil organizations.
|
|||||||
-onion="127.0.0.1:9050
|
-onion="127.0.0.1:9050
|
||||||
-i2psam="127.0.0.1:7656"
|
-i2psam="127.0.0.1:7656"
|
||||||
```
|
```
|
||||||
* Note that at least one of a Tor or i2p daemon are needed for -clearnet=0, both are not needed but supported
|
|
||||||
* Add CLI options `-disableipv4` and `-disableipv6` which can be used to disable IPv4 or IPv6
|
* Add CLI options `-disableipv4` and `-disableipv6` which can be used to disable IPv4 or IPv6
|
||||||
* Updated ASmap, which maps IP addresses to Autonomous System (AS) numbers
|
* Updated ASmap, which maps IP addresses to Autonomous System (AS) numbers
|
||||||
* Added ASmap health check, which logs stats about the ASmap once per 24 hours
|
* Added ASmap health check, which logs stats about the ASmap once per 24 hours
|
||||||
|
|||||||
@@ -5008,9 +5008,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
if (!EnsureWalletIsAvailable(fHelp))
|
if (!EnsureWalletIsAvailable(fHelp))
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
|
|
||||||
if (fHelp || params.size() < 2 || params.size() > 4)
|
if (fHelp || params.size() < 2 || params.size() > 5)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"z_sendmany \"fromaddress\" [{\"address\":... ,\"amount\":...},...] ( minconf ) ( fee )\n"
|
"z_sendmany \"fromaddress\" [{\"address\":... ,\"amount\":...},...] ( minconf ) ( fee ) (opreturn)\n"
|
||||||
"\nSend multiple times. Amounts are decimal numbers with at most 8 digits of precision."
|
"\nSend multiple times. Amounts are decimal numbers with at most 8 digits of precision."
|
||||||
"\nChange generated from a taddr flows to a new taddr address, while change generated from a zaddr returns to itself."
|
"\nChange generated from a taddr flows to a new taddr address, while change generated from a zaddr returns to itself."
|
||||||
"\nWhen sending coinbase UTXOs to a zaddr, change is not allowed. The entire value of the UTXO(s) must be consumed."
|
"\nWhen sending coinbase UTXOs to a zaddr, change is not allowed. The entire value of the UTXO(s) must be consumed."
|
||||||
@@ -5026,6 +5026,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
"3. minconf (numeric, optional, default=1) Only use funds confirmed at least this many times.\n"
|
"3. minconf (numeric, optional, default=1) Only use funds confirmed at least this many times.\n"
|
||||||
"4. fee (numeric, optional, default="
|
"4. fee (numeric, optional, default="
|
||||||
+ strprintf("%s", FormatMoney(ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
|
+ strprintf("%s", FormatMoney(ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
|
||||||
|
"5. opreturn (string, optional) Hex encoded data for OP_RETURN. Or a utf8 string prefixed with 'utf8:' which will be automatically converted to hex\n"
|
||||||
"\nResult:\n"
|
"\nResult:\n"
|
||||||
"\"operationid\" (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
|
"\"operationid\" (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
@@ -5033,6 +5034,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
+ HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]")
|
+ HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]")
|
||||||
+ HelpExampleCli("z_sendmany", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" '[{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 3.14}]'")
|
+ HelpExampleCli("z_sendmany", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" '[{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 3.14}]'")
|
||||||
+ HelpExampleRpc("z_sendmany", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 3.14}]")
|
+ HelpExampleRpc("z_sendmany", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 3.14}]")
|
||||||
|
+ HelpExampleCli("z_sendmany", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" '[{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 3.14}]' 1 0.0001 \"utf8: this will be converted to hex")
|
||||||
|
+ HelpExampleRpc("z_sendmany", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" '[{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 3.14}]' 1 0.0001 \"utf8: this will be converted to hex")
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
@@ -5157,11 +5160,28 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
CAmount nTotalOut = 0;
|
CAmount nTotalOut = 0;
|
||||||
// Optional OP_RETURN data
|
// Optional OP_RETURN data
|
||||||
CScript opret;
|
CScript opret;
|
||||||
// TODO: enforce that only a single opreturn exists
|
|
||||||
UniValue opretValue;
|
UniValue opretValue;
|
||||||
|
if(params.size() == 5) {
|
||||||
|
opretValue = params[4].get_str();
|
||||||
|
|
||||||
|
// Support a prefix "utf8:" which allows giving utf8 text instead of hex
|
||||||
|
if(opretValue.get_str().substr(0,5) == "utf8:") {
|
||||||
|
auto str = opretValue.get_str().substr(5);
|
||||||
|
if (utf8::is_valid(str)) {
|
||||||
|
opretValue = HexStr(str);
|
||||||
|
} else {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid utf8 in opreturn");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool containsSaplingOutput = false;
|
bool containsSaplingOutput = false;
|
||||||
|
|
||||||
|
// Create the CScript representation of the OP_RETURN
|
||||||
|
if (!opretValue.isNull()) {
|
||||||
|
opret << OP_RETURN << ParseHex(opretValue.get_str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
for (const UniValue& o : outputs.getValues()) {
|
for (const UniValue& o : outputs.getValues()) {
|
||||||
if (!o.isObject())
|
if (!o.isObject())
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
|
||||||
@@ -5169,7 +5189,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
// sanity check, report error if unknown key-value pairs
|
// sanity check, report error if unknown key-value pairs
|
||||||
for (const string& name_ : o.getKeys()) {
|
for (const string& name_ : o.getKeys()) {
|
||||||
std::string s = name_;
|
std::string s = name_;
|
||||||
if (s != "address" && s != "amount" && s!="memo" && s!="opreturn") {
|
if (s != "address" && s != "amount" && s!="memo") {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown key: ")+s);
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown key: ")+s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5188,24 +5208,22 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
// throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Extreme Privacy! You must send to a zaddr");
|
// throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Extreme Privacy! You must send to a zaddr");
|
||||||
//}
|
//}
|
||||||
|
|
||||||
UniValue this_opret = find_value(o, "opreturn");
|
|
||||||
if (!this_opret.isNull()) {
|
|
||||||
opretValue = this_opret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the CScript representation of the OP_RETURN
|
|
||||||
if (!opretValue.isNull()) {
|
|
||||||
opret << OP_RETURN << ParseHex(opretValue.get_str().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
UniValue memoValue = find_value(o, "memo");
|
UniValue memoValue = find_value(o, "memo");
|
||||||
string memo;
|
string memo;
|
||||||
if (!memoValue.isNull()) {
|
if (!memoValue.isNull()) {
|
||||||
memo = memoValue.get_str();
|
memo = memoValue.get_str();
|
||||||
if (!isZaddr) {
|
if (!isZaddr) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo cannot be used with a taddr. It can only be used with a zaddr.");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo cannot be used with a taddr. It can only be used with a zaddr.");
|
||||||
|
} else if(memo.substr(0,5) == "utf8:") {
|
||||||
|
// Support a prefix "utf8:" which allows giving utf8 text instead of hex
|
||||||
|
auto str = memo.substr(5);
|
||||||
|
if (utf8::is_valid(str)) {
|
||||||
|
memo = HexStr(str);
|
||||||
|
} else {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid utf8 in memo");
|
||||||
|
}
|
||||||
} else if (!IsHex(memo)) {
|
} else if (!IsHex(memo)) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format.");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format or to use 'utf8:' prefix.");
|
||||||
}
|
}
|
||||||
if (memo.length() > HUSH_MEMO_SIZE*2) {
|
if (memo.length() > HUSH_MEMO_SIZE*2) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", HUSH_MEMO_SIZE ));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", HUSH_MEMO_SIZE ));
|
||||||
|
|||||||
Reference in New Issue
Block a user