fix: autobahn InitChain height and GetValidators panic (CON-249)#3243
Open
wen-coding wants to merge 4 commits intomainfrom
Open
fix: autobahn InitChain height and GetValidators panic (CON-249)#3243wen-coding wants to merge 4 commits intomainfrom
wen-coding wants to merge 4 commits intomainfrom
Conversation
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3243 +/- ##
==========================================
- Coverage 59.26% 59.26% -0.01%
==========================================
Files 2070 2070
Lines 169788 169791 +3
==========================================
Hits 100631 100631
- Misses 60358 60362 +4
+ Partials 8799 8798 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Contributor
|
this pr seems to be a noop, no? |
Contributor
Author
Sorry, still working on it, Claude pushed before it's ready. I'll ping you when it's ready for review. |
d272836 to
85e690c
Compare
3 tasks
Without Commit after InitChain, the staking params are not persisted to the committed store. When executeBlock calls app.GetValidators(), it reads from the committed store and panics with "UnmarshalJSON cannot decode empty bytes". Also removes the testApp Committed check in FinalizeBlock since the extra Commit after InitChain changes the Committed state flow. Note: TestGigaRouter_FinalizeBlocks is pre-broken on main (times out at 120s) — this is not caused by this change. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
85e690c to
8be74ab
Compare
GetValidators now reads from the committed store first and only falls back to DeliverContext when the committed store is empty (autobahn-only path after InitChain before first Commit). This avoids changing the code path for CometBFT consensus. Remove the Committed field from testApp. The original boolean conflated two states: "post-InitChain" and "post-Commit". It blocked autobahn's valid flow (InitChain → FinalizeBlock without intermediate Commit) because InitChain set Committed=true, causing the next Commit after FinalizeBlock to fail with "double commit". The real app guards against actual double commit structurally (deliverState becomes nil after Commit, so a second Commit panics on nil pointer) — not via a boolean flag. The testApp is too simple to replicate that mechanism and doesn't need to. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The CometBFT handshaker (consensus/replay.go) always calls InitChain when appHeight==0. Having runExecute also call InitChain caused a double-init that corrupted state. Now runExecute skips InitChain and relies on the handshaker having already set up deliverState. GetValidators: at height 0, read from DeliverContext first since the committed store is empty (staking params panic on MaxValidators). After the first Commit, the committed store has the params and the normal path is used. Test: simulate the handshaker by calling InitChain before router.Run(). Verified with docker AUTOBAHN=true cluster: all 4 nodes produce blocks, bank transfer works, fault tolerance (1-down continues, 2-down halts). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Match the real SDK behavior: InitChain without Commit leaves LastBlockHeight=0. Previously the testApp returned InitialHeight-1 after InitChain with 0 blocks, causing runExecute to enter the restart path and call PushAppHash with a block number below the data layer's starting point. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 two bugs in autobahn's
runExecuteInitChain flow:Height mismatch: After InitChain,
runExecutecalled Commit which advanced the app toInitialHeight. The next FinalizeBlock atInitialHeightthen failed with "invalid height: N; expected: N+1". Fix: remove the Commit after InitChain — the SDK expects the first FinalizeBlock atInitialHeightusing thedeliverStateset up by InitChain.GetValidators panic: Without Commit, the committed store is empty (staking params not persisted).
GetValidatorsreading from committed store panics with "UnmarshalJSON cannot decode empty bytes". Fix: read committed store first (normal path), fall back toDeliverContextonly when committed store returns no validators (autobahn-only genesis path).Why the testApp
Committedfield was removedThe original
testApphad aCommitted boolfield set by bothInitChainandCommit, withFinalizeBlockcheckingif !state.Committed { error }. This conflated two states — "post-InitChain" and "post-Commit" — into one flag.For autobahn's flow (InitChain → FinalizeBlock → Commit), InitChain set
Committed=true. After the first FinalizeBlock set it tofalse, Commit correctly set it back totrue. But if InitChain setCommitted=trueand then Commit was called (CometBFT flow), it would fail with "double commit" — not because there was actually a double commit, but because the flag was alreadytrue.The real app guards against actual double commit structurally:
Commit()setsdeliverState = nil, so a secondCommit()panics on nil pointer dereference. The testApp is too simple to replicate that mechanism and doesn't need to — it only tracks blocks and txs for test assertions.Changes
sei-tendermint/internal/p2p/giga_router.go: Remove Commit after InitChain; setnext = InitialHeight(not+1)app/app.go:GetValidators()reads committed store first, falls back toDeliverContextonly when empty (autobahn genesis path)sei-cosmos/baseapp/test_helpers.go: AddDeliverContext()accessor for reading uncommitted statesei-tendermint/internal/p2p/giga_router_test.go: RemoveCommittedfield from testApp; addTestInitChainCommitThenFinalizetestTest plan
TestInitChainCommitThenFinalizepasses — verifies InitChain → FinalizeBlock → Commit flowTestGigaRouter_FinalizeBlocks— pre-broken on main (times out, caused by Made autobahn producer use TxMempool #3224), not affected by this changeAUTOBAHN=truecluster🤖 Generated with Claude Code