From 7e391959b9aebf055294b24b7f392346709dae64 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 5 Feb 2025 14:47:08 +0100 Subject: [PATCH] test: migrate last few integration tests to integration/v2 (#23359) Co-authored-by: Alex | Interchain Labs --- client/v2/go.mod | 2 +- client/v2/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- server/v2/cometbft/go.mod | 2 +- server/v2/cometbft/go.sum | 4 +- simapp/v2/go.mod | 2 +- simapp/v2/go.sum | 4 +- systemtests/CHANGELOG.md | 4 + systemtests/cli.go | 8 + tests/go.mod | 4 +- .../integration/auth/client/cli/suite_test.go | 1306 ----------------- tests/integration/baseapp/block_gas_test.go | 261 ---- tests/integration/baseapp/utils.go | 67 - tests/integration/genutil/cmt_abci.go | 69 - tests/integration/genutil/genaccount_test.go | 298 ---- tests/integration/genutil/init_test.go | 427 ------ tests/integration/v2/auth/app_test.go | 71 +- tests/integration/v2/auth/client_test.go | 1089 ++++++++++++++ tests/systemtests/go.mod | 11 +- tests/systemtests/go.sum | 6 +- tests/systemtests/init_test.go | 67 + tests/{integration => }/type_check.go | 2 +- testutil/x/genutil/helper.go | 74 - tools/benchmark/go.mod | 2 +- tools/benchmark/go.sum | 4 +- x/accounts/defaults/base/go.mod | 2 +- x/accounts/defaults/base/go.sum | 4 +- x/accounts/defaults/lockup/go.mod | 2 +- x/accounts/defaults/lockup/go.sum | 4 +- x/accounts/defaults/multisig/go.mod | 2 +- x/accounts/defaults/multisig/go.sum | 4 +- x/accounts/go.mod | 2 +- x/accounts/go.sum | 4 +- x/authz/go.mod | 2 +- x/authz/go.sum | 4 +- x/bank/go.mod | 2 +- x/bank/go.sum | 4 +- x/circuit/go.mod | 2 +- x/circuit/go.sum | 4 +- x/consensus/go.mod | 2 +- x/consensus/go.sum | 4 +- x/distribution/go.mod | 2 +- x/distribution/go.sum | 4 +- x/epochs/go.mod | 2 +- x/epochs/go.sum | 4 +- x/evidence/go.mod | 2 +- x/evidence/go.sum | 4 +- x/feegrant/go.mod | 2 +- x/feegrant/go.sum | 4 +- x/genutil/genaccounts.go | 67 +- x/genutil/genaccounts_test.go | 177 +++ x/gov/go.mod | 2 +- x/gov/go.sum | 4 +- x/group/go.mod | 2 +- x/group/go.sum | 4 +- x/mint/go.mod | 2 +- x/mint/go.sum | 4 +- x/nft/go.mod | 2 +- x/nft/go.sum | 4 +- x/protocolpool/go.mod | 2 +- x/protocolpool/go.sum | 4 +- x/slashing/go.mod | 2 +- x/slashing/go.sum | 4 +- x/staking/go.mod | 2 +- x/staking/go.sum | 4 +- x/upgrade/go.mod | 2 +- x/upgrade/go.sum | 4 +- 68 files changed, 1545 insertions(+), 2613 deletions(-) delete mode 100644 tests/integration/auth/client/cli/suite_test.go delete mode 100644 tests/integration/baseapp/block_gas_test.go delete mode 100644 tests/integration/baseapp/utils.go delete mode 100644 tests/integration/genutil/cmt_abci.go delete mode 100644 tests/integration/genutil/genaccount_test.go delete mode 100644 tests/integration/genutil/init_test.go create mode 100644 tests/integration/v2/auth/client_test.go create mode 100644 tests/systemtests/init_test.go rename tests/{integration => }/type_check.go (94%) delete mode 100644 testutil/x/genutil/helper.go create mode 100644 x/genutil/genaccounts_test.go diff --git a/client/v2/go.mod b/client/v2/go.mod index 84c95f8ba2..b0347c737e 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -35,7 +35,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/collections v1.1.0 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 // indirect cosmossdk.io/math v1.5.0 diff --git a/client/v2/go.sum b/client/v2/go.sum index b1844b1cda..cef31c7aa4 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/go.mod b/go.mod index 1b14fc5e03..69c539d408 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 diff --git a/go.sum b/go.sum index e0667e18dd..784a33cd93 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/server/v2/cometbft/go.mod b/server/v2/cometbft/go.mod index 7d6a9d7ffa..827d134e44 100644 --- a/server/v2/cometbft/go.mod +++ b/server/v2/cometbft/go.mod @@ -41,7 +41,7 @@ require ( require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/depinject v1.1.0 // indirect cosmossdk.io/math v1.5.0 // indirect cosmossdk.io/store v1.10.0-rc.1 // indirect diff --git a/server/v2/cometbft/go.sum b/server/v2/cometbft/go.sum index 435c3aea79..04c3d612ec 100644 --- a/server/v2/cometbft/go.sum +++ b/server/v2/cometbft/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 8bfdf237da..f6840d2cf4 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -63,7 +63,7 @@ require ( cloud.google.com/go/iam v1.3.1 // indirect cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/collections v1.1.0 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/errors/v2 v2.0.0 // indirect cosmossdk.io/server/v2/stf v1.0.0-beta.2 // indirect diff --git a/simapp/v2/go.sum b/simapp/v2/go.sum index 2260e27da7..2ae52afda3 100644 --- a/simapp/v2/go.sum +++ b/simapp/v2/go.sum @@ -616,8 +616,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/systemtests/CHANGELOG.md b/systemtests/CHANGELOG.md index 736ef5c248..9054829bc4 100644 --- a/systemtests/CHANGELOG.md +++ b/systemtests/CHANGELOG.md @@ -36,6 +36,10 @@ Ref: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.j ## [Unreleased] +## [v1.1.0] - 2025-01-05 + +* [#23359](https://github.com/cosmos/cosmos-sdk/pull/23359) Add `RunCommandWithInputAndArgs` on CLIWrapper. + ## [v1.0.0] - 2024-12-19 * [#22849](https://github.com/cosmos/cosmos-sdk/pull/22849) Avoid telemetry server conflicts on port 7180 diff --git a/systemtests/cli.go b/systemtests/cli.go index 6f23e2553e..5b564d8b5e 100644 --- a/systemtests/cli.go +++ b/systemtests/cli.go @@ -191,6 +191,14 @@ func (c CLIWrapper) RunCommandWithArgs(args ...string) string { return execOutput } +// RunCommandWithInputAndArgs use for run cli command, not tx +// Takes input as io.Reader for the command +func (c CLIWrapper) RunCommandWithInputAndArgs(input io.Reader, args ...string) string { + c.t.Helper() + execOutput, _ := c.runWithInput(args, input) + return execOutput +} + // AwaitTxCommitted wait for tx committed on chain // returns the server execution result and true when found within 3 blocks. func (c CLIWrapper) AwaitTxCommitted(submitResp string, timeout ...time.Duration) (string, bool) { diff --git a/tests/go.mod b/tests/go.mod index 61ca864a62..6be7b679e9 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/log v1.5.0 cosmossdk.io/math v1.5.0 @@ -33,7 +33,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.6.0 github.com/google/gofuzz v1.2.0 - github.com/spf13/viper v1.19.0 + github.com/spf13/viper v1.19.0 // indirect gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b ) diff --git a/tests/integration/auth/client/cli/suite_test.go b/tests/integration/auth/client/cli/suite_test.go deleted file mode 100644 index 8ba0ec7fdb..0000000000 --- a/tests/integration/auth/client/cli/suite_test.go +++ /dev/null @@ -1,1306 +0,0 @@ -package cli_test - -import ( - "context" - "fmt" - "io" - "strings" - "testing" - - abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" - rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/core/address" - "cosmossdk.io/math" - "cosmossdk.io/x/bank" - banktypes "cosmossdk.io/x/bank/types" - "cosmossdk.io/x/gov" - govtestutil "cosmossdk.io/x/gov/client/testutil" - govtypes "cosmossdk.io/x/gov/types/v1beta1" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - addresscodec "github.com/cosmos/cosmos-sdk/codec/address" - codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" - "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/x/auth" - authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" - authtestutil "github.com/cosmos/cosmos-sdk/x/auth/client/testutil" - "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" -) - -type CLITestSuite struct { - suite.Suite - - kr keyring.Keyring - encCfg testutilmod.TestEncodingConfig - baseCtx client.Context - clientCtx client.Context - val sdk.AccAddress - val1 sdk.AccAddress - - ac address.Codec -} - -func TestCLITestSuite(t *testing.T) { - suite.Run(t, new(CLITestSuite)) -} - -func (s *CLITestSuite) SetupSuite() { - s.encCfg = testutilmod.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, bank.AppModule{}, gov.AppModule{}) - s.kr = keyring.NewInMemory(s.encCfg.Codec) - s.baseCtx = client.Context{}. - WithKeyring(s.kr). - WithTxConfig(s.encCfg.TxConfig). - WithCodec(s.encCfg.Codec). - WithClient(clitestutil.MockCometRPC{Client: rpcclientmock.Client{}}). - WithAccountRetriever(client.MockAccountRetriever{}). - WithOutput(io.Discard). - WithChainID("test-chain"). - WithAddressCodec(addresscodec.NewBech32Codec("cosmos")). - WithValidatorAddressCodec(addresscodec.NewBech32Codec("cosmosvaloper")). - WithConsensusAddressCodec(addresscodec.NewBech32Codec("cosmosvalcons")) - - ctxGen := func() client.Context { - bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{}) - c := clitestutil.NewMockCometRPC(abci.QueryResponse{ - Value: bz, - }) - return s.baseCtx.WithClient(c) - } - s.clientCtx = ctxGen() - - kb := s.clientCtx.Keyring - valAcc, _, err := kb.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - s.val, err = valAcc.GetAddress() - s.Require().NoError(err) - pub, err := valAcc.GetPubKey() - s.Require().NoError(err) - - account1, _, err := kb.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - s.val1, err = account1.GetAddress() - s.Require().NoError(err) - - account2, _, err := kb.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - pub1, err := account1.GetPubKey() - s.Require().NoError(err) - pub2, err := account2.GetPubKey() - s.Require().NoError(err) - - // Create a dummy account for testing purpose - _, _, err = kb.NewMnemonic("dummyAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - // create a 2-3 multisig - multi := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{pub, pub1, pub2}) - _, err = kb.SaveMultisig("multi", multi) - s.Require().NoError(err) - - s.ac = addresscodec.NewBech32Codec("cosmos") -} - -func (s *CLITestSuite) TestCLIValidateSignatures() { - sendTokens := sdk.NewCoins( - sdk.NewCoin("testtoken", math.NewInt(10)), - sdk.NewCoin("stake", math.NewInt(10))) - - res, err := s.createBankMsg(s.clientCtx, s.val, sendTokens, - clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - // write unsigned tx to file - unsignedTx := testutil.WriteToNewTempFile(s.T(), res.String()) - defer unsignedTx.Close() - - res, err = authtestutil.TxSignExec(s.clientCtx, s.val, unsignedTx.Name()) - s.Require().NoError(err) - signedTx, err := s.clientCtx.TxConfig.TxJSONDecoder()(res.Bytes()) - s.Require().NoError(err) - - signedTxFile := testutil.WriteToNewTempFile(s.T(), res.String()) - defer signedTxFile.Close() - txBuilder, err := s.clientCtx.TxConfig.WrapTxBuilder(signedTx) - s.Require().NoError(err) - _, err = authtestutil.TxValidateSignaturesExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) - - txBuilder.SetMemo("MODIFIED TX") - bz, err := s.clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - modifiedTxFile := testutil.WriteToNewTempFile(s.T(), string(bz)) - defer modifiedTxFile.Close() - - _, err = authtestutil.TxValidateSignaturesExec(s.clientCtx, modifiedTxFile.Name()) - s.Require().EqualError(err, "signatures validation failed") -} - -func (s *CLITestSuite) TestCLISignBatch() { - sendTokens := sdk.NewCoins( - sdk.NewCoin("testtoken", math.NewInt(10)), - sdk.NewCoin("stake", math.NewInt(10)), - ) - - generatedStd, err := s.createBankMsg(s.clientCtx, s.val, - sendTokens, clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - outputFile := testutil.WriteToNewTempFile(s.T(), strings.Repeat(generatedStd.String(), 3)) - defer outputFile.Close() - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - - // sign-batch file - offline is set but account-number and sequence are not - _, err = authtestutil.TxSignBatchExec(s.clientCtx, s.val, outputFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, s.clientCtx.ChainID), "--offline") - s.Require().EqualError(err, "required flag(s) \"account-number\", \"sequence\" not set") - - // sign-batch file - offline and sequence is set but account-number is not set - _, err = authtestutil.TxSignBatchExec(s.clientCtx, s.val, outputFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, s.clientCtx.ChainID), fmt.Sprintf("--%s=%s", flags.FlagSequence, "1"), "--offline") - s.Require().EqualError(err, "required flag(s) \"account-number\" not set") - - // sign-batch file - offline and account-number is set but sequence is not set - _, err = authtestutil.TxSignBatchExec(s.clientCtx, s.val, outputFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, s.clientCtx.ChainID), fmt.Sprintf("--%s=%s", flags.FlagAccountNumber, "1"), "--offline") - s.Require().EqualError(err, "required flag(s) \"sequence\" not set") -} - -func (s *CLITestSuite) TestCLISignBatchTotalFees() { - txCfg := s.clientCtx.TxConfig - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - - testCases := []struct { - name string - args []string - numTransactions int - denom string - }{ - { - "Offline batch-sign one transaction", - []string{"--offline", "--account-number", "1", "--sequence", "1", "--append"}, - 1, - "stake", - }, - { - "Offline batch-sign two transactions", - []string{"--offline", "--account-number", "1", "--sequence", "1", "--append"}, - 2, - "stake", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - // Create multiple transactions and write them to separate files - sendTokens := sdk.NewCoin(tc.denom, sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)) - expectedBatchedTotalFee := int64(0) - txFiles := make([]string, tc.numTransactions) - for i := 0; i < tc.numTransactions; i++ { - tx, err := s.createBankMsg(s.clientCtx, s.val, - sdk.NewCoins(sendTokens), clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - txFile := testutil.WriteToNewTempFile(s.T(), tx.String()+"\n") - txFiles[i] = txFile.Name() - - unsignedTx, err := txCfg.TxJSONDecoder()(tx.Bytes()) - s.Require().NoError(err) - txBuilder, err := txCfg.WrapTxBuilder(unsignedTx) - s.Require().NoError(err) - expectedBatchedTotalFee += txBuilder.GetTx().GetFee().AmountOf(tc.denom).Int64() - err = txFile.Close() - s.NoError(err) - } - - // Test batch sign - batchSignArgs := append([]string{fmt.Sprintf("--from=%s", s.val.String())}, append(txFiles, tc.args...)...) - signedTx, err := clitestutil.ExecTestCLICmd(s.clientCtx, authcli.GetSignBatchCommand(), batchSignArgs) - s.Require().NoError(err) - signedFinalTx, err := txCfg.TxJSONDecoder()(signedTx.Bytes()) - s.Require().NoError(err) - txBuilder, err := txCfg.WrapTxBuilder(signedFinalTx) - s.Require().NoError(err) - finalTotalFee := txBuilder.GetTx().GetFee() - s.Require().Equal(expectedBatchedTotalFee, finalTotalFee.AmountOf(tc.denom).Int64()) - }) - } -} - -func (s *CLITestSuite) TestCLIQueryTxCmdByHash() { - sendTokens := sdk.NewInt64Coin("stake", 10) - - // Send coins. - out, err := s.createBankMsg( - s.clientCtx, s.val, - sdk.NewCoins(sendTokens), - clitestutil.TestTxConfig{}, - ) - s.Require().NoError(err) - - var txRes sdk.TxResponse - s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txRes)) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - "not enough args", - []string{}, - "", - }, - { - "with invalid hash", - []string{"somethinginvalid", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - `[somethinginvalid --output=json]`, - }, - { - "with valid and not existing hash", - []string{"C7E7D3A86A17AB3A321172239F3B61357937AF0F25D9FA4D2F4DCCAD9B0D7747", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - `[C7E7D3A86A17AB3A321172239F3B61357937AF0F25D9FA4D2F4DCCAD9B0D7747 --output=json`, - }, - { - "happy case", - []string{txRes.TxHash, fmt.Sprintf("--%s=json", flags.FlagOutput)}, - fmt.Sprintf("%s --%s=json", txRes.TxHash, flags.FlagOutput), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := authcli.QueryTxCmd() - cmd.SetArgs(tc.args) - - if len(tc.args) != 0 { - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - } - }) - } -} - -func (s *CLITestSuite) TestCLIQueryTxCmdByEvents() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - "invalid --type", - []string{ - fmt.Sprintf("--type=%s", "foo"), - "bar", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "--type=foo bar --output=json", - }, - { - "--type=acc_seq with no addr+seq", - []string{ - "--type=acc_seq", - "", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "--type=acc_seq --output=json", - }, - { - "non-existing addr+seq combo", - []string{ - "--type=acc_seq", - "foobar", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "--type=acc_seq foobar --output=json", - }, - { - "--type=signature with no signature", - []string{ - "--type=signature", - "", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "--type=signature --output=json", - }, - { - "non-existing signatures", - []string{ - "--type=signature", - "foo", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "--type=signature foo --output=json", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := authcli.QueryTxCmd() - cmd.SetArgs(tc.args) - - if len(tc.args) != 0 { - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - } - }) - } -} - -func (s *CLITestSuite) TestCLIQueryTxsCmdByEvents() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - "fee event happy case", - []string{ - fmt.Sprintf( - "--query=tx.fee='%s'", - sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String(), - ), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "", - }, - { - "no matching fee event", - []string{ - fmt.Sprintf( - "--query=tx.fee='%s'", - sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(0))).String(), - ), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := authcli.QueryTxsByEventsCmd() - - if len(tc.args) != 0 { - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - } - }) - } -} - -func (s *CLITestSuite) TestCLISendGenerateSignAndBroadcast() { - sendTokens := sdk.NewCoin("stake", sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)) - - normalGeneratedTx, err := s.createBankMsg(s.clientCtx, s.val, - sdk.NewCoins(sendTokens), clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - txCfg := s.clientCtx.TxConfig - - normalGeneratedStdTx, err := txCfg.TxJSONDecoder()(normalGeneratedTx.Bytes()) - s.Require().NoError(err) - txBuilder, err := txCfg.WrapTxBuilder(normalGeneratedStdTx) - s.Require().NoError(err) - s.Require().Equal(txBuilder.GetTx().GetGas(), uint64(flags.DefaultGasLimit)) - s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1) - sigs, err := txBuilder.GetTx().GetSignaturesV2() - s.Require().NoError(err) - s.Require().Equal(0, len(sigs)) - - // Test generate sendTx with --gas=$amount - limitedGasGeneratedTx, err := s.createBankMsg(s.clientCtx, s.val, - sdk.NewCoins(sendTokens), - clitestutil.TestTxConfig{GenOnly: true, Gas: 100}, - ) - s.Require().NoError(err) - - limitedGasStdTx, err := txCfg.TxJSONDecoder()(limitedGasGeneratedTx.Bytes()) - s.Require().NoError(err) - txBuilder, err = txCfg.WrapTxBuilder(limitedGasStdTx) - s.Require().NoError(err) - s.Require().Equal(txBuilder.GetTx().GetGas(), uint64(100)) - s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1) - sigs, err = txBuilder.GetTx().GetSignaturesV2() - s.Require().NoError(err) - s.Require().Equal(0, len(sigs)) - - // Test generate sendTx, estimate gas - finalGeneratedTx, err := s.createBankMsg(s.clientCtx, s.val, - sdk.NewCoins(sendTokens), clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - finalStdTx, err := txCfg.TxJSONDecoder()(finalGeneratedTx.Bytes()) - s.Require().NoError(err) - txBuilder, err = txCfg.WrapTxBuilder(finalStdTx) - s.Require().NoError(err) - s.Require().Equal(uint64(flags.DefaultGasLimit), txBuilder.GetTx().GetGas()) - s.Require().Equal(len(finalStdTx.GetMsgs()), 1) - - // Write the output to disk - unsignedTxFile := testutil.WriteToNewTempFile(s.T(), finalGeneratedTx.String()) - defer unsignedTxFile.Close() - - // Test validate-signatures - res, err := authtestutil.TxValidateSignaturesExec(s.clientCtx, unsignedTxFile.Name()) - s.Require().EqualError(err, "signatures validation failed") - s.Require().Contains(res.String(), fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", s.val.String())) - - // Test sign - - // Does not work in offline mode - _, err = authtestutil.TxSignExec(s.clientCtx, s.val, unsignedTxFile.Name(), "--offline") - s.Require().EqualError(err, "required flag(s) \"account-number\", \"sequence\" not set") - - // But works offline if we set account number and sequence - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - _, err = authtestutil.TxSignExec(s.clientCtx, s.val, unsignedTxFile.Name(), "--offline", "--account-number", "1", "--sequence", "1") - s.Require().NoError(err) - - // Sign transaction - signedTx, err := authtestutil.TxSignExec(s.clientCtx, s.val, unsignedTxFile.Name()) - s.Require().NoError(err) - signedFinalTx, err := txCfg.TxJSONDecoder()(signedTx.Bytes()) - s.Require().NoError(err) - txBuilder, err = s.clientCtx.TxConfig.WrapTxBuilder(signedFinalTx) - s.Require().NoError(err) - s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1) - sigs, err = txBuilder.GetTx().GetSignaturesV2() - s.Require().NoError(err) - s.Require().Equal(1, len(sigs)) - signers, err := txBuilder.GetTx().GetSigners() - s.Require().NoError(err) - s.Require().Equal([]byte(s.val), signers[0]) - - // Write the output to disk - signedTxFile := testutil.WriteToNewTempFile(s.T(), signedTx.String()) - defer signedTxFile.Close() - - // validate Signature - res, err = authtestutil.TxValidateSignaturesExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) - s.Require().True(strings.Contains(res.String(), "[OK]")) - - // Test broadcast - - // Does not work in offline mode - _, err = authtestutil.TxBroadcastExec(s.clientCtx, signedTxFile.Name(), "--offline") - s.Require().EqualError(err, "cannot broadcast tx during offline mode") - - // Broadcast correct transaction. - s.clientCtx.BroadcastMode = flags.BroadcastSync - _, err = authtestutil.TxBroadcastExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) -} - -func (s *CLITestSuite) TestCLIMultisignInsufficientCosigners() { - // Fetch account and a multisig info - account1, err := s.clientCtx.Keyring.Key("newAccount1") - s.Require().NoError(err) - - multisigRecord, err := s.clientCtx.Keyring.Key("multi") - s.Require().NoError(err) - - addr, err := multisigRecord.GetAddress() - s.Require().NoError(err) - // Send coins from validator to multisig. - _, err = s.createBankMsg( - s.clientCtx, - addr, - sdk.NewCoins( - sdk.NewInt64Coin("stake", 10), - ), - clitestutil.TestTxConfig{}, - ) - s.Require().NoError(err) - - msgSend := &banktypes.MsgSend{ - FromAddress: addr.String(), - ToAddress: s.val.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), - } - - multiGeneratedTx, err := clitestutil.SubmitTestTx( - s.clientCtx, - msgSend, - addr, - clitestutil.TestTxConfig{ - GenOnly: true, - }) - s.Require().NoError(err) - - // Save tx to file - multiGeneratedTxFile := testutil.WriteToNewTempFile(s.T(), multiGeneratedTx.String()) - defer multiGeneratedTxFile.Close() - - // Multisign, sign with one signature - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - addr1, err := account1.GetAddress() - s.Require().NoError(err) - account1Signature, err := authtestutil.TxSignExec(s.clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - - sign1File := testutil.WriteToNewTempFile(s.T(), account1Signature.String()) - defer sign1File.Close() - - multiSigWith1Signature, err := authtestutil.TxMultiSignExec(s.clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name()) - s.Require().NoError(err) - - // Save tx to file - multiSigWith1SignatureFile := testutil.WriteToNewTempFile(s.T(), multiSigWith1Signature.String()) - defer multiSigWith1SignatureFile.Close() - - _, err = authtestutil.TxValidateSignaturesExec(s.clientCtx, multiSigWith1SignatureFile.Name()) - s.Require().Error(err) -} - -func (s *CLITestSuite) TestCLIEncode() { - sendTokens := sdk.NewCoin("stake", sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)) - - normalGeneratedTx, err := s.createBankMsg( - s.clientCtx, s.val, - sdk.NewCoins(sendTokens), - clitestutil.TestTxConfig{ - GenOnly: true, - Memo: "deadbeef", - }, - ) - s.Require().NoError(err) - savedTxFile := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String()) - defer savedTxFile.Close() - - // Encode - encodeExec, err := authtestutil.TxEncodeExec(s.clientCtx, savedTxFile.Name()) - s.Require().NoError(err) - trimmedBase64 := strings.Trim(encodeExec.String(), "\"\n") - - // Check that the transaction decodes as expected - decodedTx, err := authtestutil.TxDecodeExec(s.clientCtx, trimmedBase64) - s.Require().NoError(err) - - txCfg := s.clientCtx.TxConfig - theTx, err := txCfg.TxJSONDecoder()(decodedTx.Bytes()) - s.Require().NoError(err) - txBuilder, err := s.clientCtx.TxConfig.WrapTxBuilder(theTx) - s.Require().NoError(err) - s.Require().Equal("deadbeef", txBuilder.GetTx().GetMemo()) -} - -func (s *CLITestSuite) TestCLIMultisignSortSignatures() { - // Generate 2 accounts and a multisig. - account1, err := s.clientCtx.Keyring.Key("newAccount1") - s.Require().NoError(err) - - account2, err := s.clientCtx.Keyring.Key("newAccount2") - s.Require().NoError(err) - - multisigRecord, err := s.clientCtx.Keyring.Key("multi") - s.Require().NoError(err) - - // Generate dummy account which is not a part of multisig. - dummyAcc, err := s.clientCtx.Keyring.Key("dummyAccount") - s.Require().NoError(err) - - addr, err := multisigRecord.GetAddress() - s.Require().NoError(err) - - msgSend := &banktypes.MsgSend{ - FromAddress: addr.String(), - ToAddress: s.val.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), - } - - // Generate multisig transaction. - multiGeneratedTx, err := clitestutil.SubmitTestTx(s.clientCtx, msgSend, addr, clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - // Save tx to file - multiGeneratedTxFile := testutil.WriteToNewTempFile(s.T(), multiGeneratedTx.String()) - defer multiGeneratedTxFile.Close() - - // Sign with account1 - addr1, err := account1.GetAddress() - s.Require().NoError(err) - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - account1Signature, err := authtestutil.TxSignExec(s.clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - - sign1File := testutil.WriteToNewTempFile(s.T(), account1Signature.String()) - defer sign1File.Close() - - // Sign with account2 - addr2, err := account2.GetAddress() - s.Require().NoError(err) - account2Signature, err := authtestutil.TxSignExec(s.clientCtx, addr2, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - - sign2File := testutil.WriteToNewTempFile(s.T(), account2Signature.String()) - defer sign2File.Close() - - // Sign with dummy account - dummyAddr, err := dummyAcc.GetAddress() - s.Require().NoError(err) - _, err = authtestutil.TxSignExec(s.clientCtx, dummyAddr, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().Error(err) - s.Require().Contains(err.Error(), "signing key is not a part of multisig key") - - multiSigWith2Signatures, err := authtestutil.TxMultiSignExec(s.clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) - s.Require().NoError(err) - - // Write the output to disk - signedTxFile := testutil.WriteToNewTempFile(s.T(), multiSigWith2Signatures.String()) - defer signedTxFile.Close() - - _, err = authtestutil.TxValidateSignaturesExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) - - s.clientCtx.BroadcastMode = flags.BroadcastSync - _, err = authtestutil.TxBroadcastExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) -} - -func (s *CLITestSuite) TestSignWithMultisig() { - // Generate a account for signing. - account1, err := s.clientCtx.Keyring.Key("newAccount1") - s.Require().NoError(err) - - addr1, err := account1.GetAddress() - s.Require().NoError(err) - - // Create an address that is not in the keyring, will be used to simulate `--multisig` - multisig := "cosmos1hd6fsrvnz6qkp87s3u86ludegq97agxsdkwzyh" - _, err = s.ac.StringToBytes(multisig) - s.Require().NoError(err) - - msgSend := &banktypes.MsgSend{ - FromAddress: s.val.String(), - ToAddress: s.val.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), - } - - // Generate a transaction for testing --multisig with an address not in the keyring. - multisigTx, err := clitestutil.SubmitTestTx(s.clientCtx, msgSend, s.val, clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - // Save multi tx to file - multiGeneratedTx2File := testutil.WriteToNewTempFile(s.T(), multisigTx.String()) - defer multiGeneratedTx2File.Close() - - // Sign using multisig. We're signing a tx on behalf of the multisig address, - // even though the tx signer is NOT the multisig address. This is fine though, - // as the main point of this test is to test the `--multisig` flag with an address - // that is not in the keyring. - _, err = authtestutil.TxSignExec(s.clientCtx, addr1, multiGeneratedTx2File.Name(), "--multisig", multisig) - s.Require().Contains(err.Error(), "error getting account from keybase") -} - -func (s *CLITestSuite) TestCLIMultisign() { - // Generate 2 accounts and a multisig. - account1, err := s.clientCtx.Keyring.Key("newAccount1") - s.Require().NoError(err) - - account2, err := s.clientCtx.Keyring.Key("newAccount2") - s.Require().NoError(err) - - multisigRecord, err := s.clientCtx.Keyring.Key("multi") - s.Require().NoError(err) - - addr, err := multisigRecord.GetAddress() - s.Require().NoError(err) - - msgSend := &banktypes.MsgSend{ - FromAddress: addr.String(), - ToAddress: s.val.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), - } - - // Generate multisig transaction. - multiGeneratedTx, err := clitestutil.SubmitTestTx(s.clientCtx, msgSend, addr, clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - // Save tx to file - multiGeneratedTxFile := testutil.WriteToNewTempFile(s.T(), multiGeneratedTx.String()) - defer multiGeneratedTxFile.Close() - - addr1, err := account1.GetAddress() - s.Require().NoError(err) - // Sign with account1 - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - account1Signature, err := authtestutil.TxSignExec(s.clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - - sign1File := testutil.WriteToNewTempFile(s.T(), account1Signature.String()) - defer sign1File.Close() - - addr2, err := account2.GetAddress() - s.Require().NoError(err) - // Sign with account2 - account2Signature, err := authtestutil.TxSignExec(s.clientCtx, addr2, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - - sign2File := testutil.WriteToNewTempFile(s.T(), account2Signature.String()) - defer sign2File.Close() - - s.clientCtx.Offline = false - multiSigWith2Signatures, err := authtestutil.TxMultiSignExec(s.clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) - s.Require().NoError(err) - - // Write the output to disk - signedTxFile := testutil.WriteToNewTempFile(s.T(), multiSigWith2Signatures.String()) - defer signedTxFile.Close() - - _, err = authtestutil.TxValidateSignaturesExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) - - s.clientCtx.BroadcastMode = flags.BroadcastSync - _, err = authtestutil.TxBroadcastExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) -} - -func (s *CLITestSuite) TestSignBatchMultisig() { - // Fetch 2 accounts and a multisig. - account1, err := s.clientCtx.Keyring.Key("newAccount1") - s.Require().NoError(err) - account2, err := s.clientCtx.Keyring.Key("newAccount2") - s.Require().NoError(err) - multisigRecord, err := s.clientCtx.Keyring.Key("multi") - s.Require().NoError(err) - - addr, err := multisigRecord.GetAddress() - s.Require().NoError(err) - // Send coins from validator to multisig. - sendTokens := sdk.NewInt64Coin("stake", 10) - _, err = s.createBankMsg( - s.clientCtx, - addr, - sdk.NewCoins(sendTokens), - clitestutil.TestTxConfig{}, - ) - s.Require().NoError(err) - - msgSend := &banktypes.MsgSend{ - FromAddress: addr.String(), - ToAddress: s.val.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), - } - - generatedStd, err := clitestutil.SubmitTestTx(s.clientCtx, msgSend, addr, clitestutil.TestTxConfig{GenOnly: true}) - s.Require().NoError(err) - - // Write the output to disk - filename := testutil.WriteToNewTempFile(s.T(), strings.Repeat(generatedStd.String(), 1)) - defer filename.Close() - s.clientCtx.HomeDir = strings.Replace(s.clientCtx.HomeDir, "simd", "simcli", 1) - - addr1, err := account1.GetAddress() - s.Require().NoError(err) - // sign-batch file - res, err := authtestutil.TxSignBatchExec(s.clientCtx, addr1, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, s.clientCtx.ChainID), "--multisig", addr.String(), "--signature-only") - s.Require().NoError(err) - s.Require().Equal(1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) - // write sigs to file - file1 := testutil.WriteToNewTempFile(s.T(), res.String()) - defer file1.Close() - - addr2, err := account2.GetAddress() - s.Require().NoError(err) - // sign-batch file with account2 - res, err = authtestutil.TxSignBatchExec(s.clientCtx, addr2, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, s.clientCtx.ChainID), "--multisig", addr.String(), "--signature-only") - s.Require().NoError(err) - s.Require().Equal(1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) - // write sigs to file2 - file2 := testutil.WriteToNewTempFile(s.T(), res.String()) - defer file2.Close() - _, err = authtestutil.TxMultiSignExec(s.clientCtx, multisigRecord.Name, filename.Name(), file1.Name(), file2.Name()) - s.Require().NoError(err) -} - -func (s *CLITestSuite) TestGetBroadcastCommandOfflineFlag() { - cmd := authcli.GetBroadcastCommand() - _ = testutil.ApplyMockIODiscardOutErr(cmd) - cmd.SetArgs([]string{fmt.Sprintf("--%s=true", flags.FlagOffline), ""}) - - s.Require().EqualError(cmd.Execute(), "cannot broadcast tx during offline mode") -} - -func (s *CLITestSuite) TestGetBroadcastCommandWithoutOfflineFlag() { - txCfg := s.clientCtx.TxConfig - clientCtx := client.Context{} - clientCtx = clientCtx.WithTxConfig(txCfg) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - - cmd := authcli.GetBroadcastCommand() - _, out := testutil.ApplyMockIO(cmd) - - // Create new file with tx - builder := txCfg.NewTxBuilder() - builder.SetGasLimit(200000) - - err := builder.SetMsgs(banktypes.NewMsgSend("cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw", "cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw", sdk.Coins{sdk.NewInt64Coin("stake", 10000)})) - s.Require().NoError(err) - txContents, err := txCfg.TxJSONEncoder()(builder.GetTx()) - s.Require().NoError(err) - txFile := testutil.WriteToNewTempFile(s.T(), string(txContents)) - defer txFile.Close() - - cmd.SetArgs([]string{txFile.Name()}) - err = cmd.ExecuteContext(ctx) - s.Require().Error(err) - s.Require().Contains(err.Error(), "connect: connection refused") - s.Require().Contains(out.String(), "connect: connection refused") -} - -// TestTxWithoutPublicKey makes sure sending a proto tx message without the -// public key doesn't cause any error in the RPC layer (broadcast). -// See https://github.com/cosmos/cosmos-sdk/issues/7585 for more details. -func (s *CLITestSuite) TestTxWithoutPublicKey() { - txCfg := s.clientCtx.TxConfig - - valStr, err := s.ac.BytesToString(s.val) - s.Require().NoError(err) - - // Create a txBuilder with an unsigned tx. - txBuilder := txCfg.NewTxBuilder() - msg := banktypes.NewMsgSend(valStr, valStr, sdk.NewCoins( - sdk.NewCoin("Stake", math.NewInt(10)), - )) - err = txBuilder.SetMsgs(msg) - s.Require().NoError(err) - txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("Stake", math.NewInt(150)))) - txBuilder.SetGasLimit(testdata.NewTestGasLimit()) - - // Create a file with the unsigned tx. - txJSON, err := txCfg.TxJSONEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - unsignedTxFile := testutil.WriteToNewTempFile(s.T(), string(txJSON)) - defer unsignedTxFile.Close() - - // Sign the file with the unsignedTx. - signedTx, err := authtestutil.TxSignExec(s.clientCtx, s.val, unsignedTxFile.Name(), fmt.Sprintf("--%s=true", cli.FlagOverwrite)) - s.Require().NoError(err) - - // Remove the signerInfo's `public_key` field manually from the signedTx. - // Note: this method is only used for test purposes! In general, one should - // use txBuilder and TxEncoder/TxDecoder to manipulate txs. - var tx tx.Tx - err = s.clientCtx.Codec.UnmarshalJSON(signedTx.Bytes(), &tx) - s.Require().NoError(err) - tx.AuthInfo.SignerInfos[0].PublicKey = nil - // Re-encode the tx again, to another file. - txJSON, err = s.clientCtx.Codec.MarshalJSON(&tx) - s.Require().NoError(err) - signedTxFile := testutil.WriteToNewTempFile(s.T(), string(txJSON)) - defer signedTxFile.Close() - s.Require().True(strings.Contains(string(txJSON), "\"public_key\":null")) - - // Broadcast tx, test that it shouldn't panic. - s.clientCtx.BroadcastMode = flags.BroadcastSync - out, err := authtestutil.TxBroadcastExec(s.clientCtx, signedTxFile.Name()) - s.Require().NoError(err) - var res sdk.TxResponse - s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res)) - s.Require().NotEqual(0, res.Code) -} - -// TestSignWithMultiSignersAminoJSON tests the case where a transaction with 2 -// messages which has to be signed with 2 different keys. Sign and append the -// signatures using the CLI with Amino signing mode. Finally, send the -// transaction to the blockchain. -func (s *CLITestSuite) TestSignWithMultiSignersAminoJSON() { - val0, val1 := s.val, s.val1 - val0Coin := sdk.NewCoin("test1token", math.NewInt(10)) - val1Coin := sdk.NewCoin("test2token", math.NewInt(10)) - _, _, addr1 := testdata.KeyTestPubAddr() - - valStr, err := s.ac.BytesToString(val0) - s.Require().NoError(err) - val1Str, err := s.ac.BytesToString(val1) - s.Require().NoError(err) - - addrStr, err := s.ac.BytesToString(addr1) - s.Require().NoError(err) - // Creating a tx with 2 msgs from 2 signers: val0 and val1. - // The validators need to sign with SIGN_MODE_LEGACY_AMINO_JSON, - // because DIRECT doesn't support multi signers via the CLI. - // Since we use amino, we don't need to pre-populate signer_infos. - txBuilder := s.clientCtx.TxConfig.NewTxBuilder() - err = txBuilder.SetMsgs( - banktypes.NewMsgSend(valStr, addrStr, sdk.NewCoins(val0Coin)), - banktypes.NewMsgSend(val1Str, addrStr, sdk.NewCoins(val1Coin)), - ) - s.Require().NoError(err) - txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10)))) - txBuilder.SetGasLimit(testdata.NewTestGasLimit() * 2) - signers, err := txBuilder.GetTx().GetSigners() - s.Require().NoError(err) - s.Require().Equal([][]byte{val0, val1}, signers) - - // Write the unsigned tx into a file. - txJSON, err := s.clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - unsignedTxFile := testutil.WriteToNewTempFile(s.T(), string(txJSON)) - defer unsignedTxFile.Close() - - // Let val0 sign first the file with the unsignedTx. - signedByVal0, err := authtestutil.TxSignExec(s.clientCtx, val0, unsignedTxFile.Name(), "--overwrite", "--sign-mode=amino-json") - s.Require().NoError(err) - signedByVal0File := testutil.WriteToNewTempFile(s.T(), signedByVal0.String()) - defer signedByVal0File.Close() - - // Then let val1 sign the file with signedByVal0. - val1AccNum, val1Seq, err := s.clientCtx.AccountRetriever.GetAccountNumberSequence(s.clientCtx, val1) - s.Require().NoError(err) - - signedTx, err := authtestutil.TxSignExec( - s.clientCtx, - val1, - signedByVal0File.Name(), - "--offline", - fmt.Sprintf("--account-number=%d", val1AccNum), - fmt.Sprintf("--sequence=%d", val1Seq), - "--sign-mode=amino-json", - ) - s.Require().NoError(err) - signedTxFile := testutil.WriteToNewTempFile(s.T(), signedTx.String()) - defer signedTxFile.Close() - - res, err := authtestutil.TxBroadcastExec( - s.clientCtx, - signedTxFile.Name(), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - ) - s.Require().NoError(err) - - var txRes sdk.TxResponse - s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) - s.Require().Equal(uint32(0), txRes.Code, txRes.RawLog) -} - -func (s *CLITestSuite) TestAuxSigner() { - s.T().Skip("re-enable this when we bring back sign mode aux client testing") - val0Coin := sdk.NewCoin("testtoken", math.NewInt(10)) - - testCases := []struct { - name string - args []string - expectErr bool - }{ - { - "error with SIGN_MODE_DIRECT_AUX and --aux unset", - []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - }, - true, - }, - { - "no error with SIGN_MDOE_DIRECT_AUX mode and generate-only set (ignores generate-only)", - []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - }, - false, - }, - { - "no error with SIGN_MDOE_DIRECT_AUX mode and generate-only, tip flag set", - []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=%s", flags.FlagTip, val0Coin.String()), - }, - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - _, err := govtestutil.MsgSubmitLegacyProposal( - s.clientCtx, - s.val.String(), - "test", - "test desc", - govtypes.ProposalTypeText, - tc.args..., - ) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - } - }) - } -} - -func (s *CLITestSuite) TestAuxToFeeWithTips() { - // Skipping this test as it needs a simapp with the TipDecorator in post handler. - s.T().Skip() - - require := s.Require() - - kb := s.clientCtx.Keyring - acc, _, err := kb.NewMnemonic("tipperAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - require.NoError(err) - - tipper, err := acc.GetAddress() - require.NoError(err) - tipperInitialBal := sdk.NewCoin("testtoken", math.NewInt(10000)) - - feePayer := s.val - fee := sdk.NewCoin("stake", math.NewInt(1000)) - tip := sdk.NewCoin("testtoken", math.NewInt(1000)) - - _, err = s.createBankMsg(s.clientCtx, tipper, sdk.NewCoins(tipperInitialBal), clitestutil.TestTxConfig{}) - require.NoError(err) - - bal := s.getBalances(s.clientCtx, tipper, tip.Denom) - require.True(bal.Equal(tipperInitialBal.Amount)) - - testCases := []struct { - name string - tipper sdk.AccAddress - feePayer sdk.AccAddress - tip sdk.Coin - expectErrAux bool - expectErrBroadCast bool - errMsg string - tipperArgs []string - feePayerArgs []string - }{ - { - name: "when --aux and --sign-mode = direct set: error", - tipper: tipper, - feePayer: feePayer, - tip: tip, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirect), - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - expectErrAux: true, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - }, - { - name: "both tipper, fee payer uses AMINO: no error", - tipper: tipper, - feePayer: feePayer, - tip: tip, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - }, - { - name: "tipper uses DIRECT_AUX, fee payer uses AMINO: no error", - tipper: tipper, - feePayer: feePayer, - tip: tip, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - }, - { - name: "--tip flag unset: no error", - tipper: tipper, - feePayer: feePayer, - tip: sdk.Coin{Denom: "testtoken", Amount: math.NewInt(0)}, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - }, - { - name: "legacy amino json: no error", - tipper: tipper, - feePayer: feePayer, - tip: tip, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - }, - { - name: "tipper uses direct aux, fee payer uses direct: happy case", - tipper: tipper, - feePayer: feePayer, - tip: tip, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - }, - { - name: "chain-id mismatch: error", - tipper: tipper, - feePayer: feePayer, - tip: tip, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - expectErrAux: false, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - fmt.Sprintf("--%s=%s", flags.FlagChainID, "foobar"), - }, - expectErrBroadCast: true, - }, - { - name: "wrong denom in tip: error", - tipper: tipper, - feePayer: feePayer, - tip: sdk.Coin{Denom: "testtoken", Amount: math.NewInt(0)}, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagTip, "1000wrongDenom"), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirect), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), - }, - errMsg: "insufficient funds", - }, - { - name: "insufficient fees: error", - tipper: tipper, - feePayer: feePayer, - tip: sdk.Coin{Denom: "testtoken", Amount: math.NewInt(0)}, - tipperArgs: []string{ - fmt.Sprintf("--%s=%s", flags.FlagTip, tip), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), - fmt.Sprintf("--%s=true", flags.FlagAux), - }, - feePayerArgs: []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirect), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), - }, - errMsg: "insufficient fees", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := govtestutil.MsgSubmitLegacyProposal( - s.clientCtx, - tipper.String(), - "test", - "test desc", - govtypes.ProposalTypeText, - tc.tipperArgs..., - ) - - if tc.expectErrAux { - require.Error(err) - } else { - require.NoError(err) - genTxFile := testutil.WriteToNewTempFile(s.T(), string(res.Bytes())) - defer genTxFile.Close() - - switch { - case tc.expectErrBroadCast: - require.Error(err) - - case tc.errMsg != "": - require.NoError(err) - - var txRes sdk.TxResponse - require.NoError(s.clientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) - - require.Contains(txRes.RawLog, tc.errMsg) - - default: - require.NoError(err) - - var txRes sdk.TxResponse - require.NoError(s.clientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) - - require.Equal(uint32(0), txRes.Code) - require.NotNil(int64(0), txRes.Height) - - bal = s.getBalances(s.clientCtx, tipper, tc.tip.Denom) - tipperInitialBal = tipperInitialBal.Sub(tc.tip) - require.True(bal.Equal(tipperInitialBal.Amount)) - } - } - }) - } -} - -func (s *CLITestSuite) getBalances(clientCtx client.Context, addr sdk.AccAddress, denom string) math.Int { - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s/by_denom?denom=%s", s.baseCtx.NodeURI, addr.String(), denom)) - s.Require().NoError(err) - - var balRes banktypes.QueryAllBalancesResponse - err = clientCtx.Codec.UnmarshalJSON(resp, &balRes) - s.Require().NoError(err) - startTokens := balRes.Balances.AmountOf(denom) - return startTokens -} - -func (s *CLITestSuite) createBankMsg(clientCtx client.Context, toAddr sdk.AccAddress, amount sdk.Coins, cfg clitestutil.TestTxConfig) (testutil.BufferWriter, error) { - msgSend := &banktypes.MsgSend{ - FromAddress: s.val.String(), - ToAddress: toAddr.String(), - Amount: amount, - } - - return clitestutil.SubmitTestTx(clientCtx, msgSend, s.val, cfg) -} diff --git a/tests/integration/baseapp/block_gas_test.go b/tests/integration/baseapp/block_gas_test.go deleted file mode 100644 index 4ceb23a97c..0000000000 --- a/tests/integration/baseapp/block_gas_test.go +++ /dev/null @@ -1,261 +0,0 @@ -package baseapp_test - -import ( - "context" - "math" - "testing" - - abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" - cmtjson "github.com/cometbft/cometbft/libs/json" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/anypb" - - coretesting "cosmossdk.io/core/testing" - "cosmossdk.io/depinject" - "cosmossdk.io/log" - sdkmath "cosmossdk.io/math" - store "cosmossdk.io/store/types" - _ "cosmossdk.io/x/accounts" - txsigning "cosmossdk.io/x/tx/signing" - - baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/runtime" - baseapputil "github.com/cosmos/cosmos-sdk/tests/integration/baseapp" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/configurator" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" -) - -var blockMaxGas = uint64(simtestutil.DefaultConsensusParams.Block.MaxGas) - -type BlockGasImpl struct { - panicTx bool - gasToConsume uint64 - key store.StoreKey -} - -func (m BlockGasImpl) Set(ctx context.Context, msg *baseapptestutil.MsgKeyValue) (*baseapptestutil.MsgCreateKeyValueResponse, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - sdkCtx.KVStore(m.key).Set(msg.Key, msg.Value) - sdkCtx.GasMeter().ConsumeGas(m.gasToConsume, "TestMsg") - if m.panicTx { - panic("panic in tx execution") - } - return &baseapptestutil.MsgCreateKeyValueResponse{}, nil -} - -func TestBaseApp_BlockGas(t *testing.T) { - testcases := []struct { - name string - gasToConsume uint64 // gas to consume in the msg execution - panicTx bool // panic explicitly in tx execution - expErr bool - }{ - {"less than block gas meter", 10, false, false}, - {"more than block gas meter", blockMaxGas, false, true}, - {"more than block gas meter", uint64(float64(blockMaxGas) * 1.2), false, true}, - {"consume MaxUint64", math.MaxUint64, true, true}, - {"consume MaxGasWanted", txtypes.MaxGasWanted, false, true}, - {"consume block gas when panicked", 10, true, true}, - } - - for _, tc := range testcases { - var ( - bankKeeper baseapputil.BankKeeper - accountKeeper baseapputil.AuthKeeper - appBuilder *runtime.AppBuilder - txConfig client.TxConfig - cdc codec.Codec - interfaceRegistry codectypes.InterfaceRegistry - err error - ) - - err = depinject.Inject( - depinject.Configs( - configurator.NewAppConfig( - configurator.AccountsModule(), - configurator.AuthModule(), - configurator.TxModule(), - configurator.ValidateModule(), - configurator.ConsensusModule(), - configurator.BankModule(), - configurator.StakingModule(), - ), - depinject.Supply(log.NewNopLogger()), - ), - &bankKeeper, - &accountKeeper, - &interfaceRegistry, - &txConfig, - &cdc, - &appBuilder) - require.NoError(t, err) - - bapp := appBuilder.Build(coretesting.NewMemDB(), nil) - bapp.SetTxEncoder(txConfig.TxEncoder()) - bapp.SetTxDecoder(txConfig.TxDecoder()) - - err = bapp.Load(true) - require.NoError(t, err) - - t.Run(tc.name, func(t *testing.T) { - baseapptestutil.RegisterInterfaces(interfaceRegistry) - baseapptestutil.RegisterKeyValueServer(bapp.MsgServiceRouter(), BlockGasImpl{ - panicTx: tc.panicTx, - gasToConsume: tc.gasToConsume, - key: bapp.UnsafeFindStoreKey(testutil.BankModuleName), - }) - - genState := baseapputil.GenesisStateWithSingleValidator(t, cdc, appBuilder) - stateBytes, err := cmtjson.MarshalIndent(genState, "", " ") - require.NoError(t, err) - _, err = bapp.InitChain(&abci.InitChainRequest{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: simtestutil.DefaultConsensusParams, - AppStateBytes: stateBytes, - }) - - require.NoError(t, err) - ctx := bapp.NewContext(false) - - // tx fee - feeCoin := sdk.NewCoin("atom", sdkmath.NewInt(150)) - feeAmount := sdk.NewCoins(feeCoin) - - // test account and fund - priv1, _, addr1 := testdata.KeyTestPubAddr() - err = bankKeeper.MintCoins(ctx, testutil.MintModuleName, feeAmount) - require.NoError(t, err) - err = bankKeeper.SendCoinsFromModuleToAccount(ctx, testutil.MintModuleName, addr1, feeAmount) - require.NoError(t, err) - require.Equal(t, feeCoin.Amount, bankKeeper.GetBalance(ctx, addr1, feeCoin.Denom).Amount) - - // msg and signatures - msg := &baseapptestutil.MsgKeyValue{ - Key: []byte("ok"), - Value: []byte("ok"), - Signer: addr1.String(), - } - - txBuilder := txConfig.NewTxBuilder() - - require.NoError(t, txBuilder.SetMsgs(msg)) - txBuilder.SetFeeAmount(feeAmount) - txBuilder.SetGasLimit(uint64(simtestutil.DefaultConsensusParams.Block.MaxGas)) - - privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} - _, txBytes, err := createTestTx(txConfig, txBuilder, privs, accNums, accSeqs, ctx.ChainID()) - require.NoError(t, err) - - rsp, err := bapp.FinalizeBlock(&abci.FinalizeBlockRequest{Height: 1, Txs: [][]byte{txBytes}}) - require.NoError(t, err) - - // check result - ctx = bapp.GetContextForFinalizeBlock(txBytes) - okValue := ctx.KVStore(bapp.UnsafeFindStoreKey(testutil.BankModuleName)).Get([]byte("ok")) - - if tc.expErr { - if tc.panicTx { - require.Equal(t, sdkerrors.ErrPanic.ABCICode(), rsp.TxResults[0].Code) - } else { - require.Equal(t, sdkerrors.ErrOutOfGas.ABCICode(), rsp.TxResults[0].Code) - } - require.Empty(t, okValue) - } else { - require.Equal(t, uint32(0), rsp.TxResults[0].Code, "failure", rsp.TxResults[0].Log) - require.Equal(t, []byte("ok"), okValue) - } - // check block gas is always consumed - baseGas := uint64(39075) // baseGas is the gas consumed before tx msg - expGasConsumed := addUint64Saturating(tc.gasToConsume, baseGas) - if expGasConsumed > uint64(simtestutil.DefaultConsensusParams.Block.MaxGas) { - // capped by gasLimit - expGasConsumed = uint64(simtestutil.DefaultConsensusParams.Block.MaxGas) - } - require.Equal(t, int(expGasConsumed), int(ctx.BlockGasMeter().GasConsumed())) - // tx fee is always deducted - require.Equal(t, int64(0), bankKeeper.GetBalance(ctx, addr1, feeCoin.Denom).Amount.Int64()) - // sender's sequence is always increased - seq := accountKeeper.GetAccount(ctx, addr1).GetSequence() - require.NoError(t, err) - require.Equal(t, uint64(1), seq) - }) - } -} - -func createTestTx(txConfig client.TxConfig, txBuilder client.TxBuilder, privs []cryptotypes.PrivKey, accNums, accSeqs []uint64, chainID string) (xauthsigning.Tx, []byte, 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: txConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - Sequence: accSeqs[i], - } - - sigsV2 = append(sigsV2, sigV2) - } - err := txBuilder.SetSignatures(sigsV2...) - if err != nil { - return nil, nil, err - } - - // Second round: all signer infos are set, so each signer can sign. - sigsV2 = []signing.SignatureV2{} - for i, priv := range privs { - anyPk, err := codectypes.NewAnyWithValue(priv.PubKey()) - if err != nil { - return nil, nil, err - } - - signerData := txsigning.SignerData{ - Address: sdk.AccAddress(priv.PubKey().Bytes()).String(), - ChainID: chainID, - AccountNumber: accNums[i], - Sequence: accSeqs[i], - PubKey: &anypb.Any{TypeUrl: anyPk.TypeUrl, Value: anyPk.Value}, - } - sigV2, err := tx.SignWithPrivKey( - context.TODO(), txConfig.SignModeHandler().DefaultMode(), signerData, - txBuilder, priv, txConfig, accSeqs[i]) - if err != nil { - return nil, nil, err - } - - sigsV2 = append(sigsV2, sigV2) - } - err = txBuilder.SetSignatures(sigsV2...) - if err != nil { - return nil, nil, err - } - - txBytes, err := txConfig.TxEncoder()(txBuilder.GetTx()) - if err != nil { - return nil, nil, err - } - - return txBuilder.GetTx(), txBytes, nil -} - -func addUint64Saturating(a, b uint64) uint64 { - if math.MaxUint64-a < b { - return math.MaxUint64 - } - - return a + b -} diff --git a/tests/integration/baseapp/utils.go b/tests/integration/baseapp/utils.go deleted file mode 100644 index 3c49847c33..0000000000 --- a/tests/integration/baseapp/utils.go +++ /dev/null @@ -1,67 +0,0 @@ -package baseapp - -import ( - "context" - "encoding/json" - "testing" - - cmttypes "github.com/cometbft/cometbft/types" - "github.com/stretchr/testify/require" - - "cosmossdk.io/math" - _ "cosmossdk.io/x/bank" - banktypes "cosmossdk.io/x/bank/types" - _ "cosmossdk.io/x/consensus" - _ "cosmossdk.io/x/staking" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/testutil/mock" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - sdk "github.com/cosmos/cosmos-sdk/types" - _ "github.com/cosmos/cosmos-sdk/x/auth" - _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts -// that also act as delegators. -func GenesisStateWithSingleValidator(t *testing.T, codec codec.Codec, builder *runtime.AppBuilder) map[string]json.RawMessage { - t.Helper() - - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - require.NoError(t, err) - - // create validator set with single validator - validator := cmttypes.NewValidator(pubKey, 1) - valSet := cmttypes.NewValidatorSet([]*cmttypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balances := []banktypes.Balance{ - { - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000000000000))), - }, - } - - genesisState := builder.DefaultGenesis() - // sus - genesisState, err = simtestutil.GenesisStateWithValSet(codec, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) - require.NoError(t, err) - - return genesisState -} - -type BankKeeper interface { - MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error - SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error - GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin -} - -type AuthKeeper interface { - GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI -} diff --git a/tests/integration/genutil/cmt_abci.go b/tests/integration/genutil/cmt_abci.go deleted file mode 100644 index 1cee9e1c2b..0000000000 --- a/tests/integration/genutil/cmt_abci.go +++ /dev/null @@ -1,69 +0,0 @@ -package genutil - -import ( - "context" - - abciproto "github.com/cometbft/cometbft/api/cometbft/abci/v1" - - "github.com/cosmos/cosmos-sdk/runtime" -) - -type cometABCIWrapper struct { - app *runtime.App -} - -func (w cometABCIWrapper) Info(_ context.Context, req *abciproto.InfoRequest) (*abciproto.InfoResponse, error) { - return w.app.Info(req) -} - -func (w cometABCIWrapper) Query(ctx context.Context, req *abciproto.QueryRequest) (*abciproto.QueryResponse, error) { - return w.app.Query(ctx, req) -} - -func (w cometABCIWrapper) CheckTx(_ context.Context, req *abciproto.CheckTxRequest) (*abciproto.CheckTxResponse, error) { - return w.app.CheckTx(req) -} - -func (w cometABCIWrapper) InitChain(_ context.Context, req *abciproto.InitChainRequest) (*abciproto.InitChainResponse, error) { - return w.app.InitChain(req) -} - -func (w cometABCIWrapper) PrepareProposal(_ context.Context, req *abciproto.PrepareProposalRequest) (*abciproto.PrepareProposalResponse, error) { - return w.app.PrepareProposal(req) -} - -func (w cometABCIWrapper) ProcessProposal(_ context.Context, req *abciproto.ProcessProposalRequest) (*abciproto.ProcessProposalResponse, error) { - return w.app.ProcessProposal(req) -} - -func (w cometABCIWrapper) FinalizeBlock(_ context.Context, req *abciproto.FinalizeBlockRequest) (*abciproto.FinalizeBlockResponse, error) { - return w.app.FinalizeBlock(req) -} - -func (w cometABCIWrapper) ExtendVote(ctx context.Context, req *abciproto.ExtendVoteRequest) (*abciproto.ExtendVoteResponse, error) { - return w.app.ExtendVote(ctx, req) -} - -func (w cometABCIWrapper) VerifyVoteExtension(_ context.Context, req *abciproto.VerifyVoteExtensionRequest) (*abciproto.VerifyVoteExtensionResponse, error) { - return w.app.VerifyVoteExtension(req) -} - -func (w cometABCIWrapper) Commit(_ context.Context, _ *abciproto.CommitRequest) (*abciproto.CommitResponse, error) { - return w.app.Commit() -} - -func (w cometABCIWrapper) ListSnapshots(_ context.Context, req *abciproto.ListSnapshotsRequest) (*abciproto.ListSnapshotsResponse, error) { - return w.app.ListSnapshots(req) -} - -func (w cometABCIWrapper) OfferSnapshot(_ context.Context, req *abciproto.OfferSnapshotRequest) (*abciproto.OfferSnapshotResponse, error) { - return w.app.OfferSnapshot(req) -} - -func (w cometABCIWrapper) LoadSnapshotChunk(_ context.Context, req *abciproto.LoadSnapshotChunkRequest) (*abciproto.LoadSnapshotChunkResponse, error) { - return w.app.LoadSnapshotChunk(req) -} - -func (w cometABCIWrapper) ApplySnapshotChunk(_ context.Context, req *abciproto.ApplySnapshotChunkRequest) (*abciproto.ApplySnapshotChunkResponse, error) { - return w.app.ApplySnapshotChunk(req) -} diff --git a/tests/integration/genutil/genaccount_test.go b/tests/integration/genutil/genaccount_test.go deleted file mode 100644 index 1b1bd420e9..0000000000 --- a/tests/integration/genutil/genaccount_test.go +++ /dev/null @@ -1,298 +0,0 @@ -package genutil - -import ( - "context" - "encoding/json" - "os" - "path" - "testing" - - "github.com/spf13/viper" - "github.com/stretchr/testify/require" - - corectx "cosmossdk.io/core/context" - "cosmossdk.io/log" - banktypes "cosmossdk.io/x/bank/types" - - "github.com/cosmos/cosmos-sdk/client" - codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - genutilhelpers "github.com/cosmos/cosmos-sdk/testutil/x/genutil" - sdk "github.com/cosmos/cosmos-sdk/types" - moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" -) - -func TestAddGenesisAccountCmd(t *testing.T) { - _, _, addr1 := testdata.KeyTestPubAddr() - ac := codectestutil.CodecOptions{}.GetAddressCodec() - addr1Str, err := ac.BytesToString(addr1) - require.NoError(t, err) - - tests := []struct { - name string - addr string - denom string - withKeyring bool - expectErr bool - }{ - { - name: "invalid address", - addr: "", - denom: "1000atom", - withKeyring: false, - expectErr: true, - }, - { - name: "valid address", - addr: addr1Str, - denom: "1000atom", - withKeyring: false, - expectErr: false, - }, - { - name: "multiple denoms", - addr: addr1Str, - denom: "1000atom, 2000stake", - withKeyring: false, - expectErr: false, - }, - { - name: "with keyring", - addr: "set", - denom: "1000atom", - withKeyring: true, - expectErr: false, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - v := viper.New() - - encodingConfig := moduletestutil.MakeTestEncodingConfig( - codectestutil.CodecOptions{}, - auth.AppModule{}, - ) - appCodec := encodingConfig.Codec - txConfig := encodingConfig.TxConfig - err = genutilhelpers.ExecInitCmd(testMbm, home, appCodec) - require.NoError(t, err) - - err := writeAndTrackDefaultConfig(v, home) - require.NoError(t, err) - clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home). - WithAddressCodec(ac).WithTxConfig(txConfig) - - if tc.withKeyring { - path := hd.CreateHDPath(118, 0, 0).String() - kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil, appCodec) - require.NoError(t, err) - _, _, err = kr.NewMnemonic( - tc.addr, - keyring.English, - path, - keyring.DefaultBIP39Passphrase, - hd.Secp256k1, - ) - require.NoError(t, err) - clientCtx = clientCtx.WithKeyring(kr) - } - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, v) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - cmd := genutilcli.AddGenesisAccountCmd() - cmd.SetArgs([]string{ - tc.addr, - tc.denom, - }) - - if tc.expectErr { - require.Error(t, cmd.ExecuteContext(ctx)) - } else { - require.NoError(t, cmd.ExecuteContext(ctx)) - } - }) - } -} - -func TestBulkAddGenesisAccountCmd(t *testing.T) { - ac := codectestutil.CodecOptions{}.GetAddressCodec() - _, _, addr1 := testdata.KeyTestPubAddr() - _, _, addr2 := testdata.KeyTestPubAddr() - _, _, addr3 := testdata.KeyTestPubAddr() - addr1Str, err := ac.BytesToString(addr1) - require.NoError(t, err) - addr2Str, err := ac.BytesToString(addr2) - require.NoError(t, err) - addr3Str, err := ac.BytesToString(addr3) - require.NoError(t, err) - - tests := []struct { - name string - state [][]genutil.GenesisAccount - expected map[string]sdk.Coins - appendFlag bool - expectErr bool - }{ - { - name: "invalid address", - state: [][]genutil.GenesisAccount{ - { - { - Address: "invalid", - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), - }, - }, - }, - expectErr: true, - }, - { - name: "no append flag for multiple account adds", - state: [][]genutil.GenesisAccount{ - { - { - Address: addr1Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), - }, - }, - { - { - Address: addr1Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), - }, - }, - }, - appendFlag: false, - expectErr: true, - }, - - { - name: "multiple additions with append", - state: [][]genutil.GenesisAccount{ - { - { - Address: addr1Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), - }, - { - Address: addr2Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), - }, - }, - { - { - Address: addr1Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), - }, - { - Address: addr2Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 1)), - }, - { - Address: addr3Str, - Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), - }, - }, - }, - expected: map[string]sdk.Coins{ - addr1Str: sdk.NewCoins(sdk.NewInt64Coin("test", 3)), - addr2Str: sdk.NewCoins(sdk.NewInt64Coin("test", 1), sdk.NewInt64Coin("stake", 1)), - addr3Str: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), - }, - appendFlag: true, - expectErr: false, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - v := viper.New() - - encodingConfig := moduletestutil.MakeTestEncodingConfig( - codectestutil.CodecOptions{}, - auth.AppModule{}, - ) - appCodec := encodingConfig.Codec - txConfig := encodingConfig.TxConfig - err = genutilhelpers.ExecInitCmd(testMbm, home, appCodec) - require.NoError(t, err) - - err = writeAndTrackDefaultConfig(v, home) - require.NoError(t, err) - clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home). - WithAddressCodec(ac).WithTxConfig(txConfig) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, v) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - // The first iteration (pre-append) may not error. - // Check if any errors after all state transitions to genesis. - doesErr := false - - // apply multiple state iterations if applicable (e.g. --append) - for _, state := range tc.state { - bz, err := json.Marshal(state) - require.NoError(t, err) - - filePath := path.Join(home, "accounts.json") - err = os.WriteFile(filePath, bz, 0o600) - require.NoError(t, err) - - cmd := genutilcli.AddBulkGenesisAccountCmd() - args := []string{filePath} - if tc.appendFlag { - args = append(args, "--append") - } - cmd.SetArgs(args) - - err = cmd.ExecuteContext(ctx) - if err != nil { - doesErr = true - } - } - require.Equal(t, tc.expectErr, doesErr) - - // an error already occurred, no need to check the state - if doesErr { - return - } - - appState, _, err := genutiltypes.GenesisStateFromGenFile(path.Join(home, "config", "genesis.json")) - require.NoError(t, err) - - bankState := banktypes.GetGenesisStateFromAppState(encodingConfig.Codec, appState) - - require.EqualValues(t, len(tc.expected), len(bankState.Balances)) - for _, acc := range bankState.Balances { - require.True( - t, - tc.expected[acc.Address].Equal(acc.Coins), - "expected: %v, got: %v", - tc.expected[acc.Address], - acc.Coins, - ) - } - - expectedSupply := sdk.NewCoins() - for _, coins := range tc.expected { - expectedSupply = expectedSupply.Add(coins...) - } - require.Equal(t, expectedSupply, bankState.Supply) - }) - } -} diff --git a/tests/integration/genutil/init_test.go b/tests/integration/genutil/init_test.go deleted file mode 100644 index 01414b118f..0000000000 --- a/tests/integration/genutil/init_test.go +++ /dev/null @@ -1,427 +0,0 @@ -package genutil - -import ( - "context" - "fmt" - "net" - "testing" - "time" - - abci_server "github.com/cometbft/cometbft/abci/server" - "github.com/spf13/viper" - "github.com/stretchr/testify/require" - - corectx "cosmossdk.io/core/context" - "cosmossdk.io/depinject" - "cosmossdk.io/log" - _ "cosmossdk.io/x/accounts" - _ "cosmossdk.io/x/bank" - _ "cosmossdk.io/x/consensus" - "cosmossdk.io/x/staking" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/codec/types" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/configurator" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - genutilhelpers "github.com/cosmos/cosmos-sdk/testutil/x/genutil" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - _ "github.com/cosmos/cosmos-sdk/x/validate" -) - -var testMbm = module.NewManager( - staking.NewAppModule(makeCodec(), nil), - genutil.NewAppModule(makeCodec(), nil, nil, nil, nil, nil), -) - -func TestInitCmd(t *testing.T) { - tests := []struct { - name string - flags func(dir string) []string - shouldErr bool - err error - }{ - { - name: "happy path", - flags: func(dir string) []string { - return []string{ - "appnode-test", - } - }, - shouldErr: false, - err: nil, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - viper := viper.New() - - err := writeAndTrackDefaultConfig(viper, home) - require.NoError(t, err) - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - clientCtx := client.Context{}. - WithCodec(marshaler). - WithLegacyAmino(makeAminoCodec()). - WithHomeDir(home) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - cmd := genutilcli.InitCmd(testMbm) - cmd.SetArgs( - tt.flags(home), - ) - - if tt.shouldErr { - err := cmd.ExecuteContext(ctx) - require.EqualError(t, err, tt.err.Error()) - } else { - require.NoError(t, cmd.ExecuteContext(ctx)) - } - }) - } -} - -func TestInitRecover(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - viper := viper.New() - - err := writeAndTrackDefaultConfig(viper, home) - require.NoError(t, err) - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - clientCtx := client.Context{}. - WithCodec(marshaler). - WithLegacyAmino(makeAminoCodec()). - WithHomeDir(home) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - cmd := genutilcli.InitCmd(testMbm) - cmd.SetContext(ctx) - mockIn := testutil.ApplyMockIODiscardOutErr(cmd) - - cmd.SetArgs([]string{ - "appnode-test", - fmt.Sprintf("--%s=true", genutilcli.FlagRecover), - }) - - // use valid mnemonic and complete recovery key generation successfully - mockIn.Reset( - "decide praise business actor peasant farm drastic weather extend front hurt later song give verb rhythm worry fun pond reform school tumble august one\n", - ) - require.NoError(t, cmd.ExecuteContext(ctx)) -} - -func TestInitDefaultBondDenom(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - viper := viper.New() - - err := writeAndTrackDefaultConfig(viper, home) - require.NoError(t, err) - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - clientCtx := client.Context{}. - WithCodec(marshaler). - WithLegacyAmino(makeAminoCodec()). - WithHomeDir(home) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - cmd := genutilcli.InitCmd(testMbm) - - cmd.SetArgs([]string{ - "appnode-test", - fmt.Sprintf("--%s=testtoken", genutilcli.FlagDefaultBondDenom), - }) - require.NoError(t, cmd.ExecuteContext(ctx)) -} - -func TestEmptyState(t *testing.T) { - // TODO: rewrite for v2: https://github.com/cosmos/cosmos-sdk/issues/20799 - - // home := t.TempDir() - // logger := log.NewNopLogger() - // viper := viper.New() - - // err := writeAndTrackDefaultConfig(viper, home) - // require.NoError(t, err) - // interfaceRegistry := types.NewInterfaceRegistry() - // marshaler := codec.NewProtoCodec(interfaceRegistry) - // clientCtx := client.Context{}. - // WithCodec(marshaler). - // WithLegacyAmino(makeAminoCodec()). - // WithHomeDir(home) - - // ctx := context.Background() - // ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - // ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - // ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - // cmd := genutilcli.InitCmd(testMbm) - // cmd.SetArgs([]string{"appnode-test"}) - - // require.NoError(t, cmd.ExecuteContext(ctx)) - - // old := os.Stdout - // r, w, _ := os.Pipe() - // os.Stdout = w - - // cmd = genutilcli.ExportCmd(nil) - // require.NoError(t, cmd.ExecuteContext(ctx)) - - // outC := make(chan string) - // go func() { - // var buf bytes.Buffer - // _, err := io.Copy(&buf, r) - // require.NoError(t, err) - - // outC <- buf.String() - // }() - - // w.Close() - // os.Stdout = old - // out := <-outC - - // require.Contains(t, out, "genesis_time") - // require.Contains(t, out, "chain_id") - // require.Contains(t, out, "consensus") - // require.Contains(t, out, "app_hash") - // require.Contains(t, out, "app_state") -} - -func TestStartStandAlone(t *testing.T) { - home := t.TempDir() - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - err := genutilhelpers.ExecInitCmd(testMbm, home, marshaler) - require.NoError(t, err) - - app, err := simtestutil.SetupWithConfiguration( - depinject.Configs( - configurator.NewAppConfig( - configurator.AccountsModule(), - configurator.AuthModule(), - configurator.StakingModule(), - configurator.TxModule(), - configurator.ValidateModule(), - configurator.ConsensusModule(), - configurator.BankModule(), - ), - depinject.Supply(log.NewNopLogger()), - ), simtestutil.DefaultStartUpConfig()) - require.NoError(t, err) - - svrAddr, _, closeFn, err := freeTCPAddr() - require.NoError(t, err) - require.NoError(t, closeFn()) - - cmtApp := cometABCIWrapper{app} - svr, err := abci_server.NewServer(svrAddr, "socket", cmtApp) - require.NoError(t, err, "error creating listener") - - err = svr.Start() - require.NoError(t, err) - - timer := time.NewTimer(time.Duration(2) * time.Second) - for range timer.C { - err = svr.Stop() - require.NoError(t, err) - break - } -} - -func TestInitNodeValidatorFiles(t *testing.T) { - home := t.TempDir() - cfg, err := genutilhelpers.CreateDefaultCometConfig(home) - require.NoError(t, err) - - nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(cfg, ed25519.KeyType) - require.NoError(t, err) - - require.NotEqual(t, "", nodeID) - require.NotEqual(t, 0, len(valPubKey.Bytes())) -} - -func TestInitConfig(t *testing.T) { - // TODO: rewrite for v2: https://github.com/cosmos/cosmos-sdk/issues/20799 - - // home := t.TempDir() - // logger := log.NewNopLogger() - // viper := viper.New() - - // err := writeAndTrackDefaultConfig(viper, home) - // require.NoError(t, err) - // interfaceRegistry := types.NewInterfaceRegistry() - // marshaler := codec.NewProtoCodec(interfaceRegistry) - // clientCtx := client.Context{}. - // WithCodec(marshaler). - // WithLegacyAmino(makeAminoCodec()). - // WithChainID("foo"). // add chain-id to clientCtx - // WithHomeDir(home) - - // ctx := context.Background() - // ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - // ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - // ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - // cmd := genutilcli.InitCmd(testMbm) - // cmd.SetArgs([]string{"testnode"}) - - // err = cmd.ExecuteContext(ctx) - // require.NoError(t, err) - - // old := os.Stdout - // r, w, _ := os.Pipe() - // os.Stdout = w - - // cmd = genutilcli.ExportCmd(nil) - // require.NoError(t, cmd.ExecuteContext(ctx)) - - // outC := make(chan string) - // go func() { - // var buf bytes.Buffer - // _, err := io.Copy(&buf, r) - // require.NoError(t, err) - // outC <- buf.String() - // }() - - // w.Close() - // os.Stdout = old - // out := <-outC - - // require.Contains(t, out, "\"chain_id\": \"foo\"") -} - -func TestInitWithHeight(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - viper := viper.New() - cfg, err := genutilhelpers.CreateDefaultCometConfig(home) - require.NoError(t, err) - - err = writeAndTrackDefaultConfig(viper, home) - require.NoError(t, err) - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - clientCtx := client.Context{}. - WithCodec(marshaler). - WithLegacyAmino(makeAminoCodec()). - WithChainID("foo"). // add chain-id to clientCtx - WithHomeDir(home) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - testInitialHeight := int64(333) - - cmd := genutilcli.InitCmd(testMbm) - - fmt.Println("RootDir", viper.Get(flags.FlagHome)) - cmd.SetArgs([]string{"init-height-test", fmt.Sprintf("--%s=%d", flags.FlagInitHeight, testInitialHeight)}) - - require.NoError(t, cmd.ExecuteContext(ctx)) - - appGenesis, importErr := genutiltypes.AppGenesisFromFile(cfg.GenesisFile()) - require.NoError(t, importErr) - - require.Equal(t, testInitialHeight, appGenesis.InitialHeight) -} - -func TestInitWithNegativeHeight(t *testing.T) { - home := t.TempDir() - logger := log.NewNopLogger() - viper := viper.New() - cfg, err := genutilhelpers.CreateDefaultCometConfig(home) - require.NoError(t, err) - - err = writeAndTrackDefaultConfig(viper, home) - require.NoError(t, err) - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - clientCtx := client.Context{}. - WithCodec(marshaler). - WithLegacyAmino(makeAminoCodec()). - WithChainID("foo"). // add chain-id to clientCtx - WithHomeDir(home) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - testInitialHeight := int64(-333) - - cmd := genutilcli.InitCmd(testMbm) - cmd.SetArgs([]string{"init-height-test", fmt.Sprintf("--%s=%d", flags.FlagInitHeight, testInitialHeight)}) - - require.NoError(t, cmd.ExecuteContext(ctx)) - - appGenesis, importErr := genutiltypes.AppGenesisFromFile(cfg.GenesisFile()) - require.NoError(t, importErr) - - require.Equal(t, int64(1), appGenesis.InitialHeight) -} - -// custom tx codec -func makeAminoCodec() *codec.LegacyAmino { - cdc := codec.NewLegacyAmino() - sdk.RegisterLegacyAminoCodec(cdc) - cryptocodec.RegisterCrypto(cdc) - return cdc -} - -func makeCodec() codec.Codec { - interfaceRegistry := types.NewInterfaceRegistry() - return codec.NewProtoCodec(interfaceRegistry) -} - -func writeAndTrackDefaultConfig(v *viper.Viper, home string) error { - cfg, err := genutilhelpers.CreateDefaultCometConfig(home) - if err != nil { - return err - } - return genutilhelpers.WriteAndTrackCometConfig(v, home, cfg) -} - -// Get a free address for a test CometBFT server -// protocol is either tcp, http, etc -func freeTCPAddr() (addr, port string, closeFn func() error, err error) { - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return "", "", nil, err - } - - closeFn = func() error { - return l.Close() - } - - portI := l.Addr().(*net.TCPAddr).Port - port = fmt.Sprintf("%d", portI) - addr = fmt.Sprintf("tcp://127.0.0.1:%s", port) - return -} diff --git a/tests/integration/v2/auth/app_test.go b/tests/integration/v2/auth/app_test.go index 6a20e9eef7..5422b4e5d0 100644 --- a/tests/integration/v2/auth/app_test.go +++ b/tests/integration/v2/auth/app_test.go @@ -2,8 +2,11 @@ package auth import ( "context" + "io" "testing" + abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" + rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock" "github.com/stretchr/testify/require" "cosmossdk.io/core/router" @@ -17,15 +20,26 @@ import ( "cosmossdk.io/x/accounts" basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject" accountsv1 "cosmossdk.io/x/accounts/v1" - _ "cosmossdk.io/x/bank" // import as blank for app wiring + "cosmossdk.io/x/bank" bankkeeper "cosmossdk.io/x/bank/keeper" banktypes "cosmossdk.io/x/bank/types" _ "cosmossdk.io/x/consensus" // import as blank for app wiring - _ "cosmossdk.io/x/staking" // import as blank for app wirings + "cosmossdk.io/x/gov" + _ "cosmossdk.io/x/staking" // import as blank for app wirings + "github.com/cosmos/cosmos-sdk/client" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/tests/integration/v2" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/configurator" - _ "github.com/cosmos/cosmos-sdk/x/auth" // import as blank for app wiring + sdk "github.com/cosmos/cosmos-sdk/types" + testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/auth" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import as blank for app wiring`` _ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import as blank for app wiring @@ -34,12 +48,14 @@ import ( type suite struct { app *integration.App - ctx context.Context authKeeper authkeeper.AccountKeeper accountsKeeper accounts.Keeper bankKeeper bankkeeper.Keeper + + clientCtx client.Context + val, val1 sdk.AccAddress } func (s suite) mustAddr(address []byte) string { @@ -101,6 +117,53 @@ func createTestSuite(t *testing.T) *suite { res.ctx = res.app.StateLatestContext(t) + // setup client context + encCfg := testutilmod.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, bank.AppModule{}, gov.AppModule{}) + clientCtx := client.Context{}. + WithKeyring(keyring.NewInMemory(encCfg.Codec)). + WithTxConfig(encCfg.TxConfig). + WithCodec(encCfg.Codec). + WithClient(clitestutil.MockCometRPC{Client: rpcclientmock.Client{}}). + WithAccountRetriever(client.MockAccountRetriever{}). + WithOutput(io.Discard). + WithChainID("test-chain"). + WithAddressCodec(addresscodec.NewBech32Codec("cosmos")). + WithValidatorAddressCodec(addresscodec.NewBech32Codec("cosmosvaloper")). + WithConsensusAddressCodec(addresscodec.NewBech32Codec("cosmosvalcons")) + + ctxGen := func() client.Context { + bz, _ := encCfg.Codec.Marshal(&sdk.TxResponse{}) + c := clitestutil.NewMockCometRPC(abci.QueryResponse{ + Value: bz, + }) + return clientCtx.WithClient(c) + } + res.clientCtx = ctxGen() + + // setup keyring + valAcc, _, err := res.clientCtx.Keyring.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) + require.NoError(t, err) + account1, _, err := res.clientCtx.Keyring.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) + require.NoError(t, err) + account2, _, err := res.clientCtx.Keyring.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) + require.NoError(t, err) + _, _, err = res.clientCtx.Keyring.NewMnemonic("dummyAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) // Create a dummy account for testing purpose + require.NoError(t, err) + + res.val, err = valAcc.GetAddress() + require.NoError(t, err) + require.NoError(t, err) + res.val1, err = account1.GetAddress() + require.NoError(t, err) + pub1, err := account1.GetPubKey() + require.NoError(t, err) + pub2, err := account2.GetPubKey() + require.NoError(t, err) + + multi := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{pub1, pub2}) + _, err = res.clientCtx.Keyring.SaveMultisig("multi", multi) + require.NoError(t, err) + return &res } diff --git a/tests/integration/v2/auth/client_test.go b/tests/integration/v2/auth/client_test.go new file mode 100644 index 0000000000..27ee6eb068 --- /dev/null +++ b/tests/integration/v2/auth/client_test.go @@ -0,0 +1,1089 @@ +package auth + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "cosmossdk.io/math" + banktypes "cosmossdk.io/x/bank/types" + govtestutil "cosmossdk.io/x/gov/client/testutil" + govtypes "cosmossdk.io/x/gov/types/v1beta1" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/testutil" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" + authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + authtestutil "github.com/cosmos/cosmos-sdk/x/auth/client/testutil" + "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" +) + +func TestCLIValidateSignatures(t *testing.T) { + f := createTestSuite(t) + + sendTokens := sdk.NewCoins( + sdk.NewCoin("testtoken", math.NewInt(10)), + sdk.NewCoin("stake", math.NewInt(10))) + + res, err := createBankMsg(f.clientCtx, f.val, f.val, sendTokens, clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + // write unsigned tx to file + unsignedTx := testutil.WriteToNewTempFile(t, res.String()) + defer unsignedTx.Close() + + res, err = authtestutil.TxSignExec(f.clientCtx, f.val, unsignedTx.Name()) + require.NoError(t, err) + signedTx, err := f.clientCtx.TxConfig.TxJSONDecoder()(res.Bytes()) + require.NoError(t, err) + + signedTxFile := testutil.WriteToNewTempFile(t, res.String()) + defer signedTxFile.Close() + txBuilder, err := f.clientCtx.TxConfig.WrapTxBuilder(signedTx) + require.NoError(t, err) + _, err = authtestutil.TxValidateSignaturesExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) + + txBuilder.SetMemo("MODIFIED TX") + bz, err := f.clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) + require.NoError(t, err) + + modifiedTxFile := testutil.WriteToNewTempFile(t, string(bz)) + defer modifiedTxFile.Close() + + _, err = authtestutil.TxValidateSignaturesExec(f.clientCtx, modifiedTxFile.Name()) + require.EqualError(t, err, "signatures validation failed") +} + +func TestCLISignBatch(t *testing.T) { + f := createTestSuite(t) + + sendTokens := sdk.NewCoins( + sdk.NewCoin("testtoken", math.NewInt(10)), + sdk.NewCoin("stake", math.NewInt(10)), + ) + + generatedStd, err := createBankMsg(f.clientCtx, f.val, f.val, sendTokens, clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + outputFile := testutil.WriteToNewTempFile(t, strings.Repeat(generatedStd.String(), 3)) + defer outputFile.Close() + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + + // sign-batch file - offline is set but account-number and sequence are not + _, err = authtestutil.TxSignBatchExec(f.clientCtx, f.val, outputFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, f.clientCtx.ChainID), "--offline") + require.EqualError(t, err, "required flag(s) \"account-number\", \"sequence\" not set") + + // sign-batch file - offline and sequence is set but account-number is not set + _, err = authtestutil.TxSignBatchExec(f.clientCtx, f.val, outputFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, f.clientCtx.ChainID), fmt.Sprintf("--%s=%s", flags.FlagSequence, "1"), "--offline") + require.EqualError(t, err, "required flag(s) \"account-number\" not set") + + // sign-batch file - offline and account-number is set but sequence is not set + _, err = authtestutil.TxSignBatchExec(f.clientCtx, f.val, outputFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, f.clientCtx.ChainID), fmt.Sprintf("--%s=%s", flags.FlagAccountNumber, "1"), "--offline") + require.EqualError(t, err, "required flag(s) \"sequence\" not set") +} + +func TestCLISignBatchTotalFees(t *testing.T) { + f := createTestSuite(t) + + txCfg := f.clientCtx.TxConfig + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + + testCases := []struct { + name string + args []string + numTransactions int + denom string + }{ + { + "Offline batch-sign one transaction", + []string{"--offline", "--account-number", "1", "--sequence", "1", "--append"}, + 1, + "stake", + }, + { + "Offline batch-sign two transactions", + []string{"--offline", "--account-number", "1", "--sequence", "1", "--append"}, + 2, + "stake", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Create multiple transactions and write them to separate files + sendTokens := sdk.NewCoin(tc.denom, sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)) + expectedBatchedTotalFee := int64(0) + txFiles := make([]string, tc.numTransactions) + for i := 0; i < tc.numTransactions; i++ { + tx, err := createBankMsg(f.clientCtx, f.val, f.val, sdk.NewCoins(sendTokens), clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + txFile := testutil.WriteToNewTempFile(t, tx.String()+"\n") + txFiles[i] = txFile.Name() + + unsignedTx, err := txCfg.TxJSONDecoder()(tx.Bytes()) + require.NoError(t, err) + txBuilder, err := txCfg.WrapTxBuilder(unsignedTx) + require.NoError(t, err) + expectedBatchedTotalFee += txBuilder.GetTx().GetFee().AmountOf(tc.denom).Int64() + err = txFile.Close() + require.NoError(t, err) + } + + // Test batch sign + batchSignArgs := append([]string{fmt.Sprintf("--from=%s", f.val.String())}, append(txFiles, tc.args...)...) + signedTx, err := clitestutil.ExecTestCLICmd(f.clientCtx, authcli.GetSignBatchCommand(), batchSignArgs) + require.NoError(t, err) + signedFinalTx, err := txCfg.TxJSONDecoder()(signedTx.Bytes()) + require.NoError(t, err) + txBuilder, err := txCfg.WrapTxBuilder(signedFinalTx) + require.NoError(t, err) + finalTotalFee := txBuilder.GetTx().GetFee() + require.Equal(t, expectedBatchedTotalFee, finalTotalFee.AmountOf(tc.denom).Int64()) + }) + } +} + +func TestCLISendGenerateSignAndBroadcast(t *testing.T) { + f := createTestSuite(t) + + sendTokens := sdk.NewCoin("stake", sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)) + + normalGeneratedTx, err := createBankMsg(f.clientCtx, f.val, f.val, sdk.NewCoins(sendTokens), clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + txCfg := f.clientCtx.TxConfig + + normalGeneratedStdTx, err := txCfg.TxJSONDecoder()(normalGeneratedTx.Bytes()) + require.NoError(t, err) + txBuilder, err := txCfg.WrapTxBuilder(normalGeneratedStdTx) + require.NoError(t, err) + require.Equal(t, txBuilder.GetTx().GetGas(), uint64(flags.DefaultGasLimit)) + require.Equal(t, len(txBuilder.GetTx().GetMsgs()), 1) + sigs, err := txBuilder.GetTx().GetSignaturesV2() + require.NoError(t, err) + require.Equal(t, 0, len(sigs)) + + // Test generate sendTx with --gas=$amount + limitedGasGeneratedTx, err := createBankMsg(f.clientCtx, f.val, f.val, + sdk.NewCoins(sendTokens), + clitestutil.TestTxConfig{GenOnly: true, Gas: 100}, + ) + require.NoError(t, err) + + limitedGasStdTx, err := txCfg.TxJSONDecoder()(limitedGasGeneratedTx.Bytes()) + require.NoError(t, err) + txBuilder, err = txCfg.WrapTxBuilder(limitedGasStdTx) + require.NoError(t, err) + require.Equal(t, txBuilder.GetTx().GetGas(), uint64(100)) + require.Equal(t, len(txBuilder.GetTx().GetMsgs()), 1) + sigs, err = txBuilder.GetTx().GetSignaturesV2() + require.NoError(t, err) + require.Equal(t, 0, len(sigs)) + + // Test generate sendTx, estimate gas + finalGeneratedTx, err := createBankMsg(f.clientCtx, f.val, f.val, + sdk.NewCoins(sendTokens), clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + finalStdTx, err := txCfg.TxJSONDecoder()(finalGeneratedTx.Bytes()) + require.NoError(t, err) + txBuilder, err = txCfg.WrapTxBuilder(finalStdTx) + require.NoError(t, err) + require.Equal(t, uint64(flags.DefaultGasLimit), txBuilder.GetTx().GetGas()) + require.Equal(t, len(finalStdTx.GetMsgs()), 1) + + // Write the output to disk + unsignedTxFile := testutil.WriteToNewTempFile(t, finalGeneratedTx.String()) + defer unsignedTxFile.Close() + + // Test validate-signatures + res, err := authtestutil.TxValidateSignaturesExec(f.clientCtx, unsignedTxFile.Name()) + require.EqualError(t, err, "signatures validation failed") + require.Contains(t, res.String(), fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", f.val.String())) + + // Test sign + + // Does not work in offline mode + _, err = authtestutil.TxSignExec(f.clientCtx, f.val, unsignedTxFile.Name(), "--offline") + require.EqualError(t, err, "required flag(s) \"account-number\", \"sequence\" not set") + + // But works offline if we set account number and sequence + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + _, err = authtestutil.TxSignExec(f.clientCtx, f.val, unsignedTxFile.Name(), "--offline", "--account-number", "1", "--sequence", "1") + require.NoError(t, err) + + // Sign transaction + signedTx, err := authtestutil.TxSignExec(f.clientCtx, f.val, unsignedTxFile.Name()) + require.NoError(t, err) + signedFinalTx, err := txCfg.TxJSONDecoder()(signedTx.Bytes()) + require.NoError(t, err) + txBuilder, err = f.clientCtx.TxConfig.WrapTxBuilder(signedFinalTx) + require.NoError(t, err) + require.Equal(t, len(txBuilder.GetTx().GetMsgs()), 1) + sigs, err = txBuilder.GetTx().GetSignaturesV2() + require.NoError(t, err) + require.Equal(t, 1, len(sigs)) + signers, err := txBuilder.GetTx().GetSigners() + require.NoError(t, err) + require.Equal(t, []byte(f.val), signers[0]) + + // Write the output to disk + signedTxFile := testutil.WriteToNewTempFile(t, signedTx.String()) + defer signedTxFile.Close() + + // validate Signature + res, err = authtestutil.TxValidateSignaturesExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) + require.True(t, strings.Contains(res.String(), "[OK]")) + + // Test broadcast + + // Does not work in offline mode + _, err = authtestutil.TxBroadcastExec(f.clientCtx, signedTxFile.Name(), "--offline") + require.EqualError(t, err, "cannot broadcast tx during offline mode") + + // Broadcast correct transaction. + f.clientCtx.BroadcastMode = flags.BroadcastSync + _, err = authtestutil.TxBroadcastExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) +} + +func TestCLIMultisignInsufficientCosigners(t *testing.T) { + f := createTestSuite(t) + + // Fetch account and a multisig info + account1, err := f.clientCtx.Keyring.Key("newAccount1") + require.NoError(t, err) + + multisigRecord, err := f.clientCtx.Keyring.Key("multi") + require.NoError(t, err) + + addr, err := multisigRecord.GetAddress() + require.NoError(t, err) + // Send coins from validator to multisig. + _, err = createBankMsg( + f.clientCtx, + f.val, + addr, + sdk.NewCoins( + sdk.NewInt64Coin("stake", 10), + ), + clitestutil.TestTxConfig{}, + ) + require.NoError(t, err) + + msgSend := &banktypes.MsgSend{ + FromAddress: addr.String(), + ToAddress: f.val.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), + } + + multiGeneratedTx, err := clitestutil.SubmitTestTx( + f.clientCtx, + msgSend, + addr, + clitestutil.TestTxConfig{ + GenOnly: true, + }) + require.NoError(t, err) + + // Save tx to file + multiGeneratedTxFile := testutil.WriteToNewTempFile(t, multiGeneratedTx.String()) + defer multiGeneratedTxFile.Close() + + // Multisign, sign with one signature + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + addr1, err := account1.GetAddress() + require.NoError(t, err) + account1Signature, err := authtestutil.TxSignExec(f.clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) + require.NoError(t, err) + + sign1File := testutil.WriteToNewTempFile(t, account1Signature.String()) + defer sign1File.Close() + + multiSigWith1Signature, err := authtestutil.TxMultiSignExec(f.clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name()) + require.NoError(t, err) + + // Save tx to file + multiSigWith1SignatureFile := testutil.WriteToNewTempFile(t, multiSigWith1Signature.String()) + defer multiSigWith1SignatureFile.Close() + + _, err = authtestutil.TxValidateSignaturesExec(f.clientCtx, multiSigWith1SignatureFile.Name()) + require.Error(t, err) +} + +func TestCLIEncode(t *testing.T) { + f := createTestSuite(t) + + sendTokens := sdk.NewCoin("stake", sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)) + + normalGeneratedTx, err := createBankMsg( + f.clientCtx, f.val, f.val, + sdk.NewCoins(sendTokens), + clitestutil.TestTxConfig{ + GenOnly: true, + Memo: "deadbeef", + }, + ) + require.NoError(t, err) + savedTxFile := testutil.WriteToNewTempFile(t, normalGeneratedTx.String()) + defer savedTxFile.Close() + + // Encode + encodeExec, err := authtestutil.TxEncodeExec(f.clientCtx, savedTxFile.Name()) + require.NoError(t, err) + trimmedBase64 := strings.Trim(encodeExec.String(), "\"\n") + + // Check that the transaction decodes as expected + decodedTx, err := authtestutil.TxDecodeExec(f.clientCtx, trimmedBase64) + require.NoError(t, err) + + txCfg := f.clientCtx.TxConfig + theTx, err := txCfg.TxJSONDecoder()(decodedTx.Bytes()) + require.NoError(t, err) + txBuilder, err := f.clientCtx.TxConfig.WrapTxBuilder(theTx) + require.NoError(t, err) + require.Equal(t, "deadbeef", txBuilder.GetTx().GetMemo()) +} + +func TestCLIMultisignSortSignatures(t *testing.T) { + f := createTestSuite(t) + + // Generate 2 accounts and a multisig. + account1, err := f.clientCtx.Keyring.Key("newAccount1") + require.NoError(t, err) + + account2, err := f.clientCtx.Keyring.Key("newAccount2") + require.NoError(t, err) + + multisigRecord, err := f.clientCtx.Keyring.Key("multi") + require.NoError(t, err) + + // Generate dummy account which is not a part of multisig. + dummyAcc, err := f.clientCtx.Keyring.Key("dummyAccount") + require.NoError(t, err) + + addr, err := multisigRecord.GetAddress() + require.NoError(t, err) + + msgSend := &banktypes.MsgSend{ + FromAddress: addr.String(), + ToAddress: f.val.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), + } + + // Generate multisig transaction. + multiGeneratedTx, err := clitestutil.SubmitTestTx(f.clientCtx, msgSend, addr, clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + // Save tx to file + multiGeneratedTxFile := testutil.WriteToNewTempFile(t, multiGeneratedTx.String()) + defer multiGeneratedTxFile.Close() + + // Sign with account1 + addr1, err := account1.GetAddress() + require.NoError(t, err) + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + account1Signature, err := authtestutil.TxSignExec(f.clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) + require.NoError(t, err) + + sign1File := testutil.WriteToNewTempFile(t, account1Signature.String()) + defer sign1File.Close() + + // Sign with account2 + addr2, err := account2.GetAddress() + require.NoError(t, err) + account2Signature, err := authtestutil.TxSignExec(f.clientCtx, addr2, multiGeneratedTxFile.Name(), "--multisig", addr.String()) + require.NoError(t, err) + + sign2File := testutil.WriteToNewTempFile(t, account2Signature.String()) + defer sign2File.Close() + + // Sign with dummy account + dummyAddr, err := dummyAcc.GetAddress() + require.NoError(t, err) + _, err = authtestutil.TxSignExec(f.clientCtx, dummyAddr, multiGeneratedTxFile.Name(), "--multisig", addr.String()) + require.Error(t, err) + require.Contains(t, err.Error(), "signing key is not a part of multisig key") + + multiSigWith2Signatures, err := authtestutil.TxMultiSignExec(f.clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) + require.NoError(t, err) + + // Write the output to disk + signedTxFile := testutil.WriteToNewTempFile(t, multiSigWith2Signatures.String()) + defer signedTxFile.Close() + + _, err = authtestutil.TxValidateSignaturesExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) + + f.clientCtx.BroadcastMode = flags.BroadcastSync + _, err = authtestutil.TxBroadcastExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) +} + +func TestSignWithMultisig(t *testing.T) { + f := createTestSuite(t) + + // Generate a account for signing. + account1, err := f.clientCtx.Keyring.Key("newAccount1") + require.NoError(t, err) + + addr1, err := account1.GetAddress() + require.NoError(t, err) + + // Create an address that is not in the keyring, will be used to simulate `--multisig` + multisig := "cosmos1hd6fsrvnz6qkp87s3u86ludegq97agxsdkwzyh" + _, err = f.clientCtx.AddressCodec.StringToBytes(multisig) + require.NoError(t, err) + + msgSend := &banktypes.MsgSend{ + FromAddress: f.val.String(), + ToAddress: f.val.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), + } + + // Generate a transaction for testing --multisig with an address not in the keyring. + multisigTx, err := clitestutil.SubmitTestTx(f.clientCtx, msgSend, f.val, clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + // Save multi tx to file + multiGeneratedTx2File := testutil.WriteToNewTempFile(t, multisigTx.String()) + defer multiGeneratedTx2File.Close() + + // Sign using multisig. We're signing a tx on behalf of the multisig address, + // even though the tx signer is NOT the multisig address. This is fine though, + // as the main point of this test is to test the `--multisig` flag with an address + // that is not in the keyring. + _, err = authtestutil.TxSignExec(f.clientCtx, addr1, multiGeneratedTx2File.Name(), "--multisig", multisig) + require.Contains(t, err.Error(), "error getting account from keybase") +} + +func TestCLIMultisign(t *testing.T) { + f := createTestSuite(t) + + // Generate 2 accounts and a multisig. + account1, err := f.clientCtx.Keyring.Key("newAccount1") + require.NoError(t, err) + + account2, err := f.clientCtx.Keyring.Key("newAccount2") + require.NoError(t, err) + + multisigRecord, err := f.clientCtx.Keyring.Key("multi") + require.NoError(t, err) + + addr, err := multisigRecord.GetAddress() + require.NoError(t, err) + + msgSend := &banktypes.MsgSend{ + FromAddress: addr.String(), + ToAddress: f.val.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), + } + + // Generate multisig transaction. + multiGeneratedTx, err := clitestutil.SubmitTestTx(f.clientCtx, msgSend, addr, clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + // Save tx to file + multiGeneratedTxFile := testutil.WriteToNewTempFile(t, multiGeneratedTx.String()) + defer multiGeneratedTxFile.Close() + + addr1, err := account1.GetAddress() + require.NoError(t, err) + // Sign with account1 + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + account1Signature, err := authtestutil.TxSignExec(f.clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) + require.NoError(t, err) + + sign1File := testutil.WriteToNewTempFile(t, account1Signature.String()) + defer sign1File.Close() + + addr2, err := account2.GetAddress() + require.NoError(t, err) + // Sign with account2 + account2Signature, err := authtestutil.TxSignExec(f.clientCtx, addr2, multiGeneratedTxFile.Name(), "--multisig", addr.String()) + require.NoError(t, err) + + sign2File := testutil.WriteToNewTempFile(t, account2Signature.String()) + defer sign2File.Close() + + f.clientCtx.Offline = false + multiSigWith2Signatures, err := authtestutil.TxMultiSignExec(f.clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) + require.NoError(t, err) + + // Write the output to disk + signedTxFile := testutil.WriteToNewTempFile(t, multiSigWith2Signatures.String()) + defer signedTxFile.Close() + + _, err = authtestutil.TxValidateSignaturesExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) + + f.clientCtx.BroadcastMode = flags.BroadcastSync + _, err = authtestutil.TxBroadcastExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) +} + +func TestSignBatchMultisig(t *testing.T) { + f := createTestSuite(t) + + // Fetch 2 accounts and a multisig. + account1, err := f.clientCtx.Keyring.Key("newAccount1") + require.NoError(t, err) + account2, err := f.clientCtx.Keyring.Key("newAccount2") + require.NoError(t, err) + multisigRecord, err := f.clientCtx.Keyring.Key("multi") + require.NoError(t, err) + + addr, err := multisigRecord.GetAddress() + require.NoError(t, err) + // Send coins from validator to multisig. + sendTokens := sdk.NewInt64Coin("stake", 10) + _, err = createBankMsg( + f.clientCtx, + f.val, + addr, + sdk.NewCoins(sendTokens), + clitestutil.TestTxConfig{}, + ) + require.NoError(t, err) + + msgSend := &banktypes.MsgSend{ + FromAddress: addr.String(), + ToAddress: f.val.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 5)), + } + + generatedStd, err := clitestutil.SubmitTestTx(f.clientCtx, msgSend, addr, clitestutil.TestTxConfig{GenOnly: true}) + require.NoError(t, err) + + // Write the output to disk + filename := testutil.WriteToNewTempFile(t, strings.Repeat(generatedStd.String(), 1)) + defer filename.Close() + f.clientCtx.HomeDir = strings.Replace(f.clientCtx.HomeDir, "simd", "simcli", 1) + + addr1, err := account1.GetAddress() + require.NoError(t, err) + // sign-batch file + res, err := authtestutil.TxSignBatchExec(f.clientCtx, addr1, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, f.clientCtx.ChainID), "--multisig", addr.String(), "--signature-only") + require.NoError(t, err) + require.Equal(t, 1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) + // write sigs to file + file1 := testutil.WriteToNewTempFile(t, res.String()) + defer file1.Close() + + addr2, err := account2.GetAddress() + require.NoError(t, err) + // sign-batch file with account2 + res, err = authtestutil.TxSignBatchExec(f.clientCtx, addr2, filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, f.clientCtx.ChainID), "--multisig", addr.String(), "--signature-only") + require.NoError(t, err) + require.Equal(t, 1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n"))) + // write sigs to file2 + file2 := testutil.WriteToNewTempFile(t, res.String()) + defer file2.Close() + _, err = authtestutil.TxMultiSignExec(f.clientCtx, multisigRecord.Name, filename.Name(), file1.Name(), file2.Name()) + require.NoError(t, err) +} + +func TestGetBroadcastCommandOfflineFlag(t *testing.T) { + cmd := authcli.GetBroadcastCommand() + _ = testutil.ApplyMockIODiscardOutErr(cmd) + cmd.SetArgs([]string{fmt.Sprintf("--%s=true", flags.FlagOffline), ""}) + + require.EqualError(t, cmd.Execute(), "cannot broadcast tx during offline mode") +} + +func TestGetBroadcastCommandWithoutOfflineFlag(t *testing.T) { + f := createTestSuite(t) + + txCfg := f.clientCtx.TxConfig + clientCtx := client.Context{} + clientCtx = clientCtx.WithTxConfig(txCfg) + + ctx := context.Background() + ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) + + cmd := authcli.GetBroadcastCommand() + _, out := testutil.ApplyMockIO(cmd) + + // Create new file with tx + builder := txCfg.NewTxBuilder() + builder.SetGasLimit(200000) + + err := builder.SetMsgs(banktypes.NewMsgSend("cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw", "cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw", sdk.Coins{sdk.NewInt64Coin("stake", 10000)})) + require.NoError(t, err) + txContents, err := txCfg.TxJSONEncoder()(builder.GetTx()) + require.NoError(t, err) + txFile := testutil.WriteToNewTempFile(t, string(txContents)) + defer txFile.Close() + + cmd.SetArgs([]string{txFile.Name()}) + err = cmd.ExecuteContext(ctx) + require.Error(t, err) + require.Contains(t, err.Error(), "connect: connection refused") + require.Contains(t, out.String(), "connect: connection refused") +} + +// TestTxWithoutPublicKey makes sure sending a proto tx message without the +// public key doesn't cause any error in the RPC layer (broadcast). +// See https://github.com/cosmos/cosmos-sdk/issues/7585 for more details. +func TestTxWithoutPublicKey(t *testing.T) { + f := createTestSuite(t) + + txCfg := f.clientCtx.TxConfig + + valStr, err := f.clientCtx.AddressCodec.BytesToString(f.val) + require.NoError(t, err) + + // Create a txBuilder with an unsigned tx. + txBuilder := txCfg.NewTxBuilder() + msg := banktypes.NewMsgSend(valStr, valStr, sdk.NewCoins( + sdk.NewCoin("Stake", math.NewInt(10)), + )) + err = txBuilder.SetMsgs(msg) + require.NoError(t, err) + txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("Stake", math.NewInt(150)))) + txBuilder.SetGasLimit(testdata.NewTestGasLimit()) + + // Create a file with the unsigned tx. + txJSON, err := txCfg.TxJSONEncoder()(txBuilder.GetTx()) + require.NoError(t, err) + unsignedTxFile := testutil.WriteToNewTempFile(t, string(txJSON)) + defer unsignedTxFile.Close() + + // Sign the file with the unsignedTx. + signedTx, err := authtestutil.TxSignExec(f.clientCtx, f.val, unsignedTxFile.Name(), fmt.Sprintf("--%s=true", cli.FlagOverwrite)) + require.NoError(t, err) + + // Remove the signerInfo's `public_key` field manually from the signedTx. + // Note: this method is only used for test purposes! In general, one should + // use txBuilder and TxEncoder/TxDecoder to manipulate txs. + var tx tx.Tx + err = f.clientCtx.Codec.UnmarshalJSON(signedTx.Bytes(), &tx) + require.NoError(t, err) + tx.AuthInfo.SignerInfos[0].PublicKey = nil + // Re-encode the tx again, to another file. + txJSON, err = f.clientCtx.Codec.MarshalJSON(&tx) + require.NoError(t, err) + signedTxFile := testutil.WriteToNewTempFile(t, string(txJSON)) + defer signedTxFile.Close() + require.True(t, strings.Contains(string(txJSON), "\"public_key\":null")) + + // Broadcast tx, test that it shouldn't panic. + f.clientCtx.BroadcastMode = flags.BroadcastSync + out, err := authtestutil.TxBroadcastExec(f.clientCtx, signedTxFile.Name()) + require.NoError(t, err) + var res sdk.TxResponse + require.NoError(t, f.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res)) + require.NotEqual(t, 0, res.Code) +} + +// TestSignWithMultiSignersAminoJSON tests the case where a transaction with 2 +// messages which has to be signed with 2 different keys. Sign and append the +// signatures using the CLI with Amino signing mode. Finally, send the +// transaction to the blockchain. +func TestSignWithMultiSignersAminoJSON(t *testing.T) { + f := createTestSuite(t) + + val0, val1 := f.val, f.val1 + val0Coin := sdk.NewCoin("test1token", math.NewInt(10)) + val1Coin := sdk.NewCoin("test2token", math.NewInt(10)) + _, _, addr1 := testdata.KeyTestPubAddr() + + valStr, err := f.clientCtx.AddressCodec.BytesToString(val0) + require.NoError(t, err) + val1Str, err := f.clientCtx.AddressCodec.BytesToString(val1) + require.NoError(t, err) + + addrStr, err := f.clientCtx.AddressCodec.BytesToString(addr1) + require.NoError(t, err) + // Creating a tx with 2 msgs from 2 signers: val0 and val1. + // The validators need to sign with SIGN_MODE_LEGACY_AMINO_JSON, + // because DIRECT doesn't support multi signers via the CLI. + // Since we use amino, we don't need to pre-populate signer_infos. + txBuilder := f.clientCtx.TxConfig.NewTxBuilder() + err = txBuilder.SetMsgs( + banktypes.NewMsgSend(valStr, addrStr, sdk.NewCoins(val0Coin)), + banktypes.NewMsgSend(val1Str, addrStr, sdk.NewCoins(val1Coin)), + ) + require.NoError(t, err) + txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10)))) + txBuilder.SetGasLimit(testdata.NewTestGasLimit() * 2) + signers, err := txBuilder.GetTx().GetSigners() + require.NoError(t, err) + require.Equal(t, [][]byte{val0, val1}, signers) + + // Write the unsigned tx into a file. + txJSON, err := f.clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) + require.NoError(t, err) + unsignedTxFile := testutil.WriteToNewTempFile(t, string(txJSON)) + defer unsignedTxFile.Close() + + // Let val0 sign first the file with the unsignedTx. + signedByVal0, err := authtestutil.TxSignExec(f.clientCtx, val0, unsignedTxFile.Name(), "--overwrite", "--sign-mode=amino-json") + require.NoError(t, err) + signedByVal0File := testutil.WriteToNewTempFile(t, signedByVal0.String()) + defer signedByVal0File.Close() + + // Then let val1 sign the file with signedByVal0. + val1AccNum, val1Seq, err := f.clientCtx.AccountRetriever.GetAccountNumberSequence(f.clientCtx, val1) + require.NoError(t, err) + + signedTx, err := authtestutil.TxSignExec( + f.clientCtx, + val1, + signedByVal0File.Name(), + "--offline", + fmt.Sprintf("--account-number=%d", val1AccNum), + fmt.Sprintf("--sequence=%d", val1Seq), + "--sign-mode=amino-json", + ) + require.NoError(t, err) + signedTxFile := testutil.WriteToNewTempFile(t, signedTx.String()) + defer signedTxFile.Close() + + res, err := authtestutil.TxBroadcastExec( + f.clientCtx, + signedTxFile.Name(), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + ) + require.NoError(t, err) + + var txRes sdk.TxResponse + require.NoError(t, f.clientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) + require.Equal(t, uint32(0), txRes.Code, txRes.RawLog) +} + +func TestAuxSigner(t *testing.T) { + t.Skip("re-enable this when we bring back sign mode aux client testing") + val0Coin := sdk.NewCoin("testtoken", math.NewInt(10)) + + f := createTestSuite(t) + + testCases := []struct { + name string + args []string + expectErr bool + }{ + { + "error with SIGN_MODE_DIRECT_AUX and --aux unset", + []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + }, + true, + }, + { + "no error with SIGN_MDOE_DIRECT_AUX mode and generate-only set (ignores generate-only)", + []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), + }, + false, + }, + { + "no error with SIGN_MDOE_DIRECT_AUX mode and generate-only, tip flag set", + []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), + fmt.Sprintf("--%s=%s", flags.FlagTip, val0Coin.String()), + }, + false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, err := govtestutil.MsgSubmitLegacyProposal( + f.clientCtx, + f.val.String(), + "test", + "test desc", + govtypes.ProposalTypeText, + tc.args..., + ) + if tc.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestAuxToFeeWithTips(t *testing.T) { + // Skipping this test as it needs a simapp with the TipDecorator in post handler. + t.Skip() + + f := createTestSuite(t) + + kb := f.clientCtx.Keyring + acc, _, err := kb.NewMnemonic("tipperAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) + require.NoError(t, err) + + tipper, err := acc.GetAddress() + require.NoError(t, err) + tipperInitialBal := sdk.NewCoin("testtoken", math.NewInt(10000)) + + feePayer := f.val + fee := sdk.NewCoin("stake", math.NewInt(1000)) + tip := sdk.NewCoin("testtoken", math.NewInt(1000)) + + _, err = createBankMsg(f.clientCtx, f.val, tipper, sdk.NewCoins(tipperInitialBal), clitestutil.TestTxConfig{}) + require.NoError(t, err) + + bal := getBalances(t, f.clientCtx, tipper, tip.Denom) + require.True(t, bal.Equal(tipperInitialBal.Amount)) + + testCases := []struct { + name string + tipper sdk.AccAddress + feePayer sdk.AccAddress + tip sdk.Coin + expectErrAux bool + expectErrBroadCast bool + errMsg string + tipperArgs []string + feePayerArgs []string + }{ + { + name: "when --aux and --sign-mode = direct set: error", + tipper: tipper, + feePayer: feePayer, + tip: tip, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirect), + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + expectErrAux: true, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + }, + { + name: "both tipper, fee payer uses AMINO: no error", + tipper: tipper, + feePayer: feePayer, + tip: tip, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + }, + { + name: "tipper uses DIRECT_AUX, fee payer uses AMINO: no error", + tipper: tipper, + feePayer: feePayer, + tip: tip, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + }, + { + name: "--tip flag unset: no error", + tipper: tipper, + feePayer: feePayer, + tip: sdk.Coin{Denom: "testtoken", Amount: math.NewInt(0)}, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + }, + { + name: "legacy amino json: no error", + tipper: tipper, + feePayer: feePayer, + tip: tip, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + }, + { + name: "tipper uses direct aux, fee payer uses direct: happy case", + tipper: tipper, + feePayer: feePayer, + tip: tip, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + }, + { + name: "chain-id mismatch: error", + tipper: tipper, + feePayer: feePayer, + tip: tip, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + expectErrAux: false, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + fmt.Sprintf("--%s=%s", flags.FlagChainID, "foobar"), + }, + expectErrBroadCast: true, + }, + { + name: "wrong denom in tip: error", + tipper: tipper, + feePayer: feePayer, + tip: sdk.Coin{Denom: "testtoken", Amount: math.NewInt(0)}, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagTip, "1000wrongDenom"), + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirect), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + fmt.Sprintf("--%s=%s", flags.FlagFees, fee.String()), + }, + errMsg: "insufficient funds", + }, + { + name: "insufficient fees: less error", + tipper: tipper, + feePayer: feePayer, + tip: sdk.Coin{Denom: "testtoken", Amount: math.NewInt(0)}, + tipperArgs: []string{ + fmt.Sprintf("--%s=%s", flags.FlagTip, tip), + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirectAux), + fmt.Sprintf("--%s=true", flags.FlagAux), + }, + feePayerArgs: []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeDirect), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFrom, feePayer), + }, + errMsg: "insufficient fees", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := govtestutil.MsgSubmitLegacyProposal( + f.clientCtx, + tipper.String(), + "test", + "test desc", + govtypes.ProposalTypeText, + tc.tipperArgs..., + ) + + if tc.expectErrAux { + require.Error(t, err) + } else { + require.NoError(t, err) + genTxFile := testutil.WriteToNewTempFile(t, string(res.Bytes())) + defer genTxFile.Close() + + switch { + case tc.expectErrBroadCast: + require.Error(t, err) + + case tc.errMsg != "": + require.NoError(t, err) + + var txRes sdk.TxResponse + require.NoError(t, f.clientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) + require.Contains(t, txRes.RawLog, tc.errMsg) + + default: + require.NoError(t, err) + + var txRes sdk.TxResponse + require.NoError(t, f.clientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) + + require.Equal(t, uint32(0), txRes.Code) + require.NotNil(t, int64(0), txRes.Height) + + bal = getBalances(t, f.clientCtx, tipper, tc.tip.Denom) + tipperInitialBal = tipperInitialBal.Sub(tc.tip) + require.True(t, bal.Equal(tipperInitialBal.Amount)) + } + } + }) + } +} + +func getBalances(t *testing.T, clientCtx client.Context, addr sdk.AccAddress, denom string) math.Int { + t.Helper() + + resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s/by_denom?denom=%s", clientCtx.NodeURI, addr.String(), denom)) + require.NoError(t, err) + + var balRes banktypes.QueryAllBalancesResponse + err = clientCtx.Codec.UnmarshalJSON(resp, &balRes) + require.NoError(t, err) + startTokens := balRes.Balances.AmountOf(denom) + return startTokens +} + +func createBankMsg(clientCtx client.Context, valAddr, toAddr sdk.AccAddress, amount sdk.Coins, cfg clitestutil.TestTxConfig) (testutil.BufferWriter, error) { + msgSend := &banktypes.MsgSend{ + FromAddress: valAddr.String(), + ToAddress: toAddr.String(), + Amount: amount, + } + + return clitestutil.SubmitTestTx(clientCtx, msgSend, valAddr, cfg) +} diff --git a/tests/systemtests/go.mod b/tests/systemtests/go.mod index 6f72a3d018..d6ad3efc70 100644 --- a/tests/systemtests/go.mod +++ b/tests/systemtests/go.mod @@ -2,6 +2,8 @@ module github.com/cosmos/cosmos-sdk/tests/systemtests go 1.23 +replace cosmossdk.io/systemtests => ../../systemtests + require ( cosmossdk.io/math v1.5.0 cosmossdk.io/systemtests v1.0.0 @@ -9,11 +11,6 @@ require ( github.com/fullstorydev/grpcurl v1.9.2 ) -require ( - golang.org/x/arch v0.13.0 // indirect - golang.org/x/crypto v0.32.0 // indirect -) - require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect @@ -58,7 +55,7 @@ require ( github.com/cosmos/iavl v1.2.2 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect - github.com/creachadair/tomledit v0.0.26 // indirect + github.com/creachadair/tomledit v0.0.27 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect @@ -161,6 +158,8 @@ require ( go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect + golang.org/x/arch v0.13.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/sync v0.10.0 // indirect diff --git a/tests/systemtests/go.sum b/tests/systemtests/go.sum index 9681b9c56f..163049dae3 100644 --- a/tests/systemtests/go.sum +++ b/tests/systemtests/go.sum @@ -20,8 +20,6 @@ cosmossdk.io/math v1.5.0 h1:sbOASxee9Zxdjd6OkzogvBZ25/hP929vdcYcBJQbkLc= cosmossdk.io/math v1.5.0/go.mod h1:AAwwBmUhqtk2nlku174JwSll+/DepUXW3rWIXN5q+Nw= cosmossdk.io/store v1.1.1 h1:NA3PioJtWDVU7cHHeyvdva5J/ggyLDkyH0hGHl2804Y= cosmossdk.io/store v1.1.1/go.mod h1:8DwVTz83/2PSI366FERGbWSH7hL6sB7HbYp8bqksNwM= -cosmossdk.io/systemtests v1.0.0 h1:VuEj4aA//v1icbMoA6UMuWOwO6ejb6uK7PzSBT+Y460= -cosmossdk.io/systemtests v1.0.0/go.mod h1:6kl2MKa7tLoW8vgKx4ZgwAqWVD1T7eAiL5mc/9R7XGY= cosmossdk.io/x/tx v1.1.0 h1:5C5XGNGYzbOTKbcf47oBI/VLObb5bmcMqH/C6H/sp1E= cosmossdk.io/x/tx v1.1.0/go.mod h1:QF15QyTcGH4wfKawfRdSihWwutf4OhgiA+HIwWhjle0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -174,8 +172,8 @@ github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5n github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creachadair/tomledit v0.0.26 h1:MoDdgHIHZ5PctBVsAZDjxdxreWUEa9ObPKTRkk5PPwA= -github.com/creachadair/tomledit v0.0.26/go.mod h1:SJi1OxKpMyR141tq1lzsbPtIg3j8TeVPM/ZftfieD7o= +github.com/creachadair/tomledit v0.0.27 h1:6xOpEnkKmcpT/gmKhabN0JXrqNX065lyje1/mXTSSIE= +github.com/creachadair/tomledit v0.0.27/go.mod h1:v1EWpgCisD3ct1kO8Gq4o4pdgX5JXD0rBI2PJ4UnPoA= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= diff --git a/tests/systemtests/init_test.go b/tests/systemtests/init_test.go new file mode 100644 index 0000000000..5440b95b5e --- /dev/null +++ b/tests/systemtests/init_test.go @@ -0,0 +1,67 @@ +//go:build system_test + +package systemtests + +import ( + "encoding/json" + "fmt" + "os" + "path" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + systest "cosmossdk.io/systemtests" + + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" +) + +func TestChainInit(t *testing.T) { + systest.Sut.ResetChain(t) + cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose) + + removeGenesis(t) + // init with height + testInitialHeight := int64(333) + cli.RunCommandWithArgs("init", "test-height", "--initial-height", fmt.Sprintf("%d", testInitialHeight), "--home="+systest.Sut.NodeDir(0)) + appGenesis, err := genutiltypes.AppGenesisFromFile(systest.Sut.NodeDir(0) + "/config/genesis.json") + require.NoError(t, err) + require.Equal(t, testInitialHeight, appGenesis.InitialHeight) + + removeGenesis(t) + // init with negative height + testInitialHeight = -333 + cli.RunCommandWithArgs("init", "test-height", "--initial-height", fmt.Sprintf("%d", testInitialHeight), "--home="+systest.Sut.NodeDir(0)) + appGenesis, err = genutiltypes.AppGenesisFromFile(systest.Sut.NodeDir(0) + "/config/genesis.json") + require.NoError(t, err) + require.Equal(t, int64(1), appGenesis.InitialHeight) + + removeGenesis(t) + // init with custom denom + customDenom := "mydenom" + cli.RunCommandWithArgs("init", "test-denom", "--default-denom", customDenom, "--home="+systest.Sut.NodeDir(0)) + appGenesis, err = genutiltypes.AppGenesisFromFile(systest.Sut.NodeDir(0) + "/config/genesis.json") + require.NoError(t, err) + var appState struct { + Staking struct { + Params struct { + BondDenom string `json:"bond_denom"` + } `json:"params"` + } `json:"staking"` + } + err = json.Unmarshal(appGenesis.AppState, &appState) + require.NoError(t, err) + require.Equal(t, customDenom, appState.Staking.Params.BondDenom) + + removeGenesis(t) + // init with recover + mnemonic := strings.NewReader("decide praise business actor peasant farm drastic weather extend front hurt later song give verb rhythm worry fun pond reform school tumble august one") + cli.RunCommandWithInputAndArgs(mnemonic, "init", "test-denom", "--recover", "--home="+systest.Sut.NodeDir(0)) + _, err = os.Stat(path.Join(systest.Sut.NodeDir(0), "config", "genesis.json")) + require.NoError(t, err) +} + +func removeGenesis(t *testing.T) { + require.NoError(t, os.Remove(path.Join(systest.Sut.NodeDir(0), "config", "genesis.json"))) +} diff --git a/tests/integration/type_check.go b/tests/type_check.go similarity index 94% rename from tests/integration/type_check.go rename to tests/type_check.go index 2982f79ea6..aa29ce3362 100644 --- a/tests/integration/type_check.go +++ b/tests/type_check.go @@ -1,4 +1,4 @@ -package integration +package tests import ( db "github.com/cosmos/cosmos-db" diff --git a/testutil/x/genutil/helper.go b/testutil/x/genutil/helper.go deleted file mode 100644 index a6eae578d0..0000000000 --- a/testutil/x/genutil/helper.go +++ /dev/null @@ -1,74 +0,0 @@ -package genutil - -import ( - "context" - "fmt" - "path/filepath" - - cmtcfg "github.com/cometbft/cometbft/config" - "github.com/spf13/viper" - - corectx "cosmossdk.io/core/context" - "cosmossdk.io/log" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/types/module" - genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" -) - -func ExecInitCmd(mm *module.Manager, home string, cdc codec.Codec) error { - logger := log.NewNopLogger() - viper := viper.New() - cmd := genutilcli.InitCmd(mm) - cfg, _ := CreateDefaultCometConfig(home) - err := WriteAndTrackCometConfig(viper, home, cfg) - if err != nil { - return err - } - clientCtx := client.Context{}.WithCodec(cdc).WithHomeDir(home) - - _, out := testutil.ApplyMockIO(cmd) - clientCtx = clientCtx.WithOutput(out) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, corectx.ViperContextKey, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger) - - cmd.SetArgs([]string{"appnode-test"}) - - return cmd.ExecuteContext(ctx) -} - -func CreateDefaultCometConfig(rootDir string) (*cmtcfg.Config, error) { - conf := cmtcfg.DefaultConfig() - conf.SetRoot(rootDir) - cmtcfg.EnsureRoot(rootDir) - - if err := conf.ValidateBasic(); err != nil { - return nil, fmt.Errorf("error in config file: %w", err) - } - - return conf, nil -} - -func WriteAndTrackCometConfig(v *viper.Viper, home string, cfg *cmtcfg.Config) error { - cmtcfg.WriteConfigFile(filepath.Join(home, "config", "config.toml"), cfg) - - v.Set(flags.FlagHome, home) - v.SetConfigType("toml") - v.SetConfigName("config") - v.AddConfigPath(filepath.Join(home, "config")) - return v.ReadInConfig() -} - -func TrackCometConfig(v *viper.Viper, home string) error { - v.Set(flags.FlagHome, home) - v.SetConfigType("toml") - v.SetConfigName("config") - v.AddConfigPath(filepath.Join(home, "config")) - return v.ReadInConfig() -} diff --git a/tools/benchmark/go.mod b/tools/benchmark/go.mod index fa34b466d7..67ee8fc6b0 100644 --- a/tools/benchmark/go.mod +++ b/tools/benchmark/go.mod @@ -20,7 +20,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/collections v1.1.0 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.5.0 // indirect cosmossdk.io/schema v1.0.0 // indirect diff --git a/tools/benchmark/go.sum b/tools/benchmark/go.sum index dc3a2d3aba..9402050ee1 100644 --- a/tools/benchmark/go.sum +++ b/tools/benchmark/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/accounts/defaults/base/go.mod b/x/accounts/defaults/base/go.mod index 6f505f8bc6..cc3ea0e36b 100644 --- a/x/accounts/defaults/base/go.mod +++ b/x/accounts/defaults/base/go.mod @@ -19,7 +19,7 @@ require ( require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.5.0 // indirect cosmossdk.io/math v1.5.0 // indirect diff --git a/x/accounts/defaults/base/go.sum b/x/accounts/defaults/base/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/accounts/defaults/base/go.sum +++ b/x/accounts/defaults/base/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/accounts/defaults/lockup/go.mod b/x/accounts/defaults/lockup/go.mod index 1b067811e8..507ad26144 100644 --- a/x/accounts/defaults/lockup/go.mod +++ b/x/accounts/defaults/lockup/go.mod @@ -28,7 +28,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/api v0.8.2 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/depinject v1.1.0 // indirect cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 diff --git a/x/accounts/defaults/lockup/go.sum b/x/accounts/defaults/lockup/go.sum index dc3a2d3aba..9402050ee1 100644 --- a/x/accounts/defaults/lockup/go.sum +++ b/x/accounts/defaults/lockup/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/accounts/defaults/multisig/go.mod b/x/accounts/defaults/multisig/go.mod index 63d2798a96..b045500667 100644 --- a/x/accounts/defaults/multisig/go.mod +++ b/x/accounts/defaults/multisig/go.mod @@ -19,7 +19,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/api v0.8.2 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/depinject v1.1.0 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.5.0 // indirect diff --git a/x/accounts/defaults/multisig/go.sum b/x/accounts/defaults/multisig/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/accounts/defaults/multisig/go.sum +++ b/x/accounts/defaults/multisig/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/accounts/go.mod b/x/accounts/go.mod index 6c14e72b5e..31d5c24762 100644 --- a/x/accounts/go.mod +++ b/x/accounts/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/tx v1.1.0 diff --git a/x/accounts/go.sum b/x/accounts/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/accounts/go.sum +++ b/x/accounts/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/authz/go.mod b/x/authz/go.mod index 2ba22d7bfd..48d1bd274c 100644 --- a/x/authz/go.mod +++ b/x/authz/go.mod @@ -149,7 +149,7 @@ require ( ) require ( - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000 cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 ) diff --git a/x/authz/go.sum b/x/authz/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/authz/go.sum +++ b/x/authz/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/bank/go.mod b/x/bank/go.mod index 7014bf8dc2..7113342f31 100644 --- a/x/bank/go.mod +++ b/x/bank/go.mod @@ -30,7 +30,7 @@ require ( require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect diff --git a/x/bank/go.sum b/x/bank/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/bank/go.sum +++ b/x/bank/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/circuit/go.mod b/x/circuit/go.mod index 6abd90b0b3..519164a757 100644 --- a/x/circuit/go.mod +++ b/x/circuit/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/schema v1.0.0 diff --git a/x/circuit/go.sum b/x/circuit/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/circuit/go.sum +++ b/x/circuit/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/consensus/go.mod b/x/consensus/go.mod index 474b302c18..463784cd79 100644 --- a/x/consensus/go.mod +++ b/x/consensus/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/schema v1.0.0 cosmossdk.io/store v1.10.0-rc.1 diff --git a/x/consensus/go.sum b/x/consensus/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/consensus/go.sum +++ b/x/consensus/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/distribution/go.mod b/x/distribution/go.mod index 396e34d20d..895e3a166c 100644 --- a/x/distribution/go.mod +++ b/x/distribution/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.5.0 diff --git a/x/distribution/go.sum b/x/distribution/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/distribution/go.sum +++ b/x/distribution/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/epochs/go.mod b/x/epochs/go.mod index 9eb4c2d9b7..d0dc2c1072 100644 --- a/x/epochs/go.mod +++ b/x/epochs/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/store v1.10.0-rc.1 diff --git a/x/epochs/go.sum b/x/epochs/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/epochs/go.sum +++ b/x/epochs/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/evidence/go.mod b/x/evidence/go.mod index ffa2995dba..b4038c3807 100644 --- a/x/evidence/go.mod +++ b/x/evidence/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.5.0 diff --git a/x/evidence/go.sum b/x/evidence/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/evidence/go.sum +++ b/x/evidence/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/feegrant/go.mod b/x/feegrant/go.mod index 9e0f0a4a15..508fa85ff6 100644 --- a/x/feegrant/go.mod +++ b/x/feegrant/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.5.0 diff --git a/x/feegrant/go.sum b/x/feegrant/go.sum index b1844b1cda..cef31c7aa4 100644 --- a/x/feegrant/go.sum +++ b/x/feegrant/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/genutil/genaccounts.go b/x/genutil/genaccounts.go index d3472fb792..ad6e9539f9 100644 --- a/x/genutil/genaccounts.go +++ b/x/genutil/genaccounts.go @@ -44,12 +44,41 @@ func AddGenesisAccounts( return fmt.Errorf("failed to unmarshal genesis state: %w", err) } + modifiedAppState, err := AddGenesisAccountsWithGenesis( + cdc, + addressCodec, + accounts, + appendAcct, + appState, + ) + if err != nil { + return err + } + + appStateJSON, err := json.Marshal(modifiedAppState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + + appGenesis.AppState = appStateJSON + return ExportGenesisFile(appGenesis, genesisFileURL) +} + +// AddGenesisAccountsWithGenesis modifies the provided appState by adding the provided genesis accounts. +// It returns the modified appState. +func AddGenesisAccountsWithGenesis( + cdc codec.Codec, + addressCodec address.Codec, + accounts []GenesisAccount, + appendAcct bool, + appState map[string]json.RawMessage, +) (map[string]json.RawMessage, error) { authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState) bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState) accs, err := authtypes.UnpackAccounts(authGenState.Accounts) if err != nil { - return fmt.Errorf("failed to get accounts from any: %w", err) + return nil, fmt.Errorf("failed to get accounts from any: %w", err) } newSupplyCoinsCache := sdk.NewCoins() @@ -62,13 +91,20 @@ func AddGenesisAccounts( } } + // check if provided accounts aren't duplicated + mapAddr := make(map[string]struct{}, len(accounts)) for _, acc := range accounts { + if _, ok := mapAddr[acc.Address]; ok { + return nil, fmt.Errorf("duplicate account address provided in arguments: %s", acc.Address) + } + mapAddr[acc.Address] = struct{}{} + addr := acc.Address coins := acc.Coins accAddr, err := addressCodec.StringToBytes(addr) if err != nil { - return fmt.Errorf("failed to parse account address %s: %w", addr, err) + return nil, fmt.Errorf("failed to parse account address %s: %w", addr, err) } // create concrete account type based on input parameters @@ -84,12 +120,12 @@ func AddGenesisAccounts( baseVestingAccount, err := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd) if err != nil { - return fmt.Errorf("failed to create base vesting account: %w", err) + return nil, fmt.Errorf("failed to create base vesting account: %w", err) } if (balances.Coins.IsZero() && !baseVestingAccount.OriginalVesting.IsZero()) || baseVestingAccount.OriginalVesting.IsAnyGT(balances.Coins) { - return errors.New("vesting amount cannot be greater than total amount") + return nil, errors.New("vesting amount cannot be greater than total amount") } switch { @@ -100,7 +136,7 @@ func AddGenesisAccounts( genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount) default: - return errors.New("invalid vesting parameters; must supply start and end time or end time") + return nil, errors.New("invalid vesting parameters; must supply start and end time or end time") } } else if acc.ModuleName != "" { genAccount = authtypes.NewEmptyModuleAccount(acc.ModuleName, authtypes.Burner, authtypes.Minter) @@ -109,12 +145,12 @@ func AddGenesisAccounts( } if err := genAccount.Validate(); err != nil { - return fmt.Errorf("failed to validate new genesis account: %w", err) + return nil, fmt.Errorf("failed to validate new genesis account: %w", err) } if _, ok := balanceCache[addr]; ok { if !appendAcct { - return fmt.Errorf(" Account %s already exists\nUse `append` flag to append account at existing address", accAddr) + return nil, fmt.Errorf(" Account %s already exists\nUse `append` flag to append account at existing address", accAddr) } for idx, acc := range bankGenState.Balances { @@ -138,31 +174,24 @@ func AddGenesisAccounts( authGenState.Accounts, err = authtypes.PackAccounts(accs) if err != nil { - return fmt.Errorf("failed to convert accounts into any's: %w", err) + return nil, fmt.Errorf("failed to convert accounts into any's: %w", err) } appState[authtypes.ModuleName], err = cdc.MarshalJSON(&authGenState) if err != nil { - return fmt.Errorf("failed to marshal auth genesis state: %w", err) + return nil, fmt.Errorf("failed to marshal auth genesis state: %w", err) } bankGenState.Balances, err = banktypes.SanitizeGenesisBalances(bankGenState.Balances, addressCodec) if err != nil { - return fmt.Errorf("failed to sanitize genesis bank Balances: %w", err) + return nil, fmt.Errorf("failed to sanitize genesis bank Balances: %w", err) } bankGenState.Supply = bankGenState.Supply.Add(newSupplyCoinsCache...) - appState[banktypes.ModuleName], err = cdc.MarshalJSON(bankGenState) if err != nil { - return fmt.Errorf("failed to marshal bank genesis state: %w", err) + return nil, fmt.Errorf("failed to marshal bank genesis state: %w", err) } - appStateJSON, err := json.Marshal(appState) - if err != nil { - return fmt.Errorf("failed to marshal application genesis state: %w", err) - } - - appGenesis.AppState = appStateJSON - return ExportGenesisFile(appGenesis, genesisFileURL) + return appState, nil } diff --git a/x/genutil/genaccounts_test.go b/x/genutil/genaccounts_test.go new file mode 100644 index 0000000000..9913b336b0 --- /dev/null +++ b/x/genutil/genaccounts_test.go @@ -0,0 +1,177 @@ +package genutil_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "cosmossdk.io/x/bank" + banktypes "cosmossdk.io/x/bank/types" + + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/genutil" +) + +func TestAddGenesisAccounts(t *testing.T) { + addressCodec := addresscodec.NewBech32Codec("cosmos") + cdc := testutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, bank.AppModule{}) + + addresses := []string{ + "cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw", + "cosmos1hd6fsrvnz6qkp87s3u86ludegq97agxsdkwzyh", + } + + appState := map[string]json.RawMessage{ + "auth": cdc.Codec.MustMarshalJSON(&authtypes.GenesisState{}), + "bank": cdc.Codec.MustMarshalJSON(banktypes.DefaultGenesisState()), + } + + authState := authtypes.NewGenesisState(authtypes.DefaultParams(), []authtypes.GenesisAccount{ + &authtypes.BaseAccount{Address: addresses[0]}, + &authtypes.BaseAccount{Address: addresses[1]}, + }) + + bankState := banktypes.DefaultGenesisState() + bankState.Balances = []banktypes.Balance{ + { + Address: addresses[0], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + { + Address: addresses[1], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 4)), + }, + } + bankState.Supply = sdk.NewCoins(sdk.NewInt64Coin("test", 5)) + appStateWithAccounts := map[string]json.RawMessage{ + "auth": cdc.Codec.MustMarshalJSON(authState), + "bank": cdc.Codec.MustMarshalJSON(bankState), + } + + testCases := []struct { + name string + appState map[string]json.RawMessage + genesisAccount []genutil.GenesisAccount + expected map[string]sdk.Coins + expectedError string + appendFlag bool + }{ + { + name: "single addition without append", + appState: appState, + genesisAccount: []genutil.GenesisAccount{ + { + Address: addresses[0], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + { + Address: addresses[1], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), + }, + }, + expected: map[string]sdk.Coins{ + addresses[0]: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + addresses[1]: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), + }, + }, + { + name: "already existing account additions without append", + appState: appStateWithAccounts, + genesisAccount: []genutil.GenesisAccount{ + { + Address: addresses[0], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + }, + expectedError: "already exists", + }, + { + name: "already existing account additions with append", + appState: appStateWithAccounts, + genesisAccount: []genutil.GenesisAccount{ + { + Address: addresses[0], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + { + Address: addresses[1], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1), sdk.NewInt64Coin("stake", 1)), + }, + }, + expected: map[string]sdk.Coins{ + addresses[0]: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), + addresses[1]: sdk.NewCoins(sdk.NewInt64Coin("test", 5), sdk.NewInt64Coin("stake", 1)), + }, + appendFlag: true, + }, + { + name: "duplicate accounts", + appState: appStateWithAccounts, + genesisAccount: []genutil.GenesisAccount{ + { + Address: addresses[0], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + { + Address: addresses[0], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + { + Address: addresses[1], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 2)), + }, + { + Address: addresses[1], + Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 1)), + }, + { + Address: addresses[1], + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1)), + }, + }, + appendFlag: true, + expectedError: "duplicate account", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + appState, err := genutil.AddGenesisAccountsWithGenesis(cdc.Codec, addressCodec, tc.genesisAccount, tc.appendFlag, tc.appState) + if tc.expectedError != "" { + require.ErrorContains(t, err, tc.expectedError) + return + } else { + require.NoError(t, err) + } + + authGenState := authtypes.GetGenesisStateFromAppState(cdc.Codec, appState) + bankGenState := banktypes.GetGenesisStateFromAppState(cdc.Codec, appState) + + require.Len(t, authGenState.Accounts, len(tc.expected)) + for _, acc := range tc.genesisAccount { + addr := acc.Address + accounts, _ := authtypes.UnpackAccounts(authGenState.Accounts) + found := false + for _, a := range accounts { + if a.GetAddress().String() == addr { + found = true + break + } + } + require.True(t, found, "account %s not found", addr) + } + + expectedSupply := sdk.NewCoins() + for _, coins := range tc.expected { + expectedSupply = expectedSupply.Add(coins...) + } + require.Equal(t, expectedSupply.String(), bankGenState.Supply.String()) + }) + } +} diff --git a/x/gov/go.mod b/x/gov/go.mod index 65f8608a2b..cac19dfd26 100644 --- a/x/gov/go.mod +++ b/x/gov/go.mod @@ -7,7 +7,7 @@ require ( cosmossdk.io/client/v2 v2.0.0-beta.6 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 diff --git a/x/gov/go.sum b/x/gov/go.sum index b1844b1cda..cef31c7aa4 100644 --- a/x/gov/go.sum +++ b/x/gov/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/group/go.mod b/x/group/go.mod index 42fc642114..8bf87c9a45 100644 --- a/x/group/go.mod +++ b/x/group/go.mod @@ -32,7 +32,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/collections v1.1.0 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/schema v1.0.0 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v1.1.0 // indirect diff --git a/x/group/go.sum b/x/group/go.sum index a8026766da..052289de10 100644 --- a/x/group/go.sum +++ b/x/group/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/mint/go.mod b/x/mint/go.mod index d63b5c465f..996d69b5b7 100644 --- a/x/mint/go.mod +++ b/x/mint/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 diff --git a/x/mint/go.sum b/x/mint/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/mint/go.sum +++ b/x/mint/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/nft/go.mod b/x/nft/go.mod index 29e7a8d608..da36c1617b 100644 --- a/x/nft/go.mod +++ b/x/nft/go.mod @@ -25,7 +25,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/collections v1.1.0 // indirect - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 // indirect + cosmossdk.io/core/testing v0.0.2 // indirect cosmossdk.io/schema v1.0.0 // indirect cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect diff --git a/x/nft/go.sum b/x/nft/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/nft/go.sum +++ b/x/nft/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/protocolpool/go.mod b/x/protocolpool/go.mod index f415bbc55c..5242a46bb4 100644 --- a/x/protocolpool/go.mod +++ b/x/protocolpool/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.5.0 diff --git a/x/protocolpool/go.sum b/x/protocolpool/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/protocolpool/go.sum +++ b/x/protocolpool/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/slashing/go.mod b/x/slashing/go.mod index b1ffe2a1d0..9545ee7154 100644 --- a/x/slashing/go.mod +++ b/x/slashing/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.5.0 diff --git a/x/slashing/go.sum b/x/slashing/go.sum index 1987adecaa..11b42e2dbf 100644 --- a/x/slashing/go.sum +++ b/x/slashing/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/staking/go.mod b/x/staking/go.mod index 279e025138..f3b8b90c65 100644 --- a/x/staking/go.mod +++ b/x/staking/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.8.2 cosmossdk.io/collections v1.1.0 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 diff --git a/x/staking/go.sum b/x/staking/go.sum index 582b1a6652..d65d44e654 100644 --- a/x/staking/go.sum +++ b/x/staking/go.sum @@ -10,8 +10,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/x/upgrade/go.mod b/x/upgrade/go.mod index 6c8e31b9c0..4605ed4bf4 100644 --- a/x/upgrade/go.mod +++ b/x/upgrade/go.mod @@ -5,7 +5,7 @@ go 1.23.5 require ( cosmossdk.io/api v0.8.2 cosmossdk.io/core v1.0.0 - cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 + cosmossdk.io/core/testing v0.0.2 cosmossdk.io/depinject v1.1.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.5.0 diff --git a/x/upgrade/go.sum b/x/upgrade/go.sum index 145bea2342..5fdbe316df 100644 --- a/x/upgrade/go.sum +++ b/x/upgrade/go.sum @@ -616,8 +616,8 @@ cosmossdk.io/collections v1.1.0 h1:UgfDUtQbRcA6uTrwd4Z6lhxMWhHPUTneXCHkWztyvMM= cosmossdk.io/collections v1.1.0/go.mod h1:D2iuLsFTDseILML+2rCnWIRFyFgl5cyveZ6kNTQALd4= cosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U= cosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47 h1:JTOj8GWWGSYeNMFFi2K4muXsZjAUZ2G5JxxEL+rX2WA= -cosmossdk.io/core/testing v0.0.2-0.20250203133933-bc60d1009f47/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= +cosmossdk.io/core/testing v0.0.2 h1:TXAmsnHa1C5lLiVN1z+rnkiyNS6sNwcGJCb6OouaNv8= +cosmossdk.io/core/testing v0.0.2/go.mod h1:6Y3QaoNXsgeHiV4+9oYF/IqMFqCK5cJClonw/OXxHlY= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0=