aboutsummaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
authorPedro Branco <branco@uphold.com>2016-06-16 15:57:48 +0100
committerPedro Branco <branco@uphold.com>2016-10-19 15:17:13 +0100
commitcb08fdbf78685b55029768524ca867772711c32b (patch)
treec41c0169a7a428f93527eb715ec2ae9de2df7e70 /qa
parent97c7f7362f9b59247753d6e8fa8022a6205f9c09 (diff)
Add importmulti rpc call
Diffstat (limited to 'qa')
-rwxr-xr-xqa/pull-tester/rpc-tests.py1
-rwxr-xr-xqa/rpc-tests/importmulti.py293
2 files changed, 294 insertions, 0 deletions
diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py
index 7430bb2256..778f8d8a77 100755
--- a/qa/pull-tester/rpc-tests.py
+++ b/qa/pull-tester/rpc-tests.py
@@ -145,6 +145,7 @@ testScripts = [
'signmessages.py',
'p2p-compactblocks.py',
'nulldummy.py',
+ 'importmulti.py',
]
if ENABLE_ZMQ:
testScripts.append('zmq_test.py')
diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py
new file mode 100755
index 0000000000..960cb63d76
--- /dev/null
+++ b/qa/rpc-tests/importmulti.py
@@ -0,0 +1,293 @@
+#!/usr/bin/env python3
+# Copyright (c) 2014-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+class ImportMultiTest (BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = True
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(2, self.options.tmpdir)
+ self.is_network_split=False
+
+ def run_test (self):
+ print ("Mining blocks...")
+ self.nodes[0].generate(1)
+ self.nodes[1].generate(1)
+
+ # keyword definition
+ PRIV_KEY = 'privkey'
+ PUB_KEY = 'pubkey'
+ ADDRESS_KEY = 'address'
+ SCRIPT_KEY = 'script'
+
+
+ node0_address1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ node0_address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ node0_address3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+
+ #Check only one address
+ assert_equal(node0_address1['ismine'], True)
+
+ #Node 1 sync test
+ assert_equal(self.nodes[1].getblockcount(),1)
+
+ #Address Test - before import
+ address_info = self.nodes[1].validateaddress(node0_address1['address'])
+ assert_equal(address_info['iswatchonly'], False)
+ assert_equal(address_info['ismine'], False)
+
+
+ # RPC importmulti -----------------------------------------------
+
+ # Bitcoin Address
+ print("Should import an address")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": address['address']
+ }
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], True)
+ assert_equal(address_assert['ismine'], False)
+
+
+ # ScriptPubKey + internal
+ print("Should import a scriptPubKey with internal flag")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": address['scriptPubKey'],
+ "internal": True
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], True)
+ assert_equal(address_assert['ismine'], False)
+
+ # ScriptPubKey + !internal
+ print("Should not import a scriptPubKey without internal flag")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": address['scriptPubKey']
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -8)
+ assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
+
+ # Address + Public key + !Internal
+ print("Should import an address with public key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": address['address']
+ },
+ "pubkeys": [ address['pubkey'] ]
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], True)
+ assert_equal(address_assert['ismine'], False)
+
+
+ # ScriptPubKey + Public key + internal
+ print("Should import a scriptPubKey with internal and with public key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ request = [{
+ "scriptPubKey": address['scriptPubKey'],
+ "pubkeys": [ address['pubkey'] ],
+ "internal": True
+ }];
+ result = self.nodes[1].importmulti(request)
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], True)
+ assert_equal(address_assert['ismine'], False)
+
+ # ScriptPubKey + Public key + !internal
+ print("Should not import a scriptPubKey without internal and with public key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ request = [{
+ "scriptPubKey": address['scriptPubKey'],
+ "pubkeys": [ address['pubkey'] ]
+ }];
+ result = self.nodes[1].importmulti(request)
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -8)
+ assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
+ # Address + Private key + !watchonly
+ print("Should import an address with private key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": address['address']
+ },
+ "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], True)
+
+ # Address + Private key + watchonly
+ print("Should not import an address with private key and with watchonly")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": address['address']
+ },
+ "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
+ "watchonly": True
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -8)
+ assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
+ # ScriptPubKey + Private key + internal
+ print("Should import a scriptPubKey with internal and with private key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": address['scriptPubKey'],
+ "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
+ "internal": True
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], True)
+
+ # ScriptPubKey + Private key + !internal
+ print("Should not import a scriptPubKey without internal and with private key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": address['scriptPubKey'],
+ "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -8)
+ assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
+
+ # P2SH address
+ sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ 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']])
+ self.nodes[1].generate(100)
+ transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+ self.nodes[1].generate(1)
+ transaction = self.nodes[1].gettransaction(transactionid);
+
+ print("Should import a p2sh")
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": multi_sig_script['address']
+ }
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
+ assert_equal(address_assert['isscript'], True)
+ assert_equal(address_assert['iswatchonly'], True)
+ p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
+ assert_equal(p2shunspent['spendable'], False)
+ assert_equal(p2shunspent['solvable'], False)
+
+
+ # P2SH + Redeem script
+ sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ 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']])
+ self.nodes[1].generate(100)
+ transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+ self.nodes[1].generate(1)
+ transaction = self.nodes[1].gettransaction(transactionid);
+
+ print("Should import a p2sh with respective redeem script")
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": multi_sig_script['address']
+ },
+ "redeemscript": multi_sig_script['redeemScript']
+ }])
+ assert_equal(result[0]['success'], True)
+
+ p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
+ assert_equal(p2shunspent['spendable'], False)
+ assert_equal(p2shunspent['solvable'], True)
+
+
+ # P2SH + Redeem script + Private Keys + !Watchonly
+ sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ 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']])
+ self.nodes[1].generate(100)
+ transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+ self.nodes[1].generate(1)
+ transaction = self.nodes[1].gettransaction(transactionid);
+
+ print("Should import a p2sh with respective redeem script and private keys")
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": multi_sig_script['address']
+ },
+ "redeemscript": multi_sig_script['redeemScript'],
+ "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])]
+ }])
+ assert_equal(result[0]['success'], True)
+
+ p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
+ assert_equal(p2shunspent['spendable'], False)
+ assert_equal(p2shunspent['solvable'], True)
+
+ # P2SH + Redeem script + Private Keys + Watchonly
+ sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ 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']])
+ self.nodes[1].generate(100)
+ transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+ self.nodes[1].generate(1)
+ transaction = self.nodes[1].gettransaction(transactionid);
+
+ print("Should import a p2sh with respective redeem script and private keys")
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": multi_sig_script['address']
+ },
+ "redeemscript": multi_sig_script['redeemScript'],
+ "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])],
+ "watchonly": True
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -8)
+ assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
+
+ # TODO Consistency tests?
+
+
+
+if __name__ == '__main__':
+ ImportMultiTest ().main ()