Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
99b28d8
wip
pompon0 Mar 18, 2026
f2c35c1
mapping WIP
pompon0 Mar 18, 2026
5088e24
test updates
pompon0 Mar 18, 2026
145623e
Merge branch 'main' into gprusak-header
pompon0 Mar 18, 2026
4b4820a
test fix
pompon0 Mar 18, 2026
1ba27a8
test fixes
pompon0 Mar 18, 2026
73baacf
test fixes
pompon0 Mar 18, 2026
f1c282d
RequestInitChain
pompon0 Mar 18, 2026
7898eac
more types
pompon0 Mar 18, 2026
2f1d968
removed unused getters
pompon0 Mar 18, 2026
fa577b6
applied comments
pompon0 Mar 18, 2026
e10ccba
fixed self-reference, removed unused mocks
pompon0 Mar 18, 2026
48f7cd8
Merge branch 'gprusak-header' into gprusak-abci
pompon0 Mar 18, 2026
bec8f81
header in PrepareProposal
pompon0 Mar 18, 2026
0541acc
fixes
pompon0 Mar 18, 2026
f4b4fea
removed guard
pompon0 Mar 18, 2026
4c6f98c
test fixes
pompon0 Mar 18, 2026
c0a2c2d
Merge branch 'main' into gprusak-header
pompon0 Mar 18, 2026
514cd06
Merge branch 'main' into gprusak-header
pompon0 Mar 19, 2026
2f468a0
fixed flake
pompon0 Mar 19, 2026
d9f258d
Merge branch 'gprusak-header' of https://github.com/sei-protocol/sei-…
pompon0 Mar 19, 2026
ea26d17
compresses deletion
pompon0 Mar 19, 2026
a2a9b9a
fixed worker pool test
pompon0 Mar 19, 2026
e891bd3
Merge remote-tracking branch 'origin/main' into gprusak-header
pompon0 Mar 19, 2026
805df18
Merge branch 'gprusak-header' into gprusak-abci
pompon0 Mar 19, 2026
4e0eded
reverted generated code discrepancies
pompon0 Mar 19, 2026
555caea
made DeadlineExceeded a valid termination result for critical tasks
pompon0 Mar 19, 2026
6a6072f
Merge branch 'main' into gprusak-abci
pompon0 Mar 19, 2026
b9f7009
nolint
pompon0 Mar 19, 2026
a229926
Merge branch 'gprusak-abci' of https://github.com/sei-protocol/sei-ch…
pompon0 Mar 19, 2026
9712125
pruned prepare proposal
pompon0 Mar 20, 2026
3bcc932
stripped unused fields
pompon0 Mar 20, 2026
494c572
further cleanup
pompon0 Mar 20, 2026
5f06b4b
removed prepareProposalState
pompon0 Mar 20, 2026
2744936
PrepareProposal is no more
pompon0 Mar 20, 2026
a194d06
further cleanup
pompon0 Mar 20, 2026
7a10558
Merge remote-tracking branch 'origin/main' into gprusak-header
pompon0 Mar 24, 2026
ddbd523
Merge branch 'gprusak-header' into gprusak-prepare
pompon0 Mar 24, 2026
1a5af0c
compilation fix
pompon0 Mar 24, 2026
97dd0ab
removed outdated test
pompon0 Mar 24, 2026
6f1e929
removed another obsolete test
pompon0 Mar 24, 2026
13b28d3
Merge branch 'main' into gprusak-prepare
pompon0 Mar 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1004,9 +1004,6 @@ func New(
if benchmarkEnabled {
evmChainID := evmconfig.GetEVMChainID(app.ChainID).Int64()
app.InitBenchmark(context.Background(), app.ChainID, evmChainID)
app.SetPrepareProposalHandler(app.PrepareProposalBenchmarkHandler)
} else {
app.SetPrepareProposalHandler(app.PrepareProposalHandler)
}

app.SetProcessProposalHandler(app.ProcessProposalHandler)
Expand Down Expand Up @@ -1196,14 +1193,6 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res
return app.mm.InitGenesis(ctx, app.appCodec, genesisState, app.genesisImportConfig)
}

func (app *App) PrepareProposalHandler(_ sdk.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) {
return &abci.ResponsePrepareProposal{
TxRecords: utils.Map(req.Txs, func(tx []byte) *abci.TxRecord {
return &abci.TxRecord{Action: abci.TxRecord_UNMODIFIED, Tx: tx}
}),
}, nil
}

func (app *App) GetOptimisticProcessingInfo() OptimisticProcessingInfo {
app.optimisticProcessingInfoMutex.RLock()
defer app.optimisticProcessingInfoMutex.RUnlock()
Expand Down
19 changes: 0 additions & 19 deletions app/benchmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/sei-protocol/sei-chain/app/benchmark"
sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types"
abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types"
evmcfg "github.com/sei-protocol/sei-chain/x/evm/config"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
)
Expand All @@ -31,24 +30,6 @@ func (app *App) InitBenchmark(ctx context.Context, chainID string, evmChainID in
logger.Info("Benchmark system initialized")
}

// PrepareProposalBenchmarkHandler generates benchmark transactions during PrepareProposal.
func (app *App) PrepareProposalBenchmarkHandler(_ sdk.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) {
if app.benchmarkManager == nil {
return &abci.ResponsePrepareProposal{TxRecords: []*abci.TxRecord{}}, nil
}

select {
case proposal, ok := <-app.benchmarkManager.ProposalChannel():
if proposal == nil || !ok {
return &abci.ResponsePrepareProposal{TxRecords: []*abci.TxRecord{}}, nil
}
app.benchmarkManager.Logger.Increment(int64(len(proposal.TxRecords)), req.Header.Time, req.Header.Height)
return proposal, nil
default:
return &abci.ResponsePrepareProposal{TxRecords: []*abci.TxRecord{}}, nil
}
}

// ProcessBenchmarkReceipts extracts receipts from the block and forwards them to
// the benchmark system for deployment tracking during the setup phase.
func (app *App) ProcessBenchmarkReceipts(ctx sdk.Context) {
Expand Down
5 changes: 2 additions & 3 deletions app/benchmark/benchmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/sei-protocol/sei-chain/sei-cosmos/client"
abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types"
evmcfg "github.com/sei-protocol/sei-chain/x/evm/config"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
"github.com/sei-protocol/seilog"
Expand All @@ -38,7 +37,7 @@ var logger = seilog.NewLogger("app", "benchmark")
type Manager struct {
Generator *Generator
Logger *Logger
proposalCh <-chan *abci.ResponsePrepareProposal
proposalCh <-chan [][]byte
}

// NewManager creates a new benchmark manager from configuration.
Expand Down Expand Up @@ -79,7 +78,7 @@ func NewManager(ctx context.Context, txConfig client.TxConfig, chainID string, e
}

// ProposalChannel returns the channel of prepared proposals.
func (m *Manager) ProposalChannel() <-chan *abci.ResponsePrepareProposal {
func (m *Manager) ProposalChannel() <-chan [][]byte {
return m.proposalCh
}

Expand Down
50 changes: 21 additions & 29 deletions app/benchmark/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/sei-protocol/sei-chain/sei-cosmos/client"
abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
"github.com/sei-protocol/sei-chain/x/evm/types/ethtx"
"github.com/sei-protocol/sei-load/config"
Expand Down Expand Up @@ -237,11 +236,11 @@ func (g *Generator) craftDeploymentTx(state *scenarioState, txScenario *loadtype
// generateSetupBlock creates deployment transactions for undeployed scenarios.
// This is called on every PrepareProposal during setup phase, but we only
// create a deployment transaction ONCE per scenario.
func (g *Generator) generateSetupBlock() []*abci.TxRecord {
func (g *Generator) generateSetupBlock() [][]byte {
g.mu.Lock()
defer g.mu.Unlock()

txRecords := make([]*abci.TxRecord, 0, len(g.scenarios))
txs := make([][]byte, 0, len(g.scenarios))

for _, state := range g.scenarios {
// Skip if already deployed
Expand Down Expand Up @@ -278,11 +277,11 @@ func (g *Generator) generateSetupBlock() []*abci.TxRecord {
"txHash", deployTx.Hash())

// Convert to Cosmos SDK tx
txRecord, err := g.ethTxToTxRecord(deployTx)
tx, err := g.ethTxToTx(deployTx)
if err != nil {
panic(fmt.Sprintf("benchmark: Failed to convert deployment tx for %s: %v", state.config.Name, err))
}
txRecords = append(txRecords, txRecord)
txs = append(txs, tx)
}

// Fast-path: if no scenarios need contract deployment (e.g., all EVMTransfer),
Expand All @@ -293,7 +292,7 @@ func (g *Generator) generateSetupBlock() []*abci.TxRecord {
g.transitionToLoadPhase()
}

return txRecords
return txs
}

// allScenariosDeployed returns true if all scenarios are marked as deployed.
Expand All @@ -307,7 +306,7 @@ func (g *Generator) allScenariosDeployed() bool {
}

// generateLoadBlock generates load transactions.
func (g *Generator) generateLoadBlock() []*abci.TxRecord {
func (g *Generator) generateLoadBlock() [][]byte {
g.mu.RLock()
loadGen := g.loadGenerator
g.mu.RUnlock()
Expand All @@ -317,20 +316,20 @@ func (g *Generator) generateLoadBlock() []*abci.TxRecord {
}

loadTxs := loadGen.GenerateN(g.txsPerBatch)
txRecords := make([]*abci.TxRecord, 0, len(loadTxs))
txs := make([][]byte, 0, len(loadTxs))
for _, loadTx := range loadTxs {
txRecord, err := g.ethTxToTxRecord(loadTx.EthTx)
tx, err := g.ethTxToTx(loadTx.EthTx)
if err != nil {
panic(fmt.Sprintf("benchmark: Failed to convert load tx: %v", err))
}
txRecords = append(txRecords, txRecord)
txs = append(txs, tx)
}

return txRecords
return txs
}

// ethTxToTxRecord converts an Ethereum transaction to a Cosmos SDK TxRecord.
func (g *Generator) ethTxToTxRecord(ethTx *ethtypes.Transaction) (*abci.TxRecord, error) {
// ethTxToTx converts an Ethereum transaction to an encoded Cosmos SDK tx.
func (g *Generator) ethTxToTx(ethTx *ethtypes.Transaction) ([]byte, error) {
txData, err := ethtx.NewTxDataFromTx(ethTx)
if err != nil {
return nil, fmt.Errorf("failed to convert eth tx to tx data: %w", err)
Expand All @@ -352,10 +351,7 @@ func (g *Generator) ethTxToTxRecord(ethTx *ethtypes.Transaction) (*abci.TxRecord
return nil, fmt.Errorf("failed to encode tx: %w", err)
}

return &abci.TxRecord{
Action: abci.TxRecord_UNMODIFIED,
Tx: txbz,
}, nil
return txbz, nil
}

// ProcessReceipts handles receipts from FinalizeBlock to extract deployed addresses.
Expand Down Expand Up @@ -451,8 +447,8 @@ func (g *Generator) transitionToLoadPhase() {
logger.Info("benchmark: Load generator initialized and ready", "scenarios", len(weightedConfigs))
}

// Generate returns the next batch of transaction records.
func (g *Generator) Generate() []*abci.TxRecord {
// Generate returns the next batch of encoded txs.
func (g *Generator) Generate() [][]byte {
g.mu.Lock()
phase := g.phase

Expand Down Expand Up @@ -493,9 +489,9 @@ func (g *Generator) GetPendingDeployHashes() []common.Hash {
return hashes
}

// StartProposalChannel creates a channel that generates proposals.
func (g *Generator) StartProposalChannel(ctx context.Context, logger *Logger) <-chan *abci.ResponsePrepareProposal {
ch := make(chan *abci.ResponsePrepareProposal, 100)
// StartProposalChannel creates a channel that generates raw tx batches.
func (g *Generator) StartProposalChannel(ctx context.Context, logger *Logger) <-chan [][]byte {
ch := make(chan [][]byte, 100)

go func() {
defer close(ch)
Expand All @@ -504,17 +500,13 @@ func (g *Generator) StartProposalChannel(ctx context.Context, logger *Logger) <-
return
}

txRecords := g.Generate()
if len(txRecords) == 0 {
txs := g.Generate()
if len(txs) == 0 {
continue
}

proposal := &abci.ResponsePrepareProposal{
TxRecords: txRecords,
}

select {
case ch <- proposal:
case ch <- txs:
case <-ctx.Done():
return
}
Expand Down
55 changes: 1 addition & 54 deletions app/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,9 @@ import (
"time"

"github.com/sei-protocol/sei-chain/app/benchmark"
"github.com/sei-protocol/sei-chain/sei-cosmos/store/rootmulti"
sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types"
abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types"
tmtypes "github.com/sei-protocol/sei-chain/sei-tendermint/proto/tendermint/types"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db"
)

func createTestContext() sdk.Context {
db := dbm.NewMemDB()

ms := rootmulti.NewStore(db)
return sdk.NewContext(ms, tmtypes.Header{}, false)
}

func TestPrepareProposalBenchmarkHandler(t *testing.T) {
// Create a mock app with benchmark mode enabled

app := &App{}

// Test handler with nil manager (should return empty proposal)
ctx := createTestContext()
req := &abci.RequestPrepareProposal{
Header: &tmtypes.Header{
Height: 1,
Time: time.Now(),
},
}
resp, err := app.PrepareProposalBenchmarkHandler(ctx, req)
require.NoError(t, err)
require.NotNil(t, resp)
require.Len(t, resp.TxRecords, 0)

// Create a mock manager with a channel
proposalCh := make(chan *abci.ResponsePrepareProposal, 1)
testProposal := &abci.ResponsePrepareProposal{
TxRecords: []*abci.TxRecord{
{Action: abci.TxRecord_UNMODIFIED, Tx: []byte("tx1")},
{Action: abci.TxRecord_UNMODIFIED, Tx: []byte("tx2")},
},
}
proposalCh <- testProposal

app.benchmarkManager = &benchmark.Manager{
Logger: benchmark.NewLogger(),
}
// We can't easily set the proposalCh since it's unexported, so we test the nil case

// Test that handler doesn't panic with nil manager
app.benchmarkManager = nil
resp2, err := app.PrepareProposalBenchmarkHandler(ctx, req)
require.NoError(t, err)
require.NotNil(t, resp2)
require.Len(t, resp2.TxRecords, 0)
}

func TestBenchmarkHelperMethods(t *testing.T) {
app := &App{}

Expand Down Expand Up @@ -166,7 +113,7 @@ func TestInitBenchmark_Success(t *testing.T) {
if ok {
require.NotNil(t, proposal, "Proposal should not be nil")
// EVMTransfer scenario doesn't need deployment, so should get load txs immediately
t.Logf("Received proposal with %d tx records", len(proposal.TxRecords))
t.Logf("Received proposal with %d txs", len(proposal))
}
case <-time.After(5 * time.Second):
t.Log("Timeout waiting for proposal (may be in setup phase)")
Expand Down
52 changes: 0 additions & 52 deletions sei-cosmos/baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types"
sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors"
"github.com/sei-protocol/sei-chain/sei-cosmos/types/legacytm"
"github.com/sei-protocol/sei-chain/sei-cosmos/utils"
abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types"
tmproto "github.com/sei-protocol/sei-chain/sei-tendermint/proto/tendermint/types"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -52,15 +51,13 @@ func (app *BaseApp) InitChain(ctx context.Context, req *abci.RequestInitChain) (
// initialize the deliver state and check state with a correct header
app.setDeliverState(initHeader)
app.setCheckState(initHeader)
app.setPrepareProposalState(initHeader)
app.setProcessProposalState(initHeader)

// Store the consensus params in the BaseApp's paramstore. Note, this must be
// done after the deliver state and context have been set as it's persisted
// to state.
if req.ConsensusParams != nil {
app.StoreConsensusParams(app.deliverState.ctx, req.ConsensusParams)
app.StoreConsensusParams(app.prepareProposalState.ctx, req.ConsensusParams)
app.StoreConsensusParams(app.processProposalState.ctx, req.ConsensusParams)
app.StoreConsensusParams(app.checkState.ctx, req.ConsensusParams)
}
Expand All @@ -72,7 +69,6 @@ func (app *BaseApp) InitChain(ctx context.Context, req *abci.RequestInitChain) (
}

resp := app.initChainer(app.deliverState.ctx, *req)
app.initChainer(app.prepareProposalState.ctx, *req)
app.initChainer(app.processProposalState.ctx, *req)
res = &resp

Expand Down Expand Up @@ -947,54 +943,6 @@ func splitPath(requestPath string) (path []string) {
}

// ABCI++
func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (resp *abci.ResponsePrepareProposal, err error) {
defer telemetry.MeasureSince(time.Now(), "abci", "prepare_proposal")
if app.ChainID != req.Header.ChainID {
return nil, fmt.Errorf("unexpected ChainID, got %q, want %q", req.Header.ChainID, app.ChainID)
}
if app.prepareProposalState == nil {
app.setPrepareProposalState(*req.Header)
} else {
// In the first block, app.prepareProposalState.ctx will already be initialized
// by InitChain. Context is now updated with Header information.
app.setPrepareProposalHeader(*req.Header)
}

app.preparePrepareProposalState()

defer func() {
if err := recover(); err != nil {
logger.Error(
"panic recovered in PrepareProposal",
"height", req.Header.Height,
"time", req.Header.Time,
"panic", err,
)

resp = &abci.ResponsePrepareProposal{
TxRecords: utils.Map(req.Txs, func(tx []byte) *abci.TxRecord {
return &abci.TxRecord{Action: abci.TxRecord_UNMODIFIED, Tx: tx}
}),
}
}
}()

if app.prepareProposalHandler != nil {
resp, err = app.prepareProposalHandler(app.prepareProposalState.ctx, req)
if err != nil {
return nil, err
}

if cp := app.GetConsensusParams(app.prepareProposalState.ctx); cp != nil {
resp.ConsensusParamUpdates = cp
}

return resp, nil
}

return nil, errors.New("no prepare proposal handler")
}

func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProcessProposal) (resp *abci.ResponseProcessProposal, err error) {
defer telemetry.MeasureSince(time.Now(), "abci", "process_proposal")
if app.ChainID != req.Header.ChainID {
Expand Down
Loading
Loading