kvstore

package
v0.39.0-pr6906-results.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2025 License: AGPL-3.0 Imports: 12 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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:

  1. Current model is v2, software supports v3, and we query a key which was newly added in v3.
  2. Current model is v3 and we query a key which was added in v2 then removed in v3
View Source
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

func (model *Modelv0) GetEpochExtensionViewCount() uint64

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 (model *Modelv0) GetFinalizationSafetyThreshold() uint64

func (*Modelv0) GetProtocolStateVersion

func (model *Modelv0) GetProtocolStateVersion() uint64

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

func (model *Modelv0) SetEpochExtensionViewCount(viewCount uint64) error

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.

func (*Modelv0) VersionedEncode

func (model *Modelv0) VersionedEncode() (uint64, []byte, error)

VersionedEncode encodes the key-value store, returning the version separately from the encoded bytes. No errors are expected during normal operation.

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

func (model *Modelv1) GetProtocolStateVersion() uint64

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.

func (*Modelv1) VersionedEncode

func (model *Modelv1) VersionedEncode() (uint64, []byte, error)

VersionedEncode encodes the key-value store, returning the version separately from the encoded bytes. No errors are expected during normal operation.

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

func (model *Modelv2) GetProtocolStateVersion() uint64

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.

func (*Modelv2) VersionedEncode added in v0.39.0

func (model *Modelv2) VersionedEncode() (uint64, []byte, error)

VersionedEncode encodes the key-value store, returning the version separately from the encoded bytes. No errors are expected during normal operation.

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

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

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL