mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 23:38:08 +00:00
`NodePathStack`'s checks were `XRPL_ASSERT`s, which are stripped under `NDEBUG`, so a release build walked on with a node and an ID that disagreed. Each one is now a live test that refuses the push and lets the caller stop, since a malformed map must not be walked and must not abort either. The leaf-position check was `UNREACHABLE`, and that was wrong rather than merely strict. A leaf enters a tree through paths that carry no `SHAMapNodeID` at all (`descend(parent, branch)`, `descendThrow`, `descendNoStore`), so no upstream check can exist for them and `pushChild` is the first place the position is known again. It is therefore a live, non-aborting test, and every path that does know the position now judges a node before hooking it: the two filter descents and the deferred-read hook, each marking the map invalid the way `addKnownNode` already did for an inner node too deep. `getMissingNodes` no longer calls `clearSynching()` on such a map, which would have moved the state to `Modifying` and erased that verdict. `gmnProcessDeferredReads` became non-static so it can record it. New `SHAMapMisplacedLeaf` tests build a tree whose hashes agree but whose leaf sits under the wrong branch, and drive it in through each of the two acquisition routes. Reverting the entry checks fails both; reverting only the `belowHelper` throw leaves `map.begin()` reporting such a map as empty, which the third test catches.