diff --git a/builder/builder.go b/builder/builder.go index 44201bcde..4988adb84 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -9,6 +9,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/core" + bellatrixapi "github.com/attestantio/go-builder-client/api/bellatrix" capellaapi "github.com/attestantio/go-builder-client/api/capella" apiv1 "github.com/attestantio/go-builder-client/api/v1" @@ -346,8 +348,13 @@ func (b *Builder) OnPayloadAttribute(attrs *types.BuilderPayloadAttributes) erro return fmt.Errorf("could not get validator while submitting block for slot %d - %w", attrs.Slot, err) } + parentBlock := b.eth.GetBlockByHash(attrs.HeadHash) + if parentBlock == nil { + return fmt.Errorf("parent block hash not found in block tree given head block hash %s", attrs.HeadHash) + } + attrs.SuggestedFeeRecipient = [20]byte(vd.FeeRecipient) - attrs.GasLimit = vd.GasLimit + attrs.GasLimit = core.CalcGasLimit(parentBlock.GasLimit(), vd.GasLimit) proposerPubkey, err := utils.HexToPubkey(string(vd.Pubkey)) if err != nil { @@ -358,11 +365,6 @@ func (b *Builder) OnPayloadAttribute(attrs *types.BuilderPayloadAttributes) erro return errors.New("backend not Synced") } - parentBlock := b.eth.GetBlockByHash(attrs.HeadHash) - if parentBlock == nil { - return fmt.Errorf("parent block hash not found in block tree given head block hash %s", attrs.HeadHash) - } - b.slotMu.Lock() defer b.slotMu.Unlock() diff --git a/builder/builder_test.go b/builder/builder_test.go index 7c8c4cca9..c2be63ea3 100644 --- a/builder/builder_test.go +++ b/builder/builder_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/core" + apiv1 "github.com/attestantio/go-builder-client/api/v1" "github.com/attestantio/go-eth2-client/spec/bellatrix" "github.com/attestantio/go-eth2-client/spec/phase0" @@ -21,6 +23,13 @@ import ( ) func TestOnPayloadAttributes(t *testing.T) { + const ( + validatorDesiredGasLimit = 30_000_000 + payloadAttributeGasLimit = 0 + parentBlockGasLimit = 29_000_000 + ) + expectedGasLimit := core.CalcGasLimit(parentBlockGasLimit, validatorDesiredGasLimit) + vsk, err := bls.SecretKeyFromBytes(hexutil.MustDecode("0x370bb8c1a6e62b2882f6ec76762a67b39609002076b95aae5b023997cf9b2dc9")) require.NoError(t, err) validator := &ValidatorPrivateData{ @@ -38,7 +47,7 @@ func TestOnPayloadAttributes(t *testing.T) { gvsVd: ValidatorData{ Pubkey: PubkeyHex(testBeacon.validator.Pk.String()), FeeRecipient: feeRecipient, - GasLimit: 10, + GasLimit: validatorDesiredGasLimit, }, } @@ -54,14 +63,14 @@ func TestOnPayloadAttributes(t *testing.T) { ReceiptsRoot: common.Hash{0x08, 0x20}, LogsBloom: types.Bloom{}.Bytes(), Number: uint64(10), - GasLimit: uint64(50), + GasLimit: expectedGasLimit, GasUsed: uint64(100), Timestamp: uint64(105), ExtraData: hexutil.MustDecode("0x0042fafc"), BaseFeePerGas: big.NewInt(16), - BlockHash: common.HexToHash("0xca4147f0d4150183ece9155068f34ee3c375448814e4ca557d482b1d40ee5407"), + BlockHash: common.HexToHash("0x68e516c8827b589fcb749a9e672aa16b9643437459508c467f66a9ed1de66a6c"), Transactions: [][]byte{}, } @@ -72,7 +81,7 @@ func TestOnPayloadAttributes(t *testing.T) { Timestamp: hexutil.Uint64(104), Random: common.Hash{0x05, 0x10}, SuggestedFeeRecipient: common.Address{0x04, 0x10}, - GasLimit: uint64(21), + GasLimit: uint64(payloadAttributeGasLimit), Slot: uint64(25), } @@ -99,6 +108,7 @@ func TestOnPayloadAttributes(t *testing.T) { time.Sleep(time.Second * 3) require.NotNil(t, testRelay.submittedMsg) + expectedProposerPubkey, err := utils.HexToPubkey(testBeacon.validator.Pk.String()) require.NoError(t, err) @@ -108,11 +118,11 @@ func TestOnPayloadAttributes(t *testing.T) { BuilderPubkey: builder.builderPublicKey, ProposerPubkey: expectedProposerPubkey, ProposerFeeRecipient: feeRecipient, - GasLimit: uint64(50), + GasLimit: expectedGasLimit, GasUsed: uint64(100), Value: &uint256.Int{0x0a}, } - copy(expectedMessage.BlockHash[:], hexutil.MustDecode("0xca4147f0d4150183ece9155068f34ee3c375448814e4ca557d482b1d40ee5407")[:]) + copy(expectedMessage.BlockHash[:], hexutil.MustDecode("0x68e516c8827b589fcb749a9e672aa16b9643437459508c467f66a9ed1de66a6c")[:]) require.Equal(t, expectedMessage, *testRelay.submittedMsg.Message) expectedExecutionPayload := bellatrix.ExecutionPayload{ @@ -134,7 +144,7 @@ func TestOnPayloadAttributes(t *testing.T) { require.Equal(t, expectedExecutionPayload, *testRelay.submittedMsg.ExecutionPayload) - expectedSignature, err := utils.HexToSignature("0xad09f171b1da05636acfc86778c319af69e39c79515d44bdfed616ba2ef677ffd4d155d87b3363c6bae651ce1e92786216b75f1ac91dd65f3b1d1902bf8485e742170732dd82ffdf4decb0151eeb7926dd053efa9794b2ebed1a203e62bb13e9") + expectedSignature, err := utils.HexToSignature("0x8d1dc346d469b0678ee72baa559315433af0966d2d05dad0de9ce60ff5e4954d4e28a85643496df279494d105bc4a771034fefcdd83d71df5f1b81c9369942b20d6d574b544a93588f6182ba8b09585eb1cf3e1b6551ccbd9e76a4db8eb579fe") require.NoError(t, err) require.Equal(t, expectedSignature, testRelay.submittedMsg.Signature) @@ -150,7 +160,7 @@ func TestOnPayloadAttributes(t *testing.T) { // Change the hash, expect to get the block testExecutableData.ExtraData = hexutil.MustDecode("0x0042fafd") - testExecutableData.BlockHash = common.HexToHash("0x0579b1aaca5c079c91e5774bac72c7f9bc2ddf2b126e9c632be68a1cb8f3fc71") + testExecutableData.BlockHash = common.HexToHash("0x6a259b9a148da3cc0bf139eaa89292fa9f7b136cfeddad17f7cb0ae33e0c3df9") testBlock, err = engine.ExecutableDataToBlock(*testExecutableData) testEthService.testBlockValue = big.NewInt(10) require.NoError(t, err) diff --git a/builder/local_relay_test.go b/builder/local_relay_test.go index 4b6ae1563..d536ad65b 100644 --- a/builder/local_relay_test.go +++ b/builder/local_relay_test.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/core" + "github.com/attestantio/go-builder-client/api" bellatrixapi "github.com/attestantio/go-builder-client/api/bellatrix" apiv1 "github.com/attestantio/go-builder-client/api/v1" @@ -30,6 +32,10 @@ import ( "golang.org/x/time/rate" ) +const ( + testLocalRelayValidatorGasLimit = 15_000_000 +) + func newTestBackend(t *testing.T, forkchoiceData *engine.ExecutableData, block *types.Block, blockValue *big.Int) (*Builder, *LocalRelay, *ValidatorPrivateData) { validator := NewRandomValidator() sk, _ := bls.GenerateRandomSecretKey() @@ -109,7 +115,7 @@ func prepareRegistrationMessage(t *testing.T, domain phase0.Domain, v *Validator msg := apiv1.ValidatorRegistration{ FeeRecipient: bellatrix.ExecutionAddress{0x42}, - GasLimit: 15_000_000, + GasLimit: testLocalRelayValidatorGasLimit, Timestamp: time.Now(), Pubkey: pubkey, } @@ -139,9 +145,10 @@ func TestGetHeader(t *testing.T) { ParentHash: common.HexToHash("0xafafafa"), FeeRecipient: common.Address{0x01}, LogsBloom: types.Bloom{0x00, 0x05, 0x10}.Bytes(), - BlockHash: common.HexToHash("0x24e6998e4d2b4fd85f7f0d27ac4b87aaf0ec18e156e4b6e194ab5dadee0cd004"), + BlockHash: common.HexToHash("0x64559c793c74678dff3f5d25aa328526cdb6013f13b6d989d491a8e1d9cac77a"), BaseFeePerGas: big.NewInt(12), ExtraData: []byte{}, + GasLimit: 10_000_000, } forkchoiceBlock, err := engine.ExecutableDataToBlock(*forkchoiceData) @@ -164,8 +171,13 @@ func TestGetHeader(t *testing.T) { require.Equal(t, ``, rr.Body.String()) require.Equal(t, 204, rr.Code) - err = backend.OnPayloadAttribute(&types.BuilderPayloadAttributes{}) + attrs := &types.BuilderPayloadAttributes{} + err = backend.OnPayloadAttribute(attrs) require.NoError(t, err) + + expectedGasLimit := core.CalcGasLimit(forkchoiceData.GasLimit, testLocalRelayValidatorGasLimit) + require.Equal(t, attrs.GasLimit, expectedGasLimit) + time.Sleep(2 * time.Second) path = fmt.Sprintf("/eth/v1/builder/header/%d/%s/%s", 0, forkchoiceData.ParentHash.Hex(), validator.Pk.String())