Documentation
¶
Overview ¶
Package forging contains types and utilities for block production.
Block Propagation ¶
Block propagation to peers is handled automatically by the chain package. When a forged block is added via chain.AddBlock(), the method closes the chain's waitingChan (see chain/chain.go lines 174-180), which signals any blocking ChainIterators. The ouroboros chainsync server (see ouroboros/chainsync.go chainsyncServerRequestNext) waits on these iterators via ChainIterator.Next(true), which blocks on waitingChan when at chain tip. When the channel is closed, iterators wake up and deliver the new block to connected peers via RollForward messages.
This means there is no need for explicit propagation logic when forging blocks - adding the block to the chain automatically triggers delivery to all subscribed chainsync clients.
Package forging provides block production functionality for Cardano SPOs.
Index ¶
- Constants
- type BlockBroadcaster
- type BlockBuilder
- type BlockBuilderConfig
- type BlockForger
- func (f *BlockForger) IsRunning() bool
- func (f *BlockForger) RecordSlotBattle()
- func (f *BlockForger) SignBlockHeader(kesPeriod uint64, headerBytes []byte) ([]byte, error)
- func (f *BlockForger) SlotTracker() *SlotTracker
- func (f *BlockForger) Start(ctx context.Context) error
- func (f *BlockForger) Stop()
- func (f *BlockForger) VRFProofForSlot(slot uint64, epochNonce []byte) ([]byte, []byte, error)
- type ChainTipProvider
- type DefaultBlockBuilder
- type EpochNonceProvider
- type ForgedBlockRecord
- type ForgerConfig
- type LeaderChecker
- type MempoolProvider
- type MempoolTransaction
- type Mode
- type OpCert
- type PoolCredentials
- func (pc *PoolCredentials) GetKESPeriod() uint64
- func (pc *PoolCredentials) GetKESVKey() []byte
- func (pc *PoolCredentials) GetOpCert() *OpCert
- func (pc *PoolCredentials) GetPoolID() lcommon.PoolId
- func (pc *PoolCredentials) GetVRFSKey() []byte
- func (pc *PoolCredentials) GetVRFVKey() []byte
- func (pc *PoolCredentials) IsLoaded() bool
- func (pc *PoolCredentials) KESSign(period uint64, message []byte) ([]byte, error)
- func (pc *PoolCredentials) LoadFromFiles(vrfSKeyPath string, kesSKeyPath string, opCertPath string) error
- func (pc *PoolCredentials) OpCertExpiryPeriod() uint64
- func (pc *PoolCredentials) PeriodsRemaining(currentPeriod uint64) uint64
- func (pc *PoolCredentials) UpdateKESPeriod(period uint64) error
- func (pc *PoolCredentials) VRFProve(alpha []byte) ([]byte, []byte, error)
- func (pc *PoolCredentials) ValidateOpCert() error
- type ProtocolParamsProvider
- type SlotBattleEvent
- type SlotClockProvider
- type SlotTracker
- type TxValidator
Constants ¶
const SlotBattleEventType = event.EventType("forging.slot_battle")
SlotBattleEventType is the event type for slot battles (competing blocks)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BlockBroadcaster ¶
type BlockBroadcaster interface {
// AddBlock adds a block to the local chain and propagates to peers.
AddBlock(block ledger.Block, cbor []byte) error
}
BlockBroadcaster submits built blocks to the chain.
type BlockBuilder ¶
type BlockBuilder interface {
// BuildBlock creates a new block for the given slot.
// Returns the block and its CBOR encoding.
BuildBlock(slot uint64, kesPeriod uint64) (ledger.Block, []byte, error)
}
BlockBuilder constructs blocks from mempool transactions.
type BlockBuilderConfig ¶
type BlockBuilderConfig struct {
Logger *slog.Logger
Mempool MempoolProvider
PParamsProvider ProtocolParamsProvider
ChainTip ChainTipProvider
EpochNonce EpochNonceProvider
Credentials *PoolCredentials
// TxValidator optionally re-validates each transaction against
// the current ledger state before including it in a block.
// When nil, ledger-level re-validation is skipped (but
// intra-block double-spend detection still applies).
TxValidator TxValidator
}
BlockBuilderConfig holds configuration for the DefaultBlockBuilder.
type BlockForger ¶
type BlockForger struct {
// contains filtered or unexported fields
}
BlockForger coordinates block production for a stake pool.
func NewBlockForger ¶
func NewBlockForger(cfg ForgerConfig) (*BlockForger, error)
NewBlockForger creates a new block forger.
func (*BlockForger) IsRunning ¶
func (f *BlockForger) IsRunning() bool
IsRunning returns true if the forger is currently running.
func (*BlockForger) RecordSlotBattle ¶
func (f *BlockForger) RecordSlotBattle()
RecordSlotBattle increments the slot battles counter. This is called from external components (e.g., LedgerState) when a slot battle is detected.
func (*BlockForger) SignBlockHeader ¶
func (f *BlockForger) SignBlockHeader( kesPeriod uint64, headerBytes []byte, ) ([]byte, error)
SignBlockHeader signs a block header with KES.
func (*BlockForger) SlotTracker ¶
func (f *BlockForger) SlotTracker() *SlotTracker
SlotTracker returns the forger's slot tracker, which can be used by other components (e.g., chainsync) to detect slot battles.
func (*BlockForger) Start ¶
func (f *BlockForger) Start(ctx context.Context) error
Start begins the block forging process. The provided context controls the forger's lifecycle.
func (*BlockForger) Stop ¶
func (f *BlockForger) Stop()
Stop stops the block forging process. It blocks until the runLoop goroutine has exited.
func (*BlockForger) VRFProofForSlot ¶
VRFProofForSlot generates a VRF proof for leader election at the given slot. Returns (proof, output, error).
type ChainTipProvider ¶
type ChainTipProvider interface {
Tip() ochainsync.Tip
}
ChainTipProvider provides access to the current chain tip.
type DefaultBlockBuilder ¶
type DefaultBlockBuilder struct {
// contains filtered or unexported fields
}
DefaultBlockBuilder implements BlockBuilder using LedgerState components.
func NewDefaultBlockBuilder ¶
func NewDefaultBlockBuilder(cfg BlockBuilderConfig) (*DefaultBlockBuilder, error)
NewDefaultBlockBuilder creates a new DefaultBlockBuilder.
func (*DefaultBlockBuilder) BuildBlock ¶
func (b *DefaultBlockBuilder) BuildBlock( slot uint64, kesPeriod uint64, ) (ledger.Block, []byte, error)
BuildBlock creates a new block for the given slot. Returns the block and its CBOR encoding.
type EpochNonceProvider ¶
type EpochNonceProvider interface {
// CurrentEpoch returns the current epoch number.
CurrentEpoch() uint64
// EpochNonce returns the nonce for the given epoch.
EpochNonce(epoch uint64) []byte
}
EpochNonceProvider provides the epoch nonce for VRF proof generation.
type ForgedBlockRecord ¶
type ForgedBlockRecord struct {
BlockHash []byte
}
ForgedBlockRecord stores the hash of a block we forged for a given slot.
type ForgerConfig ¶
type ForgerConfig struct {
Mode Mode
Logger *slog.Logger
SlotDuration time.Duration
// Production mode configuration
Credentials *PoolCredentials
LeaderChecker LeaderChecker
BlockBuilder BlockBuilder
BlockBroadcaster BlockBroadcaster
SlotClock SlotClockProvider
// ForgeSyncToleranceSlots controls how far the local chain can lag the
// upstream tip before forging is skipped. Zero uses the default.
ForgeSyncToleranceSlots uint64
// ForgeStaleGapThresholdSlots controls when to log an error if the
// chain tip is far ahead of the slot clock. Zero uses the default.
ForgeStaleGapThresholdSlots uint64
// Prometheus metrics registry (optional)
PromRegistry prometheus.Registerer
}
ForgerConfig holds configuration for the block forger.
type LeaderChecker ¶
type LeaderChecker interface {
// ShouldProduceBlock returns true if this pool is the leader for the slot.
ShouldProduceBlock(slot uint64) bool
// NextLeaderSlot returns the next slot where this pool is leader.
NextLeaderSlot(fromSlot uint64) (uint64, bool)
}
LeaderChecker determines if the pool should produce a block for a given slot.
type MempoolProvider ¶
type MempoolProvider interface {
Transactions() []MempoolTransaction
}
MempoolProvider provides access to mempool transactions.
type MempoolTransaction ¶
MempoolTransaction represents a transaction in the mempool.
type OpCert ¶
type OpCert struct {
KESVKey []byte // KES verification key (32 bytes)
IssueNumber uint64 // Certificate sequence number
KESPeriod uint64 // KES period when certificate was created
Signature []byte // Cold key signature (64 bytes)
ColdVKey []byte // Cold verification key (32 bytes)
}
OpCert represents an operational certificate that binds a KES key to a pool.
type PoolCredentials ¶
type PoolCredentials struct {
// contains filtered or unexported fields
}
PoolCredentials holds the cryptographic keys required for block production. All keys are loaded using Bursa from standard cardano-cli format files. Fields are unexported to enforce thread-safe access via the mutex.
func NewPoolCredentials ¶
func NewPoolCredentials() *PoolCredentials
NewPoolCredentials creates an empty PoolCredentials instance.
func (*PoolCredentials) GetKESPeriod ¶
func (pc *PoolCredentials) GetKESPeriod() uint64
GetKESPeriod returns the current KES period of the loaded key. Returns 0 if the KES key is not loaded.
func (*PoolCredentials) GetKESVKey ¶
func (pc *PoolCredentials) GetKESVKey() []byte
GetKESVKey returns a copy of the KES verification key.
func (*PoolCredentials) GetOpCert ¶
func (pc *PoolCredentials) GetOpCert() *OpCert
GetOpCert returns a copy of the operational certificate. Returns nil if no certificate is loaded.
func (*PoolCredentials) GetPoolID ¶
func (pc *PoolCredentials) GetPoolID() lcommon.PoolId
GetPoolID returns the pool ID (Blake2b-224 of cold vkey).
func (*PoolCredentials) GetVRFSKey ¶
func (pc *PoolCredentials) GetVRFSKey() []byte
GetVRFSKey returns a copy of the VRF secret key (seed).
func (*PoolCredentials) GetVRFVKey ¶
func (pc *PoolCredentials) GetVRFVKey() []byte
GetVRFVKey returns a copy of the VRF verification key.
func (*PoolCredentials) IsLoaded ¶
func (pc *PoolCredentials) IsLoaded() bool
IsLoaded returns true if all credentials have been loaded.
func (*PoolCredentials) KESSign ¶
func (pc *PoolCredentials) KESSign(period uint64, message []byte) ([]byte, error)
KESSign signs a message with the KES key at the specified absolute period. The absolute period is converted to a relative period using the opcert start KES period before signing.
func (*PoolCredentials) LoadFromFiles ¶
func (pc *PoolCredentials) LoadFromFiles( vrfSKeyPath string, kesSKeyPath string, opCertPath string, ) error
LoadFromFiles loads all pool credentials from the specified file paths. Uses Bursa to parse cardano-cli format key files.
func (*PoolCredentials) OpCertExpiryPeriod ¶
func (pc *PoolCredentials) OpCertExpiryPeriod() uint64
OpCertExpiryPeriod returns the KES period at which the OpCert expires. For depth 6, max periods = 2^6 = 64, so expiry = startPeriod + 64.
func (*PoolCredentials) PeriodsRemaining ¶
func (pc *PoolCredentials) PeriodsRemaining(currentPeriod uint64) uint64
PeriodsRemaining returns how many KES periods remain before expiry.
func (*PoolCredentials) UpdateKESPeriod ¶
func (pc *PoolCredentials) UpdateKESPeriod(period uint64) error
UpdateKESPeriod updates the KES key to the specified absolute period. The absolute period is converted to a relative period using the opcert start KES period before evolving.
func (*PoolCredentials) VRFProve ¶
func (pc *PoolCredentials) VRFProve(alpha []byte) ([]byte, []byte, error)
VRFProve generates a VRF proof for leader election. alpha should be MkInputVrf(slot, epochNonce).
func (*PoolCredentials) ValidateOpCert ¶
func (pc *PoolCredentials) ValidateOpCert() error
ValidateOpCert validates that the operational certificate matches the KES key and that the cold key signature over the certificate body is valid.
type ProtocolParamsProvider ¶
type ProtocolParamsProvider interface {
GetCurrentPParams() lcommon.ProtocolParameters
}
ProtocolParamsProvider provides access to protocol parameters.
type SlotBattleEvent ¶
type SlotBattleEvent struct {
// Slot is the slot number where the battle occurred
Slot uint64
// LocalBlockHash is the hash of our locally forged block (if any)
LocalBlockHash []byte
// RemoteBlockHash is the hash of the competing block from peers
RemoteBlockHash []byte
// Won indicates whether our local block was selected for the chain
Won bool
}
SlotBattleEvent is emitted when the node detects competing blocks for the same slot, either from receiving an external block while preparing to forge or when detecting a fork at the same slot height.
type SlotClockProvider ¶
type SlotClockProvider interface {
// CurrentSlot returns the current slot number based on wall-clock time.
CurrentSlot() (uint64, error)
// SlotsPerKESPeriod returns the number of slots in a KES period.
SlotsPerKESPeriod() uint64
// ChainTipSlot returns the slot number of the current chain tip.
ChainTipSlot() uint64
// NextSlotTime returns the wall-clock time when the next slot begins.
NextSlotTime() (time.Time, error)
// UpstreamTipSlot returns the latest known tip slot from upstream peers.
// Returns 0 if no upstream tip is known.
UpstreamTipSlot() uint64
}
SlotClockProvider provides current slot information from the slot clock.
type SlotTracker ¶
type SlotTracker struct {
// contains filtered or unexported fields
}
SlotTracker is a thread-safe tracker for recently forged block slots and their hashes. It allows chainsync to detect slot battles when an incoming block from a peer occupies a slot for which the local node has already forged a block.
func NewSlotTracker ¶
func NewSlotTracker() *SlotTracker
NewSlotTracker creates a new SlotTracker with the default capacity.
func NewSlotTrackerWithCapacity ¶
func NewSlotTrackerWithCapacity(maxSlots int) *SlotTracker
NewSlotTrackerWithCapacity creates a new SlotTracker with the given maximum capacity.
func (*SlotTracker) Len ¶
func (st *SlotTracker) Len() int
Len returns the number of tracked forged slots.
func (*SlotTracker) RecordForgedBlock ¶
func (st *SlotTracker) RecordForgedBlock(slot uint64, blockHash []byte)
RecordForgedBlock records that the local node forged a block with the given hash at the given slot. If the tracker is at capacity, the oldest entry is evicted.
func (*SlotTracker) WasForgedByUs ¶
func (st *SlotTracker) WasForgedByUs( slot uint64, ) (blockHash []byte, ok bool)
WasForgedByUs checks whether the local node forged a block for the given slot. If so, it returns the block hash and true. Otherwise it returns nil, false.
type TxValidator ¶
type TxValidator interface {
ValidateTx(tx ledger.Transaction) error
}
TxValidator re-validates a transaction against the current ledger state at block assembly time. This catches transactions whose inputs have been consumed since they entered the mempool, protocol parameter changes, or other state mutations that invalidate previously-accepted transactions.