-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathbuild.go
More file actions
91 lines (78 loc) · 2.66 KB
/
Copy pathbuild.go
File metadata and controls
91 lines (78 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Package fulu provides Fulu (builder-specs) bid building from Payload.
package fulu
import (
eth2all "github.com/ethpandaops/go-eth2-client/spec/all"
"github.com/ethpandaops/go-eth2-client/spec/phase0"
"github.com/ethpandaops/go-eth2-client/spec/version"
"github.com/holiman/uint256"
"github.com/ethpandaops/buildoor/pkg/payload_builder"
"github.com/ethpandaops/buildoor/pkg/signer"
)
// BidSigner signs a BuilderBid and returns the signature.
type BidSigner interface {
SignWithDomain(root phase0.Root, domain phase0.Domain) (phase0.BLSSignature, error)
}
// BuildSignedBuilderBid builds a Fulu SignedBuilderBid from a Payload and the proposer's pubkey,
// and signs it with the builder's BLS key using DOMAIN_APPLICATION_BUILDER with the provided genesis fork version
// and genesis validators root (matches mev-boost-relay behavior).
// subsidyGwei is added to the bid value so the proposer sees a higher bid (e.g. for testing).
func BuildSignedBuilderBid(
event *payload_builder.Payload,
proposerPubkey phase0.BLSPubKey,
blsSigner BidSigner,
subsidyGwei uint64,
genesisForkVersion phase0.Version,
genesisValidatorsRoot phase0.Root,
) (*SignedBuilderBid, error) {
if event == nil || event.ExecutionPayload == nil {
return nil, nil
}
header, err := ExecutionPayloadHeaderFromBeacon(event.ExecutionPayload)
if err != nil {
return nil, err
}
// Fulu Builder API wire format uses the Electra layout; builder
// deposit/exit requests (Gloas+) do not exist in this spec version.
execRequests := ð2all.ExecutionRequests{Version: version.DataVersionFulu}
if event.ExecutionRequests != nil {
execRequests.Deposits = event.ExecutionRequests.Deposits
execRequests.Withdrawals = event.ExecutionRequests.Withdrawals
execRequests.Consolidations = event.ExecutionRequests.Consolidations
}
value, overflow := uint256.FromBig(event.BlockValue)
if overflow || value == nil {
value = new(uint256.Int)
}
if subsidyGwei > 0 {
subsidyWei := subsidyGwei * 1_000_000_000
value.Add(value, new(uint256.Int).SetUint64(subsidyWei))
}
bid := &BuilderBid{
Header: header,
ExecutionRequests: execRequests,
Value: value,
Pubkey: proposerPubkey,
}
if event.BlobsBundle != nil {
bid.BlobKZGCommitments = event.BlobsBundle.Commitments
}
bidRoot, err := bid.HashTreeRoot()
if err != nil {
return nil, err
}
var root phase0.Root
copy(root[:], bidRoot[:])
domain := signer.ComputeDomain(
signer.DomainApplicationBuilder,
genesisForkVersion,
genesisValidatorsRoot,
)
sig, err := blsSigner.SignWithDomain(root, domain)
if err != nil {
return nil, err
}
return &SignedBuilderBid{
Message: bid,
Signature: sig,
}, nil
}