diff --git a/beacon/engine/gen_ed.go b/beacon/engine/gen_ed.go index 884b7160e8d79..336dfc6cc7559 100644 --- a/beacon/engine/gen_ed.go +++ b/beacon/engine/gen_ed.go @@ -32,8 +32,6 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) { BlockHash common.Hash `json:"blockHash" gencodec:"required"` Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` - DataGasUsed *hexutil.Uint64 `json:"dataGasUsed"` - ExcessDataGas *hexutil.Uint64 `json:"excessDataGas"` } var enc ExecutableData enc.ParentHash = e.ParentHash @@ -56,8 +54,6 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) { } } enc.Withdrawals = e.Withdrawals - enc.DataGasUsed = (*hexutil.Uint64)(e.DataGasUsed) - enc.ExcessDataGas = (*hexutil.Uint64)(e.ExcessDataGas) return json.Marshal(&enc) } @@ -79,8 +75,6 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error { BlockHash *common.Hash `json:"blockHash" gencodec:"required"` Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` - DataGasUsed *hexutil.Uint64 `json:"dataGasUsed"` - ExcessDataGas *hexutil.Uint64 `json:"excessDataGas"` } var dec ExecutableData if err := json.Unmarshal(input, &dec); err != nil { @@ -148,11 +142,5 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error { if dec.Withdrawals != nil { e.Withdrawals = dec.Withdrawals } - if dec.DataGasUsed != nil { - e.DataGasUsed = (*uint64)(dec.DataGasUsed) - } - if dec.ExcessDataGas != nil { - e.ExcessDataGas = (*uint64)(dec.ExcessDataGas) - } return nil } diff --git a/beacon/engine/gen_epe.go b/beacon/engine/gen_epe.go index 664a50fc5b299..cc66cef6cd3ec 100644 --- a/beacon/engine/gen_epe.go +++ b/beacon/engine/gen_epe.go @@ -17,12 +17,10 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) { type ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` } var enc ExecutionPayloadEnvelope enc.ExecutionPayload = e.ExecutionPayload enc.BlockValue = (*hexutil.Big)(e.BlockValue) - enc.BlobsBundle = e.BlobsBundle return json.Marshal(&enc) } @@ -31,7 +29,6 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error { type ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` } var dec ExecutionPayloadEnvelope if err := json.Unmarshal(input, &dec); err != nil { @@ -45,8 +42,5 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'blockValue' for ExecutionPayloadEnvelope") } e.BlockValue = (*big.Int)(dec.BlockValue) - if dec.BlobsBundle != nil { - e.BlobsBundle = dec.BlobsBundle - } return nil } diff --git a/beacon/engine/types.go b/beacon/engine/types.go index d96bece8560b2..07ebe544b438f 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -23,7 +23,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/trie" ) @@ -62,8 +61,6 @@ type ExecutableData struct { BlockHash common.Hash `json:"blockHash" gencodec:"required"` Transactions [][]byte `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` - DataGasUsed *uint64 `json:"dataGasUsed"` - ExcessDataGas *uint64 `json:"excessDataGas"` } // JSON type overrides for executableData. @@ -76,8 +73,6 @@ type executableDataMarshaling struct { ExtraData hexutil.Bytes LogsBloom hexutil.Bytes Transactions []hexutil.Bytes - DataGasUsed *hexutil.Uint64 - ExcessDataGas *hexutil.Uint64 } //go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go @@ -85,13 +80,6 @@ type executableDataMarshaling struct { type ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *big.Int `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` -} - -type BlobsBundleV1 struct { - Commitments []hexutil.Bytes `json:"commitments"` - Proofs []hexutil.Bytes `json:"proofs"` - Blobs []hexutil.Bytes `json:"blobs"` } // JSON type overrides for ExecutionPayloadEnvelope. @@ -164,15 +152,14 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) { // ExecutableDataToBlock constructs a block from executable data. // It verifies that the following fields: // -// len(extraData) <= 32 -// uncleHash = emptyUncleHash -// difficulty = 0 -// if versionedHashes != nil, versionedHashes match to blob transactions +// len(extraData) <= 32 +// uncleHash = emptyUncleHash +// difficulty = 0 // // and that the blockhash of the constructed block matches the parameters. Nil // Withdrawals value will propagate through the returned block. Empty // Withdrawals value must be passed via non-nil, length 0 value in params. -func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash) (*types.Block, error) { +func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) { txs, err := decodeTransactions(params.Transactions) if err != nil { return nil, err @@ -187,18 +174,6 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash) if params.BaseFeePerGas != nil && (params.BaseFeePerGas.Sign() == -1 || params.BaseFeePerGas.BitLen() > 256) { return nil, fmt.Errorf("invalid baseFeePerGas: %v", params.BaseFeePerGas) } - var blobHashes []common.Hash - for _, tx := range txs { - blobHashes = append(blobHashes, tx.BlobHashes()...) - } - if len(blobHashes) != len(versionedHashes) { - return nil, fmt.Errorf("invalid number of versionedHashes: %v blobHashes: %v", versionedHashes, blobHashes) - } - for i := 0; i < len(blobHashes); i++ { - if blobHashes[i] != versionedHashes[i] { - return nil, fmt.Errorf("invalid versionedHash at %v: %v blobHashes: %v", i, versionedHashes, blobHashes) - } - } // Only set withdrawalsRoot if it is non-nil. This allows CLs to use // ExecutableData before withdrawals are enabled by marshaling // Withdrawals as the json null value. @@ -224,8 +199,6 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash) Extra: params.ExtraData, MixDigest: params.Random, WithdrawalsHash: withdrawalsRoot, - ExcessDataGas: params.ExcessDataGas, - DataGasUsed: params.DataGasUsed, } block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals) if block.Hash() != params.BlockHash { @@ -236,7 +209,7 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash) // BlockToExecutableData constructs the ExecutableData structure by filling the // fields from the given block. It assumes the given block is post-merge block. -func BlockToExecutableData(block *types.Block, fees *big.Int, blobs []kzg4844.Blob, commitments []kzg4844.Commitment, proofs []kzg4844.Proof) *ExecutionPayloadEnvelope { +func BlockToExecutableData(block *types.Block, fees *big.Int) *ExecutionPayloadEnvelope { data := &ExecutableData{ BlockHash: block.Hash(), ParentHash: block.ParentHash(), @@ -253,20 +226,8 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, blobs []kzg4844.Bl Random: block.MixDigest(), ExtraData: block.Extra(), Withdrawals: block.Withdrawals(), - DataGasUsed: block.DataGasUsed(), - ExcessDataGas: block.ExcessDataGas(), - } - blobsBundle := BlobsBundleV1{ - Commitments: make([]hexutil.Bytes, 0), - Blobs: make([]hexutil.Bytes, 0), - Proofs: make([]hexutil.Bytes, 0), - } - for i := range blobs { - blobsBundle.Blobs = append(blobsBundle.Blobs, hexutil.Bytes(blobs[i][:])) - blobsBundle.Commitments = append(blobsBundle.Commitments, hexutil.Bytes(commitments[i][:])) - blobsBundle.Proofs = append(blobsBundle.Proofs, hexutil.Bytes(proofs[i][:])) } - return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &blobsBundle} + return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees} } // ExecutionPayloadBodyV1 is used in the response to GetPayloadBodiesByHashV1 and GetPayloadBodiesByRangeV1 diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 2e3a236e00bc1..e4b5533b753f8 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -81,10 +81,8 @@ var caps = []string{ "engine_exchangeTransitionConfigurationV1", "engine_getPayloadV1", "engine_getPayloadV2", - "engine_getPayloadV3", "engine_newPayloadV1", "engine_newPayloadV2", - "engine_newPayloadV3", "engine_getPayloadBodiesByHashV1", "engine_getPayloadBodiesByRangeV1", } @@ -407,13 +405,23 @@ func (api *ConsensusAPI) GetPayloadV2(payloadID engine.PayloadID) (*engine.Execu return api.getPayload(payloadID) } -// GetPayloadV3 returns a cached payload by id. -func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { - return api.getPayload(payloadID) -} - func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { log.Trace("Engine API request received", "method", "GetPayload", "id", payloadID) + data := api.localBlocks.get(payloadID, false) + if data == nil { + return nil, engine.UnknownPayload + } + return data, nil +} + +// getFullPayload returns a cached payload by it. The difference is that this +// function always expects a non-empty payload, but can also return empty one +// if no transaction is executable. +// +// Note, this function is not a part of standard engine API, meant to be used +// by consensus client mock in dev mode. +func (api *ConsensusAPI) getFullPayload(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { + log.Trace("Engine API request received", "method", "GetFullPayload", "id", payloadID) data := api.localBlocks.get(payloadID, true) if data == nil { return nil, engine.UnknownPayload @@ -426,7 +434,7 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl if params.Withdrawals != nil { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) } - return api.newPayload(params, nil) + return api.newPayload(params) } // NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. @@ -438,29 +446,10 @@ func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.Payl } else if params.Withdrawals != nil { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai")) } - if api.eth.BlockChain().Config().IsCancun(new(big.Int).SetUint64(params.Number), params.Timestamp) { - return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("newPayloadV2 called post-cancun")) - } - return api.newPayload(params, nil) + return api.newPayload(params) } -// NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. -func (api *ConsensusAPI) NewPayloadV3(params engine.ExecutableData, versionedHashes *[]common.Hash) (engine.PayloadStatusV1, error) { - if !api.eth.BlockChain().Config().IsCancun(new(big.Int).SetUint64(params.Number), params.Timestamp) { - return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("newPayloadV3 called pre-cancun")) - } - - if params.ExcessDataGas == nil { - return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("nil excessDataGas post-cancun")) - } - var hashes []common.Hash - if versionedHashes != nil { - hashes = *versionedHashes - } - return api.newPayload(params, hashes) -} - -func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash) (engine.PayloadStatusV1, error) { +func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.PayloadStatusV1, error) { // The locking here is, strictly, not required. Without these locks, this can happen: // // 1. NewPayload( execdata-N ) is invoked from the CL. It goes all the way down to @@ -478,9 +467,9 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe defer api.newPayloadLock.Unlock() log.Trace("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash) - block, err := engine.ExecutableDataToBlock(params, versionedHashes) + block, err := engine.ExecutableDataToBlock(params) if err != nil { - log.Warn("Invalid NewPayload params", "params", params, "error", err) + log.Debug("Invalid NewPayload params", "params", params, "error", err) return engine.PayloadStatusV1{Status: engine.INVALID}, nil } // Stash away the last update to warn the user if the beacon client goes offline @@ -741,8 +730,8 @@ func (api *ConsensusAPI) ExchangeCapabilities([]string) []string { return caps } -// GetPayloadBodiesByHashV1 implements engine_getPayloadBodiesByHashV1 which allows for retrieval of a list -// of block bodies by the engine api. +// GetPayloadBodiesByHashV1 implements engine_getPayloadBodiesByHashV1 which +// allows for retrieval of a list of block bodies by the engine api. func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engine.ExecutionPayloadBodyV1 { var bodies = make([]*engine.ExecutionPayloadBodyV1, len(hashes)) for i, hash := range hashes { @@ -752,8 +741,8 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engin return bodies } -// GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range -// of block bodies by the engine api. +// GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which +// allows for retrieval of a range of block bodies by the engine api. func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBodyV1, error) { if start == 0 || count == 0 { return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count)) @@ -779,23 +768,19 @@ func getBody(block *types.Block) *engine.ExecutionPayloadBodyV1 { if block == nil { return nil } - var ( body = block.Body() txs = make([]hexutil.Bytes, len(body.Transactions)) withdrawals = body.Withdrawals ) - for j, tx := range body.Transactions { data, _ := tx.MarshalBinary() txs[j] = hexutil.Bytes(data) } - // Post-shanghai withdrawals MUST be set to empty slice instead of nil if withdrawals == nil && block.Header().WithdrawalsHash != nil { withdrawals = make([]*types.Withdrawal, 0) } - return &engine.ExecutionPayloadBodyV1{ TransactionData: txs, Withdrawals: withdrawals, diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index 05ad3def48aec..254a510ab40f5 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -38,7 +38,6 @@ import ( "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" @@ -323,7 +322,7 @@ func TestEth2NewBlock(t *testing.T) { if err != nil { t.Fatalf("Failed to create the executable data %v", err) } - block, err := engine.ExecutableDataToBlock(*execData, nil) + block, err := engine.ExecutableDataToBlock(*execData) if err != nil { t.Fatalf("Failed to convert executable data to block %v", err) } @@ -365,7 +364,7 @@ func TestEth2NewBlock(t *testing.T) { if err != nil { t.Fatalf("Failed to create the executable data %v", err) } - block, err := engine.ExecutableDataToBlock(*execData, nil) + block, err := engine.ExecutableDataToBlock(*execData) if err != nil { t.Fatalf("Failed to convert executable data to block %v", err) } @@ -997,7 +996,7 @@ func TestSimultaneousNewBlock(t *testing.T) { t.Fatal(testErr) } } - block, err := engine.ExecutableDataToBlock(*execData, nil) + block, err := engine.ExecutableDataToBlock(*execData) if err != nil { t.Fatalf("Failed to convert executable data to block %v", err) } @@ -1520,38 +1519,3 @@ func equalBody(a *types.Body, b *engine.ExecutionPayloadBodyV1) bool { } return reflect.DeepEqual(a.Withdrawals, b.Withdrawals) } - -func TestBlockToPayloadWithBlobs(t *testing.T) { - header := types.Header{} - var txs []*types.Transaction - - inner := types.BlobTx{ - BlobHashes: make([]common.Hash, 1), - } - - txs = append(txs, types.NewTx(&inner)) - - blobs := make([]kzg4844.Blob, 1) - commitments := make([]kzg4844.Commitment, 1) - proofs := make([]kzg4844.Proof, 1) - - block := types.NewBlock(&header, txs, nil, nil, trie.NewStackTrie(nil)) - envelope := engine.BlockToExecutableData(block, nil, blobs, commitments, proofs) - var want int - for _, tx := range txs { - want += len(tx.BlobHashes()) - } - if got := len(envelope.BlobsBundle.Commitments); got != want { - t.Fatalf("invalid number of commitments: got %v, want %v", got, want) - } - if got := len(envelope.BlobsBundle.Proofs); got != want { - t.Fatalf("invalid number of proofs: got %v, want %v", got, want) - } - if got := len(envelope.BlobsBundle.Blobs); got != want { - t.Fatalf("invalid number of blobs: got %v, want %v", got, want) - } - _, err := engine.ExecutableDataToBlock(*envelope.ExecutionPayload, make([]common.Hash, 1)) - if err != nil { - t.Error(err) - } -} diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index d4b08b7ba8e1f..f0956d262c03b 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -151,7 +151,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal) error { return fmt.Errorf("error calling forkchoice update: %v", err) } - envelope, err := c.engineAPI.getPayload(*fcResponse.PayloadID) + envelope, err := c.engineAPI.getFullPayload(*fcResponse.PayloadID) if err != nil { return fmt.Errorf("error retrieving payload: %v", err) } diff --git a/miner/payload_building.go b/miner/payload_building.go index 299196a3cdf3f..9b13a4a695fe7 100644 --- a/miner/payload_building.go +++ b/miner/payload_building.go @@ -120,9 +120,9 @@ func (payload *Payload) Resolve() *engine.ExecutionPayloadEnvelope { close(payload.stop) } if payload.full != nil { - return engine.BlockToExecutableData(payload.full, payload.fullFees, nil, nil, nil) + return engine.BlockToExecutableData(payload.full, payload.fullFees) } - return engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil, nil, nil) + return engine.BlockToExecutableData(payload.empty, big.NewInt(0)) } // ResolveEmpty is basically identical to Resolve, but it expects empty block only. @@ -131,7 +131,7 @@ func (payload *Payload) ResolveEmpty() *engine.ExecutionPayloadEnvelope { payload.lock.Lock() defer payload.lock.Unlock() - return engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil, nil, nil) + return engine.BlockToExecutableData(payload.empty, big.NewInt(0)) } // ResolveFull is basically identical to Resolve, but it expects full block only. @@ -157,7 +157,7 @@ func (payload *Payload) ResolveFull() *engine.ExecutionPayloadEnvelope { default: close(payload.stop) } - return engine.BlockToExecutableData(payload.full, payload.fullFees, nil, nil, nil) + return engine.BlockToExecutableData(payload.full, payload.fullFees) } // buildPayload builds the payload according to the provided parameters.