| 426 | } |
| 427 | |
| 428 | std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainman, |
| 429 | KernelNotifications& kernel_notifications, |
| 430 | CTxMemPool* mempool, |
| 431 | const std::unique_ptr<CBlockTemplate>& block_template, |
| 432 | const BlockWaitOptions& wait_options, |
| 433 | const BlockCreateOptions& create_options, |
| 434 | bool& interrupt_wait) |
| 435 | { |
| 436 | // Delay calculating the current template fees, just in case a new block |
| 437 | // comes in before the next tick. |
| 438 | CAmount current_fees = -1; |
| 439 | |
| 440 | // Alternate waiting for a new tip and checking if fees have risen. |
| 441 | // The latter check is expensive so we only run it once per second. |
| 442 | auto now{NodeClock::now()}; |
| 443 | const auto deadline = now + wait_options.timeout; |
| 444 | const MillisecondsDouble tick{1000}; |
| 445 | const bool allow_min_difficulty{chainman.GetParams().GetConsensus().fPowAllowMinDifficultyBlocks}; |
| 446 | |
| 447 | do { |
| 448 | bool tip_changed{false}; |
| 449 | { |
| 450 | WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock); |
| 451 | // Note that wait_until() checks the predicate before waiting |
| 452 | kernel_notifications.m_tip_block_cv.wait_until(lock, std::min(now + tick, deadline), [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) { |
| 453 | AssertLockHeld(kernel_notifications.m_tip_block_mutex); |
| 454 | const auto tip_block{kernel_notifications.TipBlock()}; |
| 455 | // We assume tip_block is set, because this is an instance |
| 456 | // method on BlockTemplate and no template could have been |
| 457 | // generated before a tip exists. |
| 458 | tip_changed = Assume(tip_block) && tip_block != block_template->block.hashPrevBlock; |
| 459 | return tip_changed || chainman.m_interrupt || interrupt_wait; |
| 460 | }); |
| 461 | if (interrupt_wait) { |
| 462 | interrupt_wait = false; |
| 463 | return nullptr; |
| 464 | } |
| 465 | } |
| 466 | |
| 467 | if (chainman.m_interrupt) return nullptr; |
| 468 | // At this point the tip changed, a full tick went by or we reached |
| 469 | // the deadline. |
| 470 | |
| 471 | // Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks. |
| 472 | LOCK(::cs_main); |
| 473 | |
| 474 | // On test networks return a minimum difficulty block after 20 minutes |
| 475 | if (!tip_changed && allow_min_difficulty) { |
| 476 | const NodeClock::time_point tip_time{std::chrono::seconds{chainman.ActiveChain().Tip()->GetBlockTime()}}; |
| 477 | if (now > tip_time + 20min) { |
| 478 | tip_changed = true; |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | /** |
| 483 | * We determine if fees increased compared to the previous template by generating |
| 484 | * a fresh template. There may be more efficient ways to determine how much |
| 485 | * (approximate) fees for the next block increased, perhaps more so after |
no test coverage detected