consensus

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2021 License: AGPL-3.0 Imports: 14 Imported by: 2

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ExecForkActor

type ExecForkActor func([]*flow.IncorporatedResultSeal)

func LogForkAndCrash

func LogForkAndCrash(log zerolog.Logger) ExecForkActor

type ExecForkSuppressor

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

ExecForkSuppressor is a wrapper around a conventional mempool.IncorporatedResultSeals mempool. It implements the following mitigation strategy for execution forks:

  • In case two conflicting results are considered sealable for the same block, sealing should halt. Specifically, two results are considered conflicting, if they differ in their start or end state.
  • Even after a restart, the sealing should not resume.
  • We rely on human intervention to resolve the conflict.

The ExecForkSuppressor implements this mitigation strategy as follows:

  • For each candidate seal inserted into the mempool, inspect the state transition for the respective block.
  • If this is the first seal for a block, store the seal as an archetype for the state transition into the internal map `sealsForBlock`.
  • If the mempool already knows about a state transition for a block, and a second seal for the same block is inserted, check whether the seal has the same state transition.
  • If conflicting state transitions for the same block are detected, ExecForkSuppressor sets an internal flag and thereafter reports the mempool as empty, which will lead to the respective consensus node not including any more seals.
  • Evidence for an execution fork stored in a database (persisted across restarts).

Implementation is concurrency safe.

func NewExecStateForkSuppressor

func NewExecStateForkSuppressor(onExecFork ExecForkActor, seals mempool.IncorporatedResultSeals, db *badger.DB, log zerolog.Logger) (*ExecForkSuppressor, error)

func (*ExecForkSuppressor) Add

Add adds the given seal to the mempool. Return value indicates whether or not seal was added to mempool. Error returns:

  • engine.InvalidInputError (sentinel error) In case a seal fails one of the required consistency checks;

func (*ExecForkSuppressor) All

All returns all the IncorporatedResultSeals in the mempool

func (*ExecForkSuppressor) ByID

ByID returns an IncorporatedResultSeal by its ID

func (*ExecForkSuppressor) Clear

func (s *ExecForkSuppressor) Clear()

Clear removes all entities from the pool. The wrapper clears the internal state as well as its local (additional) state.

func (*ExecForkSuppressor) Limit

func (s *ExecForkSuppressor) Limit() uint

Limit returns the size limit of the mempool

func (*ExecForkSuppressor) RegisterEjectionCallbacks

func (s *ExecForkSuppressor) RegisterEjectionCallbacks(callbacks ...mempool.OnEjection)

RegisterEjectionCallbacks adds the provided OnEjection callbacks

func (*ExecForkSuppressor) Rem

Rem removes the IncorporatedResultSeal with id from the mempool

func (*ExecForkSuppressor) Size

func (s *ExecForkSuppressor) Size() uint

Size returns the number of items in the mempool

type ExecutionTree added in v0.14.0

type ExecutionTree struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ExecutionTree is a mempool holding receipts, which is aware of the tree structure formed by the results. The mempool supports pruning by height: only results descending from the latest sealed and finalized result are relevant. Hence, we can prune all results for blocks _below_ the latest block with a finalized seal. Results of sufficient height for forks that conflict with the finalized fork are retained. However, such orphaned forks do not grow anymore and their results will be progressively flushed out with increasing sealed-finalized height.

Safe for concurrent access. Internally, the mempool utilizes the LevelledForrest. For an in-depth discussion of the core algorithm, see ./Fork-Aware_Mempools.md

func NewExecutionTree added in v0.14.0

func NewExecutionTree() *ExecutionTree

NewExecutionTree instantiates a ExecutionTree

func (*ExecutionTree) AddReceipt added in v0.14.0

func (et *ExecutionTree) AddReceipt(receipt *flow.ExecutionReceipt, block *flow.Header) (bool, error)

Add the given execution receipt to the memory pool. Requires height of the block the receipt is for. We enforce data consistency on an API level by using the block header as input.

func (*ExecutionTree) AddResult added in v0.14.0

func (et *ExecutionTree) AddResult(result *flow.ExecutionResult, block *flow.Header) error

AddResult adds an Execution Result to the Execution Tree (without any receipts), in case the result is not already stored in the tree. This is useful for crash recovery: After recovering from a crash, the mempools are wiped and the sealed results will not be stored in the Execution Tree anymore. Adding the result to the tree allows to create a vertex in the tree without attaching any Execution Receipts to it.

func (*ExecutionTree) LowestHeight added in v0.14.0

func (et *ExecutionTree) LowestHeight() uint64

LowestHeight returns the lowest height, where results are still stored in the mempool.

func (*ExecutionTree) PruneUpToHeight added in v0.14.0

func (et *ExecutionTree) PruneUpToHeight(limit uint64) error

PruneUpToHeight prunes all results for all blocks with height up to but NOT INCLUDING `newLowestHeight`. Errors if newLowestHeight is lower than the previous value (as we cannot recover previously pruned results).

func (*ExecutionTree) ReachableReceipts added in v0.14.0

func (et *ExecutionTree) ReachableReceipts(resultID flow.Identifier, blockFilter mempool.BlockFilter, receiptFilter mempool.ReceiptFilter) ([]*flow.ExecutionReceipt, error)

ReachableReceipts returns a slice of ExecutionReceipt, whose result is computationally reachable from resultID. Context:

  • Conceptually, the Execution results form a tree, which we refer to as Execution Tree. A fork in the execution can be due to a fork in the main chain. Furthermore, the execution forks if ENs disagree about the result for the same block.
  • As the ID of an execution result contains the BlockID, which the result for, all Execution Results with the same ID necessarily are for the same block. All Execution Receipts committing to the same result from an equivalence class and can be represented as one vertex in the Execution Tree.
  • An execution result r1 points (field ExecutionResult.ParentResultID) to its parent result r0 , whose end state was used as the starting state to compute r1. Formally, we have an edge r0 -> r1 in the Execution Tree, if a result r1 is stored in the mempool, whose ParentResultID points to r0.

ReachableReceipts traverses the Execution Tree from the provided resultID. Execution Receipts are traversed in a parent-first manner, meaning that a receipt committing to the parent result is traversed first _before_ the receipt committing to the derived result. The algorithm only traverses to results, for which there exists a sequence of interim result in the mempool without any gaps.

func (*ExecutionTree) Size added in v0.14.0

func (et *ExecutionTree) Size() uint

Size returns the number of receipts stored in the mempool

type ReceiptsOfSameResult added in v0.14.0

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

ReceiptsOfSameResult represents a set of ExecutionReceipt all committing to the same ExecutionResult. As an ExecutionResult contains the Block ID, all results with the same ID must be for the same block. For optimized storage, we only store the result once. Mathematically, a ReceiptsOfSameResult struct represents an Equivalence Class of Execution Receipts. Implements LevelledForest's Vertex interface.

func NewReceiptsOfSameResult added in v0.14.0

func NewReceiptsOfSameResult(result *flow.ExecutionResult, block *flow.Header) (*ReceiptsOfSameResult, error)

NewReceiptsOfSameResult instantiates an empty Equivalence Class (without any receipts)

func (*ReceiptsOfSameResult) AddReceipt added in v0.14.0

func (rsr *ReceiptsOfSameResult) AddReceipt(receipt *flow.ExecutionReceipt) (uint, error)

AddReceipt adds the receipt to the ReceiptsOfSameResult (if not already stored). Returns:

  • uint: number of receipts added (consistent API with AddReceipts()), Possible values: 0 or 1
  • error in case of unforeseen problems

func (*ReceiptsOfSameResult) AddReceipts added in v0.14.0

func (rsr *ReceiptsOfSameResult) AddReceipts(receipts ...*flow.ExecutionReceipt) (uint, error)

AddReceipts adds the receipts to the ReceiptsOfSameResult (the ones not already stored). Returns:

  • uint: number of receipts added
  • error in case of unforeseen problems

func (*ReceiptsOfSameResult) Has added in v0.14.0

func (rsr *ReceiptsOfSameResult) Has(receiptID flow.Identifier) bool

func (*ReceiptsOfSameResult) Level added in v0.14.0

func (rsr *ReceiptsOfSameResult) Level() uint64

func (*ReceiptsOfSameResult) Parent added in v0.14.0

func (rsr *ReceiptsOfSameResult) Parent() (flow.Identifier, uint64)

func (*ReceiptsOfSameResult) Size added in v0.14.0

func (rsr *ReceiptsOfSameResult) Size() uint

Size returns the number of receipts in the equivalence class (i.e. the number of receipts known for that particular result)

func (*ReceiptsOfSameResult) VertexID added in v0.14.0

func (rsr *ReceiptsOfSameResult) VertexID() flow.Identifier

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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