Skip to content

Commit e662af3

Browse files
committed
Use 2 hour grace period for key timestamps in importmulti rescans
Gregory Maxwell <[email protected]> pointed out the lack of grace period in bitcoin/bitcoin#9490 (comment). The importwallet RPC which uses key timestamps in a similar way already has a 2 hour grace period.
1 parent 38d3e9e commit e662af3

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

qa/rpc-tests/import-rescan.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def do_import(self, timestamp):
5454
"scriptPubKey": {
5555
"address": self.address["address"]
5656
},
57-
"timestamp": timestamp + (1 if self.rescan == Rescan.late_timestamp else 0),
57+
"timestamp": timestamp + RESCAN_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0),
5858
"pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [],
5959
"keys": [self.key] if self.data == Data.priv else [],
6060
"label": self.label,
@@ -99,6 +99,9 @@ def check(self, txid=None, amount=None, confirmations=None):
9999
ImportNode = collections.namedtuple("ImportNode", "prune rescan")
100100
IMPORT_NODES = [ImportNode(*fields) for fields in itertools.product((False, True), repeat=2)]
101101

102+
# Rescans start at the earliest block up to 2 hours before the key timestamp.
103+
RESCAN_WINDOW = 2 * 60 * 60
104+
102105

103106
class ImportRescanTest(BitcoinTestFramework):
104107
def __init__(self):
@@ -130,7 +133,7 @@ def run_test(self):
130133
self.nodes[0].generate(1)
131134
assert_equal(self.nodes[0].getrawmempool(), [])
132135
timestamp = self.nodes[0].getblockheader(self.nodes[0].getbestblockhash())["time"]
133-
set_node_times(self.nodes, timestamp + 1)
136+
set_node_times(self.nodes, timestamp + RESCAN_WINDOW + 1)
134137
self.nodes[0].generate(1)
135138
sync_blocks(self.nodes)
136139

src/wallet/rpcdump.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
988988
" or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n"
989989
" key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n"
990990
" \"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n"
991-
" 0 can be specified to scan the entire blockchain.\n"
991+
" 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n"
992+
" creation time of all keys being imported by the importmulti call will be scanned.\n"
992993
" \"redeemscript\": \"<script>\" , (string, optional) Allowed only if the scriptPubKey is a P2SH address or a P2SH scriptPubKey\n"
993994
" \"pubkeys\": [\"<pubKey>\", ... ] , (array, optional) Array of strings giving pubkeys that must occur in the output or redeemscript\n"
994995
" \"keys\": [\"<key>\", ... ] , (array, optional) Array of strings giving private keys whose corresponding public keys must occur in the output or redeemscript\n"
@@ -1072,7 +1073,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
10721073
}
10731074

10741075
if (fRescan && fRunScan && requests.size() && nLowestTimestamp <= chainActive.Tip()->GetBlockTimeMax()) {
1075-
CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(nLowestTimestamp) : chainActive.Genesis();
1076+
CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(std::max<int64_t>(nLowestTimestamp - 7200, 0)) : chainActive.Genesis();
10761077

10771078
if (pindex) {
10781079
pwalletMain->ScanForWalletTransactions(pindex, true);

0 commit comments

Comments
 (0)