chain

package
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Dec 21, 2022 License: MIT Imports: 31 Imported by: 0

README

Chain component

The Chain is a component which is fully responsible for building the blockchain. It judges the validity of incoming blocks, appends them to the database, and disseminates newly approved blocks both internally (through the event bus) and externally (over the gossip network). Additionally, it is aware of the node's state in the network at all times, and controls the execution of the consensus by responding to perceived state changes.

Structure

To the rest of the system, the Chain appears as quite a monolithic component. However, it is composed by a few different, more granular components, which all fulfill their own responsibilities.

Loader

The Loader is responsible for initializing the Chain with the correct initial data, as well as checking for data integrity on startup. It abstracts over the DB, and is implemented by the loader.

Verifier

The Verifier abstracts over block verification mechanisms, and uses the verifiers package under the hood, in an attempt to simplify the API (as checks are supposed to be kept atomic from a function perspective, but always are called together). It is implemented by the loader.

Synchronizer

The Synchronizer is a stand-alone component which is fully responsible for processing blocks that come in from the network. Through the Ledger interface, it can direct the Chain into the right decisions based on the perceived state of the node against the network. More information can be found in the synchronizer documentation.

Below follows a visual workflow of how the chain and synchronizer take decisions on incoming blocks, which should help clarify the control flow.

Block processing decision tree

Loop

The Loop allows the Chain to take control of consensus execution, by allowing it to easily start and stop the work being done.

Proxy

The Proxy is used to contact the RUSK server. The Chain outsources certain operations to RUSK since the current codebase can not execute VM transactions, and this is needed for transaction validity checks and state transitions.

Documentation

Index

Constants

View Source
const (
	// SanityCheckHeight is the suggested amount of blocks to check when
	// calling Loader.SanityCheckBlockchain.
	SanityCheckHeight uint64 = 10
)

Variables

View Source
var ErrBlockAlreadyAccepted = errors.New("already accepted")

ErrBlockAlreadyAccepted block already known by blockchain state.

Functions

This section is empty.

Types

type Chain

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

Chain represents the nodes blockchain. This struct will be aware of the current state of the node.

func New

func New(ctx context.Context, db database.DB, eventBus *eventbus.EventBus, rpcBus *rpcbus.RPCBus,
	loader Loader, verifier Verifier, srv *grpc.Server, proxy transactions.Proxy, loop *loop.Consensus,
) (*Chain, error)

New returns a new chain object. It accepts the EventBus (for messages coming from (remote) consensus components.

func (*Chain) CalculateSyncProgress added in v0.4.0

func (c *Chain) CalculateSyncProgress() float64

CalculateSyncProgress of the node.

func (*Chain) ExecuteStateTransition added in v0.4.4

func (c *Chain) ExecuteStateTransition(ctx context.Context, txs []transactions.ContractCall, blockHeight uint64, blockGasLimit uint64, generator []byte) ([]transactions.ContractCall, []byte, error)

ExecuteStateTransition calls Rusk ExecuteStateTransitiongrpc method.

func (*Chain) GetSyncProgress added in v0.4.0

func (c *Chain) GetSyncProgress(_ context.Context, e *node.EmptyRequest) (*node.SyncProgressResponse, error)

GetSyncProgress returns how close the node is to being synced to the tip, as a percentage value.

func (*Chain) ProcessBlockFromNetwork added in v0.4.0

func (c *Chain) ProcessBlockFromNetwork(srcPeerID string, m message.Message) ([]bytes.Buffer, error)

ProcessBlockFromNetwork will handle blocks incoming from the network. It will allow the chain to enter sync mode if it detects that we are behind, which will cancel the running consensus loop and attempt to reach the new chain tip. Satisfies the peer.ProcessorFunc interface.

func (*Chain) ProcessSyncTimerExpired added in v0.4.0

func (c *Chain) ProcessSyncTimerExpired(strPeerAddr string) error

ProcessSyncTimerExpired called by outsync timer when a peer does not provide GetData response. It implements transition back to inSync state. strPeerAddr is the address of the peer initiated the syncing but failed to deliver.

func (*Chain) RebuildChain added in v0.4.0

func (c *Chain) RebuildChain(_ context.Context, e *node.EmptyRequest) (*node.GenericResponse, error)

RebuildChain will delete all blocks except for the genesis block, to allow for a full re-sync. NOTE: This function no longer does anything, but is still here to conform to the ChainServer interface, for GRPC communications.

func (*Chain) RestartConsensus added in v0.4.4

func (c *Chain) RestartConsensus() error

RestartConsensus implements Stop and Start Consensus. This is a safer approach to ensure we do not duplicate Consensus loop.

func (*Chain) StopConsensus added in v0.4.4

func (c *Chain) StopConsensus()

StopConsensus will send a non-blocking signal to `stopConsensusChan` to kill the consensus goroutine.

func (*Chain) TryNextConsecutiveBlockInSync added in v0.4.0

func (c *Chain) TryNextConsecutiveBlockInSync(blk block.Block, metadata *message.Metadata) error

TryNextConsecutiveBlockInSync is the processing path for accepting a block from the network during in-sync state. Returns err if the block is not valid.

func (*Chain) TryNextConsecutiveBlockIsValid added in v0.4.4

func (c *Chain) TryNextConsecutiveBlockIsValid(blk block.Block) error

TryNextConsecutiveBlockIsValid makes an attempt to validate a blk without changing any state. returns error if the block is invalid to current blockchain tip.

func (*Chain) TryNextConsecutiveBlockOutSync added in v0.4.0

func (c *Chain) TryNextConsecutiveBlockOutSync(blk block.Block, metadata *message.Metadata) error

TryNextConsecutiveBlockOutSync is the processing path for accepting a block from the network during out-of-sync state.

func (*Chain) VerifyCandidateBlock added in v0.4.0

func (c *Chain) VerifyCandidateBlock(ctx context.Context, candidate block.Block) error

VerifyCandidateBlock can be used as a callback for the consensus in order to verify potential winning candidates.

type DBLoader added in v0.3.0

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

DBLoader performs database prefetching and sanityChecks at node startup.

func NewDBLoader added in v0.3.0

func NewDBLoader(db database.DB, genesis *block.Block) *DBLoader

NewDBLoader returns a Loader which gets the Chain Tip from the DB.

func (*DBLoader) BlockAt added in v0.3.0

func (l *DBLoader) BlockAt(searchingHeight uint64) (block.Block, error)

BlockAt returns the block stored at a given height.

func (*DBLoader) Clear added in v0.3.0

func (l *DBLoader) Clear() error

Clear the underlying DB.

func (*DBLoader) Close added in v0.3.0

func (l *DBLoader) Close(driver string) error

Close the underlying DB usign the drivers.

func (*DBLoader) Height added in v0.3.0

func (l *DBLoader) Height() (uint64, error)

Height returns the height of the blockchain stored in the DB.

func (*DBLoader) LoadTip added in v0.3.0

func (l *DBLoader) LoadTip() (*block.Block, []byte, error)

LoadTip returns the tip of the chain.

func (*DBLoader) SanityCheckBlock added in v0.4.0

func (l *DBLoader) SanityCheckBlock(prevBlock block.Block, blk block.Block) error

SanityCheckBlock will verify whether we have not seed the block before (duplicate), perform a check on the block header and verifies the coinbase transactions. It leaves the bulk of transaction verification to the executor Return nil if the sanity check passes.

func (*DBLoader) SanityCheckBlockchain added in v0.5.0

func (l *DBLoader) SanityCheckBlockchain(startAt, firstBlocksAmount uint64) error

SanityCheckBlockchain checks the head and the tail of the blockchain to avoid inconsistencies and a faulty bootstrap.

type Ledger added in v0.4.0

type Ledger interface {
	TryNextConsecutiveBlockInSync(blk block.Block, metadata *message.Metadata) error
	TryNextConsecutiveBlockOutSync(blk block.Block, metadata *message.Metadata) error
	TryNextConsecutiveBlockIsValid(blk block.Block) error

	RestartConsensus() error
	// StopConsensus signals the consensus loop to terminate if exists.
	StopConsensus()

	ProcessSyncTimerExpired(strPeerAddr string) error
}

Ledger is the Chain interface used in tests.

type Loader added in v0.3.0

type Loader interface {
	// LoadTip of the chain. Returns blockchain tip and persisted hash.
	LoadTip() (*block.Block, []byte, error)
	// Clear removes everything from the DB.
	Clear() error
	// Close the Loader and finalizes any pending connection.
	Close(driver string) error
	// Height returns the current height as stored in the loader.
	Height() (uint64, error)
	// BlockAt returns the block at a given height.
	BlockAt(uint64) (block.Block, error)
}

Loader is an interface which abstracts away the storage used by the Chain to store the blockchain.

func NewMockLoader added in v0.3.0

func NewMockLoader() Loader

NewMockLoader creates a Mockup of the Loader interface.

type MockLoader added in v0.3.0

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

MockLoader is the mock of the DB loader to help testing the chain.

func (*MockLoader) Append added in v0.3.0

func (m *MockLoader) Append(blk *block.Block) error

Append the block to the internal blockchain representation.

func (*MockLoader) BlockAt added in v0.3.0

func (m *MockLoader) BlockAt(index uint64) (block.Block, error)

BlockAt the block to the internal blockchain representation.

func (*MockLoader) Clear added in v0.3.0

func (m *MockLoader) Clear() error

Clear the mock.

func (*MockLoader) Close added in v0.3.0

func (m *MockLoader) Close(driver string) error

Close the mock.

func (*MockLoader) Height added in v0.3.0

func (m *MockLoader) Height() (uint64, error)

Height returns the height currently known by the Loader.

func (*MockLoader) LoadTip added in v0.3.0

func (m *MockLoader) LoadTip() (*block.Block, []byte, error)

LoadTip of the chain.

func (*MockLoader) SanityCheckBlockchain added in v0.5.0

func (m *MockLoader) SanityCheckBlockchain(uint64, uint64, uint64) error

SanityCheckBlockchain on first N blocks and M last blocks.

type MockVerifier added in v0.3.0

type MockVerifier struct{}

MockVerifier is a mock for the chain.Verifier interface.

func (*MockVerifier) SanityCheckBlock added in v0.4.0

func (v *MockVerifier) SanityCheckBlock(prevBlock block.Block, blk block.Block) error

SanityCheckBlock will verify whether a block is valid according to the rules of the consensus.

func (*MockVerifier) SanityCheckBlockchain added in v0.5.0

func (v *MockVerifier) SanityCheckBlockchain(uint64, uint64) error

SanityCheckBlockchain on first N blocks and M last blocks.

type Verifier added in v0.3.0

type Verifier interface {
	// SanityCheckBlockchain on first N blocks and M last blocks.
	SanityCheckBlockchain(startAt uint64, firstBlocksAmount uint64) error
	// SanityCheckBlock will verify whether a block is valid according to the rules of the consensus.
	SanityCheckBlock(prevBlock block.Block, blk block.Block) error
}

Verifier performs checks on the blockchain and potentially new incoming block.

Jump to

Keyboard shortcuts

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