controller

package
v0.1.14-snapshot Latest Latest
Warning

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

Go to latest
Published: Nov 24, 2025 License: MIT Imports: 16 Imported by: 0

README

Go Reference License

Package Controller

The Controller package serves as the central coordination hub for a Canopy blockchain node. It orchestrates the interactions between various system components and manages the node's lifecycle from initialization through operation to shutdown.

Overview

The Controller acts as a "bus" between the core modules of the Canopy blockchain:

  • Blockchain state management (FSM)
  • Transaction processing and mempool
  • Byzantine Fault Tolerant (BFT) consensus
  • Peer-to-peer networking
  • Root chain interactions

This package is responsible for ensuring these components work together seamlessly to maintain blockchain consensus, process transactions, and communicate with peers and parent chains.

Core Components

Controller Structure

The Controller contains references to all major subsystems and coordinates their interactions:

  • Node identity (address, keys)
  • Configuration settings
  • Core blockchain components (FSM, Mempool, Consensus, P2P)
  • Root chain management
  • Synchronization status
graph TD
    Controller --> FSM[State Machine]
    Controller --> Mempool
    Controller --> Consensus
    Controller --> P2P
    Controller --> RootChain[Root Chain Info]

    P2P -- Messages --> Controller
    Consensus -- State Updates --> FSM
    Mempool -- Transactions --> Consensus
    RootChain -- Validator Info --> Consensus
    FSM -- Blockchain State --> Controller
Block Processing System

The block processing system handles how blocks are:

  • Received and validated from the network
  • Created during the proposal phase
  • Committed to the blockchain
  • Distributed to other nodes

This system ensures all nodes maintain consensus on the blockchain state through BFT consensus.

Consensus Management

The consensus management system:

  • Synchronizes nodes with the current blockchain state
  • Routes consensus messages between validators
  • Manages validator committees
  • Handles block requests and responses
  • Reports on consensus status
Transaction System

The transaction system:

  • Processes locally generated transactions
  • Validates incoming transactions from peers
  • Maintains the mempool of pending transactions
  • Gossips valid transactions to peers
  • Tracks failed transactions for reporting
Certificate Result System

The Certificate Result system handles the post-consensus outcomes:

  • Calculates reward distributions to network participants
  • Processes cross-chain swap orders
  • Manages slashes for Byzantine behavior
  • Creates checkpoints for cross-chain verification
  • Tracks chain lifecycle status

Security Features

The Controller implements several security measures:

  • Thread safety through mutex locks and atomic operations
  • Byzantine Fault Tolerance for consensus security
  • Reputation system to penalize malicious or faulty peers
  • Rate limiting to prevent DoS attacks
  • Message signing and verification
  • VDF iteration verification to prevent unsafe forks
  • Cross-chain checkpointing for long-range attack prevention

Usage

The Controller is the primary entry point when initializing a Canopy blockchain node. After configuration and initialization of the core components (FSM, P2P, etc.), the Controller's Start() method begins node operation, which continues until Stop() is called.

The Controller interacts closely with several other major Canopy components which in turn interact with each other at various levels:

  • FSM (Finite State Machine): Maintains blockchain state and processes transactions
  • BFT (Byzantine Fault Tolerance): Manages consensus between validators
  • P2P (Peer to Peer): Handles network communication between nodes
  • Crypto: Provides cryptographic primitives for security operations
  • Store: Persists blockchain data to disk storage

Together, these components form a complete blockchain node capable of participating in the Canopy network.

Documentation

Index

Constants

View Source
const (
	BlockRequest = lib.Topic_BLOCK_REQUEST
	Block        = lib.Topic_BLOCK
	Tx           = lib.Topic_TX
	Cons         = lib.Topic_CONSENSUS
)

convenience aliases that reference the library package

View Source
const CheckpointFrequency = 100

define how often the chain checkpoints with its root

Variables

This section is empty.

Functions

This section is empty.

Types

type CachedProposal

type CachedProposal struct {
	Block       *lib.Block
	BlockResult *lib.BlockResult
	CertResults *lib.CertificateResult
	// contains filtered or unexported fields
}

type ConsensusSummary

type ConsensusSummary struct {
	Syncing              bool                   `json:"isSyncing"`
	View                 *lib.View              `json:"view"`
	BlockHash            lib.HexBytes           `json:"blockHash"`
	ResultsHash          lib.HexBytes           `json:"resultsHash"`
	Locked               bool                   `json:"locked"`
	Address              lib.HexBytes           `json:"address"`
	PublicKey            lib.HexBytes           `json:"publicKey"`
	ProposerAddress      lib.HexBytes           `json:"proposerAddress"`
	Proposer             lib.HexBytes           `json:"proposer"`
	Proposals            bft.ProposalsForHeight `json:"proposals"`
	PartialQCs           bft.PartialQCs         `json:"partialQCs"`
	PacemakerVotes       bft.PacemakerMessages  `json:"pacemakerVotes"`
	MinimumPowerFor23Maj uint64                 `json:"minimumPowerFor23Maj"`
	Votes                bft.VotesForHeight     `json:"votes"`
	Status               string                 `json:"status"`
}

ConsensusSummary is simply a json informational structure about the local status of the BFT

type Controller

type Controller struct {
	Address          []byte                                  // self address
	PublicKey        []byte                                  // self public key
	PrivateKey       crypto.PrivateKeyI                      // self private key
	Config           lib.Config                              // node configuration
	Metrics          *lib.Metrics                            // telemetry
	LastValidatorSet map[uint64]map[uint64]*lib.ValidatorSet // cache [height][chainID] -> set

	FSM       *fsm.StateMachine // the core protocol component responsible for maintaining and updating the state of the blockchain
	Mempool   *Mempool          // the in memory list of pending transactions
	Consensus *bft.BFT          // the async consensus process between the committee members for the chain
	P2P       *p2p.P2P          // the P2P module the node uses to connect to the network

	RCManager lib.RCManagerI // the data manager for the 'root chain'

	*sync.Mutex // mutex for thread safety
	// contains filtered or unexported fields
}

Controller acts as the 'manager' of the modules of the application

func New

func New(fsm *fsm.StateMachine, c lib.Config, valKey crypto.PrivateKeyI, metrics *lib.Metrics, l lib.LoggerI) (controller *Controller, err lib.ErrorI)

New() creates a new instance of a Controller, this is the entry point when initializing an instance of a Canopy application

func (*Controller) AddPaymentPercent

func (c *Controller) AddPaymentPercent(toAdd *lib.LotteryWinner, results *lib.CertificateResult, isOwnRoot bool, rootChainId uint64)

AddPaymentPercent() adds a payment percent to the certificate result for both the root chain and nested chain ids (if different)

func (*Controller) AddRewardRecipient

func (c *Controller) AddRewardRecipient(proposer, toAdd *lib.LotteryWinner, results *lib.CertificateResult, isOwnRoot bool, rootChainId uint64)

AddRewardRecipient() adds a reward recipient to the list of reward recipients in the certificate result

func (*Controller) ApplyAndValidateBlock

func (c *Controller) ApplyAndValidateBlock(block *lib.Block, lastValidatorSet *lib.ValidatorSet, commit bool) (b *lib.BlockResult, err lib.ErrorI)

ApplyAndValidateBlock() plays the block against the state machine which returns a result that is compared against the candidate block header

func (*Controller) CalculateCheckpoint

func (c *Controller) CalculateCheckpoint(blockResult *lib.BlockResult, results *lib.CertificateResult)

CalculateCheckpoint() calculates the checkpoint for the checkpoint as a service functionality

func (*Controller) CalculateRewardRecipients

func (c *Controller) CalculateRewardRecipients(fsm *fsm.StateMachine, proposerAddress []byte, rootChainHeight uint64) (results *lib.CertificateResult)

CalculateRewardRecipients() calculates the block reward recipients of the proposal

func (*Controller) CalculateSlashRecipients

func (c *Controller) CalculateSlashRecipients(results *lib.CertificateResult, be *bft.ByzantineEvidence)

CalculateSlashRecipients() calculates the addresses who receive slashes on the root-chain

func (*Controller) ChainHeight

func (c *Controller) ChainHeight() uint64

ChainHeight() returns the height of this target chain

func (*Controller) CheckAndSetLastCertificate

func (c *Controller) CheckAndSetLastCertificate(candidate *lib.BlockHeader) lib.ErrorI

CheckAndSetLastCertificate() validates the last quorum certificate included in the block and sets it in the ephemeral indexer NOTE: This must come before ApplyBlock in order to have the proposers 'lastCertificate' which is used for distributing rewards

func (*Controller) CheckMempool

func (c *Controller) CheckMempool()

CheckMempool() periodically checks the mempool: - Validates all transactions in the mempool - Caches a proposal block based on the current state and the mempool transactions - P2P Gossip out any transactions that weren't previously gossiped

func (*Controller) CommitCertificate

func (c *Controller) CommitCertificate(qc *lib.QuorumCertificate, block *lib.Block, blockResult *lib.BlockResult, ts uint64) (err lib.ErrorI)

CommitCertificate() is executed after the quorum agrees on a block - applies block against the fsm - indexes the block and its transactions - removes block transactions from mempool - re-checks all transactions in mempool - atomically writes all to the underlying db - sets up the controller for the next height

func (*Controller) CommitCertificateParallel

func (c *Controller) CommitCertificateParallel(qc *lib.QuorumCertificate, block *lib.Block, blockResult *lib.BlockResult, ts uint64) (err lib.ErrorI)

CommitCertificate() the experimental and parallelized version of the above

func (*Controller) ConsensusSummary

func (c *Controller) ConsensusSummary() ([]byte, lib.ErrorI)

ConsensusSummary() for the RPC - returns the summary json object of the bft for a specific chainID

func (*Controller) GetFailedTxsPage

func (c *Controller) GetFailedTxsPage(address string, p lib.PageParams) (page *lib.Page, err lib.ErrorI)

GetFailedTxsPage() returns a list of failed mempool transactions

func (*Controller) GetPendingPage

func (c *Controller) GetPendingPage(p lib.PageParams) (page *lib.Page, err lib.ErrorI)

GetPendingPage() returns a page of unconfirmed mempool transactions

func (*Controller) GetProposalBlockFromMempool

func (c *Controller) GetProposalBlockFromMempool() *CachedProposal

GetProposalBlockFromMempool() returns the cached proposal block

func (*Controller) GetRootChainLotteryWinner

func (c *Controller) GetRootChainLotteryWinner(fsm *fsm.StateMachine, rootHeight uint64) (winner *lib.LotteryWinner, err lib.ErrorI)

GetRootChainLotteryWinner() gets the pseudorandomly selected delegate to reward and their cut

func (*Controller) GossipBlock

func (c *Controller) GossipBlock(certificate *lib.QuorumCertificate, senderPubToExclude []byte, timestamp uint64)

GossipBlockMsg() gossips a certificate (with block) through the P2P network for a specific chainId

func (*Controller) HandlePeerBlock

func (c *Controller) HandlePeerBlock(msg *lib.BlockMessage, syncing bool) (*lib.QuorumCertificate, lib.ErrorI)

HandlePeerBlock() validates and handles an inbound certificate (with a block) from a remote peer

func (*Controller) HandleRetired

func (c *Controller) HandleRetired(fsm *fsm.StateMachine, results *lib.CertificateResult)

HandleRetired() checks if the committee is retiring and sets in the results accordingly

func (*Controller) HandleSwaps

func (c *Controller) HandleSwaps(fsm *fsm.StateMachine, blockResult *lib.BlockResult, results *lib.CertificateResult, rootChainHeight uint64)

HandleSwaps() handles the 'buy' side of the sell orders

func (*Controller) IsValidDoubleSigner

func (c *Controller) IsValidDoubleSigner(rootChainId, rootHeight uint64, address []byte) bool

IsValidDoubleSigner() checks if the double signer is valid at a certain double sign height

func (*Controller) ListenForBlock

func (c *Controller) ListenForBlock()

ListenForBlock() listens for inbound block messages, internally routes them, and gossips them to peers

func (*Controller) ListenForBlockRequests

func (c *Controller) ListenForBlockRequests()

ListenForBlockRequests() listen for inbound block request messages from syncing peers, handles and answer them

func (*Controller) ListenForConsensus

func (c *Controller) ListenForConsensus()

ListenForConsensus() listens and internally routes inbound consensus messages

func (*Controller) ListenForTx

func (c *Controller) ListenForTx()

ListenForTx() listen for inbound tx messages, internally route them, and gossip them to peers

func (*Controller) LoadCertificate

func (c *Controller) LoadCertificate(height uint64) (*lib.QuorumCertificate, lib.ErrorI)

LoadCertificate() gets the certificate for from the indexer at a specific height

func (*Controller) LoadCommittee

func (c *Controller) LoadCommittee(rootChainId, rootHeight uint64) (lib.ValidatorSet, lib.ErrorI)

LoadCommittee() gets the ValidatorSet that is authorized to come to Consensus agreement on the Proposal for a specific height/chainId

func (*Controller) LoadCommitteeData

func (c *Controller) LoadCommitteeData() (data *lib.CommitteeData, err lib.ErrorI)

LoadCommitteeData() returns the state metadata for the 'self chain'

func (*Controller) LoadIsOwnRoot

func (c *Controller) LoadIsOwnRoot() (isOwnRoot bool)

LoadIsOwnRoot() returns if this chain is its own root (base)

func (*Controller) LoadLastCommitTime

func (c *Controller) LoadLastCommitTime(height uint64) time.Time

LoadLastCommitTime() gets a timestamp from the most recent Quorum Block

func (*Controller) LoadLastProposers

func (c *Controller) LoadLastProposers(height uint64) (*lib.Proposers, lib.ErrorI)

LoadProposerKeys() gets the last root-chainId proposer keys

func (*Controller) LoadMaxBlockSize

func (c *Controller) LoadMaxBlockSize() int

LoadMaxBlockSize() gets the max block size from the state

func (*Controller) LoadMinimumEvidenceHeight

func (c *Controller) LoadMinimumEvidenceHeight(rootChainId, rootHeight uint64) (*uint64, lib.ErrorI)

LoadMinimumEvidenceHeight() gets the minimum evidence height from the finite state machine

func (*Controller) LoadRootChainId

func (c *Controller) LoadRootChainId(height uint64) (rootChainId uint64)

RootChainId() returns the root chain id according to the FSM

func (*Controller) LoadRootChainOrderBook

func (c *Controller) LoadRootChainOrderBook(rootChainId, rootHeight uint64) (*lib.OrderBook, lib.ErrorI)

LoadRootChainOrderBook() gets the order book from the root-chain

func (*Controller) NewCertificateResults

func (c *Controller) NewCertificateResults(
	fsm *fsm.StateMachine, block *lib.Block, blockResult *lib.BlockResult,
	evidence *bft.ByzantineEvidence, rcBuildHeight uint64) (results *lib.CertificateResult)

NewCertificateResults() creates a structure to hold the results of the certificate produced by a quorum in consensus

func (*Controller) ProduceProposal

func (c *Controller) ProduceProposal(evidence *bft.ByzantineEvidence, vdf *crypto.VDF) (rcBuildHeight uint64, blockBytes []byte, results *lib.CertificateResult, err lib.ErrorI)

ProduceProposal() create a proposal in the form of a `block` and `certificate result` for the bft process

func (*Controller) RequestBlock

func (c *Controller) RequestBlock(heightOnly bool, recipients ...[]byte)

RequestBlock() sends a block request to peer(s) - `heightOnly` is a request for just the peer's max height

func (*Controller) ResetFSM

func (c *Controller) ResetFSM()

ResetFSM() resets the underlying state machine to last valid state

func (*Controller) RootChainHeight

func (c *Controller) RootChainHeight() uint64

RootChainHeight() returns the height of the canopy root-chain

func (*Controller) SelfSendBlock

func (c *Controller) SelfSendBlock(qc *lib.QuorumCertificate, timestamp uint64)

SelfSendBlock() gossips a QuorumCertificate (with block) through the P2P network for handling

func (*Controller) SendBlock

func (c *Controller) SendBlock(maxHeight, vdfIterations uint64, blockAndCert *lib.QuorumCertificate, recipient []byte)

SendBlock() responds to a `blockRequest` message to a peer - always sending the self.MaxHeight and sometimes sending the actual block and supporting QC

func (*Controller) SendCertificateResultsTx

func (c *Controller) SendCertificateResultsTx(qc *lib.QuorumCertificate)

SendCertificateResultsTx() originates and auto-sends a CertificateResultsTx after successfully leading a Consensus height

func (*Controller) SendToProposer

func (c *Controller) SendToProposer(msg lib.Signable)

SendToProposer() sends a bft message to the leader of the Consensus round

func (*Controller) SendToReplicas

func (c *Controller) SendToReplicas(replicas lib.ValidatorSet, msg lib.Signable)

SendToReplicas() directly send a bft message to each validator in a set (committee)

func (*Controller) SendTxMsg

func (c *Controller) SendTxMsg(tx []byte) lib.ErrorI

SendTxMsg() routes a locally generated transaction message to the listener for processing + gossiping

func (*Controller) SetFSMInConsensusModeForProposals

func (c *Controller) SetFSMInConsensusModeForProposals() (reset func())

SetFSMInConsensusModeForProposals() is how the Validator is configured for `base chain` specific parameter upgrades

func (*Controller) Start

func (c *Controller) Start()

Start() begins the Controller service

func (*Controller) StartListeners

func (c *Controller) StartListeners()

StartListeners() runs all listeners on separate threads

func (*Controller) Stop

func (c *Controller) Stop()

Stop() terminates the Controller service

func (*Controller) Sync

func (c *Controller) Sync()

Sync() downloads the blockchain from peers until 'synced' to the latest 'height' 1) Get the height and begin block params from the state_machine 2) Get peer max_height from P2P 3) Fill a queue of blocks by requesting them from randomly chosen peers 4) When available, process next block from queue 5) CheckBasic each block by checking if cert was signed by +2/3 maj (COMMIT message) 6) Commit block against the state machine, if error fatal 7) Do this until reach the max-peer-height 8) Stay on top by listening to incoming cert messages

func (*Controller) Syncing

func (c *Controller) Syncing() *atomic.Bool

Syncing() returns if any of the supported chains are currently syncing

func (*Controller) UpdateP2PMustConnect

func (c *Controller) UpdateP2PMustConnect(v *lib.ConsensusValidators)

UpdateP2PMustConnect() tells the P2P module which nodes are *required* to be connected to (usually fellow committee members or none if not in committee)

func (*Controller) UpdateRootChainInfo

func (c *Controller) UpdateRootChainInfo(info *lib.RootChainInfo)

UpdateRootChainInfo() receives updates from the root-chain thread

func (*Controller) UpdateTelemetry

func (c *Controller) UpdateTelemetry(qc *lib.QuorumCertificate, block *lib.Block, blockProcessingTime time.Duration)

UpdateTelemetry() updates the prometheus metrics after 'committing' a block

func (*Controller) ValidateProposal

func (c *Controller) ValidateProposal(rcBuildHeight uint64, qc *lib.QuorumCertificate, evidence *bft.ByzantineEvidence) (blockResult *lib.BlockResult, err lib.ErrorI)

ValidateProposal() fully validates a proposal in the form of a quorum certificate and resets back to begin block state

type Mempool

type Mempool struct {
	lib.Mempool                   // the memory pool itself defined as an interface
	L           *sync.Mutex       // thread safety at the mempool level
	FSM         *fsm.StateMachine // the ephemeral finite state machine used to validate inbound transactions
	// contains filtered or unexported fields
}

Mempool accepts or rejects incoming txs based on the mempool (ephemeral copy) state - recheck when

  • mempool dropped some percent of the lowest fee txs
  • new tx has higher fee than the lowest

- notes:

  • new tx added may also be evicted, this is expected behavior

func NewMempool

func NewMempool(fsm *fsm.StateMachine, address crypto.AddressI, config lib.MempoolConfig, metrics *lib.Metrics, log lib.LoggerI) (m *Mempool, err lib.ErrorI)

NewMempool() creates a new instance of a Mempool structure

func (*Mempool) CheckMempool

func (m *Mempool) CheckMempool()

CheckMempool() Checks each transaction in the mempool and caches a block proposal

func (*Mempool) HandleTransactions

func (m *Mempool) HandleTransactions(tx ...[]byte) (err lib.ErrorI)

HandleTransactions() attempts to add a transaction to the mempool by validating, adding, and evicting overfull or newly invalid txs

Jump to

Keyboard shortcuts

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