fix: harden non-deterministic eth_call reads to prevent silent data corruption (#248) - #256
Open
lukiod wants to merge 2 commits into
Open
fix: harden non-deterministic eth_call reads to prevent silent data corruption (#248)#256lukiod wants to merge 2 commits into
lukiod wants to merge 2 commits into
Conversation
lastKnownLptEthPrice is a module level variable, reset to zero on every subgraph restart since the WASM instance is recreated. A revert on the first price fetch after a restart fell through to a silent zero, the same corruption this PR sets out to fix. protocol.lptPriceEth is an entity backed field already written once per round in roundsManager.ts, so it survives restarts and is a strictly safer fallback than the in memory cache alone.
Author
|
Pushed a fix (dd65b9e) and have one thing worth a second look before merge. Fixed: LPT/ETH price cache did not survive a restartflowchart LR
A[slot0 reverts] --> B{in memory cache?}
B -- yes --> C[use it]
B -- no, just restarted --> D{protocol.lptPriceEth?}
D -- yes, new --> E[use it]
D -- no --> F[fall back to zero, old bug]
Worth a look:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the root cause of POI divergence documented in issue #248:
eth_callstate reads that return wrong-but-valid values (from a degraded or lagging RPC backend) silently corrupt indexing state. The existing PR #249 fixed the abort on null Pool but did not address the silent corruption from bad RPC responses.Changes
roundsManager.ts—newRound()handlerUse
try_getNextTranscoderInPool()instead of the bare call (case 5): A revertedeth_callduring transcoder enumeration is now logged aslog.criticaland breaks the loop, rather than silently returningEMPTY_ADDRESSand truncating the pool list.Upgrade
log.info→log.criticalforgetFirstTranscoderInPoolandgetTotalBondedreverts (cases 1, 2): Post-launch these reverts are impossible and indicate a determinism hazard (bad RPC backend), not legitimate control flow.Carry forward
protocol.totalActiveStakewhengetTotalBondedreverts or returns zero (case 2): Previously zeroing the value cascaded into zeroedparticipationRateandnumActiveTranscodersfor the entire round.helpers.ts—getPriceForPair()Cache last-known non-zero pool prices (DAI/ETH, LPT/ETH) in module-level variables (case 3): On
eth_callrevert, the cached price is carried forward instead of silently returningZERO_BD, which would permanently under-count USD volume in 7 accumulators.Only cache non-zero prices to avoid persisting the "pool not yet deployed" sentinel as the last-known value.
Verification
yarn codegensucceedsgraph buildcompiles without errorsdocker compose -f docker-compose.test.yml up) requires a local graph-node deploymentReferences