Documentation ¶
Index ¶
- Variables
- func NewDefaultKVStore(epochStateID flow.Identifier) protocol_state.KVStoreAPI
- func NewKVStoreV0(epochStateID flow.Identifier) protocol_state.KVStoreAPI
- func VersionedDecode(version uint64, bz []byte) (protocol_state.KVStoreAPI, error)
- type Modelv0
- func (model *Modelv0) GetEpochStateID() flow.Identifier
- func (model *Modelv0) GetProtocolStateVersion() uint64
- func (model *Modelv0) ID() flow.Identifier
- func (model *Modelv0) Replicate(protocolVersion uint64) (protocol_state.KVStoreMutator, error)
- func (model *Modelv0) SetEpochStateID(id flow.Identifier)
- func (model *Modelv0) VersionedEncode() (uint64, []byte, error)
- type Modelv1
- type PSVersionUpgradeStateMachine
- func (m *PSVersionUpgradeStateMachine) Build() (*transaction.DeferredBlockPersist, error)
- func (m *PSVersionUpgradeStateMachine) EvolveState(orderedUpdates []flow.ServiceEvent) error
- func (m *PSVersionUpgradeStateMachine) ParentState() protocol.KVStoreReader
- func (m *PSVersionUpgradeStateMachine) View() uint64
- 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 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 candidateView `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 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(epochStateID flow.Identifier) protocol_state.KVStoreAPI
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; Potentially we may need to carry over the KVStore during a spork (with possible migrations).
func NewKVStoreV0 ¶
func NewKVStoreV0(epochStateID flow.Identifier) protocol_state.KVStoreAPI
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 }
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) 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) 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 and performs a migration if `protocolVersion = 1`. Expected errors during normal operations:
- ErrIncompatibleVersionChange if replicating the Parent Snapshot into a Snapshot with the specified `protocolVersion` is not supported.
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 = 1`, 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 {
// 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( candidateView uint64, params protocol.GlobalParams, parentState protocol.KVStoreReader, mutator 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) Build ¶
func (m *PSVersionUpgradeStateMachine) Build() (*transaction.DeferredBlockPersist, error)
Build is a no-op, because scheduled version upgrades are stored in the KVStore only, which the caller `protocol.MutableProtocolState` persist. (There is no secondary database operations to index or persist version upgrade data separately)
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.
func (*PSVersionUpgradeStateMachine) ParentState ¶
func (m *PSVersionUpgradeStateMachine) ParentState() protocol.KVStoreReader
ParentState returns parent state associated with this state machine.
func (*PSVersionUpgradeStateMachine) View ¶
func (m *PSVersionUpgradeStateMachine) View() uint64
View returns the view associated with this state machine. The view of the state machine equals the view of the block carrying the respective updates.
type PSVersionUpgradeStateMachineFactory ¶
type PSVersionUpgradeStateMachineFactory struct {
// contains filtered or unexported fields
}
PSVersionUpgradeStateMachineFactory is a factory for creating PSVersionUpgradeStateMachine instances.
func NewPSVersionUpgradeStateMachineFactory ¶
func NewPSVersionUpgradeStateMachineFactory(params protocol.GlobalParams) *PSVersionUpgradeStateMachineFactory
func (*PSVersionUpgradeStateMachineFactory) Create ¶
func (f *PSVersionUpgradeStateMachineFactory) Create(candidateView uint64, parentBlockID flow.Identifier, parentState protocol.KVStoreReader, mutator protocol_state.KVStoreMutator) (protocol_state.KeyValueStoreStateMachine, error)
Create instantiates a new PSVersionUpgradeStateMachine, which processes ProtocolStateVersionUpgrade ServiceEvent 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 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 it has to be applied. It may return the current protocol version with a past view if the upgrade has already been activated.
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.