protocol

package
v0.0.0-...-6d4bf48 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2023 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package protocol provides the logic to tie together storage and validation for a Chain Protocol blockchain.

This comprises all behavior that's common to every full node, as well as other functions that need to operate on the blockchain state.

Here are a few examples of typical full node types.

Generator

A generator has two basic jobs: collecting transactions from other nodes and putting them into blocks.

To add a new block to the blockchain, call GenerateBlock, sign the block (possibly collecting signatures from other parties), and call CommitAppliedBlock.

Signer

A signer validates blocks generated by the Generator and signs at most one block at each height.

Participant

A participant node in a network may select outputs for spending and compose transactions.

To publish a new transaction, prepare your transaction (select outputs, and compose and sign the tx) and send the transaction to the network's generator. To wait for confirmation, call BlockWaiter on successive block heights and inspect the blockchain state until you find that the transaction has been either confirmed or rejected. Note that transactions may be malleable if there's no commitment to TXSIGHASH.

New block sequence

Every new block must be validated against the existing blockchain state. New blocks are validated by calling ValidateBlock. Blocks produced by GenerateBlock are already known to be valid.

A new block goes through the sequence:

  • If not generated locally, the block is validated by calling ValidateBlock.
  • The new block is committed to the Chain's Store through its SaveBlock method. This is the linearization point. Once a block is saved to the Store, it's committed and can be recovered after a crash.
  • The Chain's in-memory representation of the blockchain state is updated. If the block was remotely-generated, the Chain must apply the new block to its current state to retrieve the new state. If the block was generated locally, the resulting state is already known and does not need to be recalculated.
  • Other cored processes are notified of the new block through Store.FinalizeBlock.

Committing a block

As a consumer of the package, there are two ways to commit a new block: CommitBlock and CommitAppliedBlock.

When generating new blocks, GenerateBlock will return the resulting state snapshot with the new block. To ingest a block with a known resulting state snapshot, call CommitAppliedBlock.

When ingesting remotely-generated blocks, the state after the block must be calculated by taking the Chain's current state and applying the new block. To ingest a block without a known resulting state snapshot, call CommitBlock.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrBadBlock is returned when a block is invalid.
	ErrBadBlock = errors.New("invalid block")

	// ErrBadStateRoot is returned when the computed assets merkle root
	// disagrees with the one declared in a block header.
	ErrBadStateRoot = errors.New("invalid state merkle root")
)
View Source
var ErrBadTx = errors.New("invalid transaction")

ErrBadTx is returned for transactions failing validation

View Source
var (
	// ErrTheDistantFuture is returned when waiting for a blockheight
	// too far in excess of the tip of the blockchain.
	ErrTheDistantFuture = errors.New("block height too far in future")
)

Functions

func NewInitialBlock

func NewInitialBlock(pubkeys []ed25519.PublicKey, nSigs int, timestamp time.Time) (*legacy.Block, error)

Types

type Chain

type Chain struct {
	InitialBlockHash  bc.Hash
	MaxIssuanceWindow time.Duration // only used by generators
	// contains filtered or unexported fields
}

Chain provides a complete, minimal blockchain database. It delegates the underlying storage to other objects, and uses validation logic from package validation to decide what objects can be safely stored.

func NewChain

func NewChain(ctx context.Context, initialBlockHash bc.Hash, store Store, heights <-chan uint64) (*Chain, error)

NewChain returns a new Chain using store as the underlying storage.

func (*Chain) BlockSoonWaiter

func (c *Chain) BlockSoonWaiter(ctx context.Context, height uint64) <-chan error

BlockSoonWaiter returns a channel that waits for the block at the given height, but it is an error to wait for a block far in the future. WaitForBlockSoon will timeout if the context times out. To wait unconditionally, the caller should use WaitForBlock.

func (*Chain) BlockWaiter

func (c *Chain) BlockWaiter(height uint64) <-chan struct{}

BlockWaiter returns a channel that waits for the block at the given height.

func (*Chain) CommitAppliedBlock

func (c *Chain) CommitAppliedBlock(ctx context.Context, block *legacy.Block, snapshot *state.Snapshot) error

CommitAppliedBlock takes a block, commits it to persistent storage and sets c's state. Unlike CommitBlock, it accepts an already applied snapshot. CommitAppliedBlock is idempotent.

func (*Chain) CommitBlock

func (c *Chain) CommitBlock(ctx context.Context, block *legacy.Block) error

CommitBlock takes a block, commits it to persistent storage and applies it to c. CommitBlock is idempotent. A duplicate call with a previously committed block will succeed.

func (*Chain) GenerateBlock

func (c *Chain) GenerateBlock(ctx context.Context, prev *legacy.Block, snapshot *state.Snapshot, now time.Time, txs []*legacy.Tx) (*legacy.Block, *state.Snapshot, error)

GenerateBlock generates a valid, but unsigned, candidate block from the current pending transaction pool. It returns the new block and a snapshot of what the state snapshot is if the block is applied.

After generating the block, the pending transaction pool will be empty.

func (*Chain) GetBlock

func (c *Chain) GetBlock(ctx context.Context, height uint64) (*legacy.Block, error)

GetBlock returns the block at the given height, if there is one, otherwise it returns an error.

func (*Chain) Height

func (c *Chain) Height() uint64

Height returns the current height of the blockchain.

func (*Chain) Recover

func (c *Chain) Recover(ctx context.Context) (*legacy.Block, *state.Snapshot, error)

Recover performs crash recovery, restoring the blockchain to a complete state. It returns the latest confirmed block and the corresponding state snapshot.

If the blockchain is empty (missing initial block), this function returns a nil block and an empty snapshot.

func (*Chain) State

func (c *Chain) State() (*legacy.Block, *state.Snapshot)

State returns the most recent state available. It will not be current unless the current process is the leader. Callers should examine the returned block header's height if they need to verify the current state.

func (*Chain) TimestampMS

func (c *Chain) TimestampMS() uint64

TimestampMS returns the latest known block timestamp.

func (*Chain) ValidateBlock

func (c *Chain) ValidateBlock(block, prev *legacy.Block) error

ValidateBlock validates an incoming block in advance of committing it to the blockchain (with CommitBlock).

func (*Chain) ValidateBlockForSig

func (c *Chain) ValidateBlockForSig(ctx context.Context, block *legacy.Block) error

ValidateBlockForSig performs validation on an incoming _unsigned_ block in preparation for signing it. By definition it does not execute the consensus program.

func (*Chain) ValidateTx

func (c *Chain) ValidateTx(tx *bc.Tx) error

ValidateTx validates the given transaction. A cache holds per-transaction validation results and is consulted before performing full validation.

type Store

type Store interface {
	Height(context.Context) (uint64, error)
	GetBlock(context.Context, uint64) (*legacy.Block, error)
	LatestSnapshot(context.Context) (*state.Snapshot, uint64, error)

	SaveBlock(context.Context, *legacy.Block) error
	FinalizeBlock(context.Context, uint64) error
	SaveSnapshot(context.Context, uint64, *state.Snapshot) error
}

Store provides storage for blockchain data: blocks and state tree snapshots.

Note, this is different from a state snapshot. A state snapshot provides access to the state at a given point in time -- outputs and issuance memory. The Chain type uses Store to load state from storage and persist validated data.

Directories

Path Synopsis
bc
Package bc is a generated protocol buffer package.
Package bc is a generated protocol buffer package.
bctest
Package bctest provides utilities for constructing blockchain data structures.
Package bctest provides utilities for constructing blockchain data structures.
Package patricia computes the Merkle Patricia Tree Hash of a set of bit strings, as described in the Chain Protocol spec.
Package patricia computes the Merkle Patricia Tree Hash of a set of bit strings, as described in the Chain Protocol spec.
Package prottest provides utilities for Chain Protocol testing.
Package prottest provides utilities for Chain Protocol testing.
memstore
MemStore is a Store implementation that keeps all blockchain state in memory.
MemStore is a Store implementation that keeps all blockchain state in memory.
vm
Package vm implements the VM described in Chain Protocol 1.
Package vm implements the VM described in Chain Protocol 1.

Jump to

Keyboard shortcuts

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