diff --git a/app/ante_test.go b/app/ante_test.go new file mode 100644 index 0000000000..ab333d0a8c --- /dev/null +++ b/app/ante_test.go @@ -0,0 +1,209 @@ +package app_test + +import ( + "context" + "testing" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + acltypes "github.com/cosmos/cosmos-sdk/x/accesscontrol/types" + + "github.com/cosmos/cosmos-sdk/x/auth/ante" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + aclutils "github.com/sei-protocol/sei-chain/aclmapping/utils" + app "github.com/sei-protocol/sei-chain/app" + "github.com/sei-protocol/sei-chain/app/apptesting" + "github.com/sei-protocol/sei-chain/utils/tracing" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "go.opentelemetry.io/otel" +) + +// AnteTestSuite is a test suite to be used with ante handler tests. +type AnteTestSuite struct { + apptesting.KeeperTestHelper + + anteHandler sdk.AnteHandler + anteDepGenerator sdk.AnteDepGenerator + clientCtx client.Context + txBuilder client.TxBuilder + testAcc sdk.AccAddress + testAccPriv cryptotypes.PrivKey +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(AnteTestSuite)) +} + +// SetupTest setups a new test, with new app, context, and anteHandler. +func (suite *AnteTestSuite) SetupTest(isCheckTx bool) { + suite.Setup() + + // keys and addresses + suite.testAccPriv, _, suite.testAcc = testdata.KeyTestPubAddr() + initalBalance := sdk.Coins{sdk.NewInt64Coin("atom", 100000000000)} + suite.FundAcc(suite.testAcc, initalBalance) + + suite.Ctx = suite.Ctx.WithBlockHeight(1) + + msgValidator := sdkacltypes.NewMsgValidator(aclutils.StoreKeyToResourceTypePrefixMap) + suite.Ctx = suite.Ctx.WithMsgValidator(msgValidator) + + // Set up TxConfig. + encodingConfig := simapp.MakeTestEncodingConfig() + // We're using TestMsg encoding in some tests, so register it here. + encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) + testdata.RegisterInterfaces(encodingConfig.InterfaceRegistry) + + suite.clientCtx = client.Context{}. + WithTxConfig(encodingConfig.TxConfig) + + wasmConfig := wasmtypes.DefaultWasmConfig() + defaultTracer, _ := tracing.DefaultTracerProvider() + otel.SetTracerProvider(defaultTracer) + tr := defaultTracer.Tracer("component-main") + + antehandler, anteDepGenerator, err := app.NewAnteHandlerAndDepGenerator( + app.HandlerOptions{ + HandlerOptions: ante.HandlerOptions{ + AccountKeeper: suite.App.AccountKeeper, + BankKeeper: suite.App.BankKeeper, + FeegrantKeeper: suite.App.FeeGrantKeeper, + SignModeHandler: suite.clientCtx.TxConfig.SignModeHandler(), + SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + // BatchVerifier: app.batchVerifier, + }, + IBCKeeper: suite.App.IBCKeeper, + WasmConfig: &wasmConfig, + OracleKeeper: &suite.App.OracleKeeper, + DexKeeper: &suite.App.DexKeeper, + AccessControlKeeper: &suite.App.AccessControlKeeper, + TracingInfo: &tracing.Info{ + Tracer: &tr, + TracerContext: context.Background(), + }, + }, + ) + + suite.Require().NoError(err) + suite.anteHandler = antehandler + suite.anteDepGenerator = anteDepGenerator +} + +func (suite *AnteTestSuite) AnteHandlerValidateAccessOp(acessOps []sdkacltypes.AccessOperation) error { + for _, accessOp := range acessOps { + err := acltypes.ValidateAccessOp(accessOp) + if err != nil { + return err + } + } + return nil +} + +// CreateTestTx is a helper function to create a tx given multiple inputs. +func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []uint64, accSeqs []uint64, chainID string) (xauthsigning.Tx, error) { + // First round: we gather all the signer infos. We use the "set empty + // signature" hack to do that. + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + err := suite.txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + // Second round: all signer infos are set, so each signer can sign. + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + } + sigV2, err := tx.SignWithPrivKey( + suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, + suite.txBuilder, priv, suite.clientCtx.TxConfig, accSeqs[i]) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + err = suite.txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + return suite.txBuilder.GetTx(), nil +} + + +func (suite *AnteTestSuite) TestValidateDepedencies() { + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + // msg and signatures + msg := testdata.NewTestMsg(suite.testAcc) + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{}, []uint64{}, []uint64{} + invalidTx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.Ctx.ChainID()) + suite.Require().NoError(err) + + _, err = suite.anteHandler(suite.Ctx, invalidTx, false) + + suite.Require().NotNil(err, "Did not error on invalid tx") + + privs, accNums, accSeqs = []cryptotypes.PrivKey{suite.testAccPriv}, []uint64{8}, []uint64{0} + + handlerCtx, cms := aclutils.CacheTxContext(suite.Ctx) + validTx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.Ctx.ChainID()) + + suite.Require().NoError(err) + depdenencies, _ := suite.anteDepGenerator([]sdkacltypes.AccessOperation{}, validTx) + _, err = suite.anteHandler(handlerCtx, validTx, false) + suite.Require().Nil(err, "ValidateBasicDecorator returned error on valid tx. err: %v", err) + err = suite.AnteHandlerValidateAccessOp(depdenencies) + + require.NoError(suite.T(), err) + + missing := handlerCtx.MsgValidator().ValidateAccessOperations(depdenencies, cms.GetEvents()) + suite.Require().Empty(missing) + + // test decorator skips on recheck + suite.Ctx = suite.Ctx.WithIsReCheckTx(true) + + // decorator should skip processing invalidTx on recheck and thus return nil-error + handlerCtx, cms = aclutils.CacheTxContext(suite.Ctx) + depdenencies, _ = suite.anteDepGenerator([]sdkacltypes.AccessOperation{}, invalidTx) + _, err = suite.anteHandler(handlerCtx, invalidTx, false) + missing = handlerCtx.MsgValidator().ValidateAccessOperations(depdenencies, cms.GetEvents()) + + err = suite.AnteHandlerValidateAccessOp(depdenencies) + require.NoError(suite.T(), err) + + suite.Require().Empty(missing) + + suite.Require().Nil(err, "ValidateBasicDecorator ran on ReCheck") +} diff --git a/app/antedecorators/depdecorators/signers.go b/app/antedecorators/depdecorators/signers.go index f123e8dca5..9d8043c3b8 100644 --- a/app/antedecorators/depdecorators/signers.go +++ b/app/antedecorators/depdecorators/signers.go @@ -6,7 +6,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - utils "github.com/sei-protocol/sei-chain/aclmapping/utils" ) type SignerDepDecorator struct { @@ -27,8 +26,8 @@ func (d SignerDepDecorator) AnteDeps(txDeps []sdkacltypes.AccessOperation, tx sd for _, signer := range sigTx.GetSigners() { txDeps = append(txDeps, sdkacltypes.AccessOperation{ AccessType: accessType, - ResourceType: sdkacltypes.ResourceType_KV, - IdentifierTemplate: utils.GetPrefixedIdentifierTemplatePerModule(utils.ACCOUNT, signer.String(), string(authtypes.AddressStoreKeyPrefix)), + ResourceType: sdkacltypes.ResourceType_KV_AUTH_ADDRESS_STORE, + IdentifierTemplate: string(authtypes.AddressStoreKey(signer)), }) } return next(txDeps, tx) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 860d6192c3..01c71943d3 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -143,7 +143,8 @@ func (s *KeeperTestHelper) BuildTx( txBuilder client.TxBuilder, msgs []sdk.Msg, sigV2 signing.SignatureV2, - memo string, txFee sdk.Coins, + memo string, + txFee sdk.Coins, gasLimit uint64, ) authsigning.Tx { err := txBuilder.SetMsgs(msgs[0]) diff --git a/go.mod b/go.mod index 6e14e14b52..0f489b49c9 100644 --- a/go.mod +++ b/go.mod @@ -132,7 +132,7 @@ require ( ) replace ( - github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.1.246 + github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.1.249 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.1.59 diff --git a/go.sum b/go.sum index 4774c572f6..777d3e8398 100644 --- a/go.sum +++ b/go.sum @@ -1100,8 +1100,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/securego/gosec/v2 v2.11.0/go.mod h1:SX8bptShuG8reGC0XS09+a4H2BoWSJi+fscA+Pulbpo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sei-protocol/sei-cosmos v0.1.246 h1:qX6ycebWYECnh9DIP9xqCFHVgJ8U4yHuR+asr/vuOVE= -github.com/sei-protocol/sei-cosmos v0.1.246/go.mod h1:KPV8lFdD2Ki/M2wZTpfX3LCcuMAZnmcUzYJycjbmOYM= +github.com/sei-protocol/sei-cosmos v0.1.249 h1:beHuyOOGxDewo1G7l067OPO56BKyfVi1boDiuS8jNfw= +github.com/sei-protocol/sei-cosmos v0.1.249/go.mod h1:KPV8lFdD2Ki/M2wZTpfX3LCcuMAZnmcUzYJycjbmOYM= github.com/sei-protocol/sei-tendermint v0.1.59 h1:POGL60PumMQHF4EzAHzvkGfDnodQJLHpl65LuiwSO/Y= github.com/sei-protocol/sei-tendermint v0.1.59/go.mod h1:Olwbjyagrpoxj5DAUhHxMTWDVEfQ3FYdpypaJ3+6Hs8= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=