Skip to content

Commit

Permalink
[EVM] Allow multiple txs from same account in a block (#397)
Browse files Browse the repository at this point in the history
- needs tendermint pr and go.mod update
- adds evm properties to the `ResponseCheckTxV2`
- adds evm properties to context

- hardhat tests on sei-chain repo
- unit tests on tendermint repo
  • Loading branch information
stevenlanders authored and udpatil committed Feb 28, 2024
1 parent 42ebaad commit 0143731
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 16 deletions.
21 changes: 13 additions & 8 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,22 +225,27 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc
res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace)
return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err
}
gInfo, result, _, priority, pendingTxChecker, expireTxHandler, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx))
gInfo, result, _, priority, pendingTxChecker, expireTxHandler, txCtx, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx))
if err != nil {
res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err
}

res := &abci.ResponseCheckTxV2{ResponseCheckTx: &abci.ResponseCheckTx{
GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints?
Data: result.Data,
Priority: priority,
}}
res := &abci.ResponseCheckTxV2{
ResponseCheckTx: &abci.ResponseCheckTx{
GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints?
Data: result.Data,
Priority: priority,
},
ExpireTxHandler: expireTxHandler,
EVMNonce: txCtx.EVMNonce(),
EVMSenderAddress: txCtx.EVMSenderAddress(),
IsEVM: txCtx.IsEVM(),
}
if pendingTxChecker != nil {
res.IsPendingTransaction = true
res.Checker = pendingTxChecker
}
res.ExpireTxHandler = expireTxHandler

return res, nil
}
Expand Down Expand Up @@ -288,7 +293,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk
telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted")
}()

gInfo, result, anteEvents, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum)
gInfo, result, anteEvents, _, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum)
if err != nil {
resultStr = "failed"
// if we have a result, use those events instead of just the anteEvents
Expand Down
11 changes: 6 additions & 5 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [
priority int64,
pendingTxChecker abci.PendingTxChecker,
expireHandler abci.ExpireTxHandler,
txCtx sdk.Context,
err error,
) {
defer telemetry.MeasureThroughputSinceWithLabels(
Expand Down Expand Up @@ -884,13 +885,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [
}()

if tx == nil {
return sdk.GasInfo{}, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error")
return sdk.GasInfo{}, nil, nil, 0, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error")
}

msgs := tx.GetMsgs()

if err := validateBasicTxMsgs(msgs); err != nil {
return sdk.GasInfo{}, nil, nil, 0, nil, nil, err
return sdk.GasInfo{}, nil, nil, 0, nil, nil, ctx, err
}

if app.anteHandler != nil {
Expand Down Expand Up @@ -935,7 +936,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [
// GasMeter expected to be set in AnteHandler
gasWanted = ctx.GasMeter().Limit()
if err != nil {
return gInfo, nil, nil, 0, nil, nil, err
return gInfo, nil, nil, 0, nil, nil, ctx, err
}

// Dont need to validate in checkTx mode
Expand All @@ -951,7 +952,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [
op.EmitValidationFailMetrics()
}
errMessage := fmt.Sprintf("Invalid Concurrent Execution antehandler missing %d access operations", len(missingAccessOps))
return gInfo, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage)
return gInfo, nil, nil, 0, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage)
}
}

Expand Down Expand Up @@ -986,7 +987,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [
if ctx.CheckTxCallback() != nil {
ctx.CheckTxCallback()(err)
}
return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, err
return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, ctx, err
}

// runMsgs iterates through a list of messages and executes them with the provided
Expand Down
6 changes: 3 additions & 3 deletions baseapp/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk
return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err)
}
ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx))
gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz))
gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz))
if len(ctx.MultiStore().GetEvents()) > 0 {
panic("Expected checkTx events to be empty")
}
Expand All @@ -31,7 +31,7 @@ func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) {
if err != nil {
return sdk.GasInfo{}, nil, err
}
gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes))
gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes))
if len(ctx.MultiStore().GetEvents()) > 0 {
panic("Expected simulate events to be empty")
}
Expand All @@ -49,7 +49,7 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s
if err != nil {
return sdk.GasInfo{}, &sdk.Result{}, err
}
gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz))
gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz))
return gasInfo, result, err
}

Expand Down
32 changes: 32 additions & 0 deletions types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ type Context struct {
txCompletionChannels acltypes.MessageAccessOpsChannelMapping
txMsgAccessOps map[int][]acltypes.AccessOperation

// EVM properties
evm bool // EVM transaction flag
evmNonce uint64 // EVM Transaction nonce
evmSenderAddress string // EVM Sender address

msgValidator *acltypes.MsgValidator
messageIndex int // Used to track current message being processed
txIndex int
Expand Down Expand Up @@ -123,6 +128,18 @@ func (c Context) ExpireTxHandler() abci.ExpireTxHandler {
return c.expireTxHandler
}

func (c Context) EVMSenderAddress() string {
return c.evmSenderAddress
}

func (c Context) EVMNonce() uint64 {
return c.evmNonce
}

func (c Context) IsEVM() bool {
return c.evm
}

func (c Context) PendingTxChecker() abci.PendingTxChecker {
return c.pendingTxChecker
}
Expand Down Expand Up @@ -364,6 +381,21 @@ func (c Context) WithTraceSpanContext(ctx context.Context) Context {
return c
}

func (c Context) WithEVMSenderAddress(address string) Context {
c.evmSenderAddress = address
return c
}

func (c Context) WithEVMNonce(nonce uint64) Context {
c.evmNonce = nonce
return c
}

func (c Context) WithIsEVM(isEVM bool) Context {
c.evm = isEVM
return c
}

func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context {
c.pendingTxChecker = checker
return c
Expand Down

0 comments on commit 0143731

Please sign in to comment.