aboutsummaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2016-11-08 16:55:02 -0500
committerRussell Yanofsky <russ@yanofsky.org>2017-02-10 16:11:19 -0500
commita80f98b1c7a49432dc53d18d0fb51ac334de96be (patch)
treeee85a02c68e6157baabd8d7c06b0af3e96b04ec9 /qa
parenta58370e6a2d4dce50eefbcab5bde9f14facef8fc (diff)
downloadbitcoin-a80f98b1c7a49432dc53d18d0fb51ac334de96be.tar.xz
Use importmulti timestamp when importing watch only keys
When importing a watch-only address over importmulti with a specific timestamp, the wallet's nTimeFirstKey is currently set to 1. After this change, the provided timestamp will be used and stored as metadata associated with watch-only key. This can improve wallet performance because it can avoid the need to scan the entire blockchain for watch only addresses when timestamps are provided. Also adds timestamp to validateaddress return value (needed for tests). Fixes #9034.
Diffstat (limited to 'qa')
-rwxr-xr-xqa/rpc-tests/importmulti.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py
index 52e40d6c1c..02a932e737 100755
--- a/qa/rpc-tests/importmulti.py
+++ b/qa/rpc-tests/importmulti.py
@@ -20,6 +20,7 @@ class ImportMultiTest (BitcoinTestFramework):
print ("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'
@@ -59,6 +60,9 @@ class ImportMultiTest (BitcoinTestFramework):
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
# ScriptPubKey + internal
@@ -73,6 +77,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
print("Should not import a scriptPubKey without internal flag")
@@ -87,6 +92,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
@@ -103,6 +109,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
@@ -119,6 +126,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
print("Should not import a scriptPubKey without internal and with public key")
@@ -135,11 +143,11 @@ class ImportMultiTest (BitcoinTestFramework):
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
print("Should import an address with private key")
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
- timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": address['address']
@@ -170,6 +178,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
print("Should import a scriptPubKey with internal and with private key")
@@ -184,6 +193,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
print("Should not import a scriptPubKey without internal and with private key")
@@ -199,6 +209,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
@@ -209,6 +220,7 @@ class ImportMultiTest (BitcoinTestFramework):
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)
print("Should import a p2sh")
@@ -222,6 +234,7 @@ class ImportMultiTest (BitcoinTestFramework):
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)
@@ -235,6 +248,7 @@ class ImportMultiTest (BitcoinTestFramework):
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)
print("Should import a p2sh with respective redeem script")
@@ -246,6 +260,8 @@ class ImportMultiTest (BitcoinTestFramework):
"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)
@@ -260,6 +276,7 @@ class ImportMultiTest (BitcoinTestFramework):
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)
print("Should import a p2sh with respective redeem script and private keys")
@@ -272,6 +289,8 @@ class ImportMultiTest (BitcoinTestFramework):
"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)
@@ -319,6 +338,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
@@ -338,6 +358,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
@@ -357,6 +378,7 @@ class ImportMultiTest (BitcoinTestFramework):
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
@@ -375,6 +397,15 @@ class ImportMultiTest (BitcoinTestFramework):
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
print("Should throw on invalid or missing timestamp values")