diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -3,4 +3,4 @@ This release includes the following features and fixes: - + - Using addresses in createmultisig is now deprectated. Use -deprecatedrpc=createmultisig to get the old behavior. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -136,6 +136,7 @@ random.cpp rcu.cpp rpc/protocol.cpp + rpc/util.cpp support/cleanse.cpp support/lockedpool.cpp sync.cpp diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,6 +179,7 @@ rpc/server.h \ rpc/tojson.h \ rpc/register.h \ + rpc/util.h \ rwcollection.h \ scheduler.h \ script/scriptcache.h \ @@ -443,6 +444,7 @@ random.cpp \ rcu.cpp \ rpc/protocol.cpp \ + rpc/util.cpp \ support/cleanse.cpp \ sync.cpp \ threadinterrupt.cpp \ diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -290,88 +291,8 @@ // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around class CWallet; -/** - * Used by addmultisigaddress / createmultisig: - */ -CScript createmultisig_redeemScript(CWallet *const pwallet, - const UniValue ¶ms) { - int nRequired = params[0].get_int(); - const UniValue &keys = params[1].get_array(); - - // Gather public keys - if (nRequired < 1) { - throw std::runtime_error( - "a multisignature address must require at least one key to redeem"); - } - if ((int)keys.size() < nRequired) { - throw std::runtime_error( - strprintf("not enough keys supplied " - "(got %u keys, but need at least %d to redeem)", - keys.size(), nRequired)); - } - if (keys.size() > 16) { - throw std::runtime_error( - "Number of addresses involved in the " - "multisignature address creation > 16\nReduce the " - "number"); - } - std::vector pubkeys; - pubkeys.resize(keys.size()); - for (size_t i = 0; i < keys.size(); i++) { - const std::string &ks = keys[i].get_str(); -#ifdef ENABLE_WALLET - // Case 1: Bitcoin address and we have full public key: - if (pwallet) { - CTxDestination dest = DecodeDestination(ks, pwallet->chainParams); - if (IsValidDestination(dest)) { - const CKeyID *keyID = boost::get(&dest); - if (!keyID) { - throw std::runtime_error( - strprintf("%s does not refer to a key", ks)); - } - CPubKey vchPubKey; - if (!pwallet->GetPubKey(*keyID, vchPubKey)) { - throw std::runtime_error( - strprintf("no full public key for address %s", ks)); - } - if (!vchPubKey.IsFullyValid()) { - throw std::runtime_error(" Invalid public key: " + ks); - } - pubkeys[i] = vchPubKey; - continue; - } - } -#endif - // Case 2: hex public key - if (IsHex(ks)) { - CPubKey vchPubKey(ParseHex(ks)); - if (!vchPubKey.IsFullyValid()) { - throw std::runtime_error(" Invalid public key: " + ks); - } - pubkeys[i] = vchPubKey; - } else { - throw std::runtime_error(" Invalid public key: " + ks); - } - } - - CScript result = GetScriptForMultisig(nRequired, pubkeys); - if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) { - throw std::runtime_error( - strprintf("redeemScript exceeds size limit: %d > %d", result.size(), - MAX_SCRIPT_ELEMENT_SIZE)); - } - - return result; -} - static UniValue createmultisig(const Config &config, const JSONRPCRequest &request) { -#ifdef ENABLE_WALLET - CWallet *const pwallet = GetWalletForJSONRPCRequest(request); -#else - CWallet *const pwallet = nullptr; -#endif - if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) { std::string msg = @@ -379,15 +300,19 @@ "\nCreates a multi-signature address with n signature of m keys " "required.\n" "It returns a json object with the address and redeemScript.\n" - + "DEPRECATION WARNING: Using addresses with createmultisig is " + "deprecated. Clients must\n" + "transition to using addmultisigaddress to create multisig " + "addresses with addresses known\n" + "to the wallet before upgrading to v0.20. To use the deprecated " + "functionality, start bitcoind with -deprecatedrpc=createmultisig\n" "\nArguments:\n" "1. nrequired (numeric, required) The number of required " "signatures out of the n keys or addresses.\n" - "2. \"keys\" (string, required) A json array of keys which " - "are bitcoin addresses or hex-encoded public keys\n" + "2. \"keys\" (string, required) A json array of hex-encoded " + "public keys\n" " [\n" - " \"key\" (string) bitcoin address or hex-encoded public " - "key\n" + " \"key\" (string) The hex-encoded public key\n" " ,...\n" " ]\n" @@ -400,21 +325,59 @@ "}\n" "\nExamples:\n" - "\nCreate a multisig address from 2 addresses\n" + + "\nCreate a multisig address from 2 public keys\n" + HelpExampleCli("createmultisig", "2 " - "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," - "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + "\"[" + "\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd3" + "42cf11ae157a7ace5fd\\\"," + "\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e1" + "7e107ef3f6aa5a61626\\\"]\"") + "\nAs a json rpc call\n" + HelpExampleRpc("createmultisig", "2, " - "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," - "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\""); + "\"[" + "\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd3" + "42cf11ae157a7ace5fd\\\"," + "\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e1" + "7e107ef3f6aa5a61626\\\"]\""); throw std::runtime_error(msg); } + int required = request.params[0].get_int(); + + // Get the public keys + const UniValue &keys = request.params[1].get_array(); + std::vector pubkeys; + for (size_t i = 0; i < keys.size(); ++i) { + if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || + keys[i].get_str().length() == 130)) { + pubkeys.push_back(HexToPubKey(keys[i].get_str())); + } else { +#ifdef ENABLE_WALLET + CWallet *const pwallet = GetWalletForJSONRPCRequest(request); + if (IsDeprecatedRPCEnabled(gArgs, "createmultisig") && + EnsureWalletIsAvailable(pwallet, false)) { + pubkeys.push_back(AddrToPubKey(config.GetChainParams(), pwallet, + keys[i].get_str())); + } else +#endif + throw JSONRPCError( + RPC_INVALID_ADDRESS_OR_KEY, + strprintf("Invalid public key: %s\nNote that from v0.19.6, " + "createmultisig no longer accepts addresses." + " Clients must transition to using " + "addmultisigaddress to create multisig addresses " + "with addresses known to the wallet before " + "upgrading to v0.20." + " To use the deprecated functionality, start " + "bitcoind with -deprecatedrpc=createmultisig", + keys[i].get_str())); + } + } + // Construct using pay-to-script-hash: - CScript inner = createmultisig_redeemScript(pwallet, request.params); + CScript inner = CreateMultisigRedeemscript(required, pubkeys); CScriptID innerID(inner); UniValue result(UniValue::VOBJ); diff --git a/src/rpc/util.h b/src/rpc/util.h new file mode 100644 --- /dev/null +++ b/src/rpc/util.h @@ -0,0 +1,22 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPC_UTIL_H +#define BITCOIN_RPC_UTIL_H + +#include +#include + +class CChainParams; +class CKeyStore; +class CPubKey; +class CScript; + +CPubKey HexToPubKey(const std::string &hex_in); +CPubKey AddrToPubKey(const CChainParams &chainparams, CKeyStore *const keystore, + const std::string &addr_in); +CScript CreateMultisigRedeemscript(const int required, + const std::vector &pubkeys); + +#endif // BITCOIN_RPC_UTIL_H diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp new file mode 100644 --- /dev/null +++ b/src/rpc/util.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include +#include +#include +#include + +// Converts a hex string to a public key if possible +CPubKey HexToPubKey(const std::string &hex_in) { + if (!IsHex(hex_in)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "Invalid public key: " + hex_in); + } + CPubKey vchPubKey(ParseHex(hex_in)); + if (!vchPubKey.IsFullyValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "Invalid public key: " + hex_in); + } + return vchPubKey; +} + +// Retrieves a public key for an address from the given CKeyStore +CPubKey AddrToPubKey(const CChainParams &chainparams, CKeyStore *const keystore, + const std::string &addr_in) { + CTxDestination dest = DecodeDestination(addr_in, chainparams); + if (!IsValidDestination(dest)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + "Invalid address: " + addr_in); + } + CKeyID key = boost::get(dest); + if (key.IsNull()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, + strprintf("%s does not refer to a key", addr_in)); + } + CPubKey vchPubKey; + if (!keystore->GetPubKey(key, vchPubKey)) { + throw JSONRPCError( + RPC_INVALID_ADDRESS_OR_KEY, + strprintf("no full public key for address %s", addr_in)); + } + if (!vchPubKey.IsFullyValid()) { + throw JSONRPCError(RPC_INTERNAL_ERROR, + "Wallet contains an invalid public key"); + } + return vchPubKey; +} + +// Creates a multisig redeemscript from a given list of public keys and number +// required. +CScript CreateMultisigRedeemscript(const int required, + const std::vector &pubkeys) { + // Gather public keys + if (required < 1) { + throw JSONRPCError( + RPC_INVALID_PARAMETER, + "a multisignature address must require at least one key to redeem"); + } + if ((int)pubkeys.size() < required) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("not enough keys supplied (got %u keys, " + "but need at least %d to redeem)", + pubkeys.size(), required)); + } + if (pubkeys.size() > 16) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + "Number of keys involved in the multisignature " + "address creation > 16\nReduce the number"); + } + + CScript result = GetScriptForMultisig(required, pubkeys); + + if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) { + throw JSONRPCError( + RPC_INVALID_PARAMETER, + (strprintf("redeemScript exceeds size limit: %d > %d", + result.size(), MAX_SCRIPT_ELEMENT_SIZE))); + } + + return result; +} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -1339,8 +1340,8 @@ return tx->GetId().GetHex(); } -static UniValue addmultisigaddress(const Config &config, - const JSONRPCRequest &request) { +UniValue addmultisigaddress(const Config &config, + const JSONRPCRequest &request) { CWallet *const pwallet = GetWalletForJSONRPCRequest(request); if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; @@ -1370,8 +1371,18 @@ "assign the addresses to.\n" "\nResult:\n" - "\"address\" (string) A bitcoin address associated with " - "the keys.\n" + "{\n" + " \"address\":\"multisigaddress\", (string) The value of the " + "new multisig address.\n" + " \"redeemScript\":\"script\" (string) The string value " + "of the hex-encoded redemption script.\n" + "}\n" + "\nResult (DEPRECATED. To see this result in v0.19.6 instead, " + "please start bitcoind with -deprecatedrpc=addmultisigaddress).\n" + " clients should transition to the new output api before " + "upgrading to v0.20.\n" + "\"address\" (string) A bitcoin address " + "associated with the keys.\n" "\nExamples:\n" "\nAdd a multisig address from 2 addresses\n" + @@ -1394,13 +1405,38 @@ label = LabelFromValue(request.params[2]); } + int required = request.params[0].get_int(); + + // Get the public keys + const UniValue &keys_or_addrs = request.params[1].get_array(); + std::vector pubkeys; + for (size_t i = 0; i < keys_or_addrs.size(); ++i) { + if (IsHex(keys_or_addrs[i].get_str()) && + (keys_or_addrs[i].get_str().length() == 66 || + keys_or_addrs[i].get_str().length() == 130)) { + pubkeys.push_back(HexToPubKey(keys_or_addrs[i].get_str())); + } else { + pubkeys.push_back(AddrToPubKey(config.GetChainParams(), pwallet, + keys_or_addrs[i].get_str())); + } + } + // Construct using pay-to-script-hash: - CScript inner = createmultisig_redeemScript(pwallet, request.params); + CScript inner = CreateMultisigRedeemscript(required, pubkeys); CScriptID innerID(inner); pwallet->AddCScript(inner); pwallet->SetAddressBook(innerID, label, "send"); - return EncodeDestination(innerID); + + // Return old style interface + if (IsDeprecatedRPCEnabled(gArgs, "addmultisigaddress")) { + return EncodeDestination(innerID); + } + + UniValue result(UniValue::VOBJ); + result.pushKV("address", EncodeDestination(innerID)); + result.pushKV("redeemScript", HexStr(inner.begin(), inner.end())); + return result; } struct tallyitem { diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py --- a/test/functional/feature_nulldummy.py +++ b/test/functional/feature_nulldummy.py @@ -49,7 +49,8 @@ def run_test(self): self.address = self.nodes[0].getnewaddress() - self.ms_address = self.nodes[0].addmultisigaddress(1, [self.address]) + self.ms_address = self.nodes[0].addmultisigaddress(1, [self.address])[ + 'address'] network_thread_start() # Block 2 diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py new file mode 100755 --- /dev/null +++ b/test/functional/rpc_deprecated.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test deprecation of RPC calls.""" +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_raises_rpc_error + + +class DeprecatedRpcTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 2 + self.setup_clean_chain = True + self.extra_args = [ + [], ["-deprecatedrpc=createmultisig"]] + + def run_test(self): + self.log.info( + "Make sure that -deprecatedrpc=createmultisig allows it to take addresses") + assert_raises_rpc_error(-5, "Invalid public key", + self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) + self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + + +if __name__ == '__main__': + DeprecatedRpcTest().main() diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -390,7 +390,7 @@ addr2Obj = self.nodes[1].validateaddress(addr2) mSigObj = self.nodes[1].addmultisigaddress( - 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] inputs = [] outputs = {mSigObj: 1.1} @@ -423,7 +423,7 @@ addr5Obj = self.nodes[1].validateaddress(addr5) mSigObj = self.nodes[1].addmultisigaddress( - 4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']]) + 4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])['address'] inputs = [] outputs = {mSigObj: 1.1} @@ -450,7 +450,7 @@ addr2Obj = self.nodes[2].validateaddress(addr2) mSigObj = self.nodes[2].addmultisigaddress( - 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] # send 1.2 BTC to msig addr txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) diff --git a/test/functional/rpc_listtransactions.py b/test/functional/rpc_listtransactions.py --- a/test/functional/rpc_listtransactions.py +++ b/test/functional/rpc_listtransactions.py @@ -78,8 +78,9 @@ {"category": "receive", "amount": Decimal("0.44")}, {"txid": txid, "account": "toself"}) - multisig = self.nodes[1].createmultisig( - 1, [self.nodes[1].getnewaddress()]) + pubkey = self.nodes[1].validateaddress( + self.nodes[1].getnewaddress())['pubkey'] + multisig = self.nodes[1].createmultisig(1, [pubkey]) self.nodes[0].importaddress( multisig["redeemScript"], "watchonly", False, True) txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1) diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -108,8 +108,18 @@ addr1Obj = self.nodes[2].validateaddress(addr1) addr2Obj = self.nodes[2].validateaddress(addr2) - mSigObj = self.nodes[2].addmultisigaddress( + # Tests for createmultisig and addmultisigaddress + assert_raises_rpc_error(-5, "Invalid public key", + self.nodes[0].createmultisig, 1, ["01020304"]) + # createmultisig can only take public keys + self.nodes[0].createmultisig( 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here. + assert_raises_rpc_error(-5, "Invalid public key", + self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) + + mSigObj = self.nodes[2].addmultisigaddress( + 2, [addr1Obj['pubkey'], addr1])['address'] # use balance deltas instead of absolute values bal = self.nodes[2].getbalance() @@ -134,7 +144,7 @@ addr3Obj = self.nodes[2].validateaddress(addr3) mSigObj = self.nodes[2].addmultisigaddress( - 2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) + 2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address'] txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) decTx = self.nodes[0].gettransaction(txId) @@ -195,9 +205,9 @@ addr2Obj = self.nodes[2].validateaddress(addr2) self.nodes[1].addmultisigaddress( - 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] mSigObj = self.nodes[2].addmultisigaddress( - 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] mSigObjValid = self.nodes[2].validateaddress(mSigObj) txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) diff --git a/test/functional/timing.json b/test/functional/timing.json --- a/test/functional/timing.json +++ b/test/functional/timing.json @@ -1,155 +1,159 @@ [ { "name": "abc-cmdline.py", - "time": 10 + "time": 4 }, { "name": "abc-finalize-block.py", - "time": 8 + "time": 31 }, { "name": "abc-high_priority_transaction.py", - "time": 13 + "time": 7 + }, + { + "name": "abc-invalid-chains.py", + "time": 2 }, { "name": "abc-invalid-message.py", - "time": 15 + "time": 1 }, { "name": "abc-magnetic-anomaly-mining.py", - "time": 49 + "time": 29 }, { "name": "abc-mempool-accept-txn.py", - "time": 15 + "time": 1 }, { "name": "abc-mempool-coherence-on-activations.py", - "time": 11 + "time": 2 }, { "name": "abc-p2p-compactblocks.py", - "time": 361 + "time": 474 }, { "name": "abc-p2p-fullblocktest.py", - "time": 54 + "time": 79 }, { "name": "abc-parkedchain.py", - "time": 14 + "time": 9 }, { "name": "abc-replay-protection.py", - "time": 13 + "time": 3 }, { "name": "abc-rpc.py", - "time": 19 + "time": 1 }, { "name": "abc-schnorr-activation.py", - "time": 6 + "time": 18 }, { "name": "abc-segwit-recovery-activation.py", - "time": 5 + "time": 3 }, { "name": "abc-sync-chain.py", - "time": 4 + "time": 1 }, { "name": "abc-transaction-ordering.py", - "time": 6 + "time": 17 }, { "name": "example_test.py", - "time": 18 + "time": 3 }, { "name": "feature_assumevalid.py", - "time": 14 + "time": 10 }, { "name": "feature_bip68_sequence.py", - "time": 74 + "time": 29 }, { "name": "feature_block.py", - "time": 132 + "time": 131 }, { "name": "feature_cltv.py", - "time": 5 + "time": 3 }, { "name": "feature_config_args.py", - "time": 21 + "time": 7 }, { "name": "feature_csv_activation.py", - "time": 16 + "time": 26 }, { "name": "feature_dbcrash.py", - "time": 1119 + "time": 1398 }, { "name": "feature_dersig.py", - "time": 12 + "time": 3 }, { "name": "feature_logging.py", - "time": 36 + "time": 17 }, { "name": "feature_maxuploadtarget.py", - "time": 34 + "time": 41 }, { "name": "feature_minchainwork.py", - "time": 10 + "time": 4 }, { "name": "feature_notifications.py", - "time": 6 + "time": 5 }, { "name": "feature_nulldummy.py", - "time": 4 + "time": 3 }, { "name": "feature_proxy.py", - "time": 16 + "time": 3 }, { "name": "feature_pruning.py", - "time": 1256 + "time": 1436 }, { "name": "feature_reindex.py", - "time": 16 + "time": 4 }, { "name": "feature_uacomment.py", - "time": 6 + "time": 16 }, { "name": "interface_bitcoin_cli.py", - "time": 5 + "time": 3 }, { "name": "interface_http.py", - "time": 4 + "time": 2 }, { "name": "interface_rest.py", - "time": 8 + "time": 4 }, { "name": "interface_zmq.py", - "time": 6 + "time": 5 }, { "name": "mempool_limit.py", @@ -157,11 +161,11 @@ }, { "name": "mempool_packages.py", - "time": 63 + "time": 44 }, { "name": "mempool_persist.py", - "time": 20 + "time": 24 }, { "name": "mempool_reorg.py", @@ -169,83 +173,87 @@ }, { "name": "mempool_resurrect.py", - "time": 4 + "time": 2 }, { "name": "mempool_spend_coinbase.py", - "time": 3 + "time": 2 }, { "name": "mining_basic.py", - "time": 4 + "time": 2 }, { "name": "mining_getblocktemplate_longpoll.py", - "time": 70 + "time": 66 }, { "name": "mining_prioritisetransaction.py", - "time": 22 + "time": 6 }, { "name": "p2p_compactblocks.py", - "time": 46 + "time": 25 }, { "name": "p2p_disconnect_ban.py", - "time": 20 + "time": 16 }, { "name": "p2p_feefilter.py", - "time": 27 + "time": 57 }, { "name": "p2p_fingerprint.py", - "time": 16 + "time": 13 }, { "name": "p2p_invalid_block.py", - "time": 6 + "time": 2 }, { "name": "p2p_invalid_tx.py", - "time": 5 + "time": 2 }, { "name": "p2p_leak.py", - "time": 16 + "time": 6 }, { "name": "p2p_mempool.py", - "time": 3 + "time": 1 }, { "name": "p2p_node_network_limited.py", - "time": 24 + "time": 9 }, { "name": "p2p_sendheaders.py", - "time": 16 + "time": 37 }, { "name": "p2p_timeouts.py", - "time": 67 + "time": 62 }, { "name": "p2p_unrequested_blocks.py", - "time": 6 + "time": 3 }, { "name": "rpc_bind.py", - "time": 34 + "time": 7 }, { "name": "rpc_blockchain.py", - "time": 34 + "time": 20 }, { "name": "rpc_decodescript.py", - "time": 3 + "time": 1 + }, + { + "name": "rpc_deprecated.py", + "time": 2 }, { "name": "rpc_estimatefee.py", @@ -253,15 +261,15 @@ }, { "name": "rpc_fundrawtransaction.py", - "time": 49 + "time": 41 }, { "name": "rpc_getchaintips.py", - "time": 6 + "time": 3 }, { "name": "rpc_invalidateblock.py", - "time": 9 + "time": 6 }, { "name": "rpc_listtransactions.py", @@ -269,23 +277,23 @@ }, { "name": "rpc_named_arguments.py", - "time": 3 + "time": 2 }, { "name": "rpc_net.py", - "time": 14 + "time": 1 }, { "name": "rpc_preciousblock.py", - "time": 4 + "time": 2 }, { "name": "rpc_rawtransaction.py", - "time": 25 + "time": 16 }, { "name": "rpc_signmessage.py", - "time": 4 + "time": 1 }, { "name": "rpc_signrawtransaction.py", @@ -293,106 +301,106 @@ }, { "name": "rpc_txoutproof.py", - "time": 5 + "time": 2 }, { "name": "rpc_uptime.py", - "time": 17 + "time": 2 }, { "name": "rpc_users.py", - "time": 20 + "time": 3 }, { "name": "wallet_abandonconflict.py", - "time": 15 + "time": 8 }, { "name": "wallet_accounts.py", - "time": 11 + "time": 33 }, { "name": "wallet_backup.py", - "time": 92 + "time": 105 }, { "name": "wallet_basic.py", - "time": 46 + "time": 31 }, { "name": "wallet_disable.py", - "time": 9 + "time": 1 }, { "name": "wallet_dump.py", - "time": 43 + "time": 13 }, { "name": "wallet_encryption.py", - "time": 9 + "time": 4 }, { "name": "wallet_hd.py", - "time": 87 + "time": 71 }, { "name": "wallet_import_rescan.py", - "time": 30 + "time": 15 }, { "name": "wallet_importmulti.py", - "time": 26 + "time": 21 }, { "name": "wallet_importprunedfunds.py", - "time": 5 + "time": 2 }, { "name": "wallet_keypool.py", - "time": 22 + "time": 6 }, { "name": "wallet_keypool_topup.py", - "time": 19 + "time": 39 }, { "name": "wallet_listreceivedby.py", - "time": 12 + "time": 35 }, { "name": "wallet_listsinceblock.py", - "time": 5 + "time": 19 }, { "name": "wallet_multiwallet.py", - "time": 39 + "time": 24 }, { "name": "wallet_multiwallet.py --usecli", - "time": 38 + "time": 8 }, { "name": "wallet_resendwallettransactions.py", - "time": 5 + "time": 2 }, { "name": "wallet_txn_clone.py", - "time": 7 + "time": 4 }, { "name": "wallet_txn_clone.py --mineblock", - "time": 6 + "time": 4 }, { "name": "wallet_txn_doublespend.py", - "time": 8 + "time": 17 }, { "name": "wallet_txn_doublespend.py --mineblock", - "time": 19 + "time": 4 }, { "name": "wallet_zapwallettxes.py", - "time": 35 + "time": 4 } -] +] \ No newline at end of file diff --git a/test/functional/wallet_accounts.py b/test/functional/wallet_accounts.py --- a/test/functional/wallet_accounts.py +++ b/test/functional/wallet_accounts.py @@ -124,7 +124,7 @@ for x in range(10): addresses.append(node.getnewaddress()) multisig_address = node.addmultisigaddress( - 5, addresses, label.name) + 5, addresses, label.name)['address'] label.add_address(multisig_address) label.verify(node) node.sendfrom("", multisig_address, 50) diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -95,7 +95,7 @@ # Test scripts dump by adding a 1-of-1 multisig address multisig_addr = self.nodes[0].addmultisigaddress( - 1, [addrs[0]["address"]]) + 1, [addrs[0]["address"]])["address"] # dump unencrypted wallet result = self.nodes[0].dumpwallet( diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py --- a/test/functional/wallet_importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -245,7 +245,7 @@ sig_address_3 = self.nodes[0].validateaddress( self.nodes[0].getnewaddress()) multi_sig_script = self.nodes[0].createmultisig( - 2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + 2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress( multi_sig_script['address'], 10.00) @@ -279,7 +279,7 @@ sig_address_3 = self.nodes[0].validateaddress( self.nodes[0].getnewaddress()) multi_sig_script = self.nodes[0].createmultisig( - 2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + 2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress( multi_sig_script['address'], 10.00) @@ -313,7 +313,7 @@ sig_address_3 = self.nodes[0].validateaddress( self.nodes[0].getnewaddress()) multi_sig_script = self.nodes[0].createmultisig( - 2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + 2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress( multi_sig_script['address'], 10.00) @@ -349,7 +349,7 @@ sig_address_3 = self.nodes[0].validateaddress( self.nodes[0].getnewaddress()) multi_sig_script = self.nodes[0].createmultisig( - 2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + 2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress( multi_sig_script['address'], 10.00)