Browse Source

Save watch only key timestamps when reimporting keys

Previously if an existing watch only key was reimported with a new timestamp,
the new timestamp would not be saved in the key metadata, and would not be used
to update the wallet nTimeFirstKey value (which could cause rescanning to start
at the wrong point and miss transactions).

Issue was pointed out by Jonas Schnelli <dev@jonasschnelli.ch> in
https://github.com/bitcoin/bitcoin/pull/9108#issuecomment-279715550
0.15
Russell Yanofsky 8 years ago
parent
commit
7759aa23d1
  1. 19
      qa/rpc-tests/importmulti.py
  2. 10
      src/wallet/rpcdump.cpp

19
qa/rpc-tests/importmulti.py

@ -314,6 +314,7 @@ class ImportMultiTest (BitcoinTestFramework):
self.nodes[1].generate(100) self.nodes[1].generate(100)
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
self.nodes[1].generate(1) self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
transaction = self.nodes[1].gettransaction(transactionid) transaction = self.nodes[1].gettransaction(transactionid)
print("Should import a p2sh with respective redeem script and private keys") print("Should import a p2sh with respective redeem script and private keys")
@ -409,6 +410,24 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(address_assert['ismine'], False) assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False) assert_equal('timestamp' in address_assert, False)
# Importing existing watch only address with new timestamp should replace saved timestamp.
assert_greater_than(timestamp, watchonly_timestamp)
print("Should replace previously saved watch only timestamp.")
result = self.nodes[1].importmulti([{
"scriptPubKey": {
"address": watchonly_address,
},
"timestamp": "now",
}])
assert_equal(result[0]['success'], True)
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'], timestamp)
watchonly_timestamp = timestamp
# restart nodes to check for proper serialization/deserialization of watch only address # restart nodes to check for proper serialization/deserialization of watch only address
stop_nodes(self.nodes) stop_nodes(self.nodes)
self.nodes = start_nodes(2, self.options.tmpdir) self.nodes = start_nodes(2, self.options.tmpdir)

10
src/wallet/rpcdump.cpp

@ -745,7 +745,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty(); pwallet->MarkDirty();
if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) { if (!pwallet->AddWatchOnly(redeemScript, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
@ -762,7 +762,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty(); pwallet->MarkDirty();
if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) { if (!pwallet->AddWatchOnly(redeemDestination, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
@ -855,7 +855,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty(); pwallet->MarkDirty();
if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) { if (!pwallet->AddWatchOnly(pubKeyScript, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
@ -873,7 +873,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty(); pwallet->MarkDirty();
if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) { if (!pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
@ -947,7 +947,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty(); pwallet->MarkDirty();
if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) { if (!pwallet->AddWatchOnly(script, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }

Loading…
Cancel
Save