Skip to content

Use the prev inner block hash of the last non simplex block - #479

Open
yacovm wants to merge 2 commits into
mainfrom
properPrevHash
Open

yacovm wants to merge 2 commits into
mainfrom
properPrevHash

Conversation

@yacovm

@yacovm yacovm commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Previously to this commit, when building the first ever simplex block, simplex was using the previous block hash of the protocol metadata, which is computed differently and incorrectly because the block previous to the first ever simplex block is not a simplex block.

@yacovm
yacovm force-pushed the properPrevHash branch 6 times, most recently from b7ea146 to 526d19a Compare August 6, 2026 21:10
Comment thread msm/msm.go
if block.InnerBlock != nil {
return errZeroBlockHasInnerBlock
}
if prevBlock.InnerBlock.Digest() != sm.LastNonSimplexInnerBlock.Digest() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how was this passing before? prevBlock.InnerBlock is supposed to be nil after the if

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think because prevBlock.InnerBlock is sm.LastNonSimplexInnerBlock

Comment thread msm/msm_test.go
Seq: 43,
Epoch: 43,
Prev: preSimplexParent.Digest(),
Prev: preSimplexParent.InnerBlock.Digest(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but we are calling StateMachine.Digest which encodes the inner blocks digest. So with this change this says the last non-simplex block is no longer wrapped in simplex protocol metadata?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're building on top of the pre-simplex parent, so its digest is computed with the inner block.

The outer block doesn't exist for the pre-simplex parent, it's just a facade because we encode the ICMEpochInfo in the test outside of it.

Comment thread adapters.go Outdated
parsedBlock := &ParsedBlock{
msm: e.msm,
StateMachineBlock: block,
legacyBlock: seq <= e.lastNonSimplexHeight,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be easier to just wrap any non-simplex blocks in the default protocol metadata? this way we wouldn't need the legacy block fields and wouldn't need to use inner.Digest

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the protocol metadata doesn't contain the hash though, and the hash is computed differently for pre-simplex blocks.

Previously to this commit, when building the first ever simplex block,
simplex was using the previous block hash of the protocol metadata,
which is computed differently and incorrectly because the block previous
to the first ever simplex block is not a simplex block.

Signed-off-by: Yacov Manevich <yacov.manevich@avalabs.org>
Comment thread msm/msm.go
return errZeroBlockInnerDigestMismatch

// The zero block must build upon the last non-Simplex block
if block.Metadata.SimplexProtocolMetadata.Prev != sm.LastNonSimplexInnerBlock.Digest() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we also verify the sequence is as expected?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do it via line 974, because the expected block's digest depends on the sequence.

We need this because we don't have a better way of ensuring the previous block points to the non-simplex block.

I can add an explicit check.

Comment thread adapters.go
type CachedStorage struct {
msm *metadata.StateMachine
lock sync.RWMutex
lastNonSimplexHeight uint64

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a comment?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Comment thread adapters.go
return nil, nil, err
}

legacy := seq <= cs.lastNonSimplexHeight

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when are we going to need to retrieve something from storage < lastNonSimplexHeight? Aren't we only going to need to retrieve the lastNonSimplex block?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not.

Comment thread adapters.go
Signed-off-by: Yacov Manevich <yacov.manevich@avalabs.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants