Documentation
¶
Index ¶
- Constants
- func ModifyPayloadExtraData(p *engineall.ExecutionPayload, executionRequests []prague.ExecutionRequest, ...) (common.Hash, error)
- func ParseExecutionRequests(raw []prague.ExecutionRequest, dataVersion version.DataVersion) (*eth2all.ExecutionRequests, error)
- type BidRecord
- type BidTransport
- type BlobsBundle
- type BuildSkippedEvent
- type BuilderStats
- type ELClientVersion
- type EngineClient
- type Payload
- type PayloadBuildFailedEvent
- type PayloadBuildStartedEvent
- type PayloadBuilder
- type PayloadCache
- func (c *PayloadCache) Cleanup(olderThan phase0.Slot)
- func (c *PayloadCache) Delete(slot phase0.Slot)
- func (c *PayloadCache) Get(slot phase0.Slot) *Payload
- func (c *PayloadCache) GetAll() []*Payload
- func (c *PayloadCache) GetByBlockHash(blockHash phase0.Hash32) *Payload
- func (c *PayloadCache) GetCandidate(slot phase0.Slot, key chain.CandidateKey) *Payload
- func (c *PayloadCache) GetSlotPayloads(slot phase0.Slot) []*Payload
- func (c *PayloadCache) GetVariant(slot phase0.Slot, key beacon.AttrParentKey) *Payload
- func (c *PayloadCache) Size() int
- func (c *PayloadCache) Store(event *Payload)
- type ProposerSettings
- type ProposerSettingsResolver
- type RevealRecord
- type Service
- func (s *Service) AddProposerSettingsResolver(r ProposerSettingsResolver)
- func (s *Service) BuildCandidateOnDemand(ctx context.Context, slot phase0.Slot, parentRoot phase0.Root, ...) (*Payload, error)
- func (s *Service) GetCLClient() *beacon.Client
- func (s *Service) GetChainSpec() *chain.ChainSpec
- func (s *Service) GetConfig() *config.Config
- func (s *Service) GetCurrentSlot() phase0.Slot
- func (s *Service) GetELClientVersion() *ELClientVersion
- func (s *Service) GetGenesis() *beacon.Genesis
- func (s *Service) GetPayloadCache() *PayloadCache
- func (s *Service) GetStats() BuilderStats
- func (s *Service) IncrementBidsSubmitted()
- func (s *Service) IncrementBlocksIncluded()
- func (s *Service) IncrementRevealsFailed()
- func (s *Service) IncrementRevealsSkipped()
- func (s *Service) IncrementRevealsSuccess()
- func (s *Service) Start(ctx context.Context) error
- func (s *Service) Stop()
- func (s *Service) SubscribeBuildSkipped(capacity int, blocking bool) *utils.Subscription[*BuildSkippedEvent]
- func (s *Service) SubscribePayloadBuildFailed(capacity int, blocking bool) *utils.Subscription[*PayloadBuildFailedEvent]
- func (s *Service) SubscribePayloadBuildStarted(capacity int, blocking bool) *utils.Subscription[*PayloadBuildStartedEvent]
- func (s *Service) SubscribePayloadReady(capacity int, blocking bool) *utils.Subscription[*Payload]
- func (s *Service) UnmarkPayloadWon(blockHash phase0.Hash32)
- func (s *Service) UpdateConfig(cfg *config.Config) error
Constants ¶
const (
// DefaultCacheSize is the number of slots to keep in the cache.
DefaultCacheSize = 1000
)
Variables ¶
This section is empty.
Functions ¶
func ModifyPayloadExtraData ¶
func ModifyPayloadExtraData( p *engineall.ExecutionPayload, executionRequests []prague.ExecutionRequest, extraDataPrefix []byte, parentBeaconBlockRoot common.Hash, gasLimitOverride uint64, ) (common.Hash, error)
ModifyPayloadExtraData rewrites the extraData field of a built execution payload in place, prepending the given prefix (truncating the original to stay within the 32-byte limit), recomputes the block hash, updates the payload's BlockHash field, and returns the new hash.
The parentBeaconBlockRoot is required because it is part of the block header (and therefore affects the block hash) but is not carried in the execution payload itself.
executionRequests carries the EIP-7685 execution requests from the engine API response (Electra/Prague+); they are needed to compute the requestsHash header field. Pass nil for pre-Electra payloads.
gasLimitOverride, when non-zero, additionally rewrites the payload's gas limit (part of the header, so it changes the block hash): used to enforce the exact bid-gossip-legal gas limit when the EL ignored the proposer's target. Callers must ensure the payload's gas usage fits the override.
The function first verifies it can reconstruct the original block hash from the payload fields. If verification fails (e.g. an unhandled fork added new header fields) it returns an error rather than producing an incorrect hash.
func ParseExecutionRequests ¶
func ParseExecutionRequests(raw []prague.ExecutionRequest, dataVersion version.DataVersion) (*eth2all.ExecutionRequests, error)
ParseExecutionRequests decodes raw EIP-7685 execution request bytes from the Engine API into a versioned eth2all.ExecutionRequests.
Each element in raw is: [type_prefix_byte || request_1 || request_2 || ...] where all requests of the same type are concatenated after a single prefix byte. Builder deposit (0x03) and builder exit (0x04) requests are only valid from Gloas onwards.
Types ¶
type BidRecord ¶
type BidRecord struct {
Transport BidTransport
Value phase0.Gwei
ExecutionPayment phase0.Gwei
At time.Time
}
BidRecord is a lightweight record of a bid produced for this payload (not the heavy payload itself).
type BidTransport ¶
type BidTransport string
BidTransport identifies which submitter produced a bid or reveal.
const ( // BidTransportP2P is the ePBS p2p gossip submitter. BidTransportP2P BidTransport = "p2p" // BidTransportBuilderAPI is the HTTP Builder API submitter. BidTransportBuilderAPI BidTransport = "builder-api" )
type BlobsBundle ¶
type BlobsBundle struct {
Commitments []deneb.KZGCommitment `json:"commitments"`
Proofs []deneb.KZGProof `json:"proofs"`
Blobs []deneb.Blob `json:"blobs"`
}
BlobsBundle holds the blobs, KZG commitments and proofs produced alongside a payload, in beacon (deneb) types. The engine API bundle is converted to this once in the builder (see beaconBlobsBundleFromEngine) so downstream consumers use the beacon types directly instead of re-converting at every call site.
func (*BlobsBundle) BlobsAsBytes ¶
func (b *BlobsBundle) BlobsAsBytes() [][]byte
BlobsAsBytes returns the blobs as raw byte slices for beacon submission. Nil-safe: returns nil for a nil bundle.
func (*BlobsBundle) MarshalJSON ¶
func (b *BlobsBundle) MarshalJSON() ([]byte, error)
MarshalJSON renders the bundle as {commitments, proofs, blobs} hex arrays. Nil-safe: a nil bundle marshals to JSON null.
func (*BlobsBundle) ProofsAsBytes ¶
func (b *BlobsBundle) ProofsAsBytes() [][]byte
ProofsAsBytes returns the KZG proofs as raw byte slices for beacon submission. Nil-safe: returns nil for a nil bundle.
type BuildSkippedEvent ¶ added in v0.0.3
type BuildSkippedEvent struct {
Slot phase0.Slot
Reason string // one of the BuildSkipReason* constants
}
BuildSkippedEvent is emitted when the builder deliberately does not build for a slot that has a per-slot action plan or an effectively active consumer. Subscribers (e.g. the slot results tracker) use it to record explainable skips.
type BuilderStats ¶
type BuilderStats struct {
SlotsBuilt uint64
BidsSubmitted uint64
BidsWon uint64
BlocksIncluded uint64 // Blocks where our payload was included
TotalPaid uint64 // Gwei paid for won bids
RevealsSuccess uint64
RevealsFailed uint64
RevealsSkipped uint64
}
BuilderStats tracks statistics for builder operations.
type ELClientVersion ¶
ELClientVersion is the execution client's identification, as returned by engine_getClientVersionV1, in display-friendly string form.
type EngineClient ¶
type EngineClient interface {
// ForkchoiceUpdatedAgnostic updates the forkchoice and optionally starts a
// payload build, using the fork-agnostic request union.
ForkchoiceUpdatedAgnostic(
ctx context.Context,
request *engineall.ForkchoiceUpdatedRequest,
) (*paris.ForkchoiceUpdatedResponse, error)
// GetPayloadAgnostic retrieves a built payload as the fork-agnostic union,
// dispatching to the engine_getPayload version implied by dataVersion.
GetPayloadAgnostic(
ctx context.Context,
dataVersion enginev.DataVersion,
payloadID paris.PayloadID,
) (*engineall.GetPayloadResponse, error)
// ClientVersion exchanges client identity via engine_getClientVersionV1.
ClientVersion(
ctx context.Context,
clientVersion *identification.ClientVersion,
) ([]*identification.ClientVersion, error)
}
EngineClient is the subset of the go-eth-engine-client JSON-RPC service used by buildoor. It dispatches each fork-agnostic request to the matching versioned engine_* method internally. The jsonrpc.Service satisfies it.
type Payload ¶
type Payload struct {
// Attributes is the payload_attributes event this build was triggered by.
Attributes *beacon.PayloadAttributesEvent
// Candidate classifies the parent tuple this payload was built on
// relative to the chain view at build time (parent/grandparent x
// full/empty). Empty when the tuple matched no known candidate.
Candidate chain.CandidateKey
// ExecutionPayload is the fork-agnostic beacon execution payload.
ExecutionPayload *eth2all.ExecutionPayload
// BlobsBundle holds the blobs/commitments/proofs (Deneb+), nil if none.
BlobsBundle *BlobsBundle
// ExecutionRequests are the parsed execution requests (Electra+), versioned for the active fork.
ExecutionRequests *eth2all.ExecutionRequests
// Metadata not carried by the objects above.
BlockHash phase0.Hash32 // block hash after extra-data injection
FeeRecipient common.Address // resolved proposer fee recipient for the bid
BlockValue *big.Int // EL-reported block value (wei)
ReadyAt time.Time // when the payload became ready
// contains filtered or unexported fields
}
Payload is the canonical built payload, produced once by the builder and referenced (never copied) throughout the stack — it is a large object (blobs, transactions), so downstream consumers hold the same *Payload rather than copying it. The build outputs are immutable; the bid/reveal activity log is appended by the payload_bidder as bids are produced and the payload revealed.
Anything derivable from the build objects (slot, parent hashes, timestamp, gas limit, ...) is read through them rather than duplicated here.
func (*Payload) MarkRevealed ¶
func (p *Payload) MarkRevealed(rec RevealRecord)
MarkRevealed records the reveal of this payload's envelope. The first reveal wins; subsequent calls are ignored.
func (*Payload) Reveal ¶
func (p *Payload) Reveal() *RevealRecord
Reveal returns the reveal record if the payload has been revealed, else nil.
type PayloadBuildFailedEvent ¶
type PayloadBuildFailedEvent struct {
Slot phase0.Slot
Candidate string // candidate key the build targeted ("" = unclassified)
Error string // Failure reason
FailedAt time.Time // When the build failed
}
PayloadBuildFailedEvent is emitted when a payload build fails. Subscribers (e.g. the WebUI) use it to mark the in-progress build as failed instead of leaving it rendered as perpetually building.
type PayloadBuildStartedEvent ¶
type PayloadBuildStartedEvent struct {
Slot phase0.Slot
Candidate string // candidate key the build targets ("" = unclassified)
StartedAt time.Time // When the build started
}
PayloadBuildStartedEvent is emitted when payload building begins for a slot, before the build has completed. Subscribers (e.g. the WebUI) use it to render the build as in-progress rather than waiting for the payload to be ready.
type PayloadBuilder ¶
type PayloadBuilder struct {
// contains filtered or unexported fields
}
PayloadBuilder handles execution payload building via the Engine API.
func NewPayloadBuilder ¶
func NewPayloadBuilder( clClient *beacon.Client, engineClient EngineClient, chainSvc chain.Service, feeRecipient common.Address, cfg *config.Config, log logrus.FieldLogger, settingsResolvers []ProposerSettingsResolver, ) *PayloadBuilder
NewPayloadBuilder creates a new payload builder. cfg is the shared config pointer; mutable settings (e.g. PayloadBuildTime) are read live from it. settingsResolvers are asked in order for the proposer's announced fee recipient and gas limit; the first match wins.
func (*PayloadBuilder) AbortBuild ¶
func (b *PayloadBuilder) AbortBuild(slot phase0.Slot)
AbortBuild aborts every active build for the given slot.
func (*PayloadBuilder) BuildPayloadFromAttributes ¶
func (b *PayloadBuilder) BuildPayloadFromAttributes( ctx context.Context, attrs *beacon.PayloadAttributesEvent, buildTimeMs uint64, ) (*Payload, error)
BuildPayloadFromAttributes builds a payload using data from a payload_attributes event. This is the primary build path, triggered when the beacon node emits payload_attributes. The event contains all necessary information: timestamp, randao, withdrawals, etc.
The attributes may be an effective copy with the parent fields redirected to another candidate parent (reorg / payload-miss handling); this method treats whatever parent it is given as authoritative and stores it on the returned Payload, so the bid built from that payload advertises the same parent it built on.
buildTimeMs is the EL build wait; 0 uses the live-configured PayloadBuildTime.
type PayloadCache ¶
type PayloadCache struct {
// contains filtered or unexported fields
}
PayloadCache stores built payloads per slot, keyed by the parent tuple they were built on: reorg and payload-miss handling can produce several candidate payloads for the same slot.
func NewPayloadCache ¶
func NewPayloadCache(maxSlots int) *PayloadCache
NewPayloadCache creates a new payload cache with the specified maximum slots.
func (*PayloadCache) Cleanup ¶
func (c *PayloadCache) Cleanup(olderThan phase0.Slot)
Cleanup removes payloads older than the given slot.
func (*PayloadCache) Delete ¶
func (c *PayloadCache) Delete(slot phase0.Slot)
Delete removes all payloads for the given slot.
func (*PayloadCache) Get ¶
func (c *PayloadCache) Get(slot phase0.Slot) *Payload
Get retrieves the slot's primary payload: the most canonical classified candidate, falling back to the most recently built unclassified one.
func (*PayloadCache) GetAll ¶
func (c *PayloadCache) GetAll() []*Payload
GetAll returns all cached payloads.
func (*PayloadCache) GetByBlockHash ¶
func (c *PayloadCache) GetByBlockHash(blockHash phase0.Hash32) *Payload
GetByBlockHash retrieves a payload by its block hash.
func (*PayloadCache) GetCandidate ¶ added in v0.0.3
func (c *PayloadCache) GetCandidate(slot phase0.Slot, key chain.CandidateKey) *Payload
GetCandidate retrieves the slot's payload built for the given candidate key.
func (*PayloadCache) GetSlotPayloads ¶ added in v0.0.3
func (c *PayloadCache) GetSlotPayloads(slot phase0.Slot) []*Payload
GetSlotPayloads returns all payloads built for the slot (arbitrary order).
func (*PayloadCache) GetVariant ¶ added in v0.0.3
func (c *PayloadCache) GetVariant(slot phase0.Slot, key beacon.AttrParentKey) *Payload
GetVariant retrieves the slot's payload built on the given parent tuple.
func (*PayloadCache) Size ¶
func (c *PayloadCache) Size() int
Size returns the number of slots with cached payloads.
func (*PayloadCache) Store ¶
func (c *PayloadCache) Store(event *Payload)
Store stores a payload in the cache (replacing an earlier build on the same parent tuple) and evicts old slots to maintain the size limit.
type ProposerSettings ¶ added in v0.0.2
type ProposerSettings struct {
FeeRecipient common.Address
TargetGasLimit uint64 // 0 = not announced
}
ProposerSettings are the proposer-announced build parameters for a slot.
type ProposerSettingsResolver ¶ added in v0.0.2
type ProposerSettingsResolver interface {
ResolveProposerSettings(slot phase0.Slot, proposerIndex phase0.ValidatorIndex) (ProposerSettings, bool)
}
ProposerSettingsResolver resolves the proposer's announced settings for a build. Implementations self-scope: they return false when they don't apply to the slot's fork or hold no data (gossip preferences post-Gloas in payload_bidder; Builder API validator registrations pre-Gloas in the legacy dialect).
type RevealRecord ¶
type RevealRecord struct {
Transport BidTransport
BeaconBlockRoot phase0.Root
At time.Time
}
RevealRecord records that the payload's execution envelope was revealed.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the standalone builder service that handles payload building. It does NOT handle ePBS bidding or revealing - those are handled by the epbs package.
Fork-aware building: - Electra/Fulu: Build on parent block (payload is in the block) - Gloas: Build on last known payload (payload is separate from block)
Building is triggered by payload_attributes events from the beacon node, which contain all the information needed to build a payload.
func NewService ¶
func NewService( cfg *config.Config, clClient *beacon.Client, chainSvc chain.Service, planSvc *action_plan.PlanService, engineClient EngineClient, feeRecipient common.Address, log logrus.FieldLogger, ) (*Service, error)
NewService creates a new builder service. Proposer settings (fee recipient, target gas limit) are resolved through the resolvers registered via AddProposerSettingsResolver before Start. planSvc is the per-slot scheduling authority: every build decision polls it for the slot's frozen plan (schedule, force/suppress, build timing).
func (*Service) AddProposerSettingsResolver ¶ added in v0.0.2
func (s *Service) AddProposerSettingsResolver(r ProposerSettingsResolver)
AddProposerSettingsResolver appends a resolver; the builder asks each registered resolver in order and uses the first match. Register before Start().
func (*Service) BuildCandidateOnDemand ¶ added in v0.0.3
func (s *Service) BuildCandidateOnDemand( ctx context.Context, slot phase0.Slot, parentRoot phase0.Root, parentHash phase0.Hash32, ) (*Payload, error)
BuildCandidateOnDemand returns the slot's payload for the given parent tuple, building it on the fly when no candidate covers it yet (used by the Builder API to serve a proposer requesting a legal but unbuilt parent). Bounded by ctx; a tuple whose attributes cannot be resolved (unknown to the chain view and no received variant) fails.
func (*Service) GetCLClient ¶
GetCLClient returns the consensus layer client.
func (*Service) GetChainSpec ¶
GetChainSpec returns the chain specification.
func (*Service) GetCurrentSlot ¶
GetCurrentSlot returns the most recently built slot.
func (*Service) GetELClientVersion ¶
func (s *Service) GetELClientVersion() *ELClientVersion
GetELClientVersion returns the cached EL client identification. Returns nil if the EL has not yet responded or does not support engine_getClientVersionV1.
func (*Service) GetGenesis ¶
GetGenesis returns the genesis information.
func (*Service) GetPayloadCache ¶
func (s *Service) GetPayloadCache() *PayloadCache
GetPayloadCache returns the payload cache for direct access.
func (*Service) GetStats ¶
func (s *Service) GetStats() BuilderStats
GetStats returns the current builder statistics.
func (*Service) IncrementBidsSubmitted ¶
func (s *Service) IncrementBidsSubmitted()
IncrementBidsSubmitted increments the bids submitted counter. Called by the ePBS service when a bid is submitted.
func (*Service) IncrementBlocksIncluded ¶
func (s *Service) IncrementBlocksIncluded()
IncrementBlocksIncluded increments the blocks included and bids won counters. Called by the ePBS service when our payload is included in a beacon block.
func (*Service) IncrementRevealsFailed ¶
func (s *Service) IncrementRevealsFailed()
IncrementRevealsFailed increments the failed reveals counter.
func (*Service) IncrementRevealsSkipped ¶
func (s *Service) IncrementRevealsSkipped()
IncrementRevealsSkipped increments the skipped reveals counter.
func (*Service) IncrementRevealsSuccess ¶
func (s *Service) IncrementRevealsSuccess()
IncrementRevealsSuccess increments the successful reveals counter.
func (*Service) SubscribeBuildSkipped ¶ added in v0.0.3
func (s *Service) SubscribeBuildSkipped( capacity int, blocking bool, ) *utils.Subscription[*BuildSkippedEvent]
SubscribeBuildSkipped subscribes to build skipped events. Authoritative consumers (the slot results tracker) should pass blocking=true so no skip is lost; informational consumers should pass blocking=false.
func (*Service) SubscribePayloadBuildFailed ¶
func (s *Service) SubscribePayloadBuildFailed( capacity int, blocking bool, ) *utils.Subscription[*PayloadBuildFailedEvent]
SubscribePayloadBuildFailed subscribes to payload build failed events. Consumers (like the WebUI) use this to mark in-progress builds as failed.
func (*Service) SubscribePayloadBuildStarted ¶
func (s *Service) SubscribePayloadBuildStarted( capacity int, blocking bool, ) *utils.Subscription[*PayloadBuildStartedEvent]
SubscribePayloadBuildStarted subscribes to payload build started events. Consumers (like the WebUI) use this to render builds as in-progress.
func (*Service) SubscribePayloadReady ¶
SubscribePayloadReady subscribes to payload ready events. Consumers (like the ePBS service) use this to receive built payloads.
func (*Service) UnmarkPayloadWon ¶ added in v0.0.3
UnmarkPayloadWon clears the won marker of a payload whose winning block was reorged out, so a later re-inclusion is detected (and counted) again.