Documentation
¶
Index ¶
- Variables
- func NewDefaultKVStore(finalizationSafetyThreshold, epochExtensionViewCount uint64, ...) (protocol_state.KVStoreAPI, error)
- func NewKVStoreV0(finalizationSafetyThreshold, epochExtensionViewCount uint64, ...) (protocol_state.KVStoreAPI, error)
- func VersionedDecode(version uint64, bz []byte) (protocol_state.KVStoreAPI, error)
- type Modelv0
- func (model *Modelv0) GetEpochExtensionViewCount() uint64
- func (model *Modelv0) GetEpochStateID() flow.Identifier
- func (model *Modelv0) GetFinalizationSafetyThreshold() uint64
- func (model *Modelv0) GetProtocolStateVersion() uint64
- func (model *Modelv0) ID() flow.Identifier
- func (model *Modelv0) Replicate(protocolVersion uint64) (protocol_state.KVStoreMutator, error)
- func (model *Modelv0) SetEpochExtensionViewCount(viewCount uint64) error
- func (model *Modelv0) SetEpochStateID(id flow.Identifier)
- func (model *Modelv0) VersionedEncode() (uint64, []byte, error)
- type Modelv1
- type Modelv2
- type PSVersionUpgradeStateMachine
- type PSVersionUpgradeStateMachineFactory
- type ProtocolKVStore
- func (p *ProtocolKVStore) ByBlockID(blockID flow.Identifier) (protocol_state.KVStoreAPI, error)
- func (p *ProtocolKVStore) ByID(protocolStateID flow.Identifier) (protocol_state.KVStoreAPI, error)
- func (p *ProtocolKVStore) StoreTx(stateID flow.Identifier, kvStore protocol.KVStoreReader) func(*transaction.Tx) error
- type SetValueStateMachine
- type SetValueStateMachineFactory
- type UpgradableModel
Constants ¶
This section is empty.
Variables ¶
var ErrIncompatibleVersionChange = errors.New("incompatible version change when replicating the Protocol State's kvstore")
ErrIncompatibleVersionChange is a sentinel returned when we attempt to replicate a parent KV store snapshot into a snapshot with the specified `protocolVersion` but such operation is not supported by the parent snapshot.
var ErrInvalidActivationView = errors.New("invalid activation view for the new Protocol State version")
ErrInvalidActivationView is a sentinel returned when we attempt to process a KV store update, which has an activation view `V` so that `CurrentView + SafetyBuffer < V` does NOT hold.
var ErrInvalidUpgradeVersion = errors.New("invalid upgrade version for the Protocol State's kvstore")
ErrInvalidUpgradeVersion is a sentinel returned when we attempt to set a new kvstore version via a ProtocolStateVersionUpgrade event, but the new version is not strictly greater than the current version. This error happens when smart contract has different understanding of the protocol state version than the node software.
var ErrInvalidValue = errors.New("invalid value for the requested key in Protocol State's kvstore")
ErrInvalidValue is a sentinel returned when a value is not considered valid for a given key. This sentinel is applicable on a key-by-key basis: same value can be considered valid/invalid for different keys.
var ErrKeyNotSet = errors.New("no value for requested key in Protocol State's kvstore")
ErrKeyNotSet is a sentinel returned when a key is queried and no value has been set. The key must exist in the currently active key-value store version. This sentinel is used to communicate an empty/unset value rather than using zero or nil values. This sentinel is applicable on a key-by-key basis: some keys will always have a value set, others will support unset values.
var ErrKeyNotSupported = errors.New("protocol state's kvstore does not support the specified key at this version")
ErrKeyNotSupported is a sentinel returned when a key is read or written, but the key does not exist in the currently active version of the key-value store. This can happen in two circumstances, for example:
- Current model is v2, software supports v3, and we query a key which was newly added in v3.
- Current model is v3 and we query a key which was added in v2 then removed in v3
var ErrUnsupportedVersion = errors.New("unsupported version for the Protocol State's kvstore")
ErrUnsupportedVersion is a sentinel returned when we attempt to decode a key-value store instance, but provide an unsupported version. This could happen if we accept an already-encoded key-value store instance from an external source (should be avoided in general) or if the node software version is downgraded.
Functions ¶
func NewDefaultKVStore ¶
func NewDefaultKVStore(finalizationSafetyThreshold, epochExtensionViewCount uint64, epochStateID flow.Identifier) (protocol_state.KVStoreAPI, error)
NewDefaultKVStore constructs a default Key-Value Store of the *latest* protocol version for bootstrapping. Currently, the KV store is largely empty. TODO: Shortcut in bootstrapping; we will probably have to start with a non-empty KV store in the future; TODO(efm-recovery): we need to bootstrap with v1 in order to test the upgrade to v2. Afterward, we should bootstrap with v2 by default for new networks. Potentially we may need to carry over the KVStore during a spork (with possible migrations).
func NewKVStoreV0 ¶
func NewKVStoreV0(finalizationSafetyThreshold, epochExtensionViewCount uint64, epochStateID flow.Identifier) (protocol_state.KVStoreAPI, error)
NewKVStoreV0 constructs a KVStore using the v0 model. This is used to test version upgrades, from v0 to v1.
func VersionedDecode ¶
func VersionedDecode(version uint64, bz []byte) (protocol_state.KVStoreAPI, error)
VersionedDecode decodes a serialized key-value store instance with the given version. Errors:
- ErrUnsupportedVersion if input version is not supported
Types ¶
type Modelv0 ¶
type Modelv0 struct { UpgradableModel EpochStateID flow.Identifier EpochExtensionViewCount uint64 FinalizationSafetyThreshold uint64 }
Modelv0 is v0 of the Protocol State key-value store. This model version is not intended to ever be the latest version supported by any software version. Since it is important that the store support managing different model version, this is here so that we can test the implementation with multiple supported KV model versions from the beginning.
func (*Modelv0) GetEpochExtensionViewCount ¶ added in v0.37.1
GetEpochExtensionViewCount returns the number of views for a hypothetical epoch extension. Note that this value can change at runtime (through a service event). When a new extension is added, the view count is used right at this point in the protocol state's evolution. In other words, different extensions can have different view counts.
func (*Modelv0) GetEpochStateID ¶
func (model *Modelv0) GetEpochStateID() flow.Identifier
GetEpochStateID returns the state ID of the epoch state. This is part of the most basic model and is used to commit the epoch state to the KV store.
func (*Modelv0) GetFinalizationSafetyThreshold ¶ added in v0.39.0
func (*Modelv0) GetProtocolStateVersion ¶
GetProtocolStateVersion returns the version of the Protocol State Snapshot that is backing the `Reader` interface. It is the protocol version that originally created the Protocol State Snapshot. Changes in the protocol state version correspond to changes in the set of key-value pairs which are supported, and which model is used for serialization.
func (*Modelv0) ID ¶
func (model *Modelv0) ID() flow.Identifier
ID returns an identifier for this key-value store snapshot by hashing internal fields and version number.
func (*Modelv0) Replicate ¶
func (model *Modelv0) Replicate(protocolVersion uint64) (protocol_state.KVStoreMutator, error)
Replicate instantiates a Protocol State Snapshot of the given protocolVersion. It clones existing snapshot if protocolVersion = currentVersion. It transitions to next version if protocolVersion = currentVersion+1. Expected errors during normal operations:
- ErrIncompatibleVersionChange if replicating the Parent Snapshot into a Snapshot with the specified `protocolVersion` is not supported.
func (*Modelv0) SetEpochExtensionViewCount ¶ added in v0.37.1
SetEpochExtensionViewCount sets the number of views for a hypothetical epoch extension. Expected errors during normal operations:
- kvstore.ErrInvalidValue - if the view count is less than FinalizationSafetyThreshold*2.
func (*Modelv0) SetEpochStateID ¶
func (model *Modelv0) SetEpochStateID(id flow.Identifier)
SetEpochStateID sets the state ID of the epoch state. This method is used to commit the epoch state to the KV store when the state of the epoch is updated.
type Modelv1 ¶
type Modelv1 struct {
Modelv0
}
Modelv1 is v1 of the Protocol State key-value store. This represents the first model version which will be considered "latest" by any deployed software version.
func (*Modelv1) GetProtocolStateVersion ¶
GetProtocolStateVersion returns the version of the Protocol State Snapshot that is backing the `Reader` interface. It is the protocol version that originally created the Protocol State Snapshot. Changes in the protocol state version correspond to changes in the set of key-value pairs which are supported, and which model is used for serialization.
func (*Modelv1) ID ¶
func (model *Modelv1) ID() flow.Identifier
ID returns an identifier for this key-value store snapshot by hashing internal fields and version number.
func (*Modelv1) Replicate ¶
func (model *Modelv1) Replicate(protocolVersion uint64) (protocol_state.KVStoreMutator, error)
Replicate instantiates a Protocol State Snapshot of the given protocolVersion. It clones existing snapshot if protocolVersion = currentVersion. It transitions to next version if protocolVersion = currentVersion+1. Expected errors during normal operations:
- ErrIncompatibleVersionChange if replicating the Parent Snapshot into a Snapshot with the specified `protocolVersion` is not supported.
type Modelv2 ¶ added in v0.39.0
type Modelv2 struct {
Modelv1
}
Modelv2 reflects a behavioural change of the protocol (compared to Modelv1). Despite there being no change of the actual data model, we increment the version to coordinate switching between the old and the new protocol behaviour. This version adds the following changes:
- Non-system-chunk service event validation support (adds ChunkBody.ServiceEventCount field)
- EFM Recovery (adds EpochCommit.DKGIndexMap field)
func (*Modelv2) GetProtocolStateVersion ¶ added in v0.39.0
GetProtocolStateVersion returns the version of the Protocol State Snapshot that is backing the `Reader` interface. It is the protocol version that originally created the Protocol State Snapshot. Changes in the protocol state version correspond to changes in the set of key-value pairs which are supported, and which model is used for serialization.
func (*Modelv2) ID ¶ added in v0.39.0
func (model *Modelv2) ID() flow.Identifier
ID returns an identifier for this key-value store snapshot by hashing internal fields and version number.
func (*Modelv2) Replicate ¶ added in v0.39.0
func (model *Modelv2) Replicate(protocolVersion uint64) (protocol_state.KVStoreMutator, error)
Replicate instantiates a Protocol State Snapshot of the given protocolVersion. It clones existing snapshot if protocolVersion = currentVersion, other versions are not supported yet. Expected errors during normal operations:
- ErrIncompatibleVersionChange if replicating the Parent Snapshot into a Snapshot with the specified `protocolVersion` is not supported.
type PSVersionUpgradeStateMachine ¶
type PSVersionUpgradeStateMachine struct { common.BaseKeyValueStoreStateMachine // contains filtered or unexported fields }
PSVersionUpgradeStateMachine encapsulates the logic for evolving the version of the Protocol State. Specifically, it consumes ProtocolStateVersionUpgrade ServiceEvent that are sealed by the candidate block (possibly still under construction) with the given view. Each relevant event is validated before it is applied to the KV store. All updates are applied to a copy of parent KV store, so parent KV store is not modified. A separate instance should be created for each block to process the updates therein.
func NewPSVersionUpgradeStateMachine ¶
func NewPSVersionUpgradeStateMachine( telemetry protocol_state.StateMachineTelemetryConsumer, candidateView uint64, parentState protocol.KVStoreReader, evolvingState protocol_state.KVStoreMutator, ) *PSVersionUpgradeStateMachine
NewPSVersionUpgradeStateMachine creates a new state machine to update a specific sub-state of the KV Store. It schedules protocol state version upgrades upon receiving a `ProtocolStateVersionUpgrade` event. The actual model upgrade is handled in the upper layer (`ProtocolStateMachine`).
func (*PSVersionUpgradeStateMachine) EvolveState ¶
func (m *PSVersionUpgradeStateMachine) EvolveState(orderedUpdates []flow.ServiceEvent) error
EvolveState applies the state change(s) on sub-state P for the candidate block (under construction). Implementation processes only relevant service events and ignores all other events. No errors are expected during normal operations.
type PSVersionUpgradeStateMachineFactory ¶
type PSVersionUpgradeStateMachineFactory struct {
// contains filtered or unexported fields
}
PSVersionUpgradeStateMachineFactory is a factory for creating PSVersionUpgradeStateMachine instances.
func NewPSVersionUpgradeStateMachineFactory ¶
func NewPSVersionUpgradeStateMachineFactory(telemetry protocol_state.StateMachineTelemetryConsumer) *PSVersionUpgradeStateMachineFactory
NewPSVersionUpgradeStateMachineFactory returns a factory for instantiating PSVersionUpgradeStateMachines. The created state machines report their operations to the provided telemetry consumer.
func (*PSVersionUpgradeStateMachineFactory) Create ¶
func (f *PSVersionUpgradeStateMachineFactory) Create(candidateView uint64, _ flow.Identifier, parentState protocol.KVStoreReader, mutator protocol_state.KVStoreMutator) (protocol_state.KeyValueStoreStateMachine, error)
Create instantiates a new PSVersionUpgradeStateMachine, which processes ProtocolStateVersionUpgrade ServiceEvents that are sealed by the candidate block (possibly still under construction) with the given view. No errors are expected during normal operations.
type ProtocolKVStore ¶
type ProtocolKVStore struct {
storage.ProtocolKVStore
}
ProtocolKVStore persists different snapshots of key-value stores [KV-stores]. Here, we augment the low-level primitives provided by `storage.ProtocolKVStore` with logic for encoding and decoding the state snapshots into abstract representation `protocol_state.KVStoreAPI`.
TODO (optional): include a cache of the _decoded_ Protocol States, so we don't decode+encode on each consensus view (hot-path)
func NewProtocolKVStore ¶
func NewProtocolKVStore(protocolStateSnapshots storage.ProtocolKVStore) *ProtocolKVStore
NewProtocolKVStore instantiates a ProtocolKVStore for querying & storing deserialized `protocol_state.KVStoreAPIs`. At this abstraction level, we can only handle protocol state snapshots, whose data models are supported by the current software version. There might be serialized snapshots with legacy versions in the database, that are not supported anymore by this software version and can only be retrieved as versioned binary blobs via `storage.ProtocolKVStore`.
func (*ProtocolKVStore) ByBlockID ¶
func (p *ProtocolKVStore) ByBlockID(blockID flow.Identifier) (protocol_state.KVStoreAPI, error)
ByBlockID retrieves the kv-store snapshot that the block with the given ID proposes. CAUTION: this store snapshot requires confirmation by a QC and will only become active at the child block, _after_ validating the QC. Protocol convention:
- Consider block B, whose ingestion might potentially lead to an updated KV store state. For example, the state changes if we seal some execution results emitting specific service events.
- For the key `blockID`, we use the identity of block B which _proposes_ this updated KV store. As value, the hash of the resulting state at the end of processing B is to be used.
- CAUTION: The updated state requires confirmation by a QC and will only become active at the child block, _after_ validating the QC.
Expected errors during normal operations:
- storage.ErrNotFound if no snapshot has been indexed for the given block.
- ErrUnsupportedVersion if input version is not supported
func (*ProtocolKVStore) ByID ¶
func (p *ProtocolKVStore) ByID(protocolStateID flow.Identifier) (protocol_state.KVStoreAPI, error)
ByID retrieves the KV store snapshot with the given ID. Expected errors during normal operations:
- storage.ErrNotFound if no snapshot with the given Identifier is known.
- ErrUnsupportedVersion if input version is not supported
func (*ProtocolKVStore) StoreTx ¶
func (p *ProtocolKVStore) StoreTx(stateID flow.Identifier, kvStore protocol.KVStoreReader) func(*transaction.Tx) error
StoreTx returns an anonymous function (intended to be executed as part of a badger transaction), which persists the given KV-store snapshot as part of a DB tx. Per convention, all implementations of `protocol.KVStoreReader` must support encoding their state into a version and data blob. Expected errors of the returned anonymous function:
- storage.ErrAlreadyExists if a KV-store snapshot with the given id is already stored.
type SetValueStateMachine ¶ added in v0.39.0
type SetValueStateMachine struct { common.BaseKeyValueStoreStateMachine // contains filtered or unexported fields }
SetValueStateMachine encapsulates the logic for evolving sub-state of KV store by setting particular values. Specifically, it consumes service events that are sealed by the candidate block (possibly still under construction) with the given view. Each relevant event is validated before it is applied to the KV store. All updates are applied to a copy of parent KV store, so parent KV store is not modified. A separate instance should be created for each block to process the updates therein.
func NewSetValueStateMachine ¶ added in v0.39.0
func NewSetValueStateMachine( telemetry protocol_state.StateMachineTelemetryConsumer, candidateView uint64, parentState protocol.KVStoreReader, evolvingState protocol_state.KVStoreMutator, ) *SetValueStateMachine
NewSetValueStateMachine creates a new state machine to update a specific sub-state of the KV Store.
func (*SetValueStateMachine) EvolveState ¶ added in v0.39.0
func (m *SetValueStateMachine) EvolveState(orderedUpdates []flow.ServiceEvent) error
EvolveState applies the state change(s) on sub-state P for the candidate block (under construction). Implementation processes only relevant service events and ignores all other events. No errors are expected during normal operations.
type SetValueStateMachineFactory ¶ added in v0.39.0
type SetValueStateMachineFactory struct {
// contains filtered or unexported fields
}
SetValueStateMachineFactory is a factory for creating SetValueStateMachine instances.
func NewSetValueStateMachineFactory ¶ added in v0.39.0
func NewSetValueStateMachineFactory(telemetry protocol_state.StateMachineTelemetryConsumer) *SetValueStateMachineFactory
NewSetValueStateMachineFactory returns a factory for instantiating SetValueStateMachines. The created state machines report their operations to the provided telemetry consumer.
func (*SetValueStateMachineFactory) Create ¶ added in v0.39.0
func (f *SetValueStateMachineFactory) Create(candidateView uint64, _ flow.Identifier, parentState protocol.KVStoreReader, mutator protocol_state.KVStoreMutator) (protocol_state.KeyValueStoreStateMachine, error)
Create creates a new instance of SetValueStateMachine. No errors are expected during normal operations.
type UpgradableModel ¶
type UpgradableModel struct {
VersionUpgrade *protocol.ViewBasedActivator[uint64]
}
UpgradableModel is a utility struct that must be embedded in all model versions to provide a common interface for managing protocol version upgrades.
func (*UpgradableModel) GetVersionUpgrade ¶
func (model *UpgradableModel) GetVersionUpgrade() *protocol.ViewBasedActivator[uint64]
GetVersionUpgrade returns the upgrade version of protocol. VersionUpgrade is a view-based activator that specifies the version which has to be applied and the view from which on it has to be applied. After an upgrade activation view has passed, the (version, view) data remains in the state until the next upgrade is scheduled (essentially persisting the most recent past update until a subsequent update is scheduled).
func (*UpgradableModel) SetVersionUpgrade ¶
func (model *UpgradableModel) SetVersionUpgrade(activator *protocol.ViewBasedActivator[uint64])
SetVersionUpgrade sets the protocol upgrade version. This method is used to update the Protocol State version when a flow.ProtocolStateVersionUpgrade is processed. It contains the new version and the view at which it has to be applied.