diff --git a/eth/api_backend.go b/eth/api_backend.go index 63469ca76690..0be450a5e8af 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" @@ -418,12 +419,12 @@ func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Blo return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) } -func (b *EthAPIBackend) BuildBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*types.Block, *big.Int, error) { - return b.eth.Miner().BuildBlockFromTxs(ctx, buildArgs, txs) +func (b *EthAPIBackend) BuildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { + return b.eth.Miner().BuildEthBlockFromBundles(ctx, buildArgs, bundles) } -func (b *EthAPIBackend) BuildBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) { - return b.eth.Miner().BuildBlockFromBundles(ctx, buildArgs, bundles) +func (b *EthAPIBackend) BuildEthBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) { + return b.eth.Miner().BuildEthBlockFromTxs(ctx, buildArgs, txs) } func (b *EthAPIBackend) Call(ctx context.Context, contractAddr common.Address, input []byte) ([]byte, error) { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 831b865a0381..ff4679de7b52 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" @@ -48,7 +49,6 @@ import ( "github.com/ethereum/go-ethereum/internal/blocktest" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" @@ -598,18 +598,12 @@ func (b testBackend) ServiceFilter(ctx context.Context, session *bloombits.Match panic("implement me") } -func (n *testBackend) BuildBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*types.Block, *big.Int, error) { - block := types.NewBlock(&types.Header{GasUsed: 1000, BaseFee: big.NewInt(1)}, txs, nil, nil, trie.NewStackTrie(nil)) - return block, big.NewInt(11000), nil +func (n *testBackend) BuildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { + return nil, nil } -func (n *testBackend) BuildBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) { - var txs types.Transactions - for _, bundle := range bundles { - txs = append(txs, bundle.Txs...) - } - block := types.NewBlock(&types.Header{GasUsed: 1000, BaseFee: big.NewInt(1)}, txs, nil, nil, trie.NewStackTrie(nil)) - return block, big.NewInt(11000), nil +func (n *testBackend) BuildEthBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) { + return nil, nil } func (n *testBackend) Call(ctx context.Context, contractAddr common.Address, input []byte) ([]byte, error) { diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 48ba0e7fd71a..d849b0d2eb87 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" @@ -99,8 +100,8 @@ type Backend interface { ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) // SUAVE Execution Methods - BuildBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*types.Block, *big.Int, error) - BuildBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) + BuildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) + BuildEthBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) } func GetAPIs(apiBackend Backend) []rpc.API { diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 7c99cff14805..ded772e3842a 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" @@ -366,12 +367,12 @@ func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) func (b *backendMock) Engine() consensus.Engine { return nil } -func (n *backendMock) BuildBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*types.Block, *big.Int, error) { - return nil, nil, nil +func (n *backendMock) BuildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { + return nil, nil } -func (n *backendMock) BuildBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) { - return nil, nil, nil +func (n *backendMock) BuildEthBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) { + return nil, nil } func (n *backendMock) Call(ctx context.Context, contractAddr common.Address, input []byte) ([]byte, error) { diff --git a/miner/miner.go b/miner/miner.go index 20bade3da2f6..e78176827d88 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -24,6 +24,7 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" @@ -253,3 +254,11 @@ func (miner *Miner) BuildBlockFromTxs(ctx context.Context, buildArgs *types.Buil func (miner *Miner) BuildBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) { return miner.worker.buildBlockFromBundles(ctx, buildArgs, bundles) } + +func (miner *Miner) BuildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { + return miner.worker.buildEthBlockFromBundles(ctx, buildArgs, bundles) +} + +func (miner *Miner) BuildEthBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) { + return miner.worker.buildEthBlockFromTxs(ctx, buildArgs, txs) +} diff --git a/miner/worker.go b/miner/worker.go index 0d3c400d98aa..b8a6049bb83a 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -18,6 +18,7 @@ package miner import ( "context" + "crypto/sha256" "errors" "fmt" "math/big" @@ -25,7 +26,9 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" @@ -1328,6 +1331,30 @@ func (w *worker) buildBlockFromTxs(ctx context.Context, args *types.BuildBlockAr return block, blockProfit, nil } +func (w *worker) buildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { + block, profit, err := w.buildBlockFromBundles(ctx, buildArgs, bundles) + if err != nil { + return nil, err + } + exeData := engine.BlockToExecutableData(block, profit, nil) + filteredBlobs := w.getBlobsForTxs(block.Transactions()) + exeData.BlobsBundle = &filteredBlobs + + return exeData, nil +} + +func (w *worker) buildEthBlockFromTxs(ctx context.Context, buildArgs *types.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) { + block, profit, err := w.buildBlockFromTxs(ctx, buildArgs, txs) + if err != nil { + return nil, err + } + exeData := engine.BlockToExecutableData(block, profit, nil) + filteredBlobs := w.getBlobsForTxs(block.Transactions()) + exeData.BlobsBundle = &filteredBlobs + + return exeData, nil +} + func (w *worker) buildBlockFromBundles(ctx context.Context, args *types.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) { // create ephemeral addr and private key for payment txn ephemeralPrivKey, err := crypto.GenerateKey() @@ -1446,3 +1473,41 @@ func (w *worker) buildBlockFromBundles(ctx context.Context, args *types.BuildBlo } return block, proposerProfit, nil } + +func (w *worker) getBlobsForTxs(txs types.Transactions) engine.BlobsBundleV1 { + // Obtain blob hashes from txs + var blobHashes []common.Hash + for _, tx := range txs { + blobHashes = append(blobHashes, tx.BlobHashes()...) + } + + bundle := engine.BlobsBundleV1{ + Commitments: make([]hexutil.Bytes, 0), + Blobs: make([]hexutil.Bytes, 0), + Proofs: make([]hexutil.Bytes, 0), + } + hasher := sha256.New() + for _, blobHash := range blobHashes { + for _, sidecar := range w.current.sidecars { + for j := range sidecar.Blobs { + // Obtain versioned hashes + commitment := sidecar.Commitments[j] + hasher.Write(commitment[:]) + hash := hasher.Sum(nil) + hasher.Reset() + var vhash common.Hash + vhash[0] = params.BlobTxHashVersion + copy(vhash[1:], hash[1:]) + // Append blob if hash matches blob from txs + if blobHash == vhash { + bundle.Blobs = append(bundle.Blobs, hexutil.Bytes(sidecar.Blobs[j][:])) + bundle.Commitments = append(bundle.Commitments, hexutil.Bytes(sidecar.Commitments[j][:])) + bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:])) + break + } + } + } + } + + return bundle +} diff --git a/suave/backends/eth_backend_server.go b/suave/backends/eth_backend_server.go index 571f4a4eddce..c804ab84878a 100644 --- a/suave/backends/eth_backend_server.go +++ b/suave/backends/eth_backend_server.go @@ -2,7 +2,6 @@ package backends import ( "context" - "math/big" "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" @@ -23,8 +22,8 @@ var _ EthBackend = &EthBackendServer{} // to resolve the EthBackend server queries type EthBackendServerBackend interface { CurrentHeader() *types.Header - BuildBlockFromTxs(ctx context.Context, buildArgs *suave.BuildBlockArgs, txs types.Transactions) (*types.Block, *big.Int, error) - BuildBlockFromBundles(ctx context.Context, buildArgs *suave.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) + BuildEthBlockFromBundles(ctx context.Context, buildArgs *suave.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) + BuildEthBlockFromTxs(ctx context.Context, buildArgs *suave.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) Call(ctx context.Context, contractAddr common.Address, input []byte) ([]byte, error) } @@ -51,13 +50,7 @@ func (e *EthBackendServer) BuildEthBlock(ctx context.Context, buildArgs *types.B } } - block, profit, err := e.b.BuildBlockFromTxs(ctx, buildArgs, txs) - if err != nil { - return nil, err - } - - // TODO: we're not adding blobs, but this is not where you would do it anyways - return engine.BlockToExecutableData(block, profit, nil), nil + return e.b.BuildEthBlockFromTxs(ctx, buildArgs, txs) } func (e *EthBackendServer) BuildEthBlockFromBundles(ctx context.Context, buildArgs *types.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { @@ -75,13 +68,7 @@ func (e *EthBackendServer) BuildEthBlockFromBundles(ctx context.Context, buildAr } } - block, profit, err := e.b.BuildBlockFromBundles(ctx, buildArgs, bundles) - if err != nil { - return nil, err - } - - // TODO: we're not adding blobs, but this is not where you would do it anyways - return engine.BlockToExecutableData(block, profit, nil), nil + return e.b.BuildEthBlockFromBundles(ctx, buildArgs, bundles) } func (e *EthBackendServer) Call(ctx context.Context, contractAddr common.Address, input []byte) ([]byte, error) { diff --git a/suave/backends/eth_backend_server_test.go b/suave/backends/eth_backend_server_test.go index 60bc0d70b64b..9af2bde8891c 100644 --- a/suave/backends/eth_backend_server_test.go +++ b/suave/backends/eth_backend_server_test.go @@ -5,9 +5,9 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/core/types" @@ -39,20 +39,38 @@ func (n *mockBackend) CurrentHeader() *types.Header { return &types.Header{} } -func (n *mockBackend) BuildBlockFromTxs(ctx context.Context, buildArgs *suave.BuildBlockArgs, txs types.Transactions) (*types.Block, *big.Int, error) { - block := types.NewBlock(&types.Header{GasUsed: 1000, BaseFee: big.NewInt(1)}, txs, nil, nil, trie.NewStackTrie(nil)) - return block, big.NewInt(11000), nil +func (n *mockBackend) BuildEthBlockFromBundles(ctx context.Context, buildArgs *suave.BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) { + return getDummyExecutionPayloadEnvelope(), nil } -func (n *mockBackend) BuildBlockFromBundles(ctx context.Context, buildArgs *suave.BuildBlockArgs, bundles []types.SBundle) (*types.Block, *big.Int, error) { - var txs types.Transactions - for _, bundle := range bundles { - txs = append(txs, bundle.Txs...) - } - block := types.NewBlock(&types.Header{GasUsed: 1000, BaseFee: big.NewInt(1)}, txs, nil, nil, trie.NewStackTrie(nil)) - return block, big.NewInt(11000), nil +func (n *mockBackend) BuildEthBlockFromTxs(ctx context.Context, buildArgs *suave.BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) { + return getDummyExecutionPayloadEnvelope(), nil } func (n *mockBackend) Call(ctx context.Context, contractAddr common.Address, input []byte) ([]byte, error) { return []byte{0x1}, nil } + +func getDummyExecutionPayloadEnvelope() *engine.ExecutionPayloadEnvelope { + dummyExecutableData := &engine.ExecutableData{ + ParentHash: common.HexToHash("0x01"), + FeeRecipient: common.HexToAddress("0x02"), + StateRoot: common.HexToHash("0x03"), + ReceiptsRoot: common.HexToHash("0x04"), + LogsBloom: []byte("dummyLogsBloom"), + Random: common.HexToHash("0x05"), + Number: 1, + GasLimit: 10000000, + GasUsed: 500000, + Timestamp: 1640995200, + ExtraData: []byte("dummyExtraData"), + BaseFeePerGas: big.NewInt(1000000000), + BlockHash: common.HexToHash("0x06"), + Transactions: [][]byte{[]byte("dummyTransaction")}, + } + exePayloadEnv := engine.ExecutionPayloadEnvelope{ + ExecutionPayload: dummyExecutableData, + BlockValue: big.NewInt(123456789), + } + return &exePayloadEnv +}