Documentation
¶
Overview ¶
Package payload_bidder holds the shared, transport-independent mechanics for post-Gloas builder participation: constructing and signing execution payload bids and the corresponding execution payload envelope (reveal). Both the ePBS p2p submitter and the HTTP Builder API build on it; each supplies its own economics (bid value, execution payment) while the construction, hash-tree- root (always via dynamic-ssz so preset-dependent sizes resolve), signing domain, and fork handling live here.
Everything is fork-agnostic: bids and envelopes use the go-eth2-client spec/all union types and read the active fork from the payload, so adding a future fork is confined to the spec/all view tables.
Index ¶
- Constants
- Variables
- func BuildSignedBid(p *payload_builder.Payload, params BidParams, s *Signer, ...) (*eth2all.SignedExecutionPayloadBid, error)
- func BuildSignedEnvelope(p *payload_builder.Payload, rc RevealContext, s *Signer, ...) (signed *eth2all.SignedExecutionPayloadEnvelope, blobs, proofs [][]byte, ...)
- type BidParams
- type InclusionTracker
- func (t *InclusionTracker) GetWonBlocks(offset, limit int) ([]*WonBlock, int)
- func (t *InclusionTracker) SetStateDB(stateDB *db.Database)
- func (t *InclusionTracker) Start(ctx context.Context) error
- func (t *InclusionTracker) Stop()
- func (t *InclusionTracker) SubscribeIncluded(capacity int) *utils.Subscription[*PayloadIncludedEvent]
- type PayloadIncludedEvent
- type PaymentTracker
- func (t *PaymentTracker) AddDeposit(amount uint64)
- func (t *PaymentTracker) GetBalanceAdjustment() int64
- func (t *PaymentTracker) GetTotalPendingPayments() uint64
- func (t *PaymentTracker) MarkRevealed(slot phase0.Slot)
- func (t *PaymentTracker) PruneExpiredPayments(currentEpoch phase0.Epoch)
- func (t *PaymentTracker) RecordWonBid(slot phase0.Slot, value uint64)
- func (t *PaymentTracker) ResetBalanceAdjustment()
- type PendingPayment
- type ProposerPreferencesCodec
- func (ProposerPreferencesCodec) DecodeKey(key string) (phase0.Slot, error)
- func (ProposerPreferencesCodec) DecodeValue(value []byte) (*gloasspec.SignedProposerPreferences, error)
- func (ProposerPreferencesCodec) EncodeKey(slot phase0.Slot) string
- func (ProposerPreferencesCodec) EncodeValue(prefs *gloasspec.SignedProposerPreferences) ([]byte, error)
- type ProposerPreferencesService
- func (s *ProposerPreferencesService) GetStore() *memstore.Store[phase0.Slot, *gloasspec.SignedProposerPreferences]
- func (s *ProposerPreferencesService) ResolveProposerSettings(slot phase0.Slot, _ phase0.ValidatorIndex) (payload_builder.ProposerSettings, bool)
- func (s *ProposerPreferencesService) Start(ctx context.Context) error
- func (s *ProposerPreferencesService) Stop()
- type RevealContext
- type RevealRequest
- type RevealResult
- type RevealService
- type Signer
- type WonBlock
- type WonBlockCodec
Constants ¶
const ( WonBlockSourceBuilderAPI = "builder_api" WonBlockSourceEPBS = "epbs" )
WonBlockSource identifies which subsystem delivered a won block.
const ProposerPreferencesNamespace = "proposer_preferences"
ProposerPreferencesNamespace is the kv_store namespace holding the cached proposer preferences.
const WonBlocksNamespace = "won_blocks"
WonBlocksNamespace is the kv_store namespace holding the persisted won-block records, owned by the InclusionTracker.
Variables ¶
var DomainBeaconBuilder = phase0.DomainType{0x0B, 0x00, 0x00, 0x00}
DomainBeaconBuilder is DOMAIN_BEACON_BUILDER — the signing domain for execution payload bids and execution payload envelopes.
Functions ¶
func BuildSignedBid ¶
func BuildSignedBid( p *payload_builder.Payload, params BidParams, s *Signer, forkVersion phase0.Version, genesisValidatorsRoot phase0.Root, ) (*eth2all.SignedExecutionPayloadBid, error)
BuildSignedBid constructs and signs a fork-agnostic SignedExecutionPayloadBid for the given payload. The fork is read from the payload; all payload-derived fields (parent hashes, block hash, randao, gas limit, commitments, execution requests root, slot) are filled here, and only the transport's economics + identity come in via params.
func BuildSignedEnvelope ¶
func BuildSignedEnvelope( p *payload_builder.Payload, rc RevealContext, s *Signer, forkVersion phase0.Version, genesisValidatorsRoot phase0.Root, ) (signed *eth2all.SignedExecutionPayloadEnvelope, blobs, proofs [][]byte, err error)
BuildSignedEnvelope constructs and signs a fork-agnostic SignedExecutionPayloadEnvelope for the given payload, and returns the blobs and KZG proofs to publish alongside it. The fork-agnostic envelope embeds the canonical payload directly (no per-fork conversion needed).
Types ¶
type BidParams ¶
type BidParams struct {
BuilderIndex uint64
FeeRecipient bellatrix.ExecutionAddress
Value phase0.Gwei
ExecutionPayment phase0.Gwei
}
BidParams are the policy-decided inputs a transport supplies for a bid. The transport owns the economics (value, execution payment) and identity (builder index, fee recipient); every other bid field is derived from the payload.
type InclusionTracker ¶ added in v0.0.2
type InclusionTracker struct {
// contains filtered or unexported fields
}
InclusionTracker watches head events and detects inclusion of our payloads. It records the payment obligation, requests the payload reveal, records won blocks (it is the single owner of won-block records, covering both flows and all forks), and checks the follow-up block to detect orphaned (unrevealed) payloads. Shared by both the p2p and Builder API flows.
func NewInclusionTracker ¶ added in v0.0.2
func NewInclusionTracker( clClient *beacon.Client, chainSvc chain.Service, builderSvc *payload_builder.Service, revealSvc *RevealService, payments *PaymentTracker, log logrus.FieldLogger, ) *InclusionTracker
NewInclusionTracker creates a new inclusion tracker. revealSvc and payments may be nil (pre-Gloas networks); the tracker then only persists won blocks and fires inclusion events.
func (*InclusionTracker) GetWonBlocks ¶ added in v0.0.2
func (t *InclusionTracker) GetWonBlocks(offset, limit int) ([]*WonBlock, int)
GetWonBlocks returns a page of won-block records sorted by slot descending (newest first) plus the total record count.
func (*InclusionTracker) SetStateDB ¶ added in v0.0.2
func (t *InclusionTracker) SetStateDB(stateDB *db.Database)
SetStateDB sets the optional state-db used to persist won blocks (attached to the won-block store on Start). When unset, won blocks are kept in memory only.
func (*InclusionTracker) Start ¶ added in v0.0.2
func (t *InclusionTracker) Start(ctx context.Context) error
Start starts the inclusion tracker's main loop. When a state-db was set it first attaches the won-block store's persistence, rehydrating wins recorded in prior runs.
func (*InclusionTracker) Stop ¶ added in v0.0.2
func (t *InclusionTracker) Stop()
Stop stops the inclusion tracker, waits for the main loop to exit, and flushes the won-block store. Must run before the state-db closes (run.go registers the tracker's Stop defer after the state-db's close defer, so LIFO ordering guarantees this).
func (*InclusionTracker) SubscribeIncluded ¶ added in v0.0.2
func (t *InclusionTracker) SubscribeIncluded(capacity int) *utils.Subscription[*PayloadIncludedEvent]
SubscribeIncluded subscribes to payload inclusion events.
type PayloadIncludedEvent ¶ added in v0.0.2
type PayloadIncludedEvent struct {
Payload *payload_builder.Payload
BlockInfo *beacon.BlockInfo
BidValueGwei uint64
WonBlock *WonBlock // the recorded won-block entry for this inclusion
}
PayloadIncludedEvent is fired when a beacon block committing to one of our payloads is observed at the head (consumed by the WebUI).
type PaymentTracker ¶ added in v0.0.2
type PaymentTracker struct {
// contains filtered or unexported fields
}
PaymentTracker tracks the builder's payment obligations and live balance adjustments across both bid flows (p2p and Builder API). Fed by the InclusionTracker (won bids) and RevealService (reveals); consumed by the lifecycle manager (top-ups) and the WebUI. Passive and thread-safe: it runs no goroutine of its own.
func NewPaymentTracker ¶ added in v0.0.2
func NewPaymentTracker(chainSvc chain.Service, log logrus.FieldLogger) *PaymentTracker
NewPaymentTracker creates a new payment tracker.
func (*PaymentTracker) AddDeposit ¶ added in v0.0.2
func (t *PaymentTracker) AddDeposit(amount uint64)
AddDeposit adds a deposit/topup amount to the balance adjustment. Topups take effect immediately (no finalization delay).
func (*PaymentTracker) GetBalanceAdjustment ¶ added in v0.0.2
func (t *PaymentTracker) GetBalanceAdjustment() int64
GetBalanceAdjustment returns the cumulative balance adjustment since last state refresh.
func (*PaymentTracker) GetTotalPendingPayments ¶ added in v0.0.2
func (t *PaymentTracker) GetTotalPendingPayments() uint64
GetTotalPendingPayments returns the sum of unrevealed won bid obligations.
func (*PaymentTracker) MarkRevealed ¶ added in v0.0.2
func (t *PaymentTracker) MarkRevealed(slot phase0.Slot)
MarkRevealed moves a won bid from pending to an immediate balance deduction. The payment is removed from pending and subtracted from the balance adjustment.
func (*PaymentTracker) PruneExpiredPayments ¶ added in v0.0.2
func (t *PaymentTracker) PruneExpiredPayments(currentEpoch phase0.Epoch)
PruneExpiredPayments removes pending payments older than 2 epochs.
func (*PaymentTracker) RecordWonBid ¶ added in v0.0.2
func (t *PaymentTracker) RecordWonBid(slot phase0.Slot, value uint64)
RecordWonBid records a won bid as a pending payment (unrevealed). Called when our bid is included in a beacon block. If we later reveal, call MarkRevealed to move it from pending to a balance deduction. If we don't reveal, it stays pending for 2 epochs then expires.
func (*PaymentTracker) ResetBalanceAdjustment ¶ added in v0.0.2
func (t *PaymentTracker) ResetBalanceAdjustment()
ResetBalanceAdjustment resets the adjustment to 0. Called when the chain state refreshes and the balance is up to date.
type PendingPayment ¶ added in v0.0.2
PendingPayment records an unrevealed won bid that may be deducted later.
type ProposerPreferencesCodec ¶ added in v0.0.2
type ProposerPreferencesCodec struct{}
ProposerPreferencesCodec translates the proposer preference store's entries to their persisted form: decimal slot string keys, SSZ-encoded values.
func (ProposerPreferencesCodec) DecodeKey ¶ added in v0.0.2
func (ProposerPreferencesCodec) DecodeKey(key string) (phase0.Slot, error)
DecodeKey parses a decimal slot string.
func (ProposerPreferencesCodec) DecodeValue ¶ added in v0.0.2
func (ProposerPreferencesCodec) DecodeValue(value []byte) (*gloasspec.SignedProposerPreferences, error)
DecodeValue SSZ-decodes a signed proposer preference.
func (ProposerPreferencesCodec) EncodeKey ¶ added in v0.0.2
func (ProposerPreferencesCodec) EncodeKey(slot phase0.Slot) string
EncodeKey encodes a slot as its decimal string form.
func (ProposerPreferencesCodec) EncodeValue ¶ added in v0.0.2
func (ProposerPreferencesCodec) EncodeValue(prefs *gloasspec.SignedProposerPreferences) ([]byte, error)
EncodeValue SSZ-encodes a signed proposer preference.
type ProposerPreferencesService ¶ added in v0.0.2
type ProposerPreferencesService struct {
// contains filtered or unexported fields
}
ProposerPreferencesService listens to the beacon node's proposer_preferences SSE topic, caches the first valid preference per slot, prunes old slots on epoch transitions, and resolves proposer settings for Gloas+ payload builds (it implements payload_builder.ProposerSettingsResolver).
func NewProposerPreferencesService ¶ added in v0.0.2
func NewProposerPreferencesService(clClient *beacon.Client, chainSvc chain.Service, log logrus.FieldLogger) *ProposerPreferencesService
NewProposerPreferencesService creates a new proposer preferences service. The backing store keeps the first valid preference per slot (subsequent preferences for the same slot are ignored).
func (*ProposerPreferencesService) GetStore ¶ added in v0.0.2
func (s *ProposerPreferencesService) GetStore() *memstore.Store[phase0.Slot, *gloasspec.SignedProposerPreferences]
GetStore returns the underlying per-slot preference store for direct access (bid gating, bid construction, WebUI listing).
func (*ProposerPreferencesService) ResolveProposerSettings ¶ added in v0.0.2
func (s *ProposerPreferencesService) ResolveProposerSettings(slot phase0.Slot, _ phase0.ValidatorIndex) (payload_builder.ProposerSettings, bool)
ResolveProposerSettings resolves the proposer's announced settings for a build from the cached gossip preference. Self-scoped: it only applies from the Gloas fork onwards and returns false when no preference is cached for the slot.
func (*ProposerPreferencesService) Start ¶ added in v0.0.2
func (s *ProposerPreferencesService) Start(ctx context.Context) error
Start subscribes to the proposer_preferences SSE topic and to epoch stats (for pruning) and begins processing events in the service's own loop.
func (*ProposerPreferencesService) Stop ¶ added in v0.0.2
func (s *ProposerPreferencesService) Stop()
Stop stops the service and waits for the main loop to exit.
type RevealContext ¶
type RevealContext struct {
BuilderIndex uint64
BeaconBlockRoot phase0.Root
ParentBeaconBlockRoot phase0.Root
}
RevealContext are the inputs a transport supplies for a payload reveal that aren't carried by the payload: the builder index and the beacon block roots the envelope is bound to.
type RevealRequest ¶ added in v0.0.2
type RevealRequest struct {
Payload *payload_builder.Payload
BlockInfo *beacon.BlockInfo // root + parent root of the committing beacon block
Transport payload_builder.BidTransport
}
RevealRequest asks the RevealService to publish a payload's envelope at the configured reveal time. Both flows submit these; the service dedupes by slot.
type RevealResult ¶ added in v0.0.2
type RevealResult struct {
Slot phase0.Slot
Transport payload_builder.BidTransport
Success bool
Skipped bool // request arrived after the slot's reveal deadline
Error string // failure reason (when Success is false)
Attempt int // 1-based
MaxAttempts int
}
RevealResult reports the outcome of a reveal attempt.
type RevealService ¶ added in v0.0.2
type RevealService struct {
// contains filtered or unexported fields
}
RevealService publishes execution payload envelopes at the slot-relative reveal time. It runs its own main loop: requests arrive on a channel, due times are awaited with a timer (no polling), reveals are deduped per slot (the first request wins regardless of transport), and failed publishes are retried a bounded number of times. It is independent of the p2p bidder and Builder API modules and their enable flags.
func NewRevealService ¶ added in v0.0.2
func NewRevealService( cfg *config.Config, signer *Signer, publisher envelopePublisher, chainSvc chain.Service, builderSvc *payload_builder.Service, payments *PaymentTracker, log logrus.FieldLogger, ) *RevealService
NewRevealService creates a new reveal service.
func (*RevealService) RequestReveal ¶ added in v0.0.2
func (s *RevealService) RequestReveal(req *RevealRequest)
RequestReveal enqueues a reveal request; non-blocking: a full queue is logged and dropped (at most one reveal per slot, so the 16 buffer is generous).
func (*RevealService) SetBuilderIndex ¶ added in v0.0.2
func (s *RevealService) SetBuilderIndex(index uint64)
SetBuilderIndex updates the builder index used when signing envelopes.
func (*RevealService) Start ¶ added in v0.0.2
func (s *RevealService) Start(ctx context.Context) error
Start starts the reveal service's main loop.
func (*RevealService) Stop ¶ added in v0.0.2
func (s *RevealService) Stop()
Stop stops the reveal service and waits for the main loop to exit.
func (*RevealService) SubscribeResults ¶ added in v0.0.2
func (s *RevealService) SubscribeResults(capacity int) *utils.Subscription[*RevealResult]
SubscribeResults subscribes to reveal results (consumed by the WebUI).
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer signs execution payload bids and envelopes with the builder's BLS key.
func (*Signer) SignBid ¶
func (s *Signer) SignBid( bid *eth2all.ExecutionPayloadBid, forkVersion phase0.Version, genesisValidatorsRoot phase0.Root, ) (phase0.BLSSignature, error)
SignBid signs an execution payload bid. forkVersion must be the fork version the consensus client verifies against (the Gloas fork version).
func (*Signer) SignEnvelope ¶
func (s *Signer) SignEnvelope( envelope *eth2all.ExecutionPayloadEnvelope, forkVersion phase0.Version, genesisValidatorsRoot phase0.Root, ) (phase0.BLSSignature, error)
SignEnvelope signs an execution payload envelope.
type WonBlock ¶ added in v0.0.2
type WonBlock struct {
Source string `json:"source"`
Slot uint64 `json:"slot"`
BlockHash string `json:"block_hash"`
NumTransactions int `json:"num_transactions"`
NumBlobs int `json:"num_blobs"`
ValueWei string `json:"value_wei"`
ValueETH string `json:"value_eth"`
Timestamp int64 `json:"timestamp"` // Unix milliseconds at inclusion time
}
WonBlock is a block of ours that was included in a beacon block, won via either the Builder API or p2p ePBS bidding. The JSON tags are the wire shape consumed by the WebUI (bids-won REST endpoint and bid_won SSE event) — do not change them.
type WonBlockCodec ¶ added in v0.0.2
type WonBlockCodec struct{}
WonBlockCodec translates the won-block store's entries to their persisted form: decimal slot string keys, JSON-encoded values. JSON is deliberate: WonBlock is a local aggregate (not a spec SSZ type), and the kv_store value is an opaque blob either way.
func (WonBlockCodec) DecodeKey ¶ added in v0.0.2
func (WonBlockCodec) DecodeKey(key string) (phase0.Slot, error)
DecodeKey parses a decimal slot string.
func (WonBlockCodec) DecodeValue ¶ added in v0.0.2
func (WonBlockCodec) DecodeValue(value []byte) (*WonBlock, error)
DecodeValue JSON-decodes a won block.
func (WonBlockCodec) EncodeKey ¶ added in v0.0.2
func (WonBlockCodec) EncodeKey(slot phase0.Slot) string
EncodeKey encodes a slot as its decimal string form.
func (WonBlockCodec) EncodeValue ¶ added in v0.0.2
func (WonBlockCodec) EncodeValue(wonBlock *WonBlock) ([]byte, error)
EncodeValue JSON-encodes a won block.