block

package
v1.11.6-beta Latest Latest
Warning

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

Go to latest
Published: May 25, 2024 License: BSD-3-Clause Imports: 17 Imported by: 0

README

State Sync: Engine role and workflow

State sync promises to dramatically cut down the time it takes for a validator to join a chain by directly downloading and verifying the state of the chain, rather than rebuilding the state by processing all historical blocks.

Avalanche's approach to state sync leaves most of specifics to each VM, to allow maximal flexibility. However, the Avalanche engine plays a well defined role in selecting and validating state summaries, which are the state sync seeds used by a VM to kickstart its syncing process.

In this document, we outline the engine's role in state sync and the requirements for VMs implementing state sync.

StateSyncableVM Interface

The StateSyncableVM interface enumerates all the features a VM must implement to support state sync.

The Avalanche engine begins bootstrapping a VM through state-sync if StateSyncEnabled() returns true. Otherwise, the engine falls back to processing all historical blocks.

The Avalanche engine performs two state-syncing phases:

  • Frontier retrieval: retrieve the most recent state summaries from a random subset of validators
  • Frontier validation: the retrieved state summaries are voted on by all connected validators

Security is guaranteed by accepting the state summary if and only if a sufficient fraction of stake has validated them. This prevents malicious actors from poisoning a VM with a corrupt or unavailable state summary.

Frontier retrieval

The Avalanche engine waits to begin frontier retrieval until enough stake is connected.

The engine first calls GetOngoingSyncStateSummary() to retrieve a local state summary from the VM. If available, this state summary is added to the frontier.

A state summary may be locally available if the VM was previously shut down while state syncing. By revalidating this local summary, Avalanche engine helps the VM understand whether its local state summary is still widely supported by the network. If the local state summary is widely supported, the engine will allow the VM to resume state syncing from it. Otherwise the VM will be requested to drop it in favour of a fresher, more available state summary.

State summary frontier is collected as follows:

  1. The Avalanche engine samples a random subset of validators and sends each of them a GetStateSummaryFrontier message to retrieve the latest state summaries.
  2. Each target validator pulls its latest state summary from the VM via the GetLastStateSummary method, and responds with a StateSummaryFrontier message.
  3. StateSummaryFrontier responses are parsed via the ParseStateSummary method and added to the state summary frontier to be validated.

The Avalanche engine does not pose major constraints on the state summary structure; as its parsing is left to the VM to implement. However, the Avalanche engine does require each state summary to be uniquely described by two identifiers, Height and ID. The reason for this double identification will be clearer as we describe the state summary validation phase.

Height is a uint64 and represents the block height that the state summaries refers to. Height offers the most succinct way to address an accepted state summary.

ID is an ids.ID type and is the verifiable way to address a state summary, regardless of its status. In most implementations, a state summary ID is the hash of the state summary's bytes.

Frontier validation

Once the frontiers have been retrieved, a network wide voting round is initiated to validate them. Avalanche sends a GetAcceptedStateSummary message to each connected validator, containing a list of the state summary frontier's Heights. Heights provide a unique yet succinct way to identify state summaries, and they help reduce the size of the GetAcceptedStateSummary message.

When a validator receives a GetAcceptedStateSummary message, it will respond with IDs corresponding to the Heights sent in the message. This is done by calling GetStateSummary(summaryHeight uint64) on the VM for each Height. Unknown or unsupported state summary Heights are skipped. Responding with the summary IDs allows the client to verify votes easily and ensures the integrity of the state sync starting point.

AcceptedStateSummary messages returned to the state syncing node are validated by comparing responded state summaries IDs with the IDs calculated from state summary frontier previously retrieved. Valid responses are stored along with cumulative validator stake.

Once all validators respond or timeout, Avalanche will select all the state summaries with a sufficient stake verifying them.

If no state summary is backed by sufficient stake, the process of collecting a state frontier and validating it is restarted again, up to a configurable number of times.

Of all the valid state summaries, one is selected and passed to the VM by calling Summary.Accept(). The preferred state summary is selected as follows: if the locally available one is still valid and supported by the network it will be accepted to allow the VM to resume the previously interrupted state sync. Otherwise, the most recent state summary (with the highest Height value) is picked. Note that Avalanche engine will block upon Summary.Accept()'s response, hence the VM should perform actual state syncing asynchronously.

The Avalanche engine declares state syncing complete in the following cases:

  1. Summary.Accept() returns (StateSyncSkipped, nil) signalling that the VM considered the summary valid but skips the whole syncing process. This may happen if the VM estimates that bootstrapping would be faster than state syncing with the provided summary.
  2. The VM sends StateSyncDone via the Notify channel.

Note that any error returned from Summary.Accept() is considered fatal and causes the engine to shutdown.

If Summary.Accept() returns (StateSyncStatic, nil), Avalanche will wait until state synced is complete before continuing the bootstrapping process. If Summary.Accept() returns (StateSyncDynamic, nil), Avalanche will immediately continue the bootstrapping process. If bootstrapping finishes before the state sync has been completed, Chits messages will include the LastAcceptedID rather than the PreferredID.

Documentation

Overview

Package block is a generated GoMock package.

Package block is a generated GoMock package.

Package block is a generated GoMock package.

Package block is a generated GoMock package.

Index

Constants

This section is empty.

Variables

View Source
var ErrIndexIncomplete = errors.New("query failed because height index is incomplete")

ErrIndexIncomplete is used to indicate that the VM is currently repairing its index.

TODO: Remove after v1.11.x activates.

View Source
var ErrRemoteVMNotImplemented = errors.New("vm does not implement RemoteVM interface")
View Source
var ErrStateSyncableVMNotImplemented = errors.New("vm does not implement StateSyncableVM interface")

Functions

func BatchedParseBlock

func BatchedParseBlock(
	ctx context.Context,
	vm Parser,
	blks [][]byte,
) ([]snowman.Block, error)

func GetAncestors

func GetAncestors(
	ctx context.Context,
	log logging.Logger,
	vm Getter,
	blkID ids.ID,
	maxBlocksNum int,
	maxBlocksSize int,
	maxBlocksRetrivalTime time.Duration,
) ([][]byte, error)

Types

type BatchedChainVM

type BatchedChainVM interface {
	GetAncestors(
		ctx context.Context,
		blkID ids.ID,
		maxBlocksNum int,
		maxBlocksSize int,
		maxBlocksRetrivalTime time.Duration,
	) ([][]byte, error)

	BatchedParseBlock(ctx context.Context, blks [][]byte) ([]snowman.Block, error)
}

BatchedChainVM extends the minimal functionalities exposed by ChainVM for VMs communicating over network (gRPC in our case). This allows more efficient operations since calls over network can be duly batched

type BuildBlockWithContextChainVM

type BuildBlockWithContextChainVM interface {
	// Attempt to build a new block given that the P-Chain height is
	// [blockCtx.PChainHeight].
	//
	// This method will be called if and only if the proposervm is activated.
	// Otherwise [BuildBlock] will be called.
	BuildBlockWithContext(ctx context.Context, blockCtx *Context) (snowman.Block, error)
}

BuildBlockWithContextChainVM defines the interface a ChainVM can optionally implement to consider the P-Chain height when building blocks.

type ChainVM

type ChainVM interface {
	common.VM

	Getter
	Parser

	// Attempt to create a new block from data contained in the VM.
	//
	// If the VM doesn't want to issue a new block, an error should be
	// returned.
	BuildBlock(context.Context) (snowman.Block, error)

	// Notify the VM of the currently preferred block.
	//
	// This should always be a block that has no children known to consensus.
	SetPreference(ctx context.Context, blkID ids.ID) error

	// LastAccepted returns the ID of the last accepted block.
	//
	// If no blocks have been accepted by consensus yet, it is assumed there is
	// a definitionally accepted block, the Genesis block, that will be
	// returned.
	LastAccepted(context.Context) (ids.ID, error)

	// VerifyHeightIndex should return:
	// - nil if the height index is available.
	// - ErrIndexIncomplete if the height index is not currently available.
	// - Any other non-standard error that may have occurred when verifying the
	//   index.
	//
	// TODO: Remove after v1.11.x activates.
	VerifyHeightIndex(context.Context) error

	// GetBlockIDAtHeight returns:
	// - The ID of the block that was accepted with [height].
	// - database.ErrNotFound if the [height] index is unknown.
	//
	// Note: A returned value of [database.ErrNotFound] typically means that the
	//       underlying VM was state synced and does not have access to the
	//       blockID at [height].
	GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error)
}

ChainVM defines the required functionality of a Snowman VM.

A Snowman VM is responsible for defining the representation of state, the representation of operations on that state, the application of operations on that state, and the creation of the operations. Consensus will decide on if the operation is executed and the order operations are executed in.

For example, suppose we have a VM that tracks an increasing number that is agreed upon by the network. The state is a single number. The operation is setting the number to a new, larger value. Applying the operation will save to the database the new value. The VM can attempt to issue a new number, of larger value, at any time. Consensus will ensure the network agrees on the number at every block height.

type Context

type Context struct {
	// PChainHeight is the height that this block will use to verify it's state.
	// In the proposervm, blocks verify the proposer based on the P-chain height
	// recorded in the parent block. The P-chain height provided here is also
	// the parent's P-chain height, not this block's P-chain height.
	//
	// Because PreForkBlocks and PostForkOptions do not verify their execution
	// against the P-chain's state, this context is undefined for those blocks.
	PChainHeight uint64
}

Context defines the block context that will be optionally provided by the proposervm to an underlying vm.

type Getter

type Getter interface {
	// Attempt to load a block.
	//
	// If the block does not exist, database.ErrNotFound should be returned.
	//
	// It is expected that blocks that have been successfully verified should be
	// returned correctly. It is also expected that blocks that have been
	// accepted by the consensus engine should be able to be fetched. It is not
	// required for blocks that have been rejected by the consensus engine to be
	// able to be fetched.
	GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error)
}

Getter defines the functionality for fetching a block by its ID.

type MockBuildBlockWithContextChainVM

type MockBuildBlockWithContextChainVM struct {
	// contains filtered or unexported fields
}

MockBuildBlockWithContextChainVM is a mock of BuildBlockWithContextChainVM interface.

func NewMockBuildBlockWithContextChainVM

func NewMockBuildBlockWithContextChainVM(ctrl *gomock.Controller) *MockBuildBlockWithContextChainVM

NewMockBuildBlockWithContextChainVM creates a new mock instance.

func (*MockBuildBlockWithContextChainVM) BuildBlockWithContext

func (m *MockBuildBlockWithContextChainVM) BuildBlockWithContext(arg0 context.Context, arg1 *Context) (snowman.Block, error)

BuildBlockWithContext mocks base method.

func (*MockBuildBlockWithContextChainVM) EXPECT

EXPECT returns an object that allows the caller to indicate expected use.

type MockBuildBlockWithContextChainVMMockRecorder

type MockBuildBlockWithContextChainVMMockRecorder struct {
	// contains filtered or unexported fields
}

MockBuildBlockWithContextChainVMMockRecorder is the mock recorder for MockBuildBlockWithContextChainVM.

func (*MockBuildBlockWithContextChainVMMockRecorder) BuildBlockWithContext

func (mr *MockBuildBlockWithContextChainVMMockRecorder) BuildBlockWithContext(arg0, arg1 any) *gomock.Call

BuildBlockWithContext indicates an expected call of BuildBlockWithContext.

type MockChainVM

type MockChainVM struct {
	// contains filtered or unexported fields
}

MockChainVM is a mock of ChainVM interface.

func NewMockChainVM

func NewMockChainVM(ctrl *gomock.Controller) *MockChainVM

NewMockChainVM creates a new mock instance.

func (*MockChainVM) AppGossip

func (m *MockChainVM) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) error

AppGossip mocks base method.

func (*MockChainVM) AppRequest

func (m *MockChainVM) AppRequest(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 time.Time, arg4 []byte) error

AppRequest mocks base method.

func (*MockChainVM) AppRequestFailed

func (m *MockChainVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 *common.AppError) error

AppRequestFailed mocks base method.

func (*MockChainVM) AppResponse

func (m *MockChainVM) AppResponse(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []byte) error

AppResponse mocks base method.

func (*MockChainVM) BuildBlock

func (m *MockChainVM) BuildBlock(arg0 context.Context) (snowman.Block, error)

BuildBlock mocks base method.

func (*MockChainVM) Connected

func (m *MockChainVM) Connected(arg0 context.Context, arg1 ids.NodeID, arg2 *version.Application) error

Connected mocks base method.

func (*MockChainVM) CreateHandlers

func (m *MockChainVM) CreateHandlers(arg0 context.Context) (map[string]http.Handler, error)

CreateHandlers mocks base method.

func (*MockChainVM) CrossChainAppRequest

func (m *MockChainVM) CrossChainAppRequest(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 time.Time, arg4 []byte) error

CrossChainAppRequest mocks base method.

func (*MockChainVM) CrossChainAppRequestFailed

func (m *MockChainVM) CrossChainAppRequestFailed(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 *common.AppError) error

CrossChainAppRequestFailed mocks base method.

func (*MockChainVM) CrossChainAppResponse

func (m *MockChainVM) CrossChainAppResponse(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 []byte) error

CrossChainAppResponse mocks base method.

func (*MockChainVM) Disconnected

func (m *MockChainVM) Disconnected(arg0 context.Context, arg1 ids.NodeID) error

Disconnected mocks base method.

func (*MockChainVM) EXPECT

func (m *MockChainVM) EXPECT() *MockChainVMMockRecorder

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockChainVM) GetBlock

func (m *MockChainVM) GetBlock(arg0 context.Context, arg1 ids.ID) (snowman.Block, error)

GetBlock mocks base method.

func (*MockChainVM) GetBlockIDAtHeight

func (m *MockChainVM) GetBlockIDAtHeight(arg0 context.Context, arg1 uint64) (ids.ID, error)

GetBlockIDAtHeight mocks base method.

func (*MockChainVM) HealthCheck

func (m *MockChainVM) HealthCheck(arg0 context.Context) (any, error)

HealthCheck mocks base method.

func (*MockChainVM) Initialize

func (m *MockChainVM) Initialize(arg0 context.Context, arg1 *snow.Context, arg2 database.Database, arg3, arg4, arg5 []byte, arg6 chan<- common.Message, arg7 []*common.Fx, arg8 common.AppSender) error

Initialize mocks base method.

func (*MockChainVM) LastAccepted

func (m *MockChainVM) LastAccepted(arg0 context.Context) (ids.ID, error)

LastAccepted mocks base method.

func (*MockChainVM) ParseBlock

func (m *MockChainVM) ParseBlock(arg0 context.Context, arg1 []byte) (snowman.Block, error)

ParseBlock mocks base method.

func (*MockChainVM) SetPreference

func (m *MockChainVM) SetPreference(arg0 context.Context, arg1 ids.ID) error

SetPreference mocks base method.

func (*MockChainVM) SetState

func (m *MockChainVM) SetState(arg0 context.Context, arg1 snow.State) error

SetState mocks base method.

func (*MockChainVM) Shutdown

func (m *MockChainVM) Shutdown(arg0 context.Context) error

Shutdown mocks base method.

func (*MockChainVM) VerifyHeightIndex

func (m *MockChainVM) VerifyHeightIndex(arg0 context.Context) error

VerifyHeightIndex mocks base method.

func (*MockChainVM) Version

func (m *MockChainVM) Version(arg0 context.Context) (string, error)

Version mocks base method.

type MockChainVMMockRecorder

type MockChainVMMockRecorder struct {
	// contains filtered or unexported fields
}

MockChainVMMockRecorder is the mock recorder for MockChainVM.

func (*MockChainVMMockRecorder) AppGossip

func (mr *MockChainVMMockRecorder) AppGossip(arg0, arg1, arg2 any) *gomock.Call

AppGossip indicates an expected call of AppGossip.

func (*MockChainVMMockRecorder) AppRequest

func (mr *MockChainVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call

AppRequest indicates an expected call of AppRequest.

func (*MockChainVMMockRecorder) AppRequestFailed

func (mr *MockChainVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call

AppRequestFailed indicates an expected call of AppRequestFailed.

func (*MockChainVMMockRecorder) AppResponse

func (mr *MockChainVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call

AppResponse indicates an expected call of AppResponse.

func (*MockChainVMMockRecorder) BuildBlock

func (mr *MockChainVMMockRecorder) BuildBlock(arg0 any) *gomock.Call

BuildBlock indicates an expected call of BuildBlock.

func (*MockChainVMMockRecorder) Connected

func (mr *MockChainVMMockRecorder) Connected(arg0, arg1, arg2 any) *gomock.Call

Connected indicates an expected call of Connected.

func (*MockChainVMMockRecorder) CreateHandlers

func (mr *MockChainVMMockRecorder) CreateHandlers(arg0 any) *gomock.Call

CreateHandlers indicates an expected call of CreateHandlers.

func (*MockChainVMMockRecorder) CrossChainAppRequest

func (mr *MockChainVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call

CrossChainAppRequest indicates an expected call of CrossChainAppRequest.

func (*MockChainVMMockRecorder) CrossChainAppRequestFailed

func (mr *MockChainVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call

CrossChainAppRequestFailed indicates an expected call of CrossChainAppRequestFailed.

func (*MockChainVMMockRecorder) CrossChainAppResponse

func (mr *MockChainVMMockRecorder) CrossChainAppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call

CrossChainAppResponse indicates an expected call of CrossChainAppResponse.

func (*MockChainVMMockRecorder) Disconnected

func (mr *MockChainVMMockRecorder) Disconnected(arg0, arg1 any) *gomock.Call

Disconnected indicates an expected call of Disconnected.

func (*MockChainVMMockRecorder) GetBlock

func (mr *MockChainVMMockRecorder) GetBlock(arg0, arg1 any) *gomock.Call

GetBlock indicates an expected call of GetBlock.

func (*MockChainVMMockRecorder) GetBlockIDAtHeight

func (mr *MockChainVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 any) *gomock.Call

GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight.

func (*MockChainVMMockRecorder) HealthCheck

func (mr *MockChainVMMockRecorder) HealthCheck(arg0 any) *gomock.Call

HealthCheck indicates an expected call of HealthCheck.

func (*MockChainVMMockRecorder) Initialize

func (mr *MockChainVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call

Initialize indicates an expected call of Initialize.

func (*MockChainVMMockRecorder) LastAccepted

func (mr *MockChainVMMockRecorder) LastAccepted(arg0 any) *gomock.Call

LastAccepted indicates an expected call of LastAccepted.

func (*MockChainVMMockRecorder) ParseBlock

func (mr *MockChainVMMockRecorder) ParseBlock(arg0, arg1 any) *gomock.Call

ParseBlock indicates an expected call of ParseBlock.

func (*MockChainVMMockRecorder) SetPreference

func (mr *MockChainVMMockRecorder) SetPreference(arg0, arg1 any) *gomock.Call

SetPreference indicates an expected call of SetPreference.

func (*MockChainVMMockRecorder) SetState

func (mr *MockChainVMMockRecorder) SetState(arg0, arg1 any) *gomock.Call

SetState indicates an expected call of SetState.

func (*MockChainVMMockRecorder) Shutdown

func (mr *MockChainVMMockRecorder) Shutdown(arg0 any) *gomock.Call

Shutdown indicates an expected call of Shutdown.

func (*MockChainVMMockRecorder) VerifyHeightIndex

func (mr *MockChainVMMockRecorder) VerifyHeightIndex(arg0 any) *gomock.Call

VerifyHeightIndex indicates an expected call of VerifyHeightIndex.

func (*MockChainVMMockRecorder) Version

func (mr *MockChainVMMockRecorder) Version(arg0 any) *gomock.Call

Version indicates an expected call of Version.

type MockStateSyncableVM

type MockStateSyncableVM struct {
	// contains filtered or unexported fields
}

MockStateSyncableVM is a mock of StateSyncableVM interface.

func NewMockStateSyncableVM

func NewMockStateSyncableVM(ctrl *gomock.Controller) *MockStateSyncableVM

NewMockStateSyncableVM creates a new mock instance.

func (*MockStateSyncableVM) EXPECT

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockStateSyncableVM) GetLastStateSummary

func (m *MockStateSyncableVM) GetLastStateSummary(arg0 context.Context) (StateSummary, error)

GetLastStateSummary mocks base method.

func (*MockStateSyncableVM) GetOngoingSyncStateSummary

func (m *MockStateSyncableVM) GetOngoingSyncStateSummary(arg0 context.Context) (StateSummary, error)

GetOngoingSyncStateSummary mocks base method.

func (*MockStateSyncableVM) GetStateSummary

func (m *MockStateSyncableVM) GetStateSummary(arg0 context.Context, arg1 uint64) (StateSummary, error)

GetStateSummary mocks base method.

func (*MockStateSyncableVM) ParseStateSummary

func (m *MockStateSyncableVM) ParseStateSummary(arg0 context.Context, arg1 []byte) (StateSummary, error)

ParseStateSummary mocks base method.

func (*MockStateSyncableVM) StateSyncEnabled

func (m *MockStateSyncableVM) StateSyncEnabled(arg0 context.Context) (bool, error)

StateSyncEnabled mocks base method.

type MockStateSyncableVMMockRecorder

type MockStateSyncableVMMockRecorder struct {
	// contains filtered or unexported fields
}

MockStateSyncableVMMockRecorder is the mock recorder for MockStateSyncableVM.

func (*MockStateSyncableVMMockRecorder) GetLastStateSummary

func (mr *MockStateSyncableVMMockRecorder) GetLastStateSummary(arg0 any) *gomock.Call

GetLastStateSummary indicates an expected call of GetLastStateSummary.

func (*MockStateSyncableVMMockRecorder) GetOngoingSyncStateSummary

func (mr *MockStateSyncableVMMockRecorder) GetOngoingSyncStateSummary(arg0 any) *gomock.Call

GetOngoingSyncStateSummary indicates an expected call of GetOngoingSyncStateSummary.

func (*MockStateSyncableVMMockRecorder) GetStateSummary

func (mr *MockStateSyncableVMMockRecorder) GetStateSummary(arg0, arg1 any) *gomock.Call

GetStateSummary indicates an expected call of GetStateSummary.

func (*MockStateSyncableVMMockRecorder) ParseStateSummary

func (mr *MockStateSyncableVMMockRecorder) ParseStateSummary(arg0, arg1 any) *gomock.Call

ParseStateSummary indicates an expected call of ParseStateSummary.

func (*MockStateSyncableVMMockRecorder) StateSyncEnabled

func (mr *MockStateSyncableVMMockRecorder) StateSyncEnabled(arg0 any) *gomock.Call

StateSyncEnabled indicates an expected call of StateSyncEnabled.

type MockWithVerifyContext

type MockWithVerifyContext struct {
	// contains filtered or unexported fields
}

MockWithVerifyContext is a mock of WithVerifyContext interface.

func NewMockWithVerifyContext

func NewMockWithVerifyContext(ctrl *gomock.Controller) *MockWithVerifyContext

NewMockWithVerifyContext creates a new mock instance.

func (*MockWithVerifyContext) EXPECT

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockWithVerifyContext) ShouldVerifyWithContext

func (m *MockWithVerifyContext) ShouldVerifyWithContext(arg0 context.Context) (bool, error)

ShouldVerifyWithContext mocks base method.

func (*MockWithVerifyContext) VerifyWithContext

func (m *MockWithVerifyContext) VerifyWithContext(arg0 context.Context, arg1 *Context) error

VerifyWithContext mocks base method.

type MockWithVerifyContextMockRecorder

type MockWithVerifyContextMockRecorder struct {
	// contains filtered or unexported fields
}

MockWithVerifyContextMockRecorder is the mock recorder for MockWithVerifyContext.

func (*MockWithVerifyContextMockRecorder) ShouldVerifyWithContext

func (mr *MockWithVerifyContextMockRecorder) ShouldVerifyWithContext(arg0 any) *gomock.Call

ShouldVerifyWithContext indicates an expected call of ShouldVerifyWithContext.

func (*MockWithVerifyContextMockRecorder) VerifyWithContext

func (mr *MockWithVerifyContextMockRecorder) VerifyWithContext(arg0, arg1 any) *gomock.Call

VerifyWithContext indicates an expected call of VerifyWithContext.

type Parser

type Parser interface {
	// Attempt to create a block from a stream of bytes.
	//
	// The block should be represented by the full byte array, without extra
	// bytes.
	//
	// It is expected for all historical blocks to be parseable.
	ParseBlock(ctx context.Context, blockBytes []byte) (snowman.Block, error)
}

Parser defines the functionality for fetching a block by its bytes.

type StateSummary

type StateSummary interface {
	// ID uniquely identifies this state summary, regardless of the chain state.
	ID() ids.ID

	// Height uniquely identifies this an accepted state summary.
	Height() uint64

	// Bytes returns a byte slice than can be used to reconstruct this summary.
	Bytes() []byte

	// Accept triggers the VM to start state syncing to this summary.
	//
	// It returns the state sync mode selected by the VM.
	Accept(context.Context) (StateSyncMode, error)
}

StateSummary represents all the information needed to download, verify, and rebuild its state.

type StateSyncMode

type StateSyncMode uint8

StateSyncMode is returned by the StateSyncableVM when a state summary is passed to it. It indicates which type of state sync the VM is performing.

const (
	// StateSyncSkipped indicates that state sync won't be run by the VM. This
	// may happen if the VM decides that the state sync is too recent and it
	// would be faster to bootstrap the missing blocks.
	StateSyncSkipped StateSyncMode = iota + 1

	// StateSyncStatic indicates that engine should stop and wait for the VM to
	// complete state syncing before moving ahead with bootstrapping.
	StateSyncStatic

	// StateSyncDynamic indicates that engine should immediately transition
	// into bootstrapping and then normal consensus. State sync will proceed
	// asynchronously in the VM.
	//
	// Invariant: If this is returned it is assumed that the VM should be able
	// to handle requests from the engine as if the VM is fully synced.
	// Specifically, it is required that the invariants specified by
	// LastAccepted, GetBlock, ParseBlock, and Block.Verify are maintained. This
	// means that when StateSummary.Accept returns, the block that would become
	// the last accepted block must be immediately fetchable by the engine.
	StateSyncDynamic
)

func (StateSyncMode) String

func (s StateSyncMode) String() string

type StateSyncableVM

type StateSyncableVM interface {
	// StateSyncEnabled indicates whether the state sync is enabled for this VM.
	// If StateSyncableVM is not implemented, as it may happen with a wrapper
	// VM, StateSyncEnabled should return false, nil
	StateSyncEnabled(context.Context) (bool, error)

	// GetOngoingSyncStateSummary returns an in-progress state summary if it
	// exists.
	//
	// The engine can then ask the network if the ongoing summary is still
	// supported, thus helping the VM decide whether to continue an in-progress
	// sync or start over.
	//
	// Returns database.ErrNotFound if there is no in-progress sync.
	GetOngoingSyncStateSummary(context.Context) (StateSummary, error)

	// GetLastStateSummary returns the latest state summary.
	//
	// Returns database.ErrNotFound if no summary is available.
	GetLastStateSummary(context.Context) (StateSummary, error)

	// ParseStateSummary parses a state summary out of [summaryBytes].
	ParseStateSummary(ctx context.Context, summaryBytes []byte) (StateSummary, error)

	// GetStateSummary retrieves the state summary that was generated at height
	// [summaryHeight].
	//
	// Returns database.ErrNotFound if no summary is available at
	// [summaryHeight].
	GetStateSummary(ctx context.Context, summaryHeight uint64) (StateSummary, error)
}

StateSyncableVM contains the functionality to allow VMs to sync to a given state, rather then boostrapping from genesis.

type TestBatchedVM

type TestBatchedVM struct {
	T *testing.T

	CantGetAncestors    bool
	CantBatchParseBlock bool

	GetAncestorsF func(
		ctx context.Context,
		blkID ids.ID,
		maxBlocksNum int,
		maxBlocksSize int,
		maxBlocksRetrivalTime time.Duration,
	) ([][]byte, error)

	BatchedParseBlockF func(
		ctx context.Context,
		blks [][]byte,
	) ([]snowman.Block, error)
}

TestBatchedVM is a BatchedVM that is useful for testing.

func (*TestBatchedVM) BatchedParseBlock

func (vm *TestBatchedVM) BatchedParseBlock(
	ctx context.Context,
	blks [][]byte,
) ([]snowman.Block, error)

func (*TestBatchedVM) Default

func (vm *TestBatchedVM) Default(cant bool)

func (*TestBatchedVM) GetAncestors

func (vm *TestBatchedVM) GetAncestors(
	ctx context.Context,
	blkID ids.ID,
	maxBlocksNum int,
	maxBlocksSize int,
	maxBlocksRetrivalTime time.Duration,
) ([][]byte, error)

type TestStateSummary

type TestStateSummary struct {
	IDV     ids.ID
	HeightV uint64
	BytesV  []byte

	T          *testing.T
	CantAccept bool
	AcceptF    func(context.Context) (StateSyncMode, error)
}

func (*TestStateSummary) Accept

func (*TestStateSummary) Bytes

func (s *TestStateSummary) Bytes() []byte

func (*TestStateSummary) Height

func (s *TestStateSummary) Height() uint64

func (*TestStateSummary) ID

func (s *TestStateSummary) ID() ids.ID

type TestStateSyncableVM

type TestStateSyncableVM struct {
	T *testing.T

	CantStateSyncEnabled,
	CantStateSyncGetOngoingSummary,
	CantGetLastStateSummary,
	CantParseStateSummary,
	CantGetStateSummary bool

	StateSyncEnabledF           func(context.Context) (bool, error)
	GetOngoingSyncStateSummaryF func(context.Context) (StateSummary, error)
	GetLastStateSummaryF        func(context.Context) (StateSummary, error)
	ParseStateSummaryF          func(ctx context.Context, summaryBytes []byte) (StateSummary, error)
	GetStateSummaryF            func(ctx context.Context, summaryHeight uint64) (StateSummary, error)
}

func (*TestStateSyncableVM) GetLastStateSummary

func (vm *TestStateSyncableVM) GetLastStateSummary(ctx context.Context) (StateSummary, error)

func (*TestStateSyncableVM) GetOngoingSyncStateSummary

func (vm *TestStateSyncableVM) GetOngoingSyncStateSummary(ctx context.Context) (StateSummary, error)

func (*TestStateSyncableVM) GetStateSummary

func (vm *TestStateSyncableVM) GetStateSummary(ctx context.Context, summaryHeight uint64) (StateSummary, error)

func (*TestStateSyncableVM) ParseStateSummary

func (vm *TestStateSyncableVM) ParseStateSummary(ctx context.Context, summaryBytes []byte) (StateSummary, error)

func (*TestStateSyncableVM) StateSyncEnabled

func (vm *TestStateSyncableVM) StateSyncEnabled(ctx context.Context) (bool, error)

type TestVM

type TestVM struct {
	common.TestVM

	CantBuildBlock,
	CantParseBlock,
	CantGetBlock,
	CantSetPreference,
	CantLastAccepted,
	CantVerifyHeightIndex,
	CantGetBlockIDAtHeight bool

	BuildBlockF         func(context.Context) (snowman.Block, error)
	ParseBlockF         func(context.Context, []byte) (snowman.Block, error)
	GetBlockF           func(context.Context, ids.ID) (snowman.Block, error)
	SetPreferenceF      func(context.Context, ids.ID) error
	LastAcceptedF       func(context.Context) (ids.ID, error)
	VerifyHeightIndexF  func(context.Context) error
	GetBlockIDAtHeightF func(ctx context.Context, height uint64) (ids.ID, error)
}

TestVM is a ChainVM that is useful for testing.

func (*TestVM) BuildBlock

func (vm *TestVM) BuildBlock(ctx context.Context) (snowman.Block, error)

func (*TestVM) Default

func (vm *TestVM) Default(cant bool)

func (*TestVM) GetBlock

func (vm *TestVM) GetBlock(ctx context.Context, id ids.ID) (snowman.Block, error)

func (*TestVM) GetBlockIDAtHeight

func (vm *TestVM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error)

func (*TestVM) LastAccepted

func (vm *TestVM) LastAccepted(ctx context.Context) (ids.ID, error)

func (*TestVM) ParseBlock

func (vm *TestVM) ParseBlock(ctx context.Context, b []byte) (snowman.Block, error)

func (*TestVM) SetPreference

func (vm *TestVM) SetPreference(ctx context.Context, id ids.ID) error

func (*TestVM) VerifyHeightIndex

func (vm *TestVM) VerifyHeightIndex(ctx context.Context) error

type WithVerifyContext

type WithVerifyContext interface {
	// Returns true if [VerifyWithContext] should be called.
	// Returns false if [Verify] should be called.
	//
	// This method will be called if and only if the proposervm is activated.
	// Otherwise [Verify] will be called.
	ShouldVerifyWithContext(context.Context) (bool, error)

	// Verify that the state transition this block would make if accepted is
	// valid. If the state transition is invalid, a non-nil error should be
	// returned.
	//
	// It is guaranteed that the Parent has been successfully verified.
	//
	// This method may be called again with a different context.
	//
	// If nil is returned, it is guaranteed that either Accept or Reject will be
	// called on this block, unless the VM is shut down.
	//
	// Note: During `Accept` the block context is not provided. This implies
	// that the block context provided here can not be used to alter any
	// potential state transition that assumes network agreement. The block
	// context should only be used to determine the validity of the block.
	VerifyWithContext(context.Context, *Context) error
}

WithVerifyContext defines the interface a Block can optionally implement to consider the P-Chain height when verifying itself.

As with all Blocks, it is guaranteed for verification to be called in topological order.

If the status of the block is Accepted or Rejected; VerifyWithContext will never be called.

Jump to

Keyboard shortcuts

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