You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Transient account resolved to a larger read only image keeps a stale persisted copy #166
AccountsDB::store says each batch "also touches the opposite backend so stale copies are removed after mode changes", but persisted() (accountsdb/src/lib.rs) only routes an Owned entry to persisted storage when its mode is authoritative.
A Transient account is loaded as a Borrowed image. When materialize resolves it to a ReadOnly image whose data is larger than the borrowed capacity (the data length rounded up to 8 bytes), resize promotes it to Owned in the same write. The entry is then Owned and non authoritative, so it skips the persisted backend and the old Transient image stays in LMDB and the mmap.
Effects on 7c95d6a (tag 0.12.0 has the same code):
a program scan returns the key twice, the stale Transient image and the ReadOnly one
the stale image stays in the persisted checksum
after the ReadOnly mirror is evicted, or after reset() drops volatile state, load returns the old Transient image again
Reproduction
Through the public Engine API: materialize Delegated, then Transient with 1 byte of data, then ReadOnly with 64 bytes; scan, evict, scan. Expected [(key, (ReadOnly, 64))], None, [], got:
A unit version in accountsdb/src/tests.rs panics with stale transient image left in persisted storage. Both tests are ready to share.
Expected
Resolving to a ReadOnly image removes the Transient copy from persisted storage regardless of whether the data grew.
Context
In magicblock-validator this is reached when the undelegation path materializes the base chain ReadOnly image for a Transient account (cloner → materialize) and the chain image is larger than the local one, for example after a realloc on the base layer. A minimal fix that passes the accountsdb suite and the engine, keeper and replicator tests here is to also route Owned entries whose DirtyMarkers::MODE is set:
Routing every Owned entry to persisted storage would also work at the cost of more LMDB writes. Happy to open a PR with the tests for whichever you prefer.
Activity
bmuddha commentedon Oct 1, 2026
@erkancamli thanks for the report, will be fixed soon.