Skip to content

Commit 460fbaf

Browse files
committed
merge upstream changes
1 parent c9ba9b0 commit 460fbaf

37 files changed

+376
-318
lines changed

builder/builder.go

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package builder
33
import (
44
"context"
55
"errors"
6+
"math/big"
67
_ "os"
78
"sync"
89
"time"
910

11+
"github.com/attestantio/go-eth2-client/spec/bellatrix"
12+
"github.com/attestantio/go-eth2-client/spec/capella"
13+
"github.com/attestantio/go-eth2-client/spec/phase0"
1014
"github.com/ethereum/go-ethereum/common"
1115
blockvalidation "github.com/ethereum/go-ethereum/eth/block-validation"
1216
"github.com/holiman/uint256"
@@ -20,9 +24,7 @@ import (
2024

2125
capellaapi "github.com/attestantio/go-builder-client/api/capella"
2226
apiv1 "github.com/attestantio/go-builder-client/api/v1"
23-
"github.com/attestantio/go-eth2-client/spec/bellatrix"
24-
"github.com/attestantio/go-eth2-client/spec/capella"
25-
"github.com/attestantio/go-eth2-client/spec/phase0"
27+
2628
"github.com/flashbots/go-boost-utils/bls"
2729
boostTypes "github.com/flashbots/go-boost-utils/types"
2830
)
@@ -106,34 +108,34 @@ func (b *Builder) Stop() error {
106108
return nil
107109
}
108110

109-
func (b *Builder) onSealedBlock(block *types.Block, ordersClosedAt time.Time, sealedAt time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle, proposerPubkey boostTypes.PublicKey, vd ValidatorData, attrs *types.BuilderPayloadAttributes) error {
111+
func (b *Builder) onSealedBlock(block *types.Block, blockValue *big.Int, ordersClosedAt time.Time, sealedAt time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle, proposerPubkey boostTypes.PublicKey, vd ValidatorData, attrs *types.BuilderPayloadAttributes) error {
110112
if b.eth.Config().IsShanghai(block.Time()) {
111-
if err := b.submitCapellaBlock(block, ordersClosedAt, sealedAt, commitedBundles, allBundles, proposerPubkey, vd, attrs); err != nil {
113+
if err := b.submitCapellaBlock(block, blockValue, ordersClosedAt, sealedAt, commitedBundles, allBundles, proposerPubkey, vd, attrs); err != nil {
112114
return err
113115
}
114116
} else {
115-
if err := b.submitBellatrixBlock(block, ordersClosedAt, sealedAt, commitedBundles, allBundles, proposerPubkey, vd, attrs); err != nil {
117+
if err := b.submitBellatrixBlock(block, blockValue, ordersClosedAt, sealedAt, commitedBundles, allBundles, proposerPubkey, vd, attrs); err != nil {
116118
return err
117119
}
118120
}
119121

120-
log.Info("submitted block", "slot", attrs.Slot, "value", block.Profit.String(), "parent", block.ParentHash, "hash", block.Hash(), "#commitedBundles", len(commitedBundles))
122+
log.Info("submitted block", "slot", attrs.Slot, "value", blockValue.String(), "parent", block.ParentHash, "hash", block.Hash(), "#commitedBundles", len(commitedBundles))
121123

122124
return nil
123125
}
124126

125-
func (b *Builder) submitBellatrixBlock(block *types.Block, ordersClosedAt time.Time, sealedAt time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle, proposerPubkey boostTypes.PublicKey, vd ValidatorData, attrs *types.BuilderPayloadAttributes) error {
126-
value := new(boostTypes.U256Str)
127-
err := value.FromBig(block.Profit)
127+
func (b *Builder) submitBellatrixBlock(block *types.Block, blockValue *big.Int, ordersClosedAt time.Time, sealedAt time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle, proposerPubkey boostTypes.PublicKey, vd ValidatorData, attrs *types.BuilderPayloadAttributes) error {
128+
executableData := engine.BlockToExecutableData(block, blockValue)
129+
payload, err := executableDataToExecutionPayload(executableData.ExecutionPayload)
128130
if err != nil {
129-
log.Error("could not set block value", "err", err)
131+
log.Error("could not format execution payload", "err", err)
130132
return err
131133
}
132134

133-
executableData := engine.BlockToExecutableData(block, block.Profit)
134-
payload, err := executableDataToExecutionPayload(executableData.ExecutionPayload)
135+
value := new(boostTypes.U256Str)
136+
err = value.FromBig(blockValue)
135137
if err != nil {
136-
log.Error("could not format execution payload", "err", err)
138+
log.Error("could not set block value", "err", err)
137139
return err
138140
}
139141

@@ -167,26 +169,29 @@ func (b *Builder) submitBellatrixBlock(block *types.Block, ordersClosedAt time.T
167169
log.Error("could not validate block", "err", err)
168170
}
169171
} else {
170-
go b.ds.ConsumeBuiltBlock(block, ordersClosedAt, sealedAt, commitedBundles, allBundles, &blockBidMsg)
172+
go b.ds.ConsumeBuiltBlock(block, blockValue, ordersClosedAt, sealedAt, commitedBundles, allBundles, &blockBidMsg)
171173
err = b.relay.SubmitBlock(&blockSubmitReq, vd)
172174
if err != nil {
173175
log.Error("could not submit block", "err", err, "#commitedBundles", len(commitedBundles))
174176
return err
175177
}
176178
}
179+
180+
log.Info("submitted block", "slot", blockBidMsg.Slot, "value", blockBidMsg.Value.String(), "parent", blockBidMsg.ParentHash, "hash", block.Hash(), "#commitedBundles", len(commitedBundles))
181+
177182
return nil
178183
}
179184

180-
func (b *Builder) submitCapellaBlock(block *types.Block, ordersClosedAt time.Time, sealedAt time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle, proposerPubkey boostTypes.PublicKey, vd ValidatorData, attrs *types.BuilderPayloadAttributes) error {
181-
executableData := engine.BlockToExecutableData(block, block.Profit)
185+
func (b *Builder) submitCapellaBlock(block *types.Block, blockValue *big.Int, ordersClosedAt time.Time, sealedAt time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle, proposerPubkey boostTypes.PublicKey, vd ValidatorData, attrs *types.BuilderPayloadAttributes) error {
186+
executableData := engine.BlockToExecutableData(block, blockValue)
182187
payload, err := executableDataToCapellaExecutionPayload(executableData.ExecutionPayload)
183188
if err != nil {
184189
log.Error("could not format execution payload", "err", err)
185190
return err
186191
}
187192

188193
value := new(boostTypes.U256Str)
189-
err = value.FromBig(block.Profit)
194+
err = value.FromBig(blockValue)
190195
if err != nil {
191196
log.Error("could not set block value", "err", err)
192197
return err
@@ -218,13 +223,12 @@ func (b *Builder) submitCapellaBlock(block *types.Block, ordersClosedAt time.Tim
218223
ExecutionPayload: payload,
219224
}
220225

221-
go b.ds.ConsumeBuiltBlock(block, ordersClosedAt, sealedAt, commitedBundles, allBundles, &boostBidTrace)
226+
go b.ds.ConsumeBuiltBlock(block, blockValue, ordersClosedAt, sealedAt, commitedBundles, allBundles, &boostBidTrace)
222227
err = b.relay.SubmitBlockCapella(&blockSubmitReq, vd)
223228
if err != nil {
224229
log.Error("could not submit block", "err", err, "#commitedBundles", len(commitedBundles))
225230
return err
226231
}
227-
228232
return nil
229233
}
230234

@@ -274,10 +278,7 @@ func (b *Builder) OnPayloadAttribute(attrs *types.BuilderPayloadAttributes) erro
274278
}
275279

276280
for _, currentAttrs := range b.slotAttrs {
277-
seen := attrs.HeadHash == currentAttrs.HeadHash && attrs.Slot == currentAttrs.Slot &&
278-
attrs.GasLimit == currentAttrs.GasLimit && attrs.SuggestedFeeRecipient == currentAttrs.SuggestedFeeRecipient
279-
280-
if seen {
281+
if attrs.Equal(&currentAttrs) {
281282
log.Debug("ignoring known payload attribute", "slot", attrs.Slot, "hash", attrs.HeadHash)
282283
return nil
283284
}
@@ -290,6 +291,7 @@ func (b *Builder) OnPayloadAttribute(attrs *types.BuilderPayloadAttributes) erro
290291

291292
type blockQueueEntry struct {
292293
block *types.Block
294+
blockValue *big.Int
293295
ordersCloseTime time.Time
294296
sealedAt time.Time
295297
commitedBundles []types.SimulatedBundle
@@ -320,7 +322,7 @@ func (b *Builder) runBuildingJob(slotCtx context.Context, proposerPubkey boostTy
320322
submitBestBlock := func() {
321323
queueMu.Lock()
322324
if queueBestEntry.block.Hash() != queueLastSubmittedHash {
323-
err := b.onSealedBlock(queueBestEntry.block, queueBestEntry.ordersCloseTime, queueBestEntry.sealedAt, queueBestEntry.commitedBundles, queueBestEntry.allBundles, proposerPubkey, vd, attrs)
325+
err := b.onSealedBlock(queueBestEntry.block, queueBestEntry.blockValue, queueBestEntry.ordersCloseTime, queueBestEntry.sealedAt, queueBestEntry.commitedBundles, queueBestEntry.allBundles, proposerPubkey, vd, attrs)
324326

325327
if err != nil {
326328
log.Error("could not run sealed block hook", "err", err)
@@ -335,7 +337,7 @@ func (b *Builder) runBuildingJob(slotCtx context.Context, proposerPubkey boostTy
335337
go runResubmitLoop(ctx, b.limiter, queueSignal, submitBestBlock)
336338

337339
// Populates queue with submissions that increase block profit
338-
blockHook := func(block *types.Block, ordersCloseTime time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle) {
340+
blockHook := func(block *types.Block, blockValue *big.Int, ordersCloseTime time.Time, commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle) {
339341
if ctx.Err() != nil {
340342
return
341343
}
@@ -347,6 +349,7 @@ func (b *Builder) runBuildingJob(slotCtx context.Context, proposerPubkey boostTy
347349
if block.Hash() != queueLastSubmittedHash {
348350
queueBestEntry = blockQueueEntry{
349351
block: block,
352+
blockValue: new(big.Int).Set(blockValue),
350353
ordersCloseTime: ordersCloseTime,
351354
sealedAt: sealedAt,
352355
commitedBundles: commitedBundles,

builder/builder_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ func TestOnPayloadAttributes(t *testing.T) {
6262

6363
testBlock, err := engine.ExecutableDataToBlock(*testExecutableData)
6464
require.NoError(t, err)
65-
testBlock.Profit = big.NewInt(10)
6665

6766
testPayloadAttributes := &types.BuilderPayloadAttributes{
6867
Timestamp: hexutil.Uint64(104),
@@ -72,7 +71,7 @@ func TestOnPayloadAttributes(t *testing.T) {
7271
Slot: uint64(25),
7372
}
7473

75-
testEthService := &testEthereumService{synced: true, testExecutableData: testExecutableData, testBlock: testBlock}
74+
testEthService := &testEthereumService{synced: true, testExecutableData: testExecutableData, testBlock: testBlock, testBlockValue: big.NewInt(10)}
7675

7776
builder := NewBuilder(sk, flashbotsextra.NilDbService{}, &testRelay, bDomain, testEthService, false, nil)
7877
builder.Start()
@@ -127,7 +126,8 @@ func TestOnPayloadAttributes(t *testing.T) {
127126
require.Equal(t, uint64(25), testRelay.requestedSlot)
128127

129128
// Clear the submitted message and check that the job will be ran again and but a new message will not be submitted since the hash is the same
130-
testBlock.Profit = big.NewInt(10)
129+
testEthService.testBlockValue = big.NewInt(10)
130+
131131
testRelay.submittedMsg = nil
132132
time.Sleep(2200 * time.Millisecond)
133133
require.Nil(t, testRelay.submittedMsg)
@@ -136,7 +136,7 @@ func TestOnPayloadAttributes(t *testing.T) {
136136
testExecutableData.ExtraData = hexutil.MustDecode("0x0042fafd")
137137
testExecutableData.BlockHash = common.HexToHash("0x0579b1aaca5c079c91e5774bac72c7f9bc2ddf2b126e9c632be68a1cb8f3fc71")
138138
testBlock, err = engine.ExecutableDataToBlock(*testExecutableData)
139-
testBlock.Profit = big.NewInt(10)
139+
testEthService.testBlockValue = big.NewInt(10)
140140
require.NoError(t, err)
141141
testEthService.testBlock = testBlock
142142

builder/eth_service.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package builder
22

33
import (
44
"errors"
5+
"math/big"
56
"time"
67

78
"github.com/ethereum/go-ethereum/beacon/engine"
@@ -24,21 +25,22 @@ type testEthereumService struct {
2425
synced bool
2526
testExecutableData *engine.ExecutableData
2627
testBlock *types.Block
28+
testBlockValue *big.Int
2729
testBundlesMerged []types.SimulatedBundle
2830
testAllBundles []types.SimulatedBundle
2931
}
3032

3133
func (t *testEthereumService) BuildBlock(attrs *types.BuilderPayloadAttributes, sealedBlockCallback miner.BlockHookFn) error {
32-
sealedBlockCallback(t.testBlock, time.Now(), t.testBundlesMerged, t.testAllBundles)
34+
sealedBlockCallback(t.testBlock, t.testBlockValue, time.Now(), t.testBundlesMerged, t.testAllBundles)
3335
return nil
3436
}
3537

3638
func (t *testEthereumService) GetBlockByHash(hash common.Hash) *types.Block { return t.testBlock }
3739

38-
func (t *testEthereumService) Synced() bool { return t.synced }
39-
4040
func (t *testEthereumService) Config() *params.ChainConfig { return params.TestChainConfig }
4141

42+
func (t *testEthereumService) Synced() bool { return t.synced }
43+
4244
type EthereumService struct {
4345
eth *eth.Ethereum
4446
}
@@ -47,45 +49,56 @@ func NewEthereumService(eth *eth.Ethereum) *EthereumService {
4749
return &EthereumService{eth: eth}
4850
}
4951

52+
// TODO: we should move to a setup similar to catalyst local blocks & payload ids
5053
func (s *EthereumService) BuildBlock(attrs *types.BuilderPayloadAttributes, sealedBlockCallback miner.BlockHookFn) error {
5154
// Send a request to generate a full block in the background.
5255
// The result can be obtained via the returned channel.
5356
args := &miner.BuildPayloadArgs{
5457
Parent: attrs.HeadHash,
5558
Timestamp: uint64(attrs.Timestamp),
5659
FeeRecipient: attrs.SuggestedFeeRecipient,
60+
GasLimit: attrs.GasLimit,
5761
Random: attrs.Random,
5862
Withdrawals: attrs.Withdrawals,
63+
BlockHook: sealedBlockCallback,
5964
}
60-
resCh, err := s.eth.Miner().GetSealingBlock(args, false, sealedBlockCallback)
65+
66+
payload, err := s.eth.Miner().BuildPayload(args)
6167
if err != nil {
62-
log.Error("Failed to create async sealing payload", "err", err)
68+
log.Error("Failed to build payload", "err", err)
6369
return err
6470
}
6571

72+
resCh := make(chan *engine.ExecutionPayloadEnvelope, 1)
73+
go func() {
74+
resCh <- payload.ResolveFull()
75+
}()
76+
6677
timer := time.NewTimer(4 * time.Second)
6778
defer timer.Stop()
6879

6980
select {
70-
case block := <-resCh:
71-
if block == nil {
72-
return errors.New("received nil block from sealing work")
81+
case payload := <-resCh:
82+
if payload == nil {
83+
return errors.New("received nil payload from sealing work")
7384
}
7485
return nil
7586
case <-timer.C:
87+
payload.Cancel()
7688
log.Error("timeout waiting for block", "parent hash", attrs.HeadHash, "slot", attrs.Slot)
7789
return errors.New("timeout waiting for block result")
7890
}
91+
7992
}
8093

8194
func (s *EthereumService) GetBlockByHash(hash common.Hash) *types.Block {
8295
return s.eth.BlockChain().GetBlockByHash(hash)
8396
}
8497

85-
func (s *EthereumService) Synced() bool {
86-
return s.eth.Synced()
87-
}
88-
8998
func (s *EthereumService) Config() *params.ChainConfig {
9099
return s.eth.BlockChain().Config()
91100
}
101+
102+
func (s *EthereumService) Synced() bool {
103+
return s.eth.Synced()
104+
}

builder/eth_service_test.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,15 @@ func TestBuildBlock(t *testing.T) {
9393
service := NewEthereumService(ethservice)
9494
service.eth.APIBackend.Miner().SetEtherbase(common.Address{0x05, 0x11})
9595

96-
err := service.BuildBlock(testPayloadAttributes, func(block *types.Block, _ time.Time, _ []types.SimulatedBundle, _ []types.SimulatedBundle) {
97-
executableData := engine.BlockToExecutableData(block, block.Profit)
98-
executionPayload := executableData.ExecutionPayload
99-
require.Equal(t, common.Address{0x05, 0x11}, executionPayload.FeeRecipient)
100-
require.Equal(t, common.Hash{0x05, 0x10}, executionPayload.Random)
101-
require.Equal(t, parent.Hash(), executionPayload.ParentHash)
102-
require.Equal(t, parent.Time()+1, executionPayload.Timestamp)
96+
err := service.BuildBlock(testPayloadAttributes, func(block *types.Block, blockValue *big.Int, _ time.Time, _ []types.SimulatedBundle, _ []types.SimulatedBundle) {
97+
executableData := engine.BlockToExecutableData(block, blockValue)
98+
require.Equal(t, common.Address{0x05, 0x11}, executableData.ExecutionPayload.FeeRecipient)
99+
require.Equal(t, common.Hash{0x05, 0x10}, executableData.ExecutionPayload.Random)
100+
require.Equal(t, parent.Hash(), executableData.ExecutionPayload.ParentHash)
101+
require.Equal(t, parent.Time()+1, executableData.ExecutionPayload.Timestamp)
103102
require.Equal(t, block.ParentHash(), parent.Hash())
104-
require.Equal(t, block.Hash(), executionPayload.BlockHash)
105-
require.Equal(t, block.Profit.Uint64(), uint64(0))
103+
require.Equal(t, block.Hash(), executableData.ExecutionPayload.BlockHash)
104+
require.Equal(t, blockValue.Uint64(), uint64(0))
106105
})
107106

108107
require.NoError(t, err)

builder/local_relay_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ import (
2323
"github.com/stretchr/testify/require"
2424
)
2525

26-
func newTestBackend(t *testing.T, forkchoiceData *engine.ExecutableData, block *types.Block) (*Builder, *LocalRelay, *ValidatorPrivateData) {
26+
func newTestBackend(t *testing.T, forkchoiceData *engine.ExecutableData, block *types.Block, blockValue *big.Int) (*Builder, *LocalRelay, *ValidatorPrivateData) {
2727
validator := NewRandomValidator()
2828
sk, _ := bls.GenerateRandomSecretKey()
2929
bDomain := boostTypes.ComputeDomain(boostTypes.DomainTypeAppBuilder, [4]byte{0x02, 0x0, 0x0, 0x0}, boostTypes.Hash{})
3030
genesisValidatorsRoot := boostTypes.Hash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"))
3131
cDomain := boostTypes.ComputeDomain(boostTypes.DomainTypeBeaconProposer, [4]byte{0x02, 0x0, 0x0, 0x0}, genesisValidatorsRoot)
3232
beaconClient := &testBeaconClient{validator: validator}
3333
localRelay := NewLocalRelay(sk, beaconClient, bDomain, cDomain, ForkData{}, true)
34-
ethService := &testEthereumService{synced: true, testExecutableData: forkchoiceData, testBlock: block}
34+
ethService := &testEthereumService{synced: true, testExecutableData: forkchoiceData, testBlock: block, testBlockValue: blockValue}
3535
backend := NewBuilder(sk, flashbotsextra.NilDbService{}, localRelay, bDomain, ethService, false, nil)
3636
// service := NewService("127.0.0.1:31545", backend)
3737

@@ -59,7 +59,7 @@ func testRequest(t *testing.T, localRelay *LocalRelay, method string, path strin
5959
}
6060

6161
func TestValidatorRegistration(t *testing.T) {
62-
_, relay, _ := newTestBackend(t, nil, nil)
62+
_, relay, _ := newTestBackend(t, nil, nil, nil)
6363
log.Error("rsk", "sk", hexutil.Encode(relay.relaySecretKey.Serialize()))
6464

6565
v := NewRandomValidator()
@@ -128,9 +128,9 @@ func TestGetHeader(t *testing.T) {
128128

129129
forkchoiceBlock, err := engine.ExecutableDataToBlock(*forkchoiceData)
130130
require.NoError(t, err)
131-
forkchoiceBlock.Profit = big.NewInt(10)
131+
forkchoiceBlockProfit := big.NewInt(10)
132132

133-
backend, relay, validator := newTestBackend(t, forkchoiceData, forkchoiceBlock)
133+
backend, relay, validator := newTestBackend(t, forkchoiceData, forkchoiceBlock, forkchoiceBlockProfit)
134134

135135
path := fmt.Sprintf("/eth/v1/builder/header/%d/%s/%s", 0, forkchoiceData.ParentHash.Hex(), validator.Pk.String())
136136
rr := testRequest(t, relay, "GET", path, nil)
@@ -162,7 +162,7 @@ func TestGetHeader(t *testing.T) {
162162
expectedHeader, err := boostTypes.PayloadToPayloadHeader(executionPayload)
163163
require.NoError(t, err)
164164
expectedValue := new(boostTypes.U256Str)
165-
err = expectedValue.FromBig(forkchoiceBlock.Profit)
165+
err = expectedValue.FromBig(forkchoiceBlockProfit)
166166
require.NoError(t, err)
167167
require.EqualValues(t, &boostTypes.BuilderBid{
168168
Header: expectedHeader,
@@ -189,9 +189,9 @@ func TestGetPayload(t *testing.T) {
189189

190190
forkchoiceBlock, err := engine.ExecutableDataToBlock(*forkchoiceData)
191191
require.NoError(t, err)
192-
forkchoiceBlock.Profit = big.NewInt(10)
192+
forkchoiceBlockProfit := big.NewInt(10)
193193

194-
backend, relay, validator := newTestBackend(t, forkchoiceData, forkchoiceBlock)
194+
backend, relay, validator := newTestBackend(t, forkchoiceData, forkchoiceBlock, forkchoiceBlockProfit)
195195

196196
registerValidator(t, validator, relay)
197197
backend.OnPayloadAttribute(&types.BuilderPayloadAttributes{})

cmd/geth/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ var (
130130
utils.MinerExtraDataFlag,
131131
utils.MinerRecommitIntervalFlag,
132132
utils.MinerNoVerifyFlag,
133+
utils.MinerMaxMergedBundlesFlag,
134+
utils.MinerBlocklistFileFlag,
133135
utils.MinerNewPayloadTimeout,
134136
utils.NATFlag,
135137
utils.NoDiscoverFlag,

0 commit comments

Comments
 (0)