Skip to content

Commit

Permalink
avoid reading the sealing segment in the scaffold
Browse files Browse the repository at this point in the history
This change is to support nodes which bootstrapped with an invalid root
snapshot (too-short sealing segment) during the course of a v0.33
network. The software has been updated to again reject these invalid
snapshots for new nodes, but we need a temporary measure for nodes
which:
- bootstrapped using an invalid snapshot
- are unable or unwilling to re-bootstrap

In other words, we want a software version which will accomodate a
database that has been bootstrapped with an invalid snapshot (only for
the duration of v0.33 networks, this should not be ported to subsequent
major version!)

This PR:
- moves the setRootSnapshot call to after the database setup in both
  initial and subsequent startup cases
- changes the caching of root snapshot values to avoid reading the
  problematic root sealing segment

This should allow nodes with a bad root snapshot to boot, be a no-op for
nodes with a correct root snapshot, and also prevent nodes with a bad
root snapshot from producing further invalid snapshots, which would
propagate the underlying problem.
  • Loading branch information
jordanschalm committed Jun 14, 2024
1 parent 42d7ae7 commit 128bb7c
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions cmd/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -1337,10 +1337,6 @@ func (fnb *FlowNodeBuilder) initState() error {
return fmt.Errorf("failed validate root snapshot from disk: %w", err)
}
}
// set root snapshot fields
if err := fnb.setRootSnapshot(rootSnapshot); err != nil {
return err
}

// generate bootstrap config options as per NodeConfig
var options []badgerState.BootstrapConfigOptions
Expand All @@ -1360,13 +1356,18 @@ func (fnb *FlowNodeBuilder) initState() error {
fnb.Storage.EpochCommits,
fnb.Storage.Statuses,
fnb.Storage.VersionBeacons,
fnb.RootSnapshot,
rootSnapshot,
options...,
)
if err != nil {
return fmt.Errorf("could not bootstrap protocol state: %w", err)
}

// set root snapshot fields
if err := fnb.setRootSnapshot(rootSnapshot); err != nil {
return err
}

fnb.Logger.Info().
Hex("root_result_id", logging.Entity(fnb.RootResult)).
Hex("root_state_commitment", fnb.RootSeal.FinalState[:]).
Expand Down Expand Up @@ -1426,13 +1427,20 @@ func (fnb *FlowNodeBuilder) setRootSnapshot(rootSnapshot protocol.Snapshot) erro
return fmt.Errorf("failed to read root sealed result: %w", err)
}

sealingSegment, err := fnb.RootSnapshot.SealingSegment()
rootHeader, err := fnb.RootSnapshot.Head()
if err != nil {
return fmt.Errorf("could not read root header: %w", err)
}
rootBlockID := rootHeader.ID()
fnb.FinalizedRootBlock, err = fnb.Storage.Blocks.ByID(rootBlockID)
if err != nil {
return fmt.Errorf("could not read finalized root block (id=%x): %w", rootBlockID, err)
}
fnb.SealedRootBlock, err = fnb.Storage.Blocks.ByID(fnb.RootSeal.BlockID)
if err != nil {
return fmt.Errorf("failed to read root sealing segment: %w", err)
return fmt.Errorf("could not read sealed root block (id=%x): %w", fnb.RootSeal.BlockID, err)
}

fnb.FinalizedRootBlock = sealingSegment.Highest()
fnb.SealedRootBlock = sealingSegment.Sealed()
fnb.RootQC, err = fnb.RootSnapshot.QuorumCertificate()
if err != nil {
return fmt.Errorf("failed to read root QC: %w", err)
Expand Down

0 comments on commit 128bb7c

Please sign in to comment.