mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 15:28:03 +00:00
`SHAMap::walkMap` and `walkMapParallel` treat a null `descendNoStore` result as "this node is missing" and record it in their `missingNodes` output, but `descendNoStore` used the throwing `fetchNode`, so that branch could never run for a backed map. `Ledger::walkLedger` propagated the throw instead of returning false, its "N missing account node(s)" log never printed, and `LedgerCleaner` never reached the path that clears the ledger and re-acquires it. `descendNoStore` now uses `fetchNodeNT`, which makes all three behave as written, and the null check after `fetchNode` in `descend` goes away as the dead code it always was. `visitNodes` and `visitLeaves` now return whether the walk read every node it reached, and the walk ends at the first node it cannot read, since no caller can use a partial result. `SHAMapStoreImp::run` abandons the rotation cycle on false, which is what its former `catch (SHAMapMissingNode)` did and what `clearPrior` plus the archive deletion in `rotate` require. `processReplayDeltaRequest` answers `reNO_NODE`, the code `xrpl.proto` documents for nodes we do not have, rather than sending a transaction list it knows is short, and clears the header it had already set so an error reply carries no partial payload. The two `RCLConsensus` walks run on unbacked maps, which have no node store to fail to read, so they cannot report an incomplete result. `walkMapParallel` decided its result from the exceptions its workers caught, yet those workers record an unreadable child in `missingNodes` instead, so it never consulted the list it was filling. The result now counts what this call recorded, measured against the caller's initial vector size. The pass that reads the root's children runs before any worker and dropped a null child silently, because the loop that spawns workers skips one; it records the miss itself now. A one-node map reports complete, which is what `walkMap` already reported for the same input, and the worker handler catches `std::exception` so that nothing leaves a worker's thread. Nine gtests in `src/tests/libxrpl/shamap/SHAMapMissingNode.cpp` cover the three walks over a partially copied map, the missing-node budget, an early stop by the visitor, a stop at the root, a map holding only its root, and a map whose root is a leaf.