diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1001a9b5b9..b7f8eb0eb7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2776,7 +2776,7 @@ static RPCHelpMan scantxoutset() throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\""); } - if (request.params.size() < 2) { + if (request.params[1].isNull()) { throw JSONRPCError(RPC_MISC_ERROR, "scanobjects argument is required for the start action"); } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c70236cc1c..7a96ad0f24 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -145,7 +145,7 @@ static RPCHelpMan help() [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue { std::string strCommand; - if (jsonRequest.params.size() > 0) { + if (!jsonRequest.params[0].isNull()) { strCommand = jsonRequest.params[0].get_str(); } if (strCommand == "dump_all_command_conversions") { diff --git a/src/wallet/rpc/elements.cpp b/src/wallet/rpc/elements.cpp index 2eb0810dd8..1d99504277 100644 --- a/src/wallet/rpc/elements.cpp +++ b/src/wallet/rpc/elements.cpp @@ -330,7 +330,7 @@ RPCHelpMan initpegoutwallet() // Generate a new key that is added to wallet or set from argument CPubKey online_pubkey; - if (request.params.size() < 3) { + if (request.params[2].isNull()) { std::string error; if (!pwallet->GetOnlinePakKey(online_pubkey, error)) { throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error); @@ -347,7 +347,7 @@ RPCHelpMan initpegoutwallet() // Parse offline counter int counter = 0; - if (request.params.size() > 1) { + if (!request.params[1].isNull()) { counter = request.params[1].get_int(); if (counter < 0 || counter > 1000000000) { throw JSONRPCError(RPC_INVALID_PARAMETER, "bip32_counter must be between 0 and 1,000,000,000, inclusive."); @@ -502,7 +502,7 @@ RPCHelpMan sendtomainchain_base() throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); bool subtract_fee = false; - if (request.params.size() > 2) { + if (!request.params[2].isNull()) { subtract_fee = request.params[2].get_bool(); } @@ -523,7 +523,7 @@ RPCHelpMan sendtomainchain_base() EnsureWalletIsUnlocked(*pwallet); - bool verbose = request.params[3].isNull() ? false: request.params[3].get_bool(); + bool verbose = request.params[3].isNull() ? false : request.params[3].get_bool(); mapValue_t mapValue; CCoinControl no_coin_control; // This is a deprecated API return SendMoney(*pwallet, no_coin_control, recipients, std::move(mapValue), verbose, true /* ignore_blind_fail */); @@ -615,7 +615,7 @@ RPCHelpMan sendtomainchain_pak() throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount for send, must send more than 0.00100000 BTC"); bool subtract_fee = false; - if (request.params.size() > 2) { + if (!request.params[2].isNull()) { subtract_fee = request.params[2].get_bool(); } @@ -827,7 +827,7 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef std::vector txOutProofData = ParseHex(request.params[1].get_str()); std::set claim_scripts; - if (request.params.size() > 2) { + if (!request.params[2].isNull()) { const std::string claim_script = request.params[2].get_str(); if (!IsHex(claim_script)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Given claim_script is not hex."); @@ -1273,12 +1273,12 @@ RPCHelpMan blindrawtransaction() } bool ignore_blind_fail = true; - if (request.params.size() > 1) { + if (!request.params[1].isNull()) { ignore_blind_fail = request.params[1].get_bool(); } std::vector > auxiliary_generators; - if (request.params.size() > 2) { + if (!request.params[2].isNull()) { UniValue assetCommitments = request.params[2].get_array(); if (assetCommitments.size() != 0 && assetCommitments.size() < tx.vin.size()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Asset commitment array must have at least as many entries as transaction inputs."); @@ -1542,11 +1542,11 @@ RPCHelpMan issueasset() throw JSONRPCError(RPC_TYPE_ERROR, "Issuance must have one non-zero component"); } - bool blind_issuances = request.params.size() < 3 || request.params[2].get_bool(); + bool blind_issuances = request.params[2].isNull() || request.params[2].get_bool(); // Check for optional contract to hash into definition uint256 contract_hash; - if (request.params.size() >= 4) { + if (!request.params[3].isNull()) { contract_hash = ParseHashV(request.params[3], "contract_hash"); } @@ -1733,7 +1733,7 @@ RPCHelpMan listissuances() std::string assetstr; CAsset asset_filter; - if (request.params.size() > 0) { + if (!request.params[0].isNull()) { assetstr = request.params[0].get_str(); asset_filter = GetAssetFromString(assetstr); } diff --git a/test/functional/feature_fedpeg.py b/test/functional/feature_fedpeg.py index ee57b8b5d1..52b27b2534 100755 --- a/test/functional/feature_fedpeg.py +++ b/test/functional/feature_fedpeg.py @@ -600,6 +600,12 @@ class FedPegTest(BitcoinTestFramework): peg_out_txid = sidechain.sendtomainchain(some_btc_addr, 1) + self.log.info("sendtomainchain with null argument") + verbose_result = sidechain.sendtomainchain(some_btc_addr, 1, None, True) + assert isinstance(verbose_result, dict) + assert 'txid' in verbose_result + assert 'fee_reason' in verbose_result + peg_out_details = sidechain.decoderawtransaction(sidechain.getrawtransaction(peg_out_txid)) # peg-out, change, fee assert len(peg_out_details["vout"]) == 3 diff --git a/test/functional/feature_issuance.py b/test/functional/feature_issuance.py index ba34ed7291..35d056fab7 100755 --- a/test/functional/feature_issuance.py +++ b/test/functional/feature_issuance.py @@ -112,12 +112,19 @@ class IssuanceTest(BitcoinTestFramework): # Make sure test starts with no initial issuance. assert_equal(len(self.nodes[0].listissuances()), 0) + self.log.info("listissuances with null argument") + assert_equal(self.nodes[0].listissuances(None), []) + # Unblinded issuance of asset contract_hash = "deadbeef"*8 issued = self.nodes[0].issueasset(1, 1, False, contract_hash) balance = self.nodes[0].getwalletinfo()["balance"] assert_equal(balance[issued["asset"]], 1) assert_equal(balance[issued["token"]], 1) + + self.log.info("issueasset with null argument") + assert_equal(len(self.nodes[0].listissuances(None)), len(self.nodes[0].listissuances())) + # Quick unblinded reissuance check, making 2*COIN total self.nodes[0].reissueasset(issued["asset"], 1) diff --git a/test/functional/feature_pak.py b/test/functional/feature_pak.py index 8297931c4b..7ed01d8d5b 100755 --- a/test/functional/feature_pak.py +++ b/test/functional/feature_pak.py @@ -71,6 +71,11 @@ class PAKTest (BitcoinTestFramework): assert_equal(new_init["address_lookahead"][0], init_results[1]["address_lookahead"][2]) assert(new_init["liquid_pak"] != init_results[1]["liquid_pak"]) + self.log.info("initpegoutwallet with null argument") + null_pak_init = self.nodes[2].initpegoutwallet(xpub, 5, None) + assert_equal(self.nodes[2].getwalletpakinfo()["bip32_counter"], "5") + assert null_pak_init["liquid_pak"] + # Restart and connect peers to check wallet persistence self.stop_nodes() self.start_nodes() @@ -187,6 +192,12 @@ class PAKTest (BitcoinTestFramework): wpkh_stmc = self.nodes[1].sendtomainchain("", 1) wpkh_txid = wpkh_stmc['txid'] + self.log.info("sendtomainchain with null argument") + verbose_stmc = self.nodes[1].sendtomainchain("", 1, None, True) + assert isinstance(verbose_stmc, dict) + assert 'txid' in verbose_stmc + assert 'fee_reason' in verbose_stmc + # Also check some basic return fields of sendtomainchain with pak assert_equal(wpkh_stmc["bitcoin_address"], wpkh_info["address_lookahead"][0]) validata = self.nodes[1].validateaddress(wpkh_stmc["bitcoin_address"]) diff --git a/test/functional/feature_pegin_subsidy.py b/test/functional/feature_pegin_subsidy.py index 020622bde7..49f2c316ee 100755 --- a/test/functional/feature_pegin_subsidy.py +++ b/test/functional/feature_pegin_subsidy.py @@ -339,6 +339,16 @@ class PeginSubsidyTest(BitcoinTestFramework): assert_equal(len(pegin_tx["decoded"]["vout"]), 2) self.generate(sidechain2, 1, sync_fun=sync_sidechain) + self.log.info("createrawpegin with null argument") + txid, vout, txoutproof, bitcoin_txhex, claim_script = parent_pegin(parent, sidechain2, amount=1.0, feerate=2.0) + pegintx = sidechain2.createrawpegin(bitcoin_txhex, txoutproof, None, 2.0) + signed = sidechain2.signrawtransactionwithwallet(pegintx["hex"]) + assert_equal(signed["complete"], True) + pegin_txid = sidechain2.sendrawtransaction(signed["hex"]) + pegin_tx = sidechain2.gettransaction(pegin_txid, True, True) + assert_equal(len(pegin_tx["decoded"]["vout"]), 2) + self.generate(sidechain2, 1, sync_fun=sync_sidechain) + self.log.info("claimpegin before enforcement, with validatepegin, below threshold") txid, vout, txoutproof, bitcoin_txhex, claim_script = parent_pegin(parent, sidechain, amount=1.0, feerate=2.0) pegin_txid = sidechain.claimpegin(bitcoin_txhex, txoutproof, claim_script) diff --git a/test/functional/rpc_deriveaddresses.py b/test/functional/rpc_deriveaddresses.py index 413c46aafa..c759cc4497 100755 --- a/test/functional/rpc_deriveaddresses.py +++ b/test/functional/rpc_deriveaddresses.py @@ -17,6 +17,7 @@ class DeriveaddressesTest(BitcoinTestFramework): descriptor = "wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#t6wfjs64" address = "ert1qjqmxmkpmxt80xz4y3746zgt0q3u3ferrfpgxn5" assert_equal(self.nodes[0].deriveaddresses(descriptor), [address]) + assert_equal(self.nodes[0].deriveaddresses(descriptor, None), [address]) descriptor = descriptor[:-9] assert_raises_rpc_error(-5, "Missing checksum", self.nodes[0].deriveaddresses, descriptor) diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index 865d54cff6..932a2eb750 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -649,6 +649,10 @@ class RawTransactionsTest(BitcoinTestFramework): rawtx = self.nodes[1].createrawtransaction(inputs, outputs) fundedTx = self.nodes[1].fundrawtransaction(rawtx) blindedTx = self.nodes[1].blindrawtransaction(fundedTx['hex']) + assert fundedTx["changepos"] != -1 + self.log.info("blindrawtransaction with null argument") + blindedTx_null_commitments = self.nodes[1].blindrawtransaction(fundedTx['hex'], None, None, False) + assert blindedTx_null_commitments # Now we need to unlock. self.nodes[1].walletpassphrase("test", 600) diff --git a/test/functional/rpc_help.py b/test/functional/rpc_help.py index ccb380e25b..1dbf35885c 100755 --- a/test/functional/rpc_help.py +++ b/test/functional/rpc_help.py @@ -94,6 +94,9 @@ class HelpRpcTest(BitcoinTestFramework): # invalid argument assert_raises_rpc_error(-1, 'JSON value is not a string as expected', node.help, 0) + # null argument + assert_equal(node.help(None), node.help()) + # help of unknown command assert_equal(node.help('foo'), 'help: unknown command: foo') diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py index ffc814c02b..0502fc9c4e 100755 --- a/test/functional/rpc_scantxoutset.py +++ b/test/functional/rpc_scantxoutset.py @@ -126,6 +126,7 @@ class ScantxoutsetTest(BitcoinTestFramework): # Check that second arg is needed for start assert_raises_rpc_error(-1, "scanobjects argument is required for the start action", self.nodes[0].scantxoutset, "start") + assert_raises_rpc_error(-1, "scanobjects argument is required for the start action", self.nodes[0].scantxoutset, "start", None) if __name__ == "__main__":