Merge 630210e20546d04c5f008e5b3290c878ec8e97e6 into 5f4422d68dc3530c353af1f87499de1c864b60ad

This commit is contained in:
Sai Kiran Nadipilli 2025-03-16 21:50:03 -05:00 committed by GitHub
commit 421f04cac3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 11 deletions

View File

@ -1246,7 +1246,10 @@ static int64_t GetImportTimestamp(const UniValue& data, int64_t now)
} else if (timestamp.isStr() && timestamp.get_str() == "now") {
return now;
}
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" timestamp value for key. got type %s", uvTypeName(timestamp.type())));
else if (timestamp.isStr() && timestamp.get_str() == "never") {
return -1;
}
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" or \"never\" timestamp value for key. got type %s", uvTypeName(timestamp.type())));
}
throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key");
}
@ -1631,10 +1634,11 @@ RPCHelpMan importdescriptors()
{"next_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If a ranged descriptor is set to active, this specifies the next index to generate addresses from"},
{"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, "Time from which to start rescanning the blockchain for this descriptor, in " + UNIX_EPOCH_TIME + "\n"
"Use the string \"now\" to substitute the current synced blockchain time.\n"
"\"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n"
"\"now\" can be specified to scanning from last mediantime, for outputs which are known to never have been used, and\n"
"\"never\" can be specified to skip scanning, and\n"
"0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n"
"of all descriptors being imported will be scanned as well as the mempool.",
RPCArgOptions{.type_str={"timestamp | \"now\"", "integer / string"}}
RPCArgOptions{.type_str={"timestamp | \"now\" | \"never\"", "integer / string"}}
},
{"internal", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether matching outputs should be treated as not incoming payments (e.g. change)"},
{"label", RPCArg::Type::STR, RPCArg::Default{""}, "Label to assign to the address, only allowed with internal=false. Disabled for ranged descriptors"},
@ -1693,7 +1697,7 @@ RPCHelpMan importdescriptors()
const int64_t minimum_timestamp = 1;
int64_t now = 0;
int64_t lowest_timestamp = 0;
bool rescan = false;
bool rescan = true;
UniValue response(UniValue::VARR);
{
LOCK(pwallet->cs_wallet);
@ -1701,22 +1705,34 @@ RPCHelpMan importdescriptors()
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(lowest_timestamp).mtpTime(now)));
int all_rescan_value = 0;
// Get all timestamps and extract the lowest timestamp
for (const UniValue& request : requests.getValues()) {
// This throws an error if "timestamp" doesn't exist
const int64_t timestamp = std::max(GetImportTimestamp(request, now), minimum_timestamp);
auto requestTimestamp = GetImportTimestamp(request, now);
// if any one entity has valid timestamp we can skp this check
if (!all_rescan_value) {
if (requestTimestamp < 0) {
const UniValue& timestamp = request["timestamp"];
// set all_rescan_value true if requested timestamp is negative otherwise it all_rescan_value value never
if (timestamp.isNum() && timestamp.getInt<int64_t>() == requestTimestamp) {
all_rescan_value += 1;
}
} else {
all_rescan_value += 1;
}
}
const int64_t timestamp = std::max(requestTimestamp, minimum_timestamp);
const UniValue result = ProcessDescriptorImport(*pwallet, request, timestamp);
response.push_back(result);
if (lowest_timestamp > timestamp ) {
lowest_timestamp = timestamp;
}
// If we know the chain tip, and at least one request was successful then allow rescan
if (!rescan && result["success"].get_bool()) {
rescan = true;
}
}
rescan = all_rescan_value > 0 ? true:false;
pwallet->ConnectScriptPubKeyManNotifiers();
}

View File

@ -434,7 +434,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.log.info("Should throw on invalid or missing timestamp values")
assert_raises_rpc_error(-3, 'Missing required timestamp field for key',
self.nodes[1].importmulti, [{"scriptPubKey": key.p2pkh_script}])
assert_raises_rpc_error(-3, 'Expected number or "now" timestamp value for key. got type string',
assert_raises_rpc_error(-3, 'Expected number or "now" or "never" timestamp value for key. got type string',
self.nodes[1].importmulti, [{
"scriptPubKey": key.p2pkh_script,
"timestamp": ""