Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
67 changes: 65 additions & 2 deletions app/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/sha256"
"time"

"github.com/cosmos/cosmos-sdk/tasks"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -116,7 +117,52 @@ func (app *App) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTxV2, tx sdk.T
defer span.End()
// update context with trace span new context
ctx = ctx.WithTraceSpanContext(spanCtx)
return app.BaseApp.DeliverTx(ctx, req, tx, checksum)
defer telemetry.MeasureSince(time.Now(), "abci", "deliver_tx")

gInfo := sdk.GasInfo{}
resultStr := "successful"

defer func() {
telemetry.IncrCounter(1, "tx", "count")
telemetry.IncrCounter(1, "tx", resultStr)
telemetry.SetGauge(float32(gInfo.GasUsed), "tx", "gas", "used")
telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted")
}()
gInfo, result, anteEvents, resCtx, err := legacyabci.DeliverTx(ctx.WithTxBytes(req.Tx).WithTxSum(checksum).WithVoteInfos(app.UnsafeGetVoteInfos()), tx, app.GetTxConfig(), &app.DeliverTxKeepers, checksum, func(ctx sdk.Context) (sdk.Context, sdk.CacheMultiStore) {
return app.CacheTxContext(ctx, checksum)
}, app.RunMsgs, app.TracingInfo, app.AddCosmosEventsToEVMReceiptIfApplicable)
if err != nil {
resultStr = "failed"
// if we have a result, use those events instead of just the anteEvents
if result != nil {
return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(result.Events, app.IndexEvents), false)
}
return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(anteEvents, app.IndexEvents), false)
}

res := abci.ResponseDeliverTx{
GasWanted: int64(gInfo.GasWanted), //nolint:gosec
GasUsed: int64(gInfo.GasUsed), //nolint:gosec
Log: result.Log,
Data: result.Data,
Events: sdk.MarkEventsToIndex(result.Events, app.IndexEvents),
}
if resCtx.IsEVM() {
res.EvmTxInfo = &abci.EvmTxInfo{
SenderAddress: resCtx.EVMSenderAddress(),
Nonce: resCtx.EVMNonce(),
TxHash: resCtx.EVMTxHash(),
VmError: result.EvmError,
}
// TODO: populate error data for EVM err
if result.EvmError != "" {
evmErr := sdkerrors.Wrap(sdkerrors.ErrEVMVMError, result.EvmError)
res.Codespace, res.Code, res.Log = sdkerrors.ABCIInfo(evmErr, false)
resultStr = "failed"
return res
}
}
return res
}

// DeliverTxBatch is not part of the ABCI specification, but this is here for code convention
Expand All @@ -126,7 +172,24 @@ func (app *App) DeliverTxBatch(ctx sdk.Context, req sdk.DeliverTxBatchRequest) (
defer span.End()
// update context with trace span new context
ctx = ctx.WithTraceSpanContext(spanCtx)
return app.BaseApp.DeliverTxBatch(ctx, req)
responses := make([]*sdk.DeliverTxResult, 0, len(req.TxEntries))

if len(req.TxEntries) == 0 {
return sdk.DeliverTxBatchResponse{Results: responses}
}

// avoid overhead for empty batches
scheduler := tasks.NewScheduler(app.ConcurrencyWorkers(), app.TracingInfo, app.DeliverTx)
txRes, err := scheduler.ProcessAll(ctx, req.TxEntries)
if err != nil {
ctx.Logger().Error("error while processing scheduler", "err", err)
panic(err)
}
for _, tx := range txRes {
responses = append(responses, &sdk.DeliverTxResult{Response: tx})
}

return sdk.DeliverTxBatchResponse{Results: responses}
}

func (app *App) Commit(ctx context.Context) (res *abci.ResponseCommit, err error) {
Expand Down
81 changes: 58 additions & 23 deletions app/ante/cosmos_checktx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ante

import (
"bytes"
"encoding/base64"
"errors"
"fmt"

Expand Down Expand Up @@ -99,11 +100,11 @@ func CosmosCheckTxAnte(
return ctx, err
}

if err := CheckSignatures(ctx, txConfig, tx, signerAccounts, authParams); err != nil {
if _, err := CheckSignatures(ctx, txConfig, tx, signerAccounts, authParams); err != nil {
return ctx, err
}

if err := UpdateSigners(ctx, tx, accountKeeper, ek); err != nil {
if _, err := UpdateSigners(ctx, tx, accountKeeper, ek); err != nil {
return ctx, err
}

Expand Down Expand Up @@ -284,6 +285,18 @@ func CheckAndChargeFees(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.Acc
return priority, fmt.Errorf("fee collector module account (%s) has not been set", authtypes.FeeCollectorName)
}

if _, err := chargeFees(ctx, tx, feeCoins, accountKeeper, bankKeeper, feegrantKeeper); err != nil {
return priority, err
}
return priority, nil
}

func chargeFees(ctx sdk.Context, tx sdk.Tx, feeCoins sdk.Coins, accountKeeper authkeeper.AccountKeeper, bankKeeper bankkeeper.Keeper, feegrantKeeper *feegrantkeeper.Keeper) (sdk.AccAddress, error) {
if addr := accountKeeper.GetModuleAddress(authtypes.FeeCollectorName); addr == nil {
return nil, fmt.Errorf("fee collector module account (%s) has not been set", authtypes.FeeCollectorName)
}

feeTx := tx.(sdk.FeeTx)
feePayer := feeTx.FeePayer()
feeGranter := feeTx.FeeGranter()
deductFeesFrom := feePayer
Expand All @@ -292,11 +305,11 @@ func CheckAndChargeFees(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.Acc
// this works with only when feegrant enabled.
if feeGranter != nil {
if feegrantKeeper == nil {
return priority, sdkerrors.ErrInvalidRequest.Wrap("fee grants are not enabled")
return nil, sdkerrors.ErrInvalidRequest.Wrap("fee grants are not enabled")
} else if !feeGranter.Equals(feePayer) {
err := feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, feeCoins, tx.GetMsgs())
if err != nil {
return priority, sdkerrors.Wrapf(err, "%s does not not allow to pay fees for %s", feeGranter, feePayer)
return nil, sdkerrors.Wrapf(err, "%s does not not allow to pay fees for %s", feeGranter, feePayer)
}
}

Expand All @@ -305,22 +318,22 @@ func CheckAndChargeFees(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.Acc

deductFeesFromAcc := accountKeeper.GetAccount(ctx, deductFeesFrom)
if deductFeesFromAcc == nil {
return priority, sdkerrors.ErrUnknownAddress.Wrapf("fee payer address: %s does not exist", deductFeesFrom)
return nil, sdkerrors.ErrUnknownAddress.Wrapf("fee payer address: %s does not exist", deductFeesFrom)
}

// deduct the fees
if !feeCoins.IsZero() {
if !feeCoins.IsValid() {
return priority, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "invalid fee amount: %s", feeCoins)
return nil, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "invalid fee amount: %s", feeCoins)
}

err := bankKeeper.DeferredSendCoinsFromAccountToModule(ctx, deductFeesFromAcc.GetAddress(), authtypes.FeeCollectorName, feeCoins)
if err != nil {
return priority, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%s", err.Error())
return nil, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%s", err.Error())
}
}

return
return deductFeesFrom, nil
}

func DecoratePriority(ctx sdk.Context, priority int64, oracleVote bool) sdk.Context {
Expand Down Expand Up @@ -376,24 +389,33 @@ func CheckPubKeys(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.AccountKe
return signerAcounts, nil
}

func CheckSignatures(ctx sdk.Context, txConfig client.TxConfig, tx sdk.Tx, signerAccounts []authtypes.AccountI, authParams authtypes.Params) error {
func CheckSignatures(ctx sdk.Context, txConfig client.TxConfig, tx sdk.Tx, signerAccounts []authtypes.AccountI, authParams authtypes.Params) (sdk.Events, error) {
sigTx := tx.(authsigning.SigVerifiableTx)
sigs, err := sigTx.GetSignaturesV2()
if err != nil {
return err
return nil, err
}

// stdSigs contains the sequence number, account number, and signatures.
// When simulating, this would just be a 0-length slice.
signerAddrs := sigTx.GetSigners()
// check that signer length and signature length are the same
if len(sigs) != len(signerAddrs) {
return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs))
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs))
}
var events sdk.Events
for i, sig := range sigs {

if _, err := authante.SignatureDataToBz(sig.Data); err != nil {
return err
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
sdk.NewAttribute(sdk.AttributeKeyAccountSequence, fmt.Sprintf("%s/%d", signerAddrs[i], sig.Sequence)),
))
if sigBzs, err := authante.SignatureDataToBz(sig.Data); err != nil {
return nil, err
} else {
for _, sigBz := range sigBzs {
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
sdk.NewAttribute(sdk.AttributeKeySignature, base64.StdEncoding.EncodeToString(sigBz)),
))
}
}

signerAcc := signerAccounts[i]
Expand All @@ -409,13 +431,13 @@ func CheckSignatures(ctx sdk.Context, txConfig client.TxConfig, tx sdk.Tx, signe

err = authante.DefaultSigVerificationGasConsumer(ctx.GasMeter(), sig, authParams)
if err != nil {
return err
return nil, err
}

// Check account sequence number.
if sig.Sequence != signerAcc.GetSequence() {
if !authParams.GetDisableSeqnoCheck() {
return sdkerrors.Wrapf(
return nil, sdkerrors.Wrapf(
sdkerrors.ErrWrongSequence,
"account sequence mismatch, expected %d, got %d", signerAcc.GetSequence(), sig.Sequence,
)
Expand Down Expand Up @@ -449,53 +471,66 @@ func CheckSignatures(ctx sdk.Context, txConfig client.TxConfig, tx sdk.Tx, signe
} else {
errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d) and chain-id (%s)", accNum, chainID)
}
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, errMsg)
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, errMsg)

}
}
return nil
return events, nil
}

func UpdateSigners(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.AccountKeeper, evmKeeper *evmkeeper.Keeper) error {
func UpdateSigners(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.AccountKeeper, evmKeeper *evmkeeper.Keeper) (sdk.Events, error) {
signers := tx.(authsigning.SigVerifiableTx).GetSigners()
var events sdk.Events
for _, signer := range signers {
acc := accountKeeper.GetAccount(ctx, signer)
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
panic(err)
}

accountKeeper.SetAccount(ctx, acc)
if _, associated := evmKeeper.GetEVMAddress(ctx, signer); associated {
if evmAddr, associated := evmKeeper.GetEVMAddress(ctx, signer); associated {
events = append(events, sdk.NewEvent(evmtypes.EventTypeSigner,
sdk.NewAttribute(evmtypes.AttributeKeyEvmAddress, evmAddr.Hex()),
sdk.NewAttribute(evmtypes.AttributeKeySeiAddress, signer.String())))
continue
}
if acc.GetPubKey() == nil {
ctx.Logger().Error(fmt.Sprintf("missing pubkey for %s", signer.String()))
events = append(events, sdk.NewEvent(evmtypes.EventTypeSigner,
sdk.NewAttribute(evmtypes.AttributeKeySeiAddress, signer.String())))
continue
}
pk, err := btcec.ParsePubKey(acc.GetPubKey().Bytes())
if err != nil {
ctx.Logger().Debug(fmt.Sprintf("failed to parse pubkey for %s, likely due to the fact that it isn't on secp256k1 curve", acc.GetPubKey()), "err", err)
events = append(events, sdk.NewEvent(evmtypes.EventTypeSigner,
sdk.NewAttribute(evmtypes.AttributeKeySeiAddress, signer.String())))
continue
}
evmAddr, err := helpers.PubkeyToEVMAddress(pk.SerializeUncompressed())
if err != nil {
ctx.Logger().Error(fmt.Sprintf("failed to get EVM address from pubkey due to %s", err))
events = append(events, sdk.NewEvent(evmtypes.EventTypeSigner,
sdk.NewAttribute(evmtypes.AttributeKeySeiAddress, signer.String())))
continue
}
events = append(events, sdk.NewEvent(evmtypes.EventTypeSigner,
sdk.NewAttribute(evmtypes.AttributeKeyEvmAddress, evmAddr.Hex()),
sdk.NewAttribute(evmtypes.AttributeKeySeiAddress, signer.String())))
evmKeeper.SetAddressMapping(ctx, signer, evmAddr)
associationHelper := helpers.NewAssociationHelper(evmKeeper, evmKeeper.BankKeeper(), accountKeeper)
if err := associationHelper.MigrateBalance(ctx, evmAddr, signer); err != nil {
ctx.Logger().Error(fmt.Sprintf("failed to migrate EVM address balance (%s) %s", evmAddr.Hex(), err))
return err
return nil, err
}
if evmtypes.IsTxMsgAssociate(tx) {
// check if there is non-zero balance
if !evmKeeper.BankKeeper().GetBalance(ctx, signer, sdk.MustGetBaseDenom()).IsPositive() && !evmKeeper.BankKeeper().GetWeiBalance(ctx, signer).IsPositive() {
return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "account needs to have at least 1 wei to force association")
return nil, sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "account needs to have at least 1 wei to force association")
}
}
}
return nil
return events, nil
}

func CheckMessage(ctx sdk.Context, tx sdk.Tx, ibcKeeper *ibckeeper.Keeper, oracleKeeper oraclekeeper.Keeper) error {
Expand Down
91 changes: 91 additions & 0 deletions app/ante/cosmos_delivertx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package ante

import (
"github.com/cosmos/cosmos-sdk/client"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper"
oraclekeeper "github.com/sei-protocol/sei-chain/x/oracle/keeper"
)

func CosmosDeliverTxAnte(
ctx sdk.Context,
txConfig client.TxConfig,
tx sdk.Tx,
pk paramskeeper.Keeper,
oraclek oraclekeeper.Keeper,
ek *evmkeeper.Keeper,
accountKeeper authkeeper.AccountKeeper,
bankKeeper bankkeeper.Keeper,
feegrantKeeper *feegrantkeeper.Keeper,
) (returnCtx sdk.Context, returnErr error) {
if _, err := CosmosStatelessChecks(tx, ctx.BlockHeight(), ctx.ConsensusParams()); err != nil {
return ctx, err
}

defer func() {
if r := recover(); r != nil {
returnErr = HandleOutofGas(r, tx.(GasTx).GetGas(), ctx.GasMeter().GasConsumed())
}
}()
gasMeter, _, err := GetGasMeter(ctx.WithGasMeter(storetypes.NewNoConsumptionInfiniteGasMeter()), tx, oraclek, ek, pk)
if err != nil {
return ctx, err
}
ctx = ctx.WithGasMeter(gasMeter)

authParams := accountKeeper.GetParams(ctx)

if err := CheckMemoLength(tx, authParams); err != nil {
return ctx, err
}

ctx.GasMeter().ConsumeGas(authParams.TxSizeCostPerByte*sdk.Gas(len(ctx.TxBytes())), "txSize")

signerAccounts, err := CheckPubKeys(ctx, tx, accountKeeper, authParams)
if err != nil {
return ctx, err
}

sigEvents, err := CheckSignatures(ctx, txConfig, tx, signerAccounts, authParams)
if err != nil {
return ctx, err
}
ctx.EventManager().EmitEvents(sigEvents)

signerEvents, err := UpdateSigners(ctx, tx, accountKeeper, ek)
if err != nil {
return ctx, err
}
ctx.EventManager().EmitEvents(signerEvents)

if err := ChargeFees(ctx, tx, accountKeeper, bankKeeper, feegrantKeeper, pk); err != nil {
return ctx, err
}

return ctx, nil
}

func ChargeFees(ctx sdk.Context, tx sdk.Tx, accountKeeper authkeeper.AccountKeeper, bankKeeper bankkeeper.Keeper, feegrantKeeper *feegrantkeeper.Keeper, paramsKeeper paramskeeper.Keeper) error {
feeTx := tx.(sdk.FeeTx)
feeCoins := feeTx.GetFee()
feeParams := paramsKeeper.GetFeesParams(ctx)
feeCoins = feeCoins.NonZeroAmountsOf(append([]string{sdk.DefaultBondDenom}, feeParams.GetAllowedFeeDenoms()...))
deductFeesFrom, err := chargeFees(ctx, tx, feeCoins, accountKeeper, bankKeeper, feegrantKeeper)
if err != nil {
return err
}
events := sdk.Events{
sdk.NewEvent(
sdk.EventTypeTx,
sdk.NewAttribute(sdk.AttributeKeyFee, feeCoins.String()),
sdk.NewAttribute(sdk.AttributeKeyFeePayer, deductFeesFrom.String()),
),
}
ctx.EventManager().EmitEvents(events)
return nil
}
Loading
Loading