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.FinalizeHeight.
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 ¶
- Variables
- func NewInitialBlock(pubkeys []ed25519.PublicKey, quorum int, timestamp time.Time) (*bc.Block, error)
- type BlockBuilder
- type Chain
- func (c *Chain) BlockWaiter(height uint64) <-chan struct{}
- func (c *Chain) CommitAppliedBlock(ctx context.Context, block *bc.Block, snapshot *state.Snapshot) error
- func (c *Chain) CommitBlock(ctx context.Context, block *bc.Block) error
- func (c *Chain) GenerateBlock(ctx context.Context, timestampMS uint64, txs []*bc.CommitmentsTx) (*bc.UnsignedBlock, *state.Snapshot, error)
- func (c *Chain) GetBlock(ctx context.Context, height uint64) (*bc.Block, error)
- func (c *Chain) Height() uint64
- func (c *Chain) Recover(ctx context.Context) (*state.Snapshot, error)
- func (c *Chain) State() *state.Snapshot
- type Store
Constants ¶
This section is empty.
Variables ¶
var ( // ErrBadContractsRoot is returned when the computed contracts merkle root // disagrees with the one declared in a block header. ErrBadContractsRoot = errors.New("invalid contracts merkle root") // ErrBadNoncesRoot is returned when the computed nonces merkle root // disagrees with the one declared in a block header. ErrBadNoncesRoot = errors.New("invalid nonces merkle root") )
var ( // ErrBlockFull happens when trying to add a transaction to a block // that already contains MaxBlockTxs transactions. ErrBlockFull = errors.New("block is full") // ErrBlockRunlimit happens when trying to add a transaction to a // block that would cause the block's total runlimit to overflow. ErrBlockRunlimit = errors.New("block runlimit overflow") // ErrTxTooOld happens when trying to add a transaction to a block // whose timestamp is after the end of a timerange in the // transaction. ErrTxTooOld = errors.New("transaction timerange is in the past") // ErrTxTooNew happens when trying to add a transaction to a block // whose timestamp is before the beginning of a timerange in the // transaction. ErrTxTooNew = errors.New("transaction timerange is in the future") // ErrTxLongNonce happens when trying to add a transaction with a // nonce whose expiration is more than MaxNonceWindow in the future. ErrTxLongNonce = errors.New("transaction nonce expires too far in the future") )
Functions ¶
Types ¶
type BlockBuilder ¶
type BlockBuilder struct { Version uint64 MaxNonceWindow time.Duration MaxBlockWindow int64 MaxBlockTxs int // contains filtered or unexported fields }
func NewBlockBuilder ¶
func NewBlockBuilder() *BlockBuilder
func (*BlockBuilder) AddTx ¶
func (bb *BlockBuilder) AddTx(tx *bc.CommitmentsTx) error
func (*BlockBuilder) Build ¶
func (bb *BlockBuilder) Build() (*bc.UnsignedBlock, *state.Snapshot, error)
type Chain ¶
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, initialBlock *bc.Block, store Store, heights <-chan uint64) (*Chain, error)
NewChain returns a new Chain using store as the underlying storage.
func (*Chain) BlockWaiter ¶
BlockWaiter returns a channel that waits for the block at the given height.
func (*Chain) CommitAppliedBlock ¶
func (c *Chain) CommitAppliedBlock(ctx context.Context, block *bc.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 ¶
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, timestampMS uint64, txs []*bc.CommitmentsTx) (*bc.UnsignedBlock, *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 ¶
GetBlock returns the block at the given height, if there is one, otherwise it returns an error.
type Store ¶
type Store interface { Height(context.Context) (uint64, error) GetBlock(context.Context, uint64) (*bc.Block, error) LatestSnapshot(context.Context) (*state.Snapshot, error) SaveBlock(context.Context, *bc.Block) error FinalizeHeight(context.Context, uint64) error SaveSnapshot(context.Context, *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 |
---|---|
Package bc is a generated protocol buffer package.
|
Package bc is a generated protocol buffer package. |
Package merkle implements merkle binary trees.
|
Package merkle implements merkle binary trees. |
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
Package memstore is a protocol.Store implementation that keeps all blockchain state in memory.
|
Package memstore is a protocol.Store implementation that keeps all blockchain state in memory. |
Package state is a generated protocol buffer package.
|
Package state is a generated protocol buffer package. |
standard
Package standard implements standard txvm contracts for Sequence transactions.
|
Package standard implements standard txvm contracts for Sequence transactions. |
Package txvm implements Chain Protocol transactions.
|
Package txvm implements Chain Protocol transactions. |
asm
Package asm provides an assembler and disassembler for txvm bytecode.
|
Package asm provides an assembler and disassembler for txvm bytecode. |
op
Package op assigns human-readable names to numeric opcodes.
|
Package op assigns human-readable names to numeric opcodes. |
txvmutil
Package txvmutil defines a "fluent" builder type for constructing TxVM programs.
|
Package txvmutil defines a "fluent" builder type for constructing TxVM programs. |
Package validation implements the block-validation algorithms from the Chain Protocol spec.
|
Package validation implements the block-validation algorithms from the Chain Protocol spec. |