lifecycle

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: GPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package lifecycle provides builder lifecycle management (deposit, balance, exit) as an ePBS sub-concern.

Index

Constants

This section is empty.

Variables

View Source
var (
	// BuilderDepositContractAddress is the EIP-8282 builder deposit predeploy.
	BuilderDepositContractAddress = common.HexToAddress("0x00006AE84ed173D4394de5E28F9ED56b28008282")
	// BuilderExitContractAddress is the EIP-8282 builder exit predeploy.
	BuilderExitContractAddress = common.HexToAddress("0x000014574A74c805590AFF9499fc7A690f008282")
)

Builder system-contract addresses (EIP-8282 genesis predeploys). Hard-coded per ethereum-genesis-generator#297; these are proposal-stage canonical addresses and match dora's DefaultSystemContractAddresses.

View Source
var ErrContractNotActive = errors.New("builder deposit contract not active yet")

ErrContractNotActive is returned while the builder deposit contract still holds the pre-fork excess inhibitor (before GLOAS_FORK_EPOCH), so deposits can't be submitted yet.

View Source
var ErrDepositFeeTooHigh = errors.New("builder deposit queue fee exceeds configured limit")

ErrDepositFeeTooHigh is returned when the builder deposit contract's current queue fee exceeds the operator's configured limit (DepositMaxFeeGwei). It is a signal to delay the deposit/top-up and retry later, not a hard failure.

View Source
var ErrNoDepositContract = errors.New("no validator deposit contract address in spec")

ErrNoDepositContract is returned when the beacon spec does not advertise a regular validator deposit contract address, so early onboarding cannot submit a deposit.

Functions

func BuildBuilderDepositCalldata

func BuildBuilderDepositCalldata(
	pubkey []byte,
	withdrawalCredentials []byte,
	amountGwei uint64,
	signature []byte,
) ([]byte, error)

BuildBuilderDepositCalldata builds the 184-byte builder deposit request calldata: pubkey(48) ++ withdrawal_credentials(32) ++ amount(8, big-endian gwei) ++ signature(96). The source address is implicit in the deposit signature.

func BuildBuilderExitCalldata

func BuildBuilderExitCalldata(pubkey []byte) ([]byte, error)

BuildBuilderExitCalldata builds the 48-byte builder exit request calldata (the builder pubkey). The source address is the transaction sender (msg.sender), which must match the builder's registered execution address.

func BuilderWithdrawalCredentials

func BuilderWithdrawalCredentials(walletAddress common.Address) [32]byte

BuilderWithdrawalCredentials builds the withdrawal credentials for an EIP-8282 builder deposit. Format: 0xB0 + 00...00 (11 zero bytes) + wallet_address (20 bytes).

func GweiToWei

func GweiToWei(gwei uint64) *big.Int

GweiToWei converts Gwei to Wei.

func ReadQueueFee

func ReadQueueFee(
	ctx context.Context,
	reader storageReader,
	contract common.Address,
) (fee *big.Int, active bool, err error)

ReadQueueFee reads the current per-request queue fee (in wei) for a builder system contract. It returns active=false while the contract still holds the pre-fork excess inhibitor (i.e. before GLOAS_FORK_EPOCH), signalling the caller to wait. The returned fee prices in queueFeeHeadroom extra slots for safety.

func ValidatorWithdrawalCredentials

func ValidatorWithdrawalCredentials(walletAddress common.Address) [32]byte

ValidatorWithdrawalCredentials builds the withdrawal credentials for the pre-Gloas early-onboarding deposit, which is submitted through the regular validator deposit contract. Format: 0xB0 + 00...00 (11 zero bytes) + wallet_address (20 bytes).

Types

type BalanceService

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

BalanceService handles balance monitoring and automatic top-ups.

func NewBalanceService

func NewBalanceService(
	cfg *config.Config,
	clClient *beacon.Client,
	depositSvc *DepositService,
	payments *payload_bidder.PaymentTracker,
	log logrus.FieldLogger,
) *BalanceService

NewBalanceService creates a new balance service.

func (*BalanceService) CheckAndTopup

func (s *BalanceService) CheckAndTopup(ctx context.Context) error

CheckAndTopup checks the balance and performs a top-up if needed.

func (*BalanceService) GetCurrentBalance

func (s *BalanceService) GetCurrentBalance(ctx context.Context) (uint64, error)

GetCurrentBalance returns the builder's current balance from the beacon state.

func (*BalanceService) GetEffectiveBalance

func (s *BalanceService) GetEffectiveBalance(ctx context.Context) (uint64, error)

GetEffectiveBalance returns the live balance minus pending payments. Live balance = chain state balance + local adjustments (topups, revealed bid deductions). Pending payments = from chain state's BuilderPendingPayments (ground truth, survives restarts).

func (*BalanceService) NeedsTopup

func (s *BalanceService) NeedsTopup(ctx context.Context) (bool, uint64, error)

NeedsTopup checks if a top-up is needed and returns the required amount.

func (*BalanceService) RunBalanceMonitor

func (s *BalanceService) RunBalanceMonitor(ctx context.Context)

RunBalanceMonitor runs a periodic balance check loop.

type BuilderState

type BuilderState struct {
	Pubkey            []byte
	Index             uint64
	IsRegistered      bool
	Balance           uint64 // Gwei
	DepositEpoch      uint64
	WithdrawableEpoch uint64
}

BuilderState represents the current state of a builder in the beacon chain.

type DepositService

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

DepositService handles builder deposits and top-ups via the EIP-8282 builder deposit system contract.

func NewDepositService

func NewDepositService(
	cfg *config.Config,
	chainSvc chain.Service,
	blsSigner *signer.BLSSigner,
	w *wallet.Wallet,
	log logrus.FieldLogger,
) (*DepositService, error)

NewDepositService creates a new deposit service.

func (*DepositService) CreateDeposit

func (s *DepositService) CreateDeposit(ctx context.Context, amountGwei uint64) error

CreateDeposit creates and sends an EIP-8282 builder deposit transaction. It is also used for top-ups (which are simply additional deposits for the same pubkey).

Before submitting it reads the contract's current per-request queue fee and, when DepositMaxFeeGwei is set, returns ErrDepositFeeTooHigh if the fee exceeds the limit so the caller can delay and retry. The transaction value is stake + queue fee.

func (*DepositService) CreateTopup

func (s *DepositService) CreateTopup(ctx context.Context, amountGwei uint64) error

CreateTopup creates and sends a top-up transaction (an additional deposit).

func (*DepositService) IsBuilderRegistered

func (s *DepositService) IsBuilderRegistered(_ context.Context) (bool, *BuilderState, error)

IsBuilderRegistered checks if the builder is registered on the beacon chain.

type EarlyDepositService

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

EarlyDepositService submits a pre-Gloas builder onboarding deposit via the regular validator deposit contract. Both paths use 0xB0 withdrawal credentials, but unlike the post-fork builder deposit (EIP-8282 predeploy, DOMAIN_BUILDER_DEPOSIT), an early deposit is signed with the validator deposit domain — i.e. it is an ordinary validator deposit that sits in the beacon state's pending_deposits queue and is converted into a builder at the Gloas fork boundary.

func NewEarlyDepositService

func NewEarlyDepositService(
	cfg *config.Config,
	chainSvc chain.Service,
	blsSigner *signer.BLSSigner,
	w *wallet.Wallet,
	log logrus.FieldLogger,
) (*EarlyDepositService, error)

NewEarlyDepositService creates a new early deposit service.

func (*EarlyDepositService) CreateEarlyDeposit

func (s *EarlyDepositService) CreateEarlyDeposit(ctx context.Context, amountGwei uint64) error

CreateEarlyDeposit builds, signs and sends a validator deposit for this builder via the regular deposit contract. The deposit uses 0xB0 (BUILDER_WITHDRAWAL_PREFIX) withdrawal credentials pointing at the funding wallet and is signed with the validator deposit domain over GENESIS_FORK_VERSION.

func (*EarlyDepositService) HasPendingDeposit

func (s *EarlyDepositService) HasPendingDeposit() bool

HasPendingDeposit reports whether this builder's pubkey is already present in the beacon state's pending_deposits queue. It is used after a restart to avoid submitting a duplicate early deposit while a prior one is still waiting in the queue.

type ExitService

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

ExitService handles builder exits via the EIP-8282 builder exit system contract.

Unlike a validator voluntary exit (a BLS-signed beacon message), a builder exit is an execution-layer transaction to the builder exit predeploy carrying only the builder pubkey as calldata. The source is the transaction sender (msg.sender), which must match the builder's registered execution address — i.e. the funding wallet that supplied the withdrawal credentials at deposit time. A per-request queue fee is paid as msg.value.

func NewExitService

func NewExitService(
	chainSvc chain.Service,
	blsSigner *signer.BLSSigner,
	w *wallet.Wallet,
	log logrus.FieldLogger,
) *ExitService

NewExitService creates a new exit service.

func (*ExitService) CreateExit

func (s *ExitService) CreateExit(ctx context.Context) error

CreateExit submits a builder exit request transaction for this builder.

Exits always proceed regardless of the configured deposit fee limit (unlike deposits/top-ups, which are delayed when the fee is too high), so the operator can always withdraw. The queue fee is read from the contract and paid as msg.value.

type LifecycleEvent

type LifecycleEvent struct {
	Action  string // "deposit", "topup", "exit", "state_change", "waiting_gloas", "balance_topup"
	Message string // Human-readable description
	Status  string // "info", "success", "warning", "error"
}

LifecycleEvent represents a lifecycle action for UI logging.

type Manager

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

Manager orchestrates builder lifecycle operations.

func NewManager

func NewManager(
	cfg *config.Config,
	clClient *beacon.Client,
	chainSvc chain.Service,
	blsSigner *signer.BLSSigner,
	w *wallet.Wallet,
	log logrus.FieldLogger,
) (*Manager, error)

NewManager creates a new lifecycle manager.

func (*Manager) CheckAndTopup

func (m *Manager) CheckAndTopup(ctx context.Context) error

CheckAndTopup checks balance and tops up if needed.

func (*Manager) EnsureBuilderRegistered

func (m *Manager) EnsureBuilderRegistered(ctx context.Context) error

EnsureBuilderRegistered checks if builder is registered and deposits if needed. This is the synchronous version used by CLI commands (e.g. cmd/deposit.go).

func (*Manager) GetBuilderState

func (m *Manager) GetBuilderState() *BuilderState

GetBuilderState returns the current builder state.

func (*Manager) GetPaymentTracker added in v0.0.2

func (m *Manager) GetPaymentTracker() *payload_bidder.PaymentTracker

GetPaymentTracker returns the shared payment tracker.

func (*Manager) GetWallet

func (m *Manager) GetWallet() *wallet.Wallet

GetWallet returns the wallet instance.

func (*Manager) InitiateExit

func (m *Manager) InitiateExit(ctx context.Context) error

InitiateExit submits a builder exit request via the builder exit system contract.

func (*Manager) IsEnabled

func (m *Manager) IsEnabled() bool

IsEnabled returns whether the lifecycle manager is enabled.

func (*Manager) SetDepositPendingCallback

func (m *Manager) SetDepositPendingCallback(cb func())

SetDepositPendingCallback sets the callback invoked when a deposit is submitted.

func (*Manager) SetEnabled

func (m *Manager) SetEnabled(enabled bool)

SetEnabled sets whether the lifecycle manager is actively managing the builder.

func (*Manager) SetEventCallback

func (m *Manager) SetEventCallback(cb func(*LifecycleEvent))

SetEventCallback sets the callback invoked when lifecycle events occur (for UI logging).

func (*Manager) SetPaymentTracker added in v0.0.2

func (m *Manager) SetPaymentTracker(payments *payload_bidder.PaymentTracker)

SetPaymentTracker sets the shared payment tracker for the balance service and stores it for direct access.

func (*Manager) SetRegistrationCallback

func (m *Manager) SetRegistrationCallback(cb func(index uint64))

SetRegistrationCallback sets the callback invoked when builder registration completes.

func (*Manager) Start

func (m *Manager) Start(ctx context.Context) error

Start starts the lifecycle manager with async registration and balance monitoring.

func (*Manager) Stop

func (m *Manager) Stop()

Stop stops the lifecycle manager.

func (*Manager) WaitForRegistration

func (m *Manager) WaitForRegistration(ctx context.Context, timeout time.Duration) error

WaitForRegistration waits for the builder to be registered.

Jump to

Keyboard shortcuts

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