From e5d02b9fd50860258749e02a5c7d8946075ab9e5 Mon Sep 17 00:00:00 2001 From: Tom Trevethan Date: Tue, 7 Jul 2026 16:26:00 +0100 Subject: [PATCH] fix RPC documentation inconsistencies --- src/rpc/blockchain.cpp | 12 ++++---- src/rpc/mining.cpp | 18 ++++++------ src/rpc/rawtransaction.cpp | 17 ++++++----- src/wallet/rpc/coins.cpp | 14 +++++----- src/wallet/rpc/elements.cpp | 2 +- src/wallet/rpc/spend.cpp | 4 +-- src/wallet/rpc/wallet.cpp | 9 ++---- test/functional/feature_blocksign.py | 42 ++++++++++++++++++++++++++++ 8 files changed, 77 insertions(+), 41 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index aa80fb6fee..8f2ebb12f2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -641,7 +641,6 @@ static RPCHelpMan getblockheader() {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, {RPCResult::Type::NUM, "nonce", /*optional=*/true, "The nonce"}, {RPCResult::Type::STR_HEX, "bits", /*optional=*/true, "The bits"}, - {RPCResult::Type::STR_HEX, "target", /*optional=*/true, "The difficulty target"}, {RPCResult::Type::NUM, "difficulty", /*optional=*/true, "The difficulty"}, {RPCResult::Type::STR_HEX, "chainwork", /*optional=*/true, "Expected number of hashes required to produce the current chain"}, {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, @@ -843,7 +842,6 @@ static RPCHelpMan getblock() {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, {RPCResult::Type::NUM, "nonce", /*optional=*/true, "The nonce"}, {RPCResult::Type::STR_HEX, "bits", /*optional=*/true, "The bits"}, - {RPCResult::Type::STR_HEX, "target", /*optional=*/true, "The difficulty target"}, {RPCResult::Type::NUM, "difficulty", /*optional=*/true, "The difficulty"}, {RPCResult::Type::STR_HEX, "chainwork", /*optional=*/true, "Expected number of hashes required to produce the chain up to this block"}, {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, @@ -867,7 +865,7 @@ static RPCHelpMan getblock() {RPCResult::Type::ELISION, "", ""} }}, }}, - {RPCResult::Type::OBJ, "proposed", "Proposed parameters. Uninforced. Must be published in full", + {RPCResult::Type::OBJ, "proposed", "Proposed parameters. Unenforced. Must be published in full", { {RPCResult::Type::ELISION, "", "same entries as \"current\""} }}, @@ -2477,7 +2475,7 @@ static RPCHelpMan scantxoutset() {RPCResult::Type::STR_HEX, "scriptPubKey", "The output script"}, {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched output script"}, {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"}, - {RPCResult::Type::STR_HEX, "asset", "The asset ID"}, + {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "The asset ID"}, {RPCResult::Type::BOOL, "coinbase", "Whether this is a coinbase output"}, {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"}, {RPCResult::Type::STR_HEX, "blockhash", "Blockhash of the unspent transaction output"}, @@ -2900,7 +2898,7 @@ static RPCHelpMan getdescriptoractivity() {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "The blockhash this spend appears in (omitted if unconfirmed)"}, {RPCResult::Type::NUM, "height", /*optional=*/true, "Height of the spend (omitted if unconfirmed)"}, {RPCResult::Type::STR_HEX, "spend_txid", "The txid of the spending transaction"}, - {RPCResult::Type::NUM, "spend_vout", "The vout of the spend"}, + {RPCResult::Type::NUM, "spend_vin", "The vin of the spend"}, {RPCResult::Type::STR_HEX, "prevout_txid", "The txid of the prevout"}, {RPCResult::Type::NUM, "prevout_vout", "The vout of the prevout"}, {RPCResult::Type::OBJ, "prevout_spk", "", ScriptPubKeyDoc()}, @@ -3679,10 +3677,10 @@ static RPCHelpMan getsidechaininfo() RPCResult::Type::OBJ, "", "", { {RPCResult::Type::STR_HEX, "fedpegscript", "The fedpegscript from genesis block"}, - {RPCResult::Type::ARR, "current_fedpegscripts", "The currently-enforced fedpegscripts in hex. Peg-ins for any entries on this list are honored by consensus and policy. Newest first. Two total entries are possible", - {{RPCResult::Type::STR_HEX, "", "active fedpegscript"}}}, {RPCResult::Type::ARR, "current_fedpeg_programs", "The currently-enforced fedpegscript scriptPubKeys in hex. Prior to a transition this may be P2SH scriptpubkey, otherwise it will be a native segwit script. Results are paired in-order with current_fedpegscripts", {{RPCResult::Type::STR_HEX, "", "active fedpegscript scriptPubKeys"}}}, + {RPCResult::Type::ARR, "current_fedpegscripts", "The currently-enforced fedpegscripts in hex. Peg-ins for any entries on this list are honored by consensus and policy. Newest first. Two total entries are possible", + {{RPCResult::Type::STR_HEX, "", "active fedpegscript"}}}, {RPCResult::Type::STR_HEX, "pegged_asset", "Pegged asset type"}, {RPCResult::Type::STR, "min_peg_diff", "The minimum difficulty parent chain header target. Peg-in headers that have less work will be rejected as an anti-Dos measure"}, {RPCResult::Type::STR_HEX, "parent_blockhash", "The parent genesis blockhash as source of pegged-in funds"}, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index d620a286ff..40d766518c 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -450,14 +450,14 @@ static RPCHelpMan getmininginfo() {RPCResult::Type::NUM, "networkhashps", /*optional=*/true, "The network hashes per second"}, {RPCResult::Type::NUM, "pooledtx", "The size of the mempool"}, {RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"}, - {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"}, - {RPCResult::Type::OBJ, "next", "The next block", + {RPCResult::Type::OBJ, "next", /*optional=*/true, "The next block", { {RPCResult::Type::NUM, "height", "The next height"}, {RPCResult::Type::STR_HEX, "bits", "The next target nBits"}, {RPCResult::Type::NUM, "difficulty", "The next difficulty"}, {RPCResult::Type::STR_HEX, "target", "The next target"} }}, + {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"}, (IsDeprecatedRPCEnabled("warnings") ? RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} : RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)", @@ -663,6 +663,10 @@ static RPCHelpMan getblocktemplate() RPCResult{"If the proposal was not accepted with mode=='proposal'", RPCResult::Type::STR, "", "According to BIP22"}, RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "", { + {RPCResult::Type::ARR, "capabilities", "", + { + {RPCResult::Type::STR, "value", "A supported feature, for example 'proposal'"}, + }}, {RPCResult::Type::NUM, "version", "The preferred block version"}, {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced", { @@ -672,10 +676,6 @@ static RPCHelpMan getblocktemplate() { {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"}, }}, - {RPCResult::Type::ARR, "capabilities", "", - { - {RPCResult::Type::STR, "value", "A supported feature, for example 'proposal'"}, - }}, {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"}, {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"}, {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block", @@ -1262,7 +1262,7 @@ static RPCHelpMan getnewblockhex() std::unique_ptr pblocktemplate(BlockAssembler(chainman.ActiveChainstate(), node.mempool.get(), options).CreateNewBlock()); if (!pblocktemplate.get()) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block template empty"); } { @@ -1310,7 +1310,7 @@ static RPCHelpMan combineblocksigs() }, }, }, - {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hex-encoded witnessScript for the signblockscript"}, + {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hex-encoded witnessScript for the signblockscript. Required for dynafed blocks; omitted for non-dynafed blocks."}, }, RPCResult{ RPCResult::Type::OBJ, "", "", @@ -1391,7 +1391,7 @@ static RPCHelpMan getcompactsketch() {"block_hex", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialized block proposal from `getnewblockhex`."}, }, RPCResult{ - RPCResult::Type::STR, "sketch", "serialized block sketch", + RPCResult::Type::STR_HEX, "sketch", "serialized block sketch", }, RPCExamples{ HelpExampleCli("getcompactsketch", ""), diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index d339fa5365..1877d08777 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -343,7 +343,7 @@ static RPCHelpMan getrawtransaction() }, { RPCResult{"if verbosity is not set or set to 0", - RPCResult::Type::STR, "data", "The serialized transaction as a hex-encoded string for 'txid'" + RPCResult::Type::STR_HEX, "data", "The serialized transaction as a hex-encoded string for 'txid'" }, RPCResult{"if verbosity is set to 1", RPCResult::Type::OBJ, "", "", @@ -711,7 +711,7 @@ static RPCHelpMan combinerawtransaction() }, }, RPCResult{ - RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)" + RPCResult::Type::STR_HEX, "", "The hex-encoded raw transaction with signature(s)" }, RPCExamples{ HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')") @@ -795,7 +795,7 @@ static RPCHelpMan signrawtransactionwithkey() {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"}, {"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing", { - {"privatekey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "private key in base58-encoding"}, + {"privatekey", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "private key in base58-encoding"}, }, }, {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs", @@ -1171,9 +1171,8 @@ static RPCHelpMan decodepsbt() }}, {RPCResult::Type::NUM, "tx_version", /*optional=*/true, "The version number of the unsigned transaction. Not to be confused with PSBT version"}, {RPCResult::Type::NUM, "fallback_locktime", /*optional=*/true, "The locktime to fallback to if no inputs specify a required locktime."}, - {RPCResult::Type::NUM, "fees", "The fees specified in this psbt.", {}, /*skip_type_check=*/true}, // ELEMENTS has an explicit fee output, bitcoin does not (they are implicit) - {RPCResult::Type::NUM, "input_count", "The number of inputs in this psbt"}, - {RPCResult::Type::NUM, "output_count", "The number of outputs in this psbt."}, + {RPCResult::Type::NUM, "input_count", /*optional=*/true, "The number of inputs in this psbt"}, + {RPCResult::Type::NUM, "output_count", /*optional=*/true, "The number of outputs in this psbt."}, {RPCResult::Type::BOOL, "inputs_modifiable", /*optional=*/true, "Whether inputs can be modified"}, {RPCResult::Type::BOOL, "outputs_modifiable", /*optional=*/true, "Whether outputs can be modified"}, {RPCResult::Type::BOOL, "has_sighash_single", /*optional=*/true, "Whether this PSBT has SIGHASH_SINGLE inputs"}, @@ -2608,7 +2607,7 @@ static RPCHelpMan rawblindrawtransaction() {"ignoreblindfail", RPCArg::Type::BOOL, RPCArg::Default{true}, "Return a transaction even when a blinding attempt fails due to number of blinded inputs/outputs."}, }, RPCResult{ - RPCResult::Type::STR, "transaction", "hex string of the transaction" + RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction" }, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue @@ -2642,7 +2641,7 @@ static RPCHelpMan rawblindrawtransaction() } if (inputAmounts.size() != tx.vin.size()) { throw JSONRPCError(RPC_INVALID_PARAMETER, - "Invalid parameter: one (potentially empty) input blind for each input must be provided"); + "Invalid parameter: one (potentially empty) input amount for each input must be provided"); } if (inputAssets.size() != tx.vin.size()) { throw JSONRPCError(RPC_INVALID_PARAMETER, @@ -2694,7 +2693,7 @@ static RPCHelpMan rawblindrawtransaction() if (!IsHex(assetblind) || assetblind.length() != 32*2) throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset blinds must be an array of 32-byte hex-encoded strings"); if (!IsHex(asset) || asset.length() != 32*2) - throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset blinds must be an array of 32-byte hex-encoded strings"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset IDs must be an array of 32-byte hex-encoded strings"); input_blinds.push_back(uint256S(blind)); input_asset_blinds.push_back(uint256S(assetblind)); diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp index fd3bddc22a..2b004eb59e 100644 --- a/src/wallet/rpc/coins.cpp +++ b/src/wallet/rpc/coins.cpp @@ -120,7 +120,7 @@ RPCHelpMan getreceivedbyaddress() "\nThe amount with at least 6 confirmations\n" + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6") + "\nThe amount with at least 6 confirmations including immature coinbase outputs\n" - + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6 true") + + + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6 \"\" true") + "\nAs a JSON-RPC call\n" + HelpExampleRpc("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 6") }, @@ -178,9 +178,9 @@ RPCHelpMan getreceivedbylabel() "\nThe amount with at least 6 confirmations\n" + HelpExampleCli("getreceivedbylabel", "\"tabby\" 6") + "\nThe amount with at least 6 confirmations including immature coinbase outputs\n" - + HelpExampleCli("getreceivedbylabel", "\"tabby\" 6 true") + + + HelpExampleCli("getreceivedbylabel", "\"tabby\" 6 \"\" true") + "\nAs a JSON-RPC call\n" - + HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6, true") + + HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6, \"\", true") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -640,14 +640,14 @@ RPCHelpMan listunspent() {RPCResult::Type::STR, "scriptPubKey", "the output script"}, {RPCResult::Type::STR_AMOUNT, "amount", "the transaction output amount in " + CURRENCY_UNIT}, {RPCResult::Type::STR_HEX, "amountcommitment", /*optional=*/true, "the transaction output commitment in hex"}, - {RPCResult::Type::STR_HEX, "asset", "the transaction output asset in hex"}, + {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "the transaction output asset in hex"}, {RPCResult::Type::STR_HEX, "assetcommitment", /*optional=*/true, "the transaction output asset commitment in hex"}, - {RPCResult::Type::STR_HEX, "amountblinder", "the transaction output amount blinding factor in hex"}, - {RPCResult::Type::STR_HEX, "assetblinder", "the transaction output asset blinding factor in hex"}, + {RPCResult::Type::STR_HEX, "amountblinder", /*optional=*/true, "the transaction output amount blinding factor in hex"}, + {RPCResult::Type::STR_HEX, "assetblinder", /*optional=*/true, "the transaction output asset blinding factor in hex"}, {RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, {RPCResult::Type::NUM, "ancestorcount", /*optional=*/true, "The number of in-mempool ancestor transactions, including this one (if transaction is in the mempool)"}, {RPCResult::Type::NUM, "ancestorsize", /*optional=*/true, "The virtual transaction size of in-mempool ancestors, including this one (if transaction is in the mempool)"}, - {RPCResult::Type::STR_AMOUNT, "ancestorfees", /*optional=*/true, "The total fees of in-mempool ancestors (including this one) with fee deltas used for mining priority in " + CURRENCY_ATOM + " (if transaction is in the mempool)"}, + {RPCResult::Type::NUM, "ancestorfees", /*optional=*/true, "The total fees of in-mempool ancestors (including this one) with fee deltas used for mining priority in " + CURRENCY_ATOM + " (if transaction is in the mempool)"}, {RPCResult::Type::STR_HEX, "redeemScript", /*optional=*/true, "The redeem script if the output script is P2SH"}, {RPCResult::Type::STR, "witnessScript", /*optional=*/true, "witness script if the output script is P2WSH or P2SH-P2WSH"}, {RPCResult::Type::BOOL, "spendable", "Whether we have the private keys to spend this output"}, diff --git a/src/wallet/rpc/elements.cpp b/src/wallet/rpc/elements.cpp index 455c55979a..3ae240081a 100644 --- a/src/wallet/rpc/elements.cpp +++ b/src/wallet/rpc/elements.cpp @@ -1000,7 +1000,7 @@ RPCHelpMan createrawpegin() RPCResult{ RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR, "hex", "raw transaction data"}, + {RPCResult::Type::STR_HEX, "hex", "raw transaction data"}, {RPCResult::Type::BOOL, "mature", /*optional=*/true, "Whether the peg-in is mature (only included when validating peg-ins)"}, }, }, diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index b044140abb..393d04787e 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -1001,7 +1001,7 @@ RPCHelpMan signrawtransactionwithwallet() {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"}, {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"}, {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "The amount spent (required if non-confidential segwit output)"}, - {"amountcommitment", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The amount commitment spent (required if confidential segwit output)"}, + {"amountcommitment", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The amount commitment spent (required if confidential segwit output)"}, }, }, }, @@ -1917,7 +1917,7 @@ RPCHelpMan walletcreatefundedpsbt() FundTxDoc()), RPCArgOptions{.oneline_description="options"}}, {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"}, - {"psbt_version", RPCArg::Type::NUM, RPCArg::Default{2}, "The PSBT version number to use."}, + {"psbt_version", RPCArg::Type::NUM, RPCArg::Default{2}, "The PSBT version number to use. Must be 2."}, }, RPCResult{ RPCResult::Type::OBJ, "", "", diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index f4d140076c..14ee67f18e 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -52,16 +52,13 @@ static RPCHelpMan getwalletinfo() {RPCResult::Type::NUM, "walletversion", "the wallet version"}, {RPCResult::Type::STR, "format", "the database format (bdb or sqlite)"}, {RPCResult::Type::OBJ, "balance", "DEPRECATED. Identical to getbalances().mine.trusted", { - // A different entry for each asset in the wallet - {RPCResult::Type::STR_AMOUNT, "bitcoin", "amount of bitcoin in the wallet"}, + {RPCResult::Type::ELISION, "", "the amount for each asset"}, }, /*skip_type_check=*/true}, {RPCResult::Type::OBJ, "unconfirmed_balance", "DEPRECATED. Identical to getbalances().mine.untrusted_pending", { - // A different entry for each asset in the wallet - {RPCResult::Type::STR_AMOUNT, "bitcoin", "amount of bitcoin in the wallet"}, + {RPCResult::Type::ELISION, "", "the amount for each asset"}, }, /*skip_type_check=*/true}, {RPCResult::Type::OBJ, "immature_balance", "DEPRECATED. Identical to getbalances().mine.immature", { - // A different entry for each asset in the wallet - {RPCResult::Type::STR_AMOUNT, "bitcoin", "amount of bitcoin in the wallet"}, + {RPCResult::Type::ELISION, "", "the amount for each asset"}, }, /*skip_type_check=*/true}, {RPCResult::Type::NUM, "txcount", "the total number of transactions in the wallet"}, {RPCResult::Type::NUM_TIME, "keypoololdest", /*optional=*/true, "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool. Legacy wallets only."}, diff --git a/test/functional/feature_blocksign.py b/test/functional/feature_blocksign.py index 03069026a6..1dbd2939b4 100755 --- a/test/functional/feature_blocksign.py +++ b/test/functional/feature_blocksign.py @@ -180,6 +180,39 @@ def mine_blocks(self, num_blocks, transactions): for i in range(num_blocks): self.mine_block(transactions) + def test_combineblocksigs_witnessscript_arg(self): + # Regression test for combineblocksigs witnessScript optionality. + + node = self.nodes[0] + block = node.getnewblockhex() + + is_dyna = node.getdeploymentinfo()['deployments']['dynafed']['bip9']['status'] == "active" + + if is_dyna: + # no witnessScript must give RPC_INVALID_PARAMETER, not a help error from arg-count validation. + assert_raises_rpc_error( + -8, + "Signing dynamic blocks requires the witnessScript argument", + node.combineblocksigs, + block, + [], + ) + # Supplying witnessScript must work normally. + result = node.combineblocksigs(block, [], self.witnessScript) + assert "hex" in result + assert "complete" in result + else: + # Non-dynafed: 2-argument call must not be rejected by arg-count validation. + try: + result = node.combineblocksigs(block, []) + assert "hex" in result + assert "complete" in result + except Exception as e: + # If exception it must not be the help string + assert "combineblocksigs" not in str(e), \ + "Got help text — 2-arg call was rejected by arg-count validation" + raise + def run_test(self): # Have every node except last import its block signing private key. for i in range(self.num_keys): @@ -211,6 +244,10 @@ def run_test(self): assert_equal(info['deployments']['dynafed']['bip9']['status'], "defined") + # Test combineblocksigs witnessScript optionality pre-dynafed + self.log.info("Testing combineblocksigs witnessScript argument (pre-dynafed)") + self.test_combineblocksigs_witnessscript_arg() + # Next let's activate dynafed blocks_til_dynafed = 431 - self.nodes[0].getblockcount() self.log.info("Activating dynafed") @@ -221,6 +258,11 @@ def run_test(self): self.log.info("Mine some dynamic federation blocks without txns") self.mine_blocks(10, False) + + # Test combineblocksigs witnessScript optionality post-dynafed + self.log.info("Testing combineblocksigs witnessScript argument (post-dynafed)") + self.test_combineblocksigs_witnessscript_arg() + self.log.info("Mine some dynamic federation blocks with txns") self.mine_blocks(10, True)