forkchoice

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const VoteConfirmationTimeoutSlots = 32

VoteConfirmationTimeoutSlots is the grace window (in slots) before an unresolved slot (no supermajority winner) transitions from NeedWait to NoSupermajority. This is NOT a mandatory delay before confirmation — a slot with observed supermajority is confirmed immediately regardless of this window. abcd.

View Source
const VoteThresholdSize = 2.0 / 3.0

VoteThresholdSize matches Agave's VOTE_THRESHOLD_SIZE = 2f64 / 3f64. See: agave/runtime/src/commitment.rs:9

Variables

View Source
var (
	ErrNeedWait        = errors.New("consensus: vote landing window not reached, need to wait")
	ErrNoSupermajority = errors.New("consensus: no hash reached supermajority for target slot")
)
View Source
var (
	ErrDepthExceeded  = errors.New("skip path: depth exceeded max allowed")
	ErrNoPath         = errors.New("skip path: no valid path found to target slot")
	ErrPathIncomplete = errors.New("skip path: path is incomplete and needs more observations")
	ErrEquivocation   = errors.New("skip path: observed conflicting blocks for the same slot")
)

Functions

This section is empty.

Types

type BankhashResult

type BankhashResult struct {
	Status          BankhashStatus
	WinningHash     solana.Hash
	StakeForHash    uint64 // stake accumulated for the queried hash
	WinningStake    uint64 // stake accumulated for the winning hash (may differ from StakeForHash)
	TotalEpochStake uint64
	ThresholdStake  uint64
}

BankhashResult provides detailed fork choice query results.

type BankhashStatus

type BankhashStatus int

BankhashStatus represents the confirmation status of a slot's bankhash.

const (
	BankhashHasSupermajority BankhashStatus = iota
	BankhashNoSupermajority
	BankhashNeedWait
)

func (BankhashStatus) String

func (s BankhashStatus) String() string

type ConfirmedLeaf

type ConfirmedLeaf struct {
	Slot     uint64
	Bankhash solana.Hash
}

ConfirmedLeaf is a vote-confirmed bankhash winner paired with the observed block slot it belongs to.

type ConsensusCoordinator

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

ConsensusCoordinator bridges the ForkChoiceService (vote accumulation) and the PoH path resolver. It finds a confirmed leaf ahead of the current anchor, then reconstructs which slots should use blocks versus be treated as skipped.

func NewConsensusCoordinator

func NewConsensusCoordinator(fc *ForkChoiceService, maxDepth int, policy string) *ConsensusCoordinator

NewConsensusCoordinator creates a coordinator with the given forkchoice service, maximum path depth, and unresolved policy.

func (*ConsensusCoordinator) Policy

func (cc *ConsensusCoordinator) Policy() string

Policy returns the coordinator's unresolved policy ("halt" or "warn").

func (*ConsensusCoordinator) ResolveFromAnchor

func (cc *ConsensusCoordinator) ResolveFromAnchor(anchorSlot uint64) (*ResolvedPath, error)

ResolveFromAnchor finds the highest confirmed leaf reachable within maxDepth from the current execution anchor, then reconstructs the block/skip path to it.

type ForkChoiceService

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

func NewForkChoiceService

func NewForkChoiceService(
	epoch uint64,
	epochStakes map[solana.PublicKey]uint64,
	totalEpochStake uint64,
	epochAuthorizedVoters *epochstakes.EpochAuthorizedVotersCache,
) *ForkChoiceService

func (*ForkChoiceService) FindConfirmedLeaf

func (s *ForkChoiceService) FindConfirmedLeaf(anchorSlot uint64, maxDepth int) (ConfirmedLeaf, error)

FindConfirmedLeaf returns the highest slot above the current anchor that has both an observed block and a vote-confirmed bankhash winner.

func (*ForkChoiceService) GetSupermajorityHash

func (s *ForkChoiceService) GetSupermajorityHash(slot uint64) (solana.Hash, BankhashStatus)

GetSupermajorityHash returns the vote-confirmed hash for a slot, if any hash has crossed the 2/3 supermajority threshold.

func (*ForkChoiceService) IsBankhashCorrect

func (s *ForkChoiceService) IsBankhashCorrect(slot uint64, bankHash solana.Hash) BankhashResult

IsBankhashCorrect queries the confirmation status of a slot's bankhash. Returns a BankhashResult with status, winning hash, stake details, and threshold.

A slot is confirmed immediately when a winner is observed — no mandatory delay. The timeout window (VoteConfirmationTimeoutSlots) only governs how long an unresolved slot (no winner) stays in NeedWait before becoming NoSupermajority.

func (*ForkChoiceService) LatestObservedSlot

func (s *ForkChoiceService) LatestObservedSlot() uint64

func (*ForkChoiceService) ObserveBlock

func (s *ForkChoiceService) ObserveBlock(meta ObservedBlockMeta, txs []*solana.Transaction) error

ObserveBlock ingests pre-execution block metadata and vote transactions.

func (*ForkChoiceService) ObserveExecutionAnchor

func (s *ForkChoiceService) ObserveExecutionAnchor(slot uint64, blockhash solana.Hash)

ObserveExecutionAnchor seeds the blockhash->slot index with the last known confirmed slot. This lets RPC-fetched children that only carry a parent blockhash recover their parent slot without extra RPC lookups.

func (*ForkChoiceService) ObserveSkippedSlot

func (s *ForkChoiceService) ObserveSkippedSlot(slot uint64)

ObserveSkippedSlot advances the observed watermark when the source tells us a slot was skipped. This keeps confirmed-leaf search moving even when no block exists for the slot.

func (*ForkChoiceService) PruneBeforeSlot

func (s *ForkChoiceService) PruneBeforeSlot(slot uint64)

PruneBeforeSlot drops forkchoice state older than the given slot. This is useful for post-execution verification paths that need to retain a small trailing window of recent slots without advancing the full execution anchor.

func (*ForkChoiceService) ResolvePathToLeaf

func (s *ForkChoiceService) ResolvePathToLeaf(anchorSlot uint64, leafSlot uint64, maxDepth int) (*SolveResult, error)

ResolvePathToLeaf reconstructs the block/skip decisions from anchorSlot to leafSlot using the observed pre-execution block metadata.

func (*ForkChoiceService) Start

func (s *ForkChoiceService) Start()

func (*ForkChoiceService) Stop

func (s *ForkChoiceService) Stop()

func (*ForkChoiceService) SubmitBlock

func (s *ForkChoiceService) SubmitBlock(slot uint64, txs []*solana.Transaction)

func (*ForkChoiceService) UpdateEpoch

func (s *ForkChoiceService) UpdateEpoch(
	epoch uint64,
	epochStakes map[solana.PublicKey]uint64,
	totalEpochStake uint64,
	epochAuthorizedVoters *epochstakes.EpochAuthorizedVotersCache,
)

UpdateEpoch swaps in new epoch stake data. Called at epoch boundaries so that vote stake weights and authorized voter lookups use current data.

type ObservedBlockMeta

type ObservedBlockMeta struct {
	Slot            uint64
	Blockhash       solana.Hash
	ParentSlot      uint64
	ParentSlotKnown bool
	ParentBlockhash solana.Hash
}

ObservedBlockMeta is the pre-execution PoH metadata we know about a block.

type ResolvedPath

type ResolvedPath struct {
	LeafSlot      uint64
	LeafBankhash  solana.Hash
	SlotDecisions []SlotDecision
}

ResolvedPath is a confirmed execution path from the current anchor to a vote-confirmed leaf.

type SlotDecision

type SlotDecision struct {
	Slot     uint64
	UseBlock bool // true = use the block, false = slot is empty/skipped
}

SlotDecision represents the resolved action for a single slot.

type SolveResult

type SolveResult struct {
	Path        []bool
	MatchedSlot uint64
}

SolveResult contains the resolved block/skip path. Path[i] corresponds to slot (anchorSlot + 1 + i):

true  -> use the block at that slot
false -> slot is empty/skipped

func ResolvePohPath

func ResolvePohPath(
	anchorSlot uint64,
	leafSlot uint64,
	observed map[uint64]*ObservedBlockMeta,
	equivocatedSlots map[uint64]struct{},
	maxDepth int,
) (*SolveResult, error)

ResolvePohPath walks backwards from a confirmed leaf slot to a known anchor slot using observed PoH parent links. Slots not present on the leaf's ancestry are treated as skipped.

Jump to

Keyboard shortcuts

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