| 2501 | } |
| 2502 | |
| 2503 | static const CBlockIndex *FindBlockToFinalize(CBlockIndex *pindexNew) |
| 2504 | // EXCLUSIVE_LOCKS_REQUIRED(cs_main) |
| 2505 | { |
| 2506 | AssertLockHeld(cs_main); |
| 2507 | |
| 2508 | const int32_t minfinalizationdepth = |
| 2509 | gArgs.GetArg("-minfinalizationdepth", DEFAULT_MAX_REORG_DEPTH); |
| 2510 | |
| 2511 | const int64_t minfinalizationage = |
| 2512 | gArgs.GetArg("-minfinalizationage", DEFAULT_MIN_FINALIZATION_DELAY); |
| 2513 | |
| 2514 | // Find our candidate. |
| 2515 | // If minfinalizationdepth is < 0 pindex will be null and auto finalization |
| 2516 | // disabled |
| 2517 | const CBlockIndex *pindex = |
| 2518 | pindexNew->GetAncestor(pindexNew->nHeight - minfinalizationdepth); |
| 2519 | |
| 2520 | int64_t now = GetTime(); |
| 2521 | |
| 2522 | // If the finalization delay is not expired since the startup time, |
| 2523 | // finalization should be avoided. Header receive time is not saved to disk |
| 2524 | // and so cannot be anterior to startup time. |
| 2525 | if (now < (GetStartupTime() + minfinalizationage)) { |
| 2526 | return nullptr; |
| 2527 | } |
| 2528 | |
| 2529 | // While our candidate is not eligible (finalization delay not expired), try |
| 2530 | // the previous one. |
| 2531 | while (pindex && (pindex != pindexFinalized)) { |
| 2532 | // Check that the block to finalize is known for a long enough time. |
| 2533 | // This test will ensure that an attacker could not cause a block to |
| 2534 | // finalize by forking the chain with a depth > minfinalizationdepth. |
| 2535 | // If the block is loaded from disk, header receive time is 0 and the |
| 2536 | // block will be finalized. This is safe because the delay since the |
| 2537 | // node startup is already expired. |
| 2538 | auto headerReceivedTime = pindex->GetHeaderReceivedTime(); |
| 2539 | |
| 2540 | // If finalization delay is <= 0, finalization always occurs immediately |
| 2541 | if (now >= (headerReceivedTime + minfinalizationage)) { |
| 2542 | return pindex; |
| 2543 | } |
| 2544 | |
| 2545 | pindex = pindex->pprev; |
| 2546 | } |
| 2547 | |
| 2548 | return nullptr; |
| 2549 | } |
| 2550 | |
| 2551 | /** |
| 2552 | * Connect a new block to chainActive. pblock is either nullptr or a pointer to a CBlock |
no test coverage detected