From 0786b7509acd7e160345eea5fc25acd3c795d01c Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Thu, 21 Nov 2024 13:35:19 +0100 Subject: [PATCH 1/2] rpc: add optional blockhash to waitfornewblock --- doc/release-30635.md | 4 ++++ src/rpc/blockchain.cpp | 19 ++++++++++++++++--- test/functional/rpc_blockchain.py | 3 ++- 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 doc/release-30635.md diff --git a/doc/release-30635.md b/doc/release-30635.md new file mode 100644 index 00000000000..179a4f49a0a --- /dev/null +++ b/doc/release-30635.md @@ -0,0 +1,4 @@ +Updated RPCs +------------ + +- The waitfornewblock RPC takes an optional `current_tip` argument. (#30635) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6e5c656f3d8..ef1a7ed3939 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -266,6 +266,7 @@ static RPCHelpMan waitfornewblock() "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)", { {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + {"current_tip", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Method waits for the chain tip to differ from this."}, }, RPCResult{ RPCResult::Type::OBJ, "", "", @@ -287,10 +288,22 @@ static RPCHelpMan waitfornewblock() NodeContext& node = EnsureAnyNodeContext(request.context); Mining& miner = EnsureMining(node); - // Abort if RPC came out of warmup too early + // If the caller provided a current_tip value, pass it to waitTipChanged(). + // + // If the caller did not provide a current tip hash, call getTip() to get + // one and wait for the tip to be different from this value. This mode is + // less reliable because if the tip changed between waitfornewblock calls, + // it will need to change a second time before this call returns. BlockRef current_block{CHECK_NONFATAL(miner.getTip()).value()}; - std::optional block = timeout ? miner.waitTipChanged(current_block.hash, std::chrono::milliseconds(timeout)) : - miner.waitTipChanged(current_block.hash); + + uint256 tip_hash{request.params[1].isNull() + ? current_block.hash + : ParseHashV(request.params[1], "current_tip")}; + + // If the user provided an invalid current_tip then this call immediately + // returns the current tip. + std::optional block = timeout ? miner.waitTipChanged(tip_hash, std::chrono::milliseconds(timeout)) : + miner.waitTipChanged(tip_hash); // Return current block upon shutdown if (block) current_block = *block; diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 2976f9188ae..b0ac519de0d 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -579,7 +579,8 @@ class BlockchainTest(BitcoinTestFramework): node.reconsiderblock(rollback_hash) # The chain has probably already been restored by the time reconsiderblock returns, # but poll anyway. - self.wait_until(lambda: node.waitfornewblock(timeout=100)['hash'] == current_hash) + self.wait_until(lambda: node.waitfornewblock(current_tip=rollback_header['previousblockhash'])['hash'] == current_hash) + assert_raises_rpc_error(-1, "Negative timeout", node.waitfornewblock, -1) def _test_waitforblockheight(self): From c6e2c31c55123cc97b4400bcbf3c37a39b067a22 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Wed, 19 Feb 2025 13:39:41 +0100 Subject: [PATCH 2/2] rpc: unhide waitfor{block,newblock,blockheight} They are now reliable. An earlier commit dropped their IsRPCRunning() guards so they also work in the GUI. --- doc/release-30635.md | 3 ++- src/rpc/blockchain.cpp | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/release-30635.md b/doc/release-30635.md index 179a4f49a0a..0ec68e93cc5 100644 --- a/doc/release-30635.md +++ b/doc/release-30635.md @@ -1,4 +1,5 @@ Updated RPCs ------------ -- The waitfornewblock RPC takes an optional `current_tip` argument. (#30635) +- The waitfornewblock now takes an optional `current_tip` argument. It is also no longer hidden. (#30635) +- The waitforblock and waitforblockheight RPCs are no longer hidden. (#30635) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ef1a7ed3939..a51c4843b79 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -3437,9 +3437,9 @@ void RegisterBlockchainRPCCommands(CRPCTable& t) {"blockchain", &getchainstates}, {"hidden", &invalidateblock}, {"hidden", &reconsiderblock}, - {"hidden", &waitfornewblock}, - {"hidden", &waitforblock}, - {"hidden", &waitforblockheight}, + {"blockchain", &waitfornewblock}, + {"blockchain", &waitforblock}, + {"blockchain", &waitforblockheight}, {"hidden", &syncwithvalidationinterfacequeue}, }; for (const auto& c : commands) {