1717package execmodule_test
1818
1919import (
20+ "bytes"
2021 "context"
2122 "encoding/binary"
2223 "errors"
@@ -37,11 +38,14 @@ import (
3738 "github.com/erigontech/erigon/execution/commitment/commitmentdb"
3839 "github.com/erigontech/erigon/execution/execmodule"
3940 eth1utils "github.com/erigontech/erigon/execution/execmodule/moduleutil"
41+ "github.com/erigontech/erigon/execution/protocol/params"
4042 "github.com/erigontech/erigon/execution/tests/blockgen"
4143 "github.com/erigontech/erigon/execution/tests/mock"
4244 "github.com/erigontech/erigon/execution/types"
4345 "github.com/erigontech/erigon/node/gointerfaces"
4446 "github.com/erigontech/erigon/node/gointerfaces/executionproto"
47+ "github.com/erigontech/erigon/node/gointerfaces/txpoolproto"
48+ "github.com/erigontech/erigon/node/gointerfaces/typesproto"
4549)
4650
4751func TestValidateChainWithLastTxNumOfBlockAtStepBoundary (t * testing.T ) {
@@ -61,7 +65,7 @@ func TestValidateChainWithLastTxNumOfBlockAtStepBoundary(t *testing.T) {
6165 },
6266 }
6367 stepSize := uint64 (5 ) // 2 for block 0 (0,1) and 3 for block 1 (2,3,4)
64- m := mock .MockWithGenesis (t , genesis , privKey , false , mock .WithStepSize (stepSize ))
68+ m := mock .MockWithGenesis (t , genesis , privKey , mock .WithStepSize (stepSize ))
6569 chainPack , err := blockgen .GenerateChain (m .ChainConfig , m .Genesis , m .Engine , m .DB , 1 , func (i int , b * blockgen.BlockGen ) {
6670 tx , err := types .SignTx (
6771 types .NewTransaction (0 , senderAddr , uint256 .NewInt (0 ), 50000 , uint256 .NewInt (m .Genesis .BaseFee ().Uint64 ()), nil ),
@@ -130,7 +134,7 @@ func TestValidateChainAndUpdateForkChoiceWithSideForksThatGoBackAndForwardInHeig
130134 senderAddr2 : {Balance : new (big.Int ).Exp (big .NewInt (10 ), big .NewInt (18 ), nil )},
131135 },
132136 }
133- m := mock .MockWithGenesis (t , genesis , privKey , false )
137+ m := mock .MockWithGenesis (t , genesis , privKey )
134138 longerFork , err := blockgen .GenerateChain (m .ChainConfig , m .Genesis , m .Engine , m .DB , 2 , func (i int , b * blockgen.BlockGen ) {
135139 tx , err := types .SignTx (
136140 types .NewTransaction (uint64 (i ), senderAddr , uint256 .NewInt (1_000 ), 50000 , uint256 .NewInt (m .Genesis .BaseFee ().Uint64 ()), nil ),
@@ -171,6 +175,61 @@ func TestValidateChainAndUpdateForkChoiceWithSideForksThatGoBackAndForwardInHeig
171175 require .NoError (t , err )
172176}
173177
178+ func TestAssembleBlock (t * testing.T ) {
179+ if testing .Short () {
180+ t .Skip ("skipping test in short mode" )
181+ }
182+ t .Parallel ()
183+ ctx := t .Context ()
184+ m := mock .MockWithTxPoolOsaka (t )
185+ exec := m .Eth1ExecutionService
186+ txpool := m .TxPoolGrpcServer
187+ chainPack , err := blockgen .GenerateChain (m .ChainConfig , m .Genesis , m .Engine , m .DB , 1 , func (i int , gen * blockgen.BlockGen ) {
188+ // In block 1, addr1 sends addr2 some ether.
189+ tx , err := types .SignTx (types .NewTransaction (gen .TxNonce (m .Address ), common.Address {1 }, uint256 .NewInt (10_000 ), params .TxGas , uint256 .NewInt (m .Genesis .BaseFee ().Uint64 ()), nil ), * types .LatestSignerForChainID (m .ChainConfig .ChainID ), m .Key )
190+ require .NoError (t , err )
191+ gen .AddTx (tx )
192+ })
193+ require .NoError (t , err )
194+ err = m .InsertChain (chainPack )
195+ require .NoError (t , err )
196+ tx2 , err := types .SignTx (types .NewTransaction (1 , common.Address {1 }, uint256 .NewInt (10_000 ), params .TxGas , uint256 .NewInt (chainPack .TopBlock .BaseFee ().Uint64 ()), nil ), * types .LatestSignerForChainID (m .ChainConfig .ChainID ), m .Key )
197+ require .NoError (t , err )
198+ tx3 , err := types .SignTx (types .NewTransaction (2 , common.Address {1 }, uint256 .NewInt (10_000 ), params .TxGas , uint256 .NewInt (chainPack .TopBlock .BaseFee ().Uint64 ()), nil ), * types .LatestSignerForChainID (m .ChainConfig .ChainID ), m .Key )
199+ require .NoError (t , err )
200+ rlpTxs := make ([][]byte , 2 )
201+ for i , tx := range []types.Transaction {tx2 , tx3 } {
202+ var buf bytes.Buffer
203+ err = tx .EncodeRLP (& buf )
204+ require .NoError (t , err )
205+ rlpTxs [i ] = buf .Bytes ()
206+ }
207+ r , err := txpool .Add (ctx , & txpoolproto.AddRequest {
208+ RlpTxs : rlpTxs ,
209+ })
210+ require .NoError (t , err )
211+ require .Len (t , r .Errors , 2 )
212+ for _ , err := range r .Errors {
213+ require .Equal (t , "success" , err )
214+ }
215+ require .Len (t , r .Imported , 2 )
216+ for _ , res := range r .Imported {
217+ require .Equal (t , txpoolproto .ImportResult_SUCCESS , res )
218+ }
219+ payloadId , err := assembleBlock (ctx , exec , & executionproto.AssembleBlockRequest {
220+ ParentHash : gointerfaces .ConvertHashToH256 (chainPack .TopBlock .Hash ()),
221+ Timestamp : chainPack .TopBlock .Header ().Time + 1 ,
222+ PrevRandao : gointerfaces .ConvertHashToH256 (chainPack .TopBlock .Header ().MixDigest ),
223+ SuggestedFeeRecipient : gointerfaces .ConvertAddressToH160 (common.Address {1 }),
224+ Withdrawals : make ([]* typesproto.Withdrawal , 0 ),
225+ })
226+ require .NoError (t , err )
227+ blockData , err := getAssembledBlock (ctx , exec , payloadId )
228+ require .NoError (t , err )
229+ require .Equal (t , uint64 (2 ), blockData .ExecutionPayload .BlockNumber )
230+ require .Len (t , blockData .ExecutionPayload .Transactions , 2 )
231+ }
232+
174233func insertBlocks (ctx context.Context , exec * execmodule.EthereumExecutionModule , chainPack * blockgen.ChainPack ) (* executionproto.InsertionResult , error ) {
175234 blocks := make ([]* executionproto.Block , len (chainPack .Blocks ))
176235 for i , b := range chainPack .Blocks {
@@ -242,6 +301,32 @@ func insertValidateAndUfc1By1(ctx context.Context, exec *execmodule.EthereumExec
242301 return nil
243302}
244303
304+ func assembleBlock (ctx context.Context , exec * execmodule.EthereumExecutionModule , req * executionproto.AssembleBlockRequest ) (uint64 , error ) {
305+ return retryBusy (ctx , func () (uint64 , executionproto.ExecutionStatus , error ) {
306+ r , err := exec .AssembleBlock (ctx , req )
307+ if err != nil {
308+ return 0 , 0 , err
309+ }
310+ if r .Busy {
311+ return 0 , executionproto .ExecutionStatus_Busy , nil
312+ }
313+ return r .Id , executionproto .ExecutionStatus_Success , nil
314+ })
315+ }
316+
317+ func getAssembledBlock (ctx context.Context , exe * execmodule.EthereumExecutionModule , payloadId uint64 ) (* executionproto.AssembledBlockData , error ) {
318+ return retryBusy (ctx , func () (* executionproto.AssembledBlockData , executionproto.ExecutionStatus , error ) {
319+ br , err := exe .GetAssembledBlock (ctx , & executionproto.GetAssembledBlockRequest {Id : payloadId })
320+ if err != nil {
321+ return nil , 0 , err
322+ }
323+ if br .Busy {
324+ return nil , executionproto .ExecutionStatus_Busy , nil
325+ }
326+ return br .Data , executionproto .ExecutionStatus_Success , nil
327+ })
328+ }
329+
245330func retryBusy [T any ](ctx context.Context , f func () (T , executionproto.ExecutionStatus , error )) (T , error ) {
246331 ctx , cancel := context .WithTimeout (ctx , time .Minute )
247332 defer cancel ()
0 commit comments