Skip to content

Commit 7759aa2

Browse files
committed
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 <[email protected]> in bitcoin/bitcoin#9108 (comment)
1 parent 53c300f commit 7759aa2

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

qa/rpc-tests/importmulti.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ def run_test (self):
314314
self.nodes[1].generate(100)
315315
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
316316
self.nodes[1].generate(1)
317+
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
317318
transaction = self.nodes[1].gettransaction(transactionid)
318319

319320
print("Should import a p2sh with respective redeem script and private keys")
@@ -409,6 +410,24 @@ def run_test (self):
409410
assert_equal(address_assert['ismine'], False)
410411
assert_equal('timestamp' in address_assert, False)
411412

413+
414+
# Importing existing watch only address with new timestamp should replace saved timestamp.
415+
assert_greater_than(timestamp, watchonly_timestamp)
416+
print("Should replace previously saved watch only timestamp.")
417+
result = self.nodes[1].importmulti([{
418+
"scriptPubKey": {
419+
"address": watchonly_address,
420+
},
421+
"timestamp": "now",
422+
}])
423+
assert_equal(result[0]['success'], True)
424+
address_assert = self.nodes[1].validateaddress(watchonly_address)
425+
assert_equal(address_assert['iswatchonly'], True)
426+
assert_equal(address_assert['ismine'], False)
427+
assert_equal(address_assert['timestamp'], timestamp)
428+
watchonly_timestamp = timestamp
429+
430+
412431
# restart nodes to check for proper serialization/deserialization of watch only address
413432
stop_nodes(self.nodes)
414433
self.nodes = start_nodes(2, self.options.tmpdir)

src/wallet/rpcdump.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
745745

746746
pwallet->MarkDirty();
747747

748-
if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) {
748+
if (!pwallet->AddWatchOnly(redeemScript, timestamp)) {
749749
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
750750
}
751751

@@ -762,7 +762,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
762762

763763
pwallet->MarkDirty();
764764

765-
if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) {
765+
if (!pwallet->AddWatchOnly(redeemDestination, timestamp)) {
766766
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
767767
}
768768

@@ -855,7 +855,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
855855

856856
pwallet->MarkDirty();
857857

858-
if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) {
858+
if (!pwallet->AddWatchOnly(pubKeyScript, timestamp)) {
859859
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
860860
}
861861

@@ -873,7 +873,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
873873

874874
pwallet->MarkDirty();
875875

876-
if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) {
876+
if (!pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) {
877877
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
878878
}
879879

@@ -947,7 +947,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
947947

948948
pwallet->MarkDirty();
949949

950-
if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) {
950+
if (!pwallet->AddWatchOnly(script, timestamp)) {
951951
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
952952
}
953953

0 commit comments

Comments
 (0)