@@ -124,6 +124,7 @@ import (
124124 "github.com/sei-protocol/sei-chain/x/evm"
125125 evmante "github.com/sei-protocol/sei-chain/x/evm/ante"
126126 "github.com/sei-protocol/sei-chain/x/evm/blocktest"
127+ evmconfig "github.com/sei-protocol/sei-chain/x/evm/config"
127128 evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper"
128129 "github.com/sei-protocol/sei-chain/x/evm/querier"
129130 "github.com/sei-protocol/sei-chain/x/evm/replay"
@@ -263,8 +264,11 @@ var (
263264 // EnableOCC allows tests to override default OCC enablement behavior
264265 EnableOCC = true
265266 // EnablePipelineProcessing enables the new pipeline-based block processing path
266- EnablePipelineProcessing = true
267+ EnablePipelineProcessing = false
267268 EmptyAppOptions []AppOption
269+
270+ // EnableBenchmarkMode enables benchmark mode using sei-load generator
271+ EnableBenchmarkMode = false
268272)
269273
270274var (
@@ -397,6 +401,10 @@ type App struct {
397401
398402 // Pipeline processing (if enabled)
399403 blockPipeline * BlockPipeline
404+
405+ // Benchmark mode - generator channel for load testing
406+ benchmarkGeneratorCh <- chan * abci.ResponsePrepareProposal
407+ enableBenchmarkMode bool
400408}
401409
402410type AppOption func (* App )
@@ -466,6 +474,7 @@ func New(
466474 stateStore : stateStore ,
467475 httpServerStartSignal : make (chan struct {}, 1 ),
468476 wsServerStartSignal : make (chan struct {}, 1 ),
477+ enableBenchmarkMode : EnableBenchmarkMode ,
469478 }
470479
471480 for _ , option := range appOptions {
@@ -921,7 +930,11 @@ func New(
921930 app .SetAnteDepGenerator (anteDepGenerator )
922931 app .SetMidBlocker (app .MidBlocker )
923932 app .SetEndBlocker (app .EndBlocker )
924- app .SetPrepareProposalHandler (app .PrepareProposalHandler )
933+ if app .enableBenchmarkMode {
934+ app .SetPrepareProposalHandler (app .PrepareProposalGeneratorHandler )
935+ } else {
936+ app .SetPrepareProposalHandler (app .PrepareProposalHandler )
937+ }
925938 app .SetProcessProposalHandler (app .ProcessProposalHandler )
926939 app .SetFinalizeBlocker (app .FinalizeBlocker )
927940 app .SetInplaceTestnetInitializer (app .inplacetestnetInitializer )
@@ -996,7 +1009,7 @@ func New(
9961009 PreprocessBlock ,
9971010 ExecutePreprocessedEVMTransaction ,
9981011 ExecuteCosmosTransaction ,
999- 10 , // preprocessorWorkers
1012+ 25 , // preprocessorWorkers
10001013 1000 , // bufferSize
10011014 1 , // startSequence
10021015 )
@@ -1008,6 +1021,20 @@ func New(
10081021 logger .Info ("Using legacy block processing" , "mode" , "legacy" )
10091022 }
10101023
1024+ // Initialize benchmark generator if enabled
1025+ if app .enableBenchmarkMode {
1026+ logger .Info ("Initializing benchmark mode generator" , "mode" , "benchmark" )
1027+ genCtx := context .Background ()
1028+ // Get EVM chain ID from config mapping (not Cosmos chain ID)
1029+ evmChainID := evmconfig .GetEVMChainID (app .ChainID ).Int64 ()
1030+ // Use a reasonable default for MaxTxBytes (20MB - conservative estimate)
1031+ // The generator will filter transactions to fit within this limit
1032+ // Tendermint will still validate the final proposal doesn't exceed req.MaxTxBytes
1033+ defaultMaxTxBytes := int64 (20 * 1024 * 1024 ) // 20MB
1034+ app .benchmarkGeneratorCh = NewGeneratorCh (genCtx , app .encodingConfig .TxConfig , evmChainID , defaultMaxTxBytes , logger )
1035+ logger .Info ("Benchmark generator initialized and started" , "maxTxBytes" , defaultMaxTxBytes )
1036+ }
1037+
10111038 return app
10121039}
10131040
@@ -1147,6 +1174,25 @@ func (app *App) PrepareProposalHandler(_ sdk.Context, req *abci.RequestPreparePr
11471174 }, nil
11481175}
11491176
1177+ func (app * App ) PrepareProposalGeneratorHandler (_ sdk.Context , req * abci.RequestPrepareProposal ) (* abci.ResponsePrepareProposal , error ) {
1178+ // Pull from generator channel - the generator has already filtered transactions by size
1179+ select {
1180+ case proposal , ok := <- app .benchmarkGeneratorCh :
1181+ if proposal == nil || ! ok {
1182+ // Channel closed or no proposal available, return empty (req.Txs will remain in mempool)
1183+ return & abci.ResponsePrepareProposal {
1184+ TxRecords : []* abci.TxRecord {},
1185+ }, nil
1186+ }
1187+ return proposal , nil
1188+ default :
1189+ // No proposal ready yet, return empty (req.Txs will remain in mempool)
1190+ return & abci.ResponsePrepareProposal {
1191+ TxRecords : []* abci.TxRecord {},
1192+ }, nil
1193+ }
1194+ }
1195+
11501196func (app * App ) GetOptimisticProcessingInfo () OptimisticProcessingInfo {
11511197 app .optimisticProcessingInfoMutex .RLock ()
11521198 defer app .optimisticProcessingInfoMutex .RUnlock ()
@@ -1266,6 +1312,12 @@ func (app *App) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock)
12661312 return nil , fmt .Errorf ("timeout waiting for pipeline result" )
12671313 }
12681314
1315+ // Check if preprocessing failed
1316+ if processed .ExecutedBlock .PreprocessedBlock .PreprocessError != nil {
1317+ ctx .Logger ().Error ("Pipeline preprocessing failed" , "error" , processed .ExecutedBlock .PreprocessedBlock .PreprocessError , "height" , req .Height )
1318+ return nil , fmt .Errorf ("pipeline preprocessing failed: %w" , processed .ExecutedBlock .PreprocessedBlock .PreprocessError )
1319+ }
1320+
12691321 // Verify we got the correct block
12701322 if processed .ExecutedBlock .PreprocessedBlock .Height != req .Height {
12711323 ctx .Logger ().Error ("Pipeline returned wrong block" , "expected" , req .Height , "got" , processed .ExecutedBlock .PreprocessedBlock .Height )
0 commit comments