Skip to content

Commit 0786b75

Browse files
committed
rpc: add optional blockhash to waitfornewblock
1 parent bfeacc1 commit 0786b75

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

doc/release-30635.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Updated RPCs
2+
------------
3+
4+
- The waitfornewblock RPC takes an optional `current_tip` argument. (#30635)

src/rpc/blockchain.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ static RPCHelpMan waitfornewblock()
266266
"\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
267267
{
268268
{"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},
269+
{"current_tip", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Method waits for the chain tip to differ from this."},
269270
},
270271
RPCResult{
271272
RPCResult::Type::OBJ, "", "",
@@ -287,10 +288,22 @@ static RPCHelpMan waitfornewblock()
287288
NodeContext& node = EnsureAnyNodeContext(request.context);
288289
Mining& miner = EnsureMining(node);
289290

290-
// Abort if RPC came out of warmup too early
291+
// If the caller provided a current_tip value, pass it to waitTipChanged().
292+
//
293+
// If the caller did not provide a current tip hash, call getTip() to get
294+
// one and wait for the tip to be different from this value. This mode is
295+
// less reliable because if the tip changed between waitfornewblock calls,
296+
// it will need to change a second time before this call returns.
291297
BlockRef current_block{CHECK_NONFATAL(miner.getTip()).value()};
292-
std::optional<BlockRef> block = timeout ? miner.waitTipChanged(current_block.hash, std::chrono::milliseconds(timeout)) :
293-
miner.waitTipChanged(current_block.hash);
298+
299+
uint256 tip_hash{request.params[1].isNull()
300+
? current_block.hash
301+
: ParseHashV(request.params[1], "current_tip")};
302+
303+
// If the user provided an invalid current_tip then this call immediately
304+
// returns the current tip.
305+
std::optional<BlockRef> block = timeout ? miner.waitTipChanged(tip_hash, std::chrono::milliseconds(timeout)) :
306+
miner.waitTipChanged(tip_hash);
294307

295308
// Return current block upon shutdown
296309
if (block) current_block = *block;

test/functional/rpc_blockchain.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ def _test_waitforblock(self):
579579
node.reconsiderblock(rollback_hash)
580580
# The chain has probably already been restored by the time reconsiderblock returns,
581581
# but poll anyway.
582-
self.wait_until(lambda: node.waitfornewblock(timeout=100)['hash'] == current_hash)
582+
self.wait_until(lambda: node.waitfornewblock(current_tip=rollback_header['previousblockhash'])['hash'] == current_hash)
583+
583584
assert_raises_rpc_error(-1, "Negative timeout", node.waitfornewblock, -1)
584585

585586
def _test_waitforblockheight(self):

0 commit comments

Comments
 (0)