mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
dad8c67d38
64c0800
Use logging in individual tests (John Newbery)38ad281
Use logging in test_framework/comptool.py (John Newbery)ff19073
Use logging in test_framework/blockstore.py (John Newbery)2a9c7c7
Use logging in test_framework/util.py (John Newbery)b0dec4a
Remove manual debug settings in qa tests. (John Newbery)af1363c
Always enable debug log and microsecond logging for test nodes. (John Newbery)6d0e325
Use logging in mininode.py (John Newbery)553a976
Add logging to p2p-segwit.py (John Newbery)0e6d23d
Add logging to test_framework.py (John Newbery) Tree-SHA512: 42ee2acbf444ec32d796f930f9f6e272da03c75e93d974a126d4ea9b2dbaa77cc57ab5e63ce3fd33d609049d884eb8d9f65272c08922d10f8db69d4a60ad05a3
435 lines
20 KiB
Python
Executable File
435 lines
20 KiB
Python
Executable File
#!/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.
|
|
"""Test the importmulti RPC."""
|
|
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):
|
|
self.log.info("Mining blocks...")
|
|
self.nodes[0].generate(1)
|
|
self.nodes[1].generate(1)
|
|
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
|
|
|
|
# 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
|
|
self.log.info("Should import an address")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": address['address']
|
|
},
|
|
"timestamp": "now",
|
|
}])
|
|
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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
watchonly_address = address['address']
|
|
watchonly_timestamp = timestamp
|
|
|
|
self.log.info("Should not import an invalid address")
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": "not valid address",
|
|
},
|
|
"timestamp": "now",
|
|
}])
|
|
assert_equal(result[0]['success'], False)
|
|
assert_equal(result[0]['error']['code'], -5)
|
|
assert_equal(result[0]['error']['message'], 'Invalid address')
|
|
|
|
# ScriptPubKey + internal
|
|
self.log.info("Should import a scriptPubKey with internal flag")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
# ScriptPubKey + !internal
|
|
self.log.info("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'],
|
|
"timestamp": "now",
|
|
}])
|
|
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)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
|
|
# Address + Public key + !Internal
|
|
self.log.info("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']
|
|
},
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
|
|
# ScriptPubKey + Public key + internal
|
|
self.log.info("Should import a scriptPubKey with internal and with public key")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
request = [{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
# ScriptPubKey + Public key + !internal
|
|
self.log.info("Should not import a scriptPubKey without internal and with public key")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
request = [{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
# Address + Private key + !watchonly
|
|
self.log.info("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']
|
|
},
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
# Address + Private key + watchonly
|
|
self.log.info("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']
|
|
},
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
# ScriptPubKey + Private key + internal
|
|
self.log.info("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'],
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
# ScriptPubKey + Private key + !internal
|
|
self.log.info("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'],
|
|
"timestamp": "now",
|
|
"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)
|
|
assert_equal('timestamp' in address_assert, 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)
|
|
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
|
|
transaction = self.nodes[1].gettransaction(transactionid)
|
|
|
|
self.log.info("Should import a p2sh")
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": multi_sig_script['address']
|
|
},
|
|
"timestamp": "now",
|
|
}])
|
|
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)
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
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)
|
|
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
|
|
transaction = self.nodes[1].gettransaction(transactionid)
|
|
|
|
self.log.info("Should import a p2sh with respective redeem script")
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": multi_sig_script['address']
|
|
},
|
|
"timestamp": "now",
|
|
"redeemscript": multi_sig_script['redeemScript']
|
|
}])
|
|
assert_equal(result[0]['success'], True)
|
|
address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
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)
|
|
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
|
|
transaction = self.nodes[1].gettransaction(transactionid)
|
|
|
|
self.log.info("Should import a p2sh with respective redeem script and private keys")
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": multi_sig_script['address']
|
|
},
|
|
"timestamp": "now",
|
|
"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)
|
|
address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
|
|
assert_equal(address_assert['timestamp'], timestamp)
|
|
|
|
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)
|
|
|
|
self.log.info("Should import a p2sh with respective redeem script and private keys")
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": multi_sig_script['address']
|
|
},
|
|
"timestamp": "now",
|
|
"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')
|
|
|
|
|
|
# Address + Public key + !Internal + Wrong pubkey
|
|
self.log.info("Should not import an address with a wrong public key")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": address['address']
|
|
},
|
|
"timestamp": "now",
|
|
"pubkeys": [ address2['pubkey'] ]
|
|
}])
|
|
assert_equal(result[0]['success'], False)
|
|
assert_equal(result[0]['error']['code'], -5)
|
|
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
|
address_assert = self.nodes[1].validateaddress(address['address'])
|
|
assert_equal(address_assert['iswatchonly'], False)
|
|
assert_equal(address_assert['ismine'], False)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
|
|
# ScriptPubKey + Public key + internal + Wrong pubkey
|
|
self.log.info("Should not import a scriptPubKey with internal and with a wrong public key")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
request = [{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
"timestamp": "now",
|
|
"pubkeys": [ address2['pubkey'] ],
|
|
"internal": True
|
|
}]
|
|
result = self.nodes[1].importmulti(request)
|
|
assert_equal(result[0]['success'], False)
|
|
assert_equal(result[0]['error']['code'], -5)
|
|
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
|
address_assert = self.nodes[1].validateaddress(address['address'])
|
|
assert_equal(address_assert['iswatchonly'], False)
|
|
assert_equal(address_assert['ismine'], False)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
|
|
# Address + Private key + !watchonly + Wrong private key
|
|
self.log.info("Should not import an address with a wrong private key")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": {
|
|
"address": address['address']
|
|
},
|
|
"timestamp": "now",
|
|
"keys": [ self.nodes[0].dumpprivkey(address2['address']) ]
|
|
}])
|
|
assert_equal(result[0]['success'], False)
|
|
assert_equal(result[0]['error']['code'], -5)
|
|
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
|
address_assert = self.nodes[1].validateaddress(address['address'])
|
|
assert_equal(address_assert['iswatchonly'], False)
|
|
assert_equal(address_assert['ismine'], False)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
|
|
# ScriptPubKey + Private key + internal + Wrong private key
|
|
self.log.info("Should not import a scriptPubKey with internal and with a wrong private key")
|
|
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
|
result = self.nodes[1].importmulti([{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
"timestamp": "now",
|
|
"keys": [ self.nodes[0].dumpprivkey(address2['address']) ],
|
|
"internal": True
|
|
}])
|
|
assert_equal(result[0]['success'], False)
|
|
assert_equal(result[0]['error']['code'], -5)
|
|
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
|
address_assert = self.nodes[1].validateaddress(address['address'])
|
|
assert_equal(address_assert['iswatchonly'], False)
|
|
assert_equal(address_assert['ismine'], False)
|
|
assert_equal('timestamp' in address_assert, False)
|
|
|
|
# restart nodes to check for proper serialization/deserialization of watch only address
|
|
stop_nodes(self.nodes)
|
|
self.nodes = start_nodes(2, self.options.tmpdir)
|
|
address_assert = self.nodes[1].validateaddress(watchonly_address)
|
|
assert_equal(address_assert['iswatchonly'], True)
|
|
assert_equal(address_assert['ismine'], False)
|
|
assert_equal(address_assert['timestamp'], watchonly_timestamp);
|
|
|
|
# Bad or missing timestamps
|
|
self.log.info("Should throw on invalid or missing timestamp values")
|
|
assert_raises_message(JSONRPCException, 'Missing required timestamp field for key',
|
|
self.nodes[1].importmulti, [{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
}])
|
|
assert_raises_message(JSONRPCException, 'Expected number or "now" timestamp value for key. got type string',
|
|
self.nodes[1].importmulti, [{
|
|
"scriptPubKey": address['scriptPubKey'],
|
|
"timestamp": "",
|
|
}])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
ImportMultiTest ().main ()
|