Files
rippled/include
Bart f887be7dce fix: Stop a ledger built from a header from claiming to be immutable
Ledger(LedgerHeader const&, Rules, Family&) starts at immutable_ false. Its maps are constructed
Synching and filled in afterwards, by an acquisition syncing against the hashes the header carries or
by a replay that only reads the header, so the ledger is settled by setImmutable() once both maps are
sound rather than at construction. Every consumer of isImmutable() therefore sees an in-flight
acquisition for what it is, which is what LedgerHistory::insert() and LedgerReplayMsgHandler gate on.
InboundLedger::done() already publishes completeness only after settling, so no reader observes the
flag before the ledger it describes is immutable.

mapHashesFromHeader_ records that this constructor's transaction and account hashes are input rather
than derived, and setImmutable() therefore leaves them alone. Deriving them from the maps would turn a
ledger verified against a hash we asked for into one that is merely self-consistent: a map that fell
short of its target would be relabelled instead of refused. It is fixed at construction, unlike
immutable_, and set by this constructor alone, so every other constructor still derives its map
hashes.

Two gtest cases cover it. The first builds a ledger from a header naming a chain root, checks both maps
report as syncing and the ledger does not report as immutable, then abandons the transaction map and
checks settling refuses. The second leaves the transaction map empty while the header names that root,
so settling succeeds and both the named root and the ledger hash it was verified against are still
what the header carried.
2026-08-23 16:31:37 -04:00
..