Back to

Package forkable

Latest Go to latest

The latest major version is .

Published: Jun 22, 2020 | License: Apache-2.0 | Module:



const (
	StepNew          = StepType(1 << iota) //1  First time we're seeing this block
	StepUndo                               //2  We are undoing this block (it was done previously)
	StepRedo                               //4  We are redoing this block (it was done previously)
	StepHandoff                            //8  The block passed a handoff from one producer to another
	StepIrreversible                       //16 This block passed the LIB barrier and is in chain
	StepStalled                            //32 This block passed the LIB and is definitely forked out
	StepsAll         = StepType(StepNew | StepUndo | StepRedo | StepHandoff | StepIrreversible | StepStalled)

func NewWithLIB

func NewWithLIB(libID bstream.BlockRef, h bstream.Handler)

NewWithLIB DEPRECATED, use `New(h, WithExclusiveLIB(libID))`. Also use `EnsureBlockFlows`, `WithFilters`, `EnsureAllBlocksTriggerLongestChain` options

type Block

type Block struct {
	BlockID         string
	BlockNum        uint64
	PreviousBlockID string
	Object          interface{}

type ForkDB

type ForkDB struct {
	// contains filtered or unexported fields

ForkDB holds the graph of block headBlockID to previous block.

func NewForkDB

func NewForkDB() *ForkDB
func (f *ForkDB) AddLink(blockRef, previousRef bstream.BlockRef, obj interface{}) (exists bool)

func (*ForkDB) BlockForID

func (f *ForkDB) BlockForID(blockID string) *Block

func (*ForkDB) BlockInCurrentChain

func (f *ForkDB) BlockInCurrentChain(startAtBlock bstream.BlockRef, blockNum uint64) bstream.BlockRef

BlockInCurrentChain finds the block_id at height `blockNum` under the requested `startAtBlockID` base block. Passing the head block id as `startAtBlockID` will tell you if the block num is part of the longuest chain.

func (*ForkDB) ChainSwitchSegments

func (f *ForkDB) ChainSwitchSegments(oldHeadBlockID, newHeadsPreviousID string) (undo []string, redo []string)

ChainSwitchSegments returns the list of block IDs that should be `undo`ne (in reverse chain order) and the list of blocks that should be `redo`ne (in chain order) for `blockID` (linking to `previousID`) to become the longest chain.

This assumes you are querying for something that *is* the longest chain (or the to-become longest chain).

func (f *ForkDB) ClonedLinks() (out map[string]string, nums map[string]uint64)

CloneLinks retrieves a snapshot of the links in the ForkDB. Used only in ForkViewerin `eosws`.

func (*ForkDB) Exists

func (f *ForkDB) Exists(blockID string) bool

func (*ForkDB) HasLIB

func (f *ForkDB) HasLIB() bool

func (*ForkDB) HasNewIrreversibleSegment

func (f *ForkDB) HasNewIrreversibleSegment(newLIB bstream.BlockRef) (hasNew bool, irreversibleSegment, staleBlocks []*Block)

HasNewIrreversibleSegment returns segments upon psasing the newDposLIBID that are irreversible and stale. If there was no new segment, `hasNew` will be false. WARN: this method can only be called when `HasLIB()` is true. Otherwise, it panics.

func (*ForkDB) InitLIB

func (f *ForkDB) InitLIB(ref bstream.BlockRef)

func (*ForkDB) IsBehindLIB

func (f *ForkDB) IsBehindLIB(blockNum uint64) bool

func (*ForkDB) LIBID

func (f *ForkDB) LIBID() string

Get the last irreversible block ID

func (*ForkDB) LIBNum

func (f *ForkDB) LIBNum() uint64

Get the last irreversible block num

func (*ForkDB) MoveLIB

func (f *ForkDB) MoveLIB(blockRef bstream.BlockRef) (purgedBlocks []*Block)

func (*ForkDB) ReversibleSegment

func (f *ForkDB) ReversibleSegment(upToBlock bstream.BlockRef) (blocks []*Block)

ReversibleSegment returns the blocks between the previous irreversible Block ID and the given block ID. The LIB is excluded and the given block ID is included in the results.

Do not call this function is the .HasLIB() is false, as the result would make no sense.

WARN: if the segment is broken by some unlinkable blocks, the return value is `nil`.

func (*ForkDB) SetName

func (f *ForkDB) SetName(name string)

func (*ForkDB) TrySetLIB

func (f *ForkDB) TrySetLIB(headRef, previousRef bstream.BlockRef, libNum uint64)

TrySetLIB will move the lib if crawling from the given blockID up to the dposlibNum succeeds, giving us effectively the dposLIBID. It will perform the set LIB and set the new headBlockID unknown behaviour if it was already set ... maybe it explodes

type Forkable

type Forkable struct {
	// contains filtered or unexported fields

func New

func New(h bstream.Handler, opts ...Option) *Forkable

func (*Forkable) ProcessBlock

func (p *Forkable) ProcessBlock(blk *bstream.Block, obj interface{}) error

type ForkableBlock

type ForkableBlock struct {
	Block     *bstream.Block
	Obj       interface{}
	SentAsNew bool

type ForkableObject

type ForkableObject struct {
	Step StepType

	HandoffCount int

	// The three following fields are filled when handling multi-block steps, like when passing Irreversibile segments, the whole segment is represented in here.
	StepCount  int                          // Total number of steps in multi-block steps.
	StepIndex  int                          // Index for the current block
	StepBlocks []*bstream.PreprocessedBlock // You can decide to process them when StepCount == StepIndex +1 or when StepIndex == 0 only.

	ForkDB *ForkDB // ForkDB is a reference to the `Forkable`'s ForkDB instance. Provided you don't use it in goroutines, it is safe for use in `ProcessBlock` calls.

	// Object that was returned by PreprocessBlock(). Could be nil
	Obj interface{}

type IrreversibleBlockIDGate

type IrreversibleBlockIDGate struct {
	Name string

	MaxHoldOff int
	// contains filtered or unexported fields

This gate lets all blocks through once the target block ID has passed AS IRREVERSIBLE

func NewIrreversibleBlockIDGate

func NewIrreversibleBlockIDGate(blockID string, gateType bstream.GateType, h bstream.Handler) *IrreversibleBlockIDGate

func (*IrreversibleBlockIDGate) ProcessBlock

func (g *IrreversibleBlockIDGate) ProcessBlock(blk *bstream.Block, obj interface{}) error

type IrreversibleBlockNumGate

type IrreversibleBlockNumGate struct {
	Name string

	MaxHoldOff int
	// contains filtered or unexported fields

This gate lets all blocks through once the target blocknum has passed AS IRREVERSIBLE

func NewIrreversibleBlockNumGate

func NewIrreversibleBlockNumGate(blockNum uint64, gateType bstream.GateType, h bstream.Handler) *IrreversibleBlockNumGate

func (*IrreversibleBlockNumGate) ProcessBlock

func (g *IrreversibleBlockNumGate) ProcessBlock(blk *bstream.Block, obj interface{}) error

type Option

type Option func(f *Forkable)

func EnsureAllBlocksTriggerLongestChain

func EnsureAllBlocksTriggerLongestChain() Option

EnsureAllBlocksTriggerLongestChain will force every block to be considered as the longest chain, therefore making it appear as New at least once. The only edge case is if there is a hole between a block and LIB when it is received, and it is forked out: in this case, that block would never appear. It is extremely unlikely to happen, because incoming blocks should be linkable, and blocks that are not forked out will eventually be processed anyway.

func EnsureBlockFlows

func EnsureBlockFlows(blockRef bstream.BlockRef) Option

func WithExclusiveLIB

func WithExclusiveLIB(irreversibleBlock bstream.BlockRef) Option

func WithFilters

func WithFilters(steps StepType) Option

WithFilters choses the steps we want to pass through the sub handler. It defaults to StepsAll upon creation.

func WithInclusiveLIB

func WithInclusiveLIB(irreversibleBlock bstream.BlockRef) Option

func WithName

func WithName(name string) Option

type StepType

type StepType int

func (StepType) String

func (t StepType) String() string

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier