-
Notifications
You must be signed in to change notification settings - Fork 4
Use the prev inner block hash of the last non simplex block #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,6 +67,7 @@ func (s *CallbackStorage) Retrieve(seq uint64) (common.VerifiedBlock, common.Fin | |
| return nil, common.Finalization{}, err | ||
| } | ||
| parsedBlock := &ParsedBlock{ | ||
| legacyBlock: seq <= s.lastNonSimplexHeight, | ||
| msm: s.msm, | ||
| StateMachineBlock: block, | ||
| } | ||
|
|
@@ -108,16 +109,20 @@ func (cb *cachedBlock) Verify(ctx context.Context, verifyOpts ...common.VerifyOp | |
| } | ||
|
|
||
| type CachedStorage struct { | ||
| msm *metadata.StateMachine | ||
| lock sync.RWMutex | ||
| // lastNonSimplexHeight is the height of the last block that is not a Simplex block. | ||
| // Blocks with height <= this are called legacy blocks. | ||
| lastNonSimplexHeight uint64 | ||
| msm *metadata.StateMachine | ||
| lock sync.RWMutex | ||
| Storage | ||
| cache map[common.Digest]cachedBlock | ||
| } | ||
|
|
||
| func NewCachedStorage(storage Storage) *CachedStorage { | ||
| func NewCachedStorage(storage Storage, lastNonSimplexHeight uint64) *CachedStorage { | ||
| return &CachedStorage{ | ||
| Storage: storage, | ||
| cache: make(map[common.Digest]cachedBlock), | ||
| lastNonSimplexHeight: lastNonSimplexHeight, | ||
| Storage: storage, | ||
| cache: make(map[common.Digest]cachedBlock), | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -151,11 +156,25 @@ func (cs *CachedStorage) Retrieve(seq uint64, digest common.Digest) (common.Veri | |
|
|
||
| // We don't populate the cache here because we populate it externally. | ||
| block, finalization, err := cs.GetBlock(seq) | ||
| if digest != (common.Digest{}) && block.Digest() != digest { | ||
| return nil, nil, common.ErrBlockNotFound | ||
| if err != nil { | ||
| return nil, nil, err | ||
| } | ||
|
|
||
| legacy := seq <= cs.lastNonSimplexHeight | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're not. |
||
|
|
||
| if digest != (common.Digest{}) { | ||
| // A block predating Simplex is identified by its inner block's digest, not by a Simplex block digest. | ||
| blockDigest := block.Digest() | ||
|
yacovm marked this conversation as resolved.
|
||
| if legacy && block.InnerBlock != nil { | ||
| blockDigest = common.Digest(block.InnerBlock.Digest()) | ||
| } | ||
| if blockDigest != digest { | ||
| return nil, nil, common.ErrBlockNotFound | ||
| } | ||
| } | ||
|
|
||
| return &ParsedBlock{ | ||
| legacyBlock: legacy, | ||
| StateMachineBlock: block, | ||
| msm: cs.msm, | ||
| }, finalization, err | ||
|
|
@@ -259,6 +278,7 @@ func (bw *blockBuilderWaiter) BuildBlock(ctx context.Context, metadata common.Pr | |
| } | ||
|
|
||
| pb := &ParsedBlock{ | ||
| legacyBlock: metadata.Seq <= bw.cs.lastNonSimplexHeight, | ||
| StateMachineBlock: *block, | ||
| msm: bw.msm, | ||
| } | ||
|
|
@@ -289,8 +309,12 @@ func (bd *blockDeserializer) DeserializeBlock(ctx context.Context, bytes []byte) | |
| innerBlock = block | ||
| } | ||
|
|
||
| seq := rawBlock.Metadata.SimplexProtocolMetadata.Seq | ||
| legacy := seq <= bd.cs.lastNonSimplexHeight | ||
|
|
||
| return &cachedBlock{ | ||
| ParsedBlock: &ParsedBlock{ | ||
| legacyBlock: legacy, | ||
| StateMachineBlock: metadata.StateMachineBlock{ | ||
| InnerBlock: innerBlock, | ||
| Metadata: rawBlock.Metadata, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -71,7 +71,8 @@ var ( | |
| errNilBlock = errors.New("block is nil") | ||
| errInvalidPChainHeight = errors.New("invalid P-chain height") | ||
| errZeroBlockHasInnerBlock = errors.New("zero block must not have an inner block") | ||
| errZeroBlockInnerDigestMismatch = errors.New("zero block inner block digest does not match last non-Simplex inner block digest") | ||
| errZeroBlockPrevDigestMismatch = errors.New("zero block previous digest does not match last non-Simplex block digest") | ||
| errZeroBlockSeqMismatch = errors.New("zero block sequence does not succeed the last non-Simplex block sequence") | ||
| errZeroBlockTimestampMismatch = errors.New("zero block timestamp does not match last non-Simplex inner block timestamp") | ||
| errPrevSealingBlockNotFinalized = errors.New("previous sealing block is not finalized") | ||
| errBlockDigestMismatch = errors.New("does not match proposed block digest") | ||
|
|
@@ -905,6 +906,11 @@ func (sm *StateMachine) buildBlockZero(parentBlock StateMachineBlock, simplexMet | |
| timestamp := sm.LastNonSimplexInnerBlock.Timestamp().UnixMilli() | ||
| simplexEpochInfo := constructSimplexZeroBlockSimplexEpochInfo(pChainHeight, validatorSet, prevVMBlockSeq) | ||
|
|
||
| // The zero block builds on top of the last non-Simplex block, which is identified by its inner block's | ||
| // digest rather than by a Simplex block digest, and sits right above it in the sequence. | ||
| simplexMetadata.Prev = sm.LastNonSimplexInnerBlock.Digest() | ||
| simplexMetadata.Seq = sm.LastNonSimplexInnerBlock.Height() + 1 | ||
|
|
||
| // The zero block carries over the parent's ICM epoch unchanged, just as it carries over the | ||
| // timestamp. If the parent is a genesis block that predates ICM, the carried-over epoch is empty, | ||
| // and the first ICM epoch begins on the block built on top of the zero block. | ||
|
|
@@ -984,8 +990,13 @@ func (sm *StateMachine) verifyBlockZero(block *StateMachineBlock, prevBlock Stat | |
| if block.InnerBlock != nil { | ||
| return errZeroBlockHasInnerBlock | ||
| } | ||
| if prevBlock.InnerBlock.Digest() != sm.LastNonSimplexInnerBlock.Digest() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think because |
||
| return errZeroBlockInnerDigestMismatch | ||
|
|
||
| // The zero block must build upon the last non-Simplex block | ||
| if block.Metadata.SimplexProtocolMetadata.Prev != sm.LastNonSimplexInnerBlock.Digest() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we also verify the sequence is as expected?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| return errZeroBlockPrevDigestMismatch | ||
| } | ||
| if block.Metadata.SimplexProtocolMetadata.Seq != sm.LastNonSimplexInnerBlock.Height()+1 { | ||
| return errZeroBlockSeqMismatch | ||
| } | ||
|
|
||
| // The timestamp must equal the last non-Simplex inner block's timestamp. | ||
|
|
||
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added