Documentation
¶
Index ¶
- func IsBootstrapped(db storage.DB) (bool, error)
- func SkipNetworkAddressValidation(conf *BootstrapConfig)
- type BootstrapConfig
- type BootstrapConfigOptions
- type EpochQuery
- type FinalizedSnapshot
- type FollowerState
- type ParticipantState
- type Snapshot
- func (s *Snapshot) Commit() (flow.StateCommitment, error)
- func (s *Snapshot) Descendants() ([]flow.Identifier, error)
- func (s *Snapshot) EpochPhase() (flow.EpochPhase, error)
- func (s *Snapshot) EpochProtocolState() (protocol.EpochProtocolState, error)
- func (s *Snapshot) Epochs() protocol.EpochQuery
- func (s *Snapshot) Head() (*flow.Header, error)
- func (s *Snapshot) Identities(selector flow.IdentityFilter[flow.Identity]) (flow.IdentityList, error)
- func (s *Snapshot) Identity(nodeID flow.Identifier) (*flow.Identity, error)
- func (s *Snapshot) Params() protocol.GlobalParams
- func (s *Snapshot) ProtocolState() (protocol.KVStoreReader, error)
- func (s *Snapshot) QuorumCertificate() (*flow.QuorumCertificate, error)
- func (s *Snapshot) RandomSource() ([]byte, error)
- func (s *Snapshot) SealedResult() (*flow.ExecutionResult, *flow.Seal, error)
- func (s *Snapshot) SealingSegment() (*flow.SealingSegment, error)
- func (s *Snapshot) VersionBeacon() (*flow.SealedVersionBeacon, error)
- type State
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsBootstrapped ¶ added in v0.14.0
IsBootstrapped returns whether the database contains a bootstrapped state
func SkipNetworkAddressValidation ¶ added in v0.22.0
func SkipNetworkAddressValidation(conf *BootstrapConfig)
Types ¶
type BootstrapConfig ¶ added in v0.22.0
type BootstrapConfig struct { // SkipNetworkAddressValidation flags allows skipping all the network address related // validations not needed for an unstaked node SkipNetworkAddressValidation bool }
type BootstrapConfigOptions ¶ added in v0.22.0
type BootstrapConfigOptions func(conf *BootstrapConfig)
type EpochQuery ¶
type EpochQuery struct {
// contains filtered or unexported fields
}
EpochQuery encapsulates querying epochs w.r.t. a snapshot.
func (*EpochQuery) Current ¶
func (q *EpochQuery) Current() (protocol.CommittedEpoch, error)
Current returns the current epoch. No errors are expected during normal operation.
func (*EpochQuery) NextCommitted ¶ added in v0.39.2
func (q *EpochQuery) NextCommitted() (protocol.CommittedEpoch, error)
NextCommitted returns the next epoch as of this snapshot, only if it has been committed already. Error returns:
- protocol.ErrNextEpochNotCommitted if the next epoch has not yet been committed at the snapshot's reference block (the reference block does not reside in the EpochCommitted phase)
- generic error in case of unexpected critical internal corruption or bugs
func (*EpochQuery) NextUnsafe ¶ added in v0.39.2
func (q *EpochQuery) NextUnsafe() (protocol.TentativeEpoch, error)
NextUnsafe returns the next epoch, if it has been set up but not yet committed. Error returns:
- protocol.ErrNextEpochNotSetup if the next epoch has not yet been set up as of the snapshot's reference block (the reference block resides in the EpochStaking phase)
- protocol.ErrNextEpochAlreadyCommitted if the next epoch has already been committed at the snapshot's reference block (the reference block resides in the EpochCommitted phase)
- generic error in case of unexpected critical internal corruption or bugs
func (*EpochQuery) Previous ¶ added in v0.13.0
func (q *EpochQuery) Previous() (protocol.CommittedEpoch, error)
Previous returns the previous epoch. During the first epoch after the root block, this returns protocol.ErrNoPreviousEpoch (since there is no previous epoch). For all other epochs, returns the previous epoch.
type FinalizedSnapshot ¶ added in v0.31.0
type FinalizedSnapshot struct { Snapshot // contains filtered or unexported fields }
FinalizedSnapshot represents a read-only immutable snapshot of the protocol state at a finalized block. It is guaranteed to have a header available.
func NewFinalizedSnapshot ¶ added in v0.31.0
func NewFinalizedSnapshot(state *State, blockID flow.Identifier, header *flow.Header) *FinalizedSnapshot
NewFinalizedSnapshot instantiates a `FinalizedSnapshot`. CAUTION: the header's ID _must_ match `blockID` (not checked)
type FollowerState ¶ added in v0.14.0
type FollowerState struct { *State // contains filtered or unexported fields }
FollowerState implements a lighter version of a mutable protocol state. When extending the state, it performs hardly any checks on the block payload. Instead, the FollowerState relies on the consensus nodes to run the full payload check and uses quorum certificates to prove validity of block payloads. Consequently, a block B should only be considered valid, if there is a certifying QC for that block QC.View == Block.View && QC.BlockID == Block.ID().
The FollowerState allows non-consensus nodes to execute fork-aware queries against the protocol state, while minimizing the amount of payload checks the non-consensus nodes have to perform.
func NewFollowerState ¶ added in v0.14.0
func NewFollowerState( logger zerolog.Logger, tracer module.Tracer, consumer protocol.Consumer, state *State, index storage.Index, payloads storage.Payloads, blockTimer protocol.BlockTimer, ) (*FollowerState, error)
NewFollowerState initializes a light-weight version of a mutable protocol state. This implementation is suitable only for NON-Consensus nodes.
func (*FollowerState) ExtendCertified ¶ added in v0.30.0
func (m *FollowerState) ExtendCertified(ctx context.Context, certified *flow.CertifiedBlock) error
ExtendCertified extends the protocol state of a CONSENSUS FOLLOWER. While it checks the validity of the header; it does _not_ check the validity of the payload. Instead, the consensus follower relies on the consensus participants to validate the full payload. Payload validity must be proven by a valid quorum certificate (field `CertifiedBlock.CertifyingQC`). The certifying QC must match candidate block:
candidate.View == certifyingQC.View && candidate.ID() == certifyingQC.BlockID
CAUTION:
- This function expects that `certified.CertifyingQC` has been validated. (otherwise, the state will be corrupted)
- The PARENT block must already have been INGESTED.
- Attempts to extend the state with the _same block concurrently_ are not allowed. (will not corrupt the state, but may lead to an exception)
Per convention, the protocol state requires that the candidate's parent has already been ingested. Other than that, all valid extensions are accepted. Even if we have enough information to determine that a candidate block is already orphaned (e.g. its view is below the latest finalized view), it is important to accept it nevertheless to avoid spamming vulnerabilities. If a block is orphaned, consensus rules guarantee that there exists only a limited number of descendants which cannot increase anymore. So there is only a finite (generally small) amount of work to do accepting orphaned blocks and all their descendants. However, if we were to drop orphaned blocks, e.g. block X of the orphaned fork X <- Y <- Z, we might not have enough information to reject blocks Y, Z later if we receive them. We would re-request X, then determine it is orphaned and drop it, attempt to ingest Y re-request the unknown parent X and repeat potentially very often.
To ensure that all ancestors of a candidate block are correct and known to the FollowerState, some external ordering and queuing of incoming blocks is generally necessary (responsibility of Compliance Layer). Once a block is successfully ingested, repeated extension requests with this block are no-ops. This is convenient for the Compliance Layer after a crash, so it doesn't have to worry about which blocks have already been ingested before the crash. However, while running it is very easy for the Compliance Layer to avoid concurrent extension requests with the same block. Hence, for simplicity, the FollowerState may reject such requests with an exception.
No errors are expected during normal operations.
- In case of concurrent calls with the same `candidate` block, ExtendCertified may return a storage.ErrAlreadyExists or it may gracefully return. At the moment, ExtendCertified should be considered as NOT CONCURRENCY-SAFE.
func (*FollowerState) Finalize ¶ added in v0.14.0
func (m *FollowerState) Finalize(ctx context.Context, blockID flow.Identifier) error
Finalize marks the specified block as finalized. This method only finalizes one block at a time. Hence, the parent of `blockID` has to be the last finalized block. No errors are expected during normal operations.
type ParticipantState ¶ added in v0.30.0
type ParticipantState struct { *FollowerState // contains filtered or unexported fields }
ParticipantState implements a mutable state for consensus participant. It can extend the state with a new block, by checking the _entire_ block payload.
func NewFullConsensusState ¶ added in v0.14.0
func NewFullConsensusState( logger zerolog.Logger, tracer module.Tracer, consumer protocol.Consumer, state *State, index storage.Index, payloads storage.Payloads, blockTimer protocol.BlockTimer, receiptValidator module.ReceiptValidator, sealValidator module.SealValidator, ) (*ParticipantState, error)
NewFullConsensusState initializes a new mutable protocol state backed by a badger database. When extending the state with a new block, it checks the _entire_ block payload. Consensus nodes should use the FullConsensusState, while other node roles can use the lighter FollowerState.
func (*ParticipantState) Extend ¶ added in v0.30.0
Extend extends the protocol state of a CONSENSUS PARTICIPANT. It checks the validity of the _entire block_ (header and full payload).
CAUTION:
- per convention, the protocol state requires that the candidate's PARENT has already been INGESTED. Otherwise, an exception is returned.
- Attempts to extend the state with the _same block concurrently_ are not allowed. (will not corrupt the state, but may lead to an exception)
- We reject orphaned blocks with state.OutdatedExtensionError ! This is more performant, but requires careful handling by the calling code. Specifically, the caller should not just drop orphaned blocks from the cache to avoid wasteful re-requests. If we were to entirely forget orphaned blocks, e.g. block X of the orphaned fork X ← Y ← Z, we might not have enough information to reject blocks Y, Z later if we receive them. We would re-request X, then determine it is orphaned and drop it, attempt to ingest Y re-request the unknown parent X and repeat potentially very often.
To ensure that all ancestors of a candidate block are correct and known to the Protocol State, some external ordering and queuing of incoming blocks is generally necessary (responsibility of Compliance Layer). Once a block is successfully ingested, repeated extension requests with this block are no-ops. This is convenient for the Compliance Layer after a crash, so it doesn't have to worry about which blocks have already been ingested before the crash. However, while running it is very easy for the Compliance Layer to avoid concurrent extension requests with the same block. Hence, for simplicity, the Protocol State may reject such requests with an exception.
Expected errors during normal operations:
- state.OutdatedExtensionError if the candidate block is orphaned
- state.InvalidExtensionError if the candidate block is invalid
- In case of concurrent calls with the same `candidate` block, `Extend` may return a storage.ErrAlreadyExists or it may gracefully return. At the moment, `Extend` should be considered as NOT CONCURRENCY-SAFE.
type Snapshot ¶
type Snapshot struct {
// contains filtered or unexported fields
}
Snapshot implements the protocol.Snapshot interface. It represents a read-only immutable snapshot of the protocol state at the block it is constructed with. It allows efficient access to data associated directly with blocks at a given state (finalized, sealed), such as the related header, commit, seed or descending blocks. A block snapshot can lazily convert to an epoch snapshot in order to make data associated directly with epochs accessible through its API.
func (*Snapshot) Commit ¶
func (s *Snapshot) Commit() (flow.StateCommitment, error)
Commit retrieves the latest execution state commitment at the current block snapshot. This commitment represents the execution state as currently finalized.
func (*Snapshot) Descendants ¶ added in v0.17.6
func (s *Snapshot) Descendants() ([]flow.Identifier, error)
func (*Snapshot) EpochPhase ¶ added in v0.37.1
func (s *Snapshot) EpochPhase() (flow.EpochPhase, error)
func (*Snapshot) EpochProtocolState ¶ added in v0.33.30
func (s *Snapshot) EpochProtocolState() (protocol.EpochProtocolState, error)
EpochProtocolState returns the epoch part of dynamic protocol state that the Head block commits to. The compliance layer guarantees that only valid blocks are appended to the protocol state. Returns state.ErrUnknownSnapshotReference if snapshot reference block is unknown. All other errors should be treated as exceptions. For each block stored there should be a protocol state stored.
func (*Snapshot) Epochs ¶
func (s *Snapshot) Epochs() protocol.EpochQuery
func (*Snapshot) Identities ¶
func (s *Snapshot) Identities(selector flow.IdentityFilter[flow.Identity]) (flow.IdentityList, error)
func (*Snapshot) Params ¶ added in v0.23.2
func (s *Snapshot) Params() protocol.GlobalParams
func (*Snapshot) ProtocolState ¶ added in v0.33.30
func (s *Snapshot) ProtocolState() (protocol.KVStoreReader, error)
ProtocolState returns the dynamic protocol state that the Head block commits to. The compliance layer guarantees that only valid blocks are appended to the protocol state. Returns state.ErrUnknownSnapshotReference if snapshot reference block is unknown. All other errors should be treated as exceptions. For each block stored there should be a protocol state stored.
func (*Snapshot) QuorumCertificate ¶ added in v0.15.0
func (s *Snapshot) QuorumCertificate() (*flow.QuorumCertificate, error)
QuorumCertificate (QC) returns a valid quorum certificate pointing to the header at this snapshot. The sentinel error storage.ErrNotFound is returned if the QC is unknown.
func (*Snapshot) RandomSource ¶ added in v0.25.0
RandomSource returns the seed for the current block's snapshot. Expected error returns: * storage.ErrNotFound is returned if the QC is unknown.
func (*Snapshot) SealedResult ¶ added in v0.15.0
SealedResult returns the most recent included seal as of this block and the corresponding execution result. The seal may have been included in a parent block, if this block is empty. If this block contains multiple seals, this returns the seal for the block with the greatest height. TODO document error returns
func (*Snapshot) SealingSegment ¶ added in v0.15.0
func (s *Snapshot) SealingSegment() (*flow.SealingSegment, error)
SealingSegment will walk through the chain backward until we reach the block referenced by the latest seal and build a SealingSegment. As we visit each block we check each execution receipt in the block's payload to make sure we have a corresponding execution result, any execution results missing from blocks are stored in the `SealingSegment.ExecutionResults` field. See `model/flow/sealing_segment.md` for detailed technical specification of the Sealing Segment
Expected errors during normal operations:
- protocol.ErrSealingSegmentBelowRootBlock if sealing segment would stretch beyond the node's local history cut-off
- protocol.UnfinalizedSealingSegmentError if sealing segment would contain unfinalized blocks (including orphaned blocks)
func (*Snapshot) VersionBeacon ¶ added in v0.31.0
func (s *Snapshot) VersionBeacon() (*flow.SealedVersionBeacon, error)
type State ¶
type State struct {
// contains filtered or unexported fields
}
func Bootstrap ¶ added in v0.14.0
func Bootstrap( metrics module.ComplianceMetrics, db storage.DB, lockManager lockctx.Manager, headers storage.Headers, seals storage.Seals, results storage.ExecutionResults, blocks storage.Blocks, qcs storage.QuorumCertificates, setups storage.EpochSetups, commits storage.EpochCommits, epochProtocolStateSnapshots storage.EpochProtocolStateEntries, protocolKVStoreSnapshots storage.ProtocolKVStore, versionBeacons storage.VersionBeacons, root protocol.Snapshot, options ...BootstrapConfigOptions, ) (*State, error)
Bootstrap initializes a the protocol state from the provided root snapshot and persists it to the database. No errors expected during normal operation.
func OpenState ¶ added in v0.14.0
func OpenState( metrics module.ComplianceMetrics, db storage.DB, lockManager lockctx.Manager, headers storage.Headers, seals storage.Seals, results storage.ExecutionResults, blocks storage.Blocks, qcs storage.QuorumCertificates, setups storage.EpochSetups, commits storage.EpochCommits, epochProtocolState storage.EpochProtocolStateEntries, protocolKVStoreSnapshots storage.ProtocolKVStore, versionBeacons storage.VersionBeacons, ) (*State, error)
func (*State) AtBlockID ¶
func (state *State) AtBlockID(blockID flow.Identifier) protocol.Snapshot
AtBlockID returns a snapshot for the block with the given ID. The block may be finalized or un-finalized. This function may return an invalid.Snapshot with:
- state.ErrUnknownSnapshotReference: -> if no block with the given ID exists in the state
- exception for critical unexpected storage errors
func (*State) AtHeight ¶
AtHeight returns a snapshot for the finalized block at the given height. This function may return an invalid.Snapshot with:
- state.ErrUnknownSnapshotReference: -> if no block with the given height has been finalized, even if it is incorporated -> if the given height is below the root height
- exception for critical unexpected storage errors