2222#include < hash.h>
2323#include < index/blockfilterindex.h>
2424#include < index/coinstatsindex.h>
25+ #include < interfaces/mining.h>
2526#include < kernel/coinstats.h>
2627#include < logging/timer.h>
2728#include < net.h>
6162using kernel::CCoinsStats;
6263using kernel::CoinStatsHashType;
6364
65+ using interfaces::Mining;
6466using node::BlockManager;
6567using node::NodeContext;
6668using node::SnapshotMetadata;
6769using util::MakeUnorderedList;
6870
69- struct CUpdatedBlock
70- {
71- uint256 hash;
72- int height;
73- };
74-
75- static GlobalMutex cs_blockchange;
76- static std::condition_variable cond_blockchange;
77- static CUpdatedBlock latestblock GUARDED_BY (cs_blockchange);
78-
7971std::tuple<std::unique_ptr<CCoinsViewCursor>, CCoinsStats, const CBlockIndex*>
8072PrepareUTXOSnapshot (
8173 Chainstate& chainstate,
@@ -262,16 +254,6 @@ static RPCHelpMan getbestblockhash()
262254 };
263255}
264256
265- void RPCNotifyBlockChange (const CBlockIndex* pindex)
266- {
267- if (pindex) {
268- LOCK (cs_blockchange);
269- latestblock.hash = pindex->GetBlockHash ();
270- latestblock.height = pindex->nHeight ;
271- }
272- cond_blockchange.notify_all ();
273- }
274-
275257static RPCHelpMan waitfornewblock ()
276258{
277259 return RPCHelpMan{" waitfornewblock" ,
@@ -298,16 +280,14 @@ static RPCHelpMan waitfornewblock()
298280 timeout = request.params [0 ].getInt <int >();
299281 if (timeout < 0 ) throw JSONRPCError (RPC_MISC_ERROR, " Negative timeout" );
300282
301- CUpdatedBlock block;
302- {
303- WAIT_LOCK (cs_blockchange, lock);
304- block = latestblock;
305- if (timeout)
306- cond_blockchange.wait_for (lock, std::chrono::milliseconds (timeout), [&block]() EXCLUSIVE_LOCKS_REQUIRED (cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning (); });
307- else
308- cond_blockchange.wait (lock, [&block]() EXCLUSIVE_LOCKS_REQUIRED (cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning (); });
309- block = latestblock;
283+ NodeContext& node = EnsureAnyNodeContext (request.context );
284+ Mining& miner = EnsureMining (node);
285+
286+ auto block{CHECK_NONFATAL (miner.getTip ()).value ()};
287+ if (IsRPCRunning ()) {
288+ block = timeout ? miner.waitTipChanged (block.hash , std::chrono::milliseconds (timeout)) : miner.waitTipChanged (block.hash );
310289 }
290+
311291 UniValue ret (UniValue::VOBJ);
312292 ret.pushKV (" hash" , block.hash .GetHex ());
313293 ret.pushKV (" height" , block.height );
@@ -346,14 +326,20 @@ static RPCHelpMan waitforblock()
346326 timeout = request.params [1 ].getInt <int >();
347327 if (timeout < 0 ) throw JSONRPCError (RPC_MISC_ERROR, " Negative timeout" );
348328
349- CUpdatedBlock block;
350- {
351- WAIT_LOCK (cs_blockchange, lock);
352- if (timeout)
353- cond_blockchange.wait_for (lock, std::chrono::milliseconds (timeout), [&hash]() EXCLUSIVE_LOCKS_REQUIRED (cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning ();});
354- else
355- cond_blockchange.wait (lock, [&hash]() EXCLUSIVE_LOCKS_REQUIRED (cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning (); });
356- block = latestblock;
329+ NodeContext& node = EnsureAnyNodeContext (request.context );
330+ Mining& miner = EnsureMining (node);
331+
332+ auto block{CHECK_NONFATAL (miner.getTip ()).value ()};
333+ const auto deadline{std::chrono::steady_clock::now () + 1ms * timeout};
334+ while (IsRPCRunning () && block.hash != hash) {
335+ if (timeout) {
336+ auto now{std::chrono::steady_clock::now ()};
337+ if (now >= deadline) break ;
338+ const MillisecondsDouble remaining{deadline - now};
339+ block = miner.waitTipChanged (block.hash , remaining);
340+ } else {
341+ block = miner.waitTipChanged (block.hash );
342+ }
357343 }
358344
359345 UniValue ret (UniValue::VOBJ);
@@ -395,15 +381,23 @@ static RPCHelpMan waitforblockheight()
395381 timeout = request.params [1 ].getInt <int >();
396382 if (timeout < 0 ) throw JSONRPCError (RPC_MISC_ERROR, " Negative timeout" );
397383
398- CUpdatedBlock block;
399- {
400- WAIT_LOCK (cs_blockchange, lock);
401- if (timeout)
402- cond_blockchange.wait_for (lock, std::chrono::milliseconds (timeout), [&height]() EXCLUSIVE_LOCKS_REQUIRED (cs_blockchange) {return latestblock.height >= height || !IsRPCRunning ();});
403- else
404- cond_blockchange.wait (lock, [&height]() EXCLUSIVE_LOCKS_REQUIRED (cs_blockchange) {return latestblock.height >= height || !IsRPCRunning (); });
405- block = latestblock;
384+ NodeContext& node = EnsureAnyNodeContext (request.context );
385+ Mining& miner = EnsureMining (node);
386+
387+ auto block{CHECK_NONFATAL (miner.getTip ()).value ()};
388+ const auto deadline{std::chrono::steady_clock::now () + 1ms * timeout};
389+
390+ while (IsRPCRunning () && block.height < height) {
391+ if (timeout) {
392+ auto now{std::chrono::steady_clock::now ()};
393+ if (now >= deadline) break ;
394+ const MillisecondsDouble remaining{deadline - now};
395+ block = miner.waitTipChanged (block.hash , remaining);
396+ } else {
397+ block = miner.waitTipChanged (block.hash );
398+ }
406399 }
400+
407401 UniValue ret (UniValue::VOBJ);
408402 ret.pushKV (" hash" , block.hash .GetHex ());
409403 ret.pushKV (" height" , block.height );
0 commit comments