Skip to content

Commit

Permalink
Add more explicit builder flags and other QoL improvements (ethereum#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruteri authored and avalonche committed Mar 8, 2023
1 parent 643b3b6 commit 5118498
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 81 deletions.
154 changes: 82 additions & 72 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,82 +63,92 @@ func NewBuilder(sk *bls.SecretKey, bc IBeaconClient, relay IRelay, builderSignin
}
}

func (b *Builder) OnPayloadAttribute(attrs *BuilderPayloadAttributes) error {
if attrs != nil {
vd, err := b.relay.GetValidatorForSlot(attrs.Slot)
if err != nil {
log.Info("could not get validator while submitting block", "err", err, "slot", attrs.Slot)
return err
}

attrs.SuggestedFeeRecipient = [20]byte(vd.FeeRecipient)
attrs.GasLimit = vd.GasLimit

if b.eth.Synced() {
parentBlock := b.eth.GetBlockByHash(attrs.HeadHash)
if parentBlock == nil {
log.Info("Block hash not found in blocktree", "head block hash", attrs.HeadHash)
return err
}

executableData, block := b.eth.BuildBlock(attrs)
if executableData == nil || block == nil {
log.Error("did not receive the payload")
return errors.New("could not build block")
}
payload, err := executableDataToExecutionPayload(executableData)
if err != nil {
log.Error("could not format execution payload", "err", err)
return err
}

pubkey, err := boostTypes.HexToPubkey(string(vd.Pubkey))
if err != nil {
log.Error("could not parse pubkey", "err", err, "pubkey", vd.Pubkey)
return err
}

value := new(boostTypes.U256Str)
err = value.FromBig(block.Profit)
if err != nil {
log.Error("could not set block value", "err", err)
return err
}

blockBidMsg := boostTypes.BidTrace{
Slot: attrs.Slot,
ParentHash: payload.ParentHash,
BlockHash: payload.BlockHash,
BuilderPubkey: b.builderPublicKey,
ProposerPubkey: pubkey,
ProposerFeeRecipient: boostTypes.Address(attrs.SuggestedFeeRecipient),
GasLimit: executableData.GasLimit,
GasUsed: executableData.GasUsed,
Value: *value,
}

signature, err := boostTypes.SignMessage(&blockBidMsg, b.builderSigningDomain, b.builderSecretKey)
if err != nil {
log.Error("could not sign builder bid", "err", err)
return err
}

blockSubmitReq := boostTypes.BuilderSubmitBlockRequest{
Signature: signature,
Message: &blockBidMsg,
ExecutionPayload: payload,
}

err = b.relay.SubmitBlock(&blockSubmitReq)
if err != nil {
log.Error("could not submit block", "err", err)
return err
}
}
func (b *Builder) onSealedBlock(executableData *beacon.ExecutableDataV1, block *types.Block, proposerPubkey boostTypes.PublicKey, proposerFeeRecipient boostTypes.Address, slot uint64) error {
payload, err := executableDataToExecutionPayload(executableData)
if err != nil {
log.Error("could not format execution payload", "err", err)
return err
}

value := new(boostTypes.U256Str)
err = value.FromBig(block.Profit)
if err != nil {
log.Error("could not set block value", "err", err)
return err
}

blockBidMsg := boostTypes.BidTrace{
Slot: slot,
ParentHash: payload.ParentHash,
BlockHash: payload.BlockHash,
BuilderPubkey: b.builderPublicKey,
ProposerPubkey: proposerPubkey,
ProposerFeeRecipient: proposerFeeRecipient,
GasLimit: executableData.GasLimit,
GasUsed: executableData.GasUsed,
Value: *value,
}

signature, err := boostTypes.SignMessage(&blockBidMsg, b.builderSigningDomain, b.builderSecretKey)
if err != nil {
log.Error("could not sign builder bid", "err", err)
return err
}

blockSubmitReq := boostTypes.BuilderSubmitBlockRequest{
Signature: signature,
Message: &blockBidMsg,
ExecutionPayload: payload,
}

err = b.relay.SubmitBlock(&blockSubmitReq)
if err != nil {
log.Error("could not submit block", "err", err)
return err
}

return nil
}

func (b *Builder) OnPayloadAttribute(attrs *BuilderPayloadAttributes) error {
if attrs == nil {
return nil
}

vd, err := b.relay.GetValidatorForSlot(attrs.Slot)
if err != nil {
log.Info("could not get validator while submitting block", "err", err, "slot", attrs.Slot)
return err
}

attrs.SuggestedFeeRecipient = [20]byte(vd.FeeRecipient)
attrs.GasLimit = vd.GasLimit

proposerPubkey, err := boostTypes.HexToPubkey(string(vd.Pubkey))
if err != nil {
log.Error("could not parse pubkey", "err", err, "pubkey", vd.Pubkey)
return err
}

if !b.eth.Synced() {
return errors.New("backend not Synced")
}

parentBlock := b.eth.GetBlockByHash(attrs.HeadHash)
if parentBlock == nil {
log.Info("Block hash not found in blocktree", "head block hash", attrs.HeadHash)
return errors.New("parent block not found in blocktree")
}

executableData, block := b.eth.BuildBlock(attrs)
if executableData == nil || block == nil {
log.Error("did not receive the payload")
return errors.New("could not build block")
}

return b.onSealedBlock(executableData, block, proposerPubkey, vd.FeeRecipient, attrs.Slot)
}

func executableDataToExecutionPayload(data *beacon.ExecutableDataV1) (*boostTypes.ExecutionPayload, error) {
transactionData := make([]hexutil.Bytes, len(data.Transactions))
for i, tx := range data.Transactions {
Expand Down
28 changes: 21 additions & 7 deletions builder/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ type Service struct {
}

func (s *Service) Start() {
log.Info("Service started")
go s.srv.ListenAndServe()
if s.srv != nil {
log.Info("Service started")
go s.srv.ListenAndServe()
}
}

func (s *Service) PayloadAttributes(payloadAttributes *BuilderPayloadAttributes) error {
Expand All @@ -65,8 +67,9 @@ func getRouter(localRelay *LocalRelay) http.Handler {
}

func NewService(listenAddr string, localRelay *LocalRelay, builder *Builder) *Service {
return &Service{
srv: &http.Server{
var srv *http.Server
if localRelay != nil {
srv = &http.Server{
Addr: listenAddr,
Handler: getRouter(localRelay),
/*
Expand All @@ -75,13 +78,19 @@ func NewService(listenAddr string, localRelay *LocalRelay, builder *Builder) *Se
WriteTimeout:
IdleTimeout:
*/
},
}
}

return &Service{
srv: srv,
builder: builder,
}
}

type BuilderConfig struct {
Enabled bool
EnableValidatorChecks bool
EnableLocalRelay bool
BuilderSecretKey string
RelaySecretKey string
ListenAddr string
Expand Down Expand Up @@ -134,13 +143,18 @@ func Register(stack *node.Node, backend *eth.Ethereum, cfg *BuilderConfig) error

beaconClient := NewBeaconClient(cfg.BeaconEndpoint)

localRelay := NewLocalRelay(relaySk, beaconClient, builderSigningDomain, proposerSigningDomain, ForkData{cfg.GenesisForkVersion, cfg.BellatrixForkVersion, cfg.GenesisValidatorsRoot}, cfg.EnableValidatorChecks)
var localRelay *LocalRelay
if cfg.EnableLocalRelay {
localRelay = NewLocalRelay(relaySk, beaconClient, builderSigningDomain, proposerSigningDomain, ForkData{cfg.GenesisForkVersion, cfg.BellatrixForkVersion, cfg.GenesisValidatorsRoot}, cfg.EnableValidatorChecks)
}

var relay IRelay
if cfg.RemoteRelayEndpoint != "" {
relay = NewRemoteRelay(cfg.RemoteRelayEndpoint, localRelay)
} else {
} else if localRelay != nil {
relay = localRelay
} else {
return errors.New("neither local nor remote relay specified")
}

ethereumService := NewEthereumService(backend)
Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ var (
}, utils.NetworkFlags, utils.DatabasePathFlags)

builderApiFlags = []cli.Flag{
utils.BuilderEnabled,
utils.BuilderEnableValidatorChecks,
utils.BuilderEnableLocalRelay,
utils.BuilderSecretKey,
utils.BuilderRelaySecretKey,
utils.BuilderListenAddr,
Expand Down
14 changes: 12 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,10 +668,18 @@ var (
Category: flags.MiscCategory,
}
// Builder API settings
BuilderEnabled = &cli.BoolFlag{
Name: "builder",
Usage: "Enable the builder",
}
BuilderEnableValidatorChecks = &cli.BoolFlag{
Name: "builder.validator_checks",
Usage: "Enable the validator checks",
}
BuilderEnableLocalRelay = &cli.BoolFlag{
Name: "builder.local_relay",
Usage: "Enable the local relay",
}
BuilderSecretKey = &cli.StringFlag{
Name: "builder.secret_key",
Usage: "Builder key used for signing blocks",
Expand Down Expand Up @@ -2067,8 +2075,10 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config, bpCfg *builder.
Fatalf("Failed to register the Engine API service: %v", err)
}

if err := builder.Register(stack, backend, bpCfg); err != nil {
Fatalf("Failed to register the builder service: %v", err)
if bpCfg.Enabled {
if err := builder.Register(stack, backend, bpCfg); err != nil {
Fatalf("Failed to register the builder service: %v", err)
}
}

stack.RegisterAPIs(tracers.APIs(backend.APIBackend))
Expand Down

0 comments on commit 5118498

Please sign in to comment.