From 67dd26e24a7fa9d30cafc0f3281e87a5c4d6280c Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Thu, 17 Oct 2024 19:35:06 +0200 Subject: [PATCH 1/8] (test): x/accounts systemtests --- tests/systemtests/account_test.go | 108 ++++++++++++++++++++++++++++++ tests/systemtests/cli.go | 17 +++++ 2 files changed, 125 insertions(+) diff --git a/tests/systemtests/account_test.go b/tests/systemtests/account_test.go index 5f3ee7e340ad..5645826cb351 100644 --- a/tests/systemtests/account_test.go +++ b/tests/systemtests/account_test.go @@ -1,6 +1,7 @@ package systemtests import ( + "fmt" "strings" "testing" @@ -51,3 +52,110 @@ func TestAccountCreation(t *testing.T) { rsp5 := cli.CustomQuery("q", "auth", "account", account1Addr) assert.Equal(t, "1", gjson.Get(rsp5, "account.value.sequence").String(), rsp5) } + +func TestAccountsMigration(t *testing.T) { + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // Create legacy-account with some tokens + legacyName := "legacy-account" + legacyAddress := cli.AddKey(legacyName) + require.NotEmpty(t, legacyAddress) + + // Create a receiver account + receiverName := "receiver-account" + receiverAddress := cli.AddKey(receiverName) + require.NotEmpty(t, receiverAddress) + + sut.ModifyGenesisCLI(t, + []string{"genesis", "add-genesis-account", legacyAddress, "20000000stake"}, + []string{"genesis", "add-genesis-account", receiverAddress, "1000000stake"}, + ) + + sut.StartChain(t) + + // Get pubkey + pubKeyValue := cli.GetPubKeyByCustomField(legacyAddress, "address") + require.NotEmpty(t, pubKeyValue, "Public key for legacy-account not found") + + // 1. Verify the account + rsp := cli.CustomQuery("q", "auth", "account", legacyAddress) + require.NotEmpty(t, rsp) + accountInfo := gjson.Parse(rsp) + addressFromResponse := accountInfo.Get("account.value.address").String() + require.Equal(t, legacyAddress, addressFromResponse, "The address in the response should match the legacy address") + + // 2. Migrate this account from x/auth to x/accounts + + // Verify the account not exist in account + rsp = cli.WithRunErrorsIgnored().CustomQuery("q", "accounts", "query", legacyAddress, "cosmos.accounts.defaults.base.v1.QuerySequence", "{}") + require.Contains(t, rsp, "not found: key") + + accountInitMsg := fmt.Sprintf(`{ + "@type": "/cosmos.accounts.defaults.base.v1.MsgInit", + "pub_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "%s" + }, + "init_sequence": "0" + }`, pubKeyValue) + + rsp = cli.RunAndWait("tx", "auth", "migrate-account", + "--account-type=base", + fmt.Sprintf("--account-init-msg=%s", accountInitMsg), + fmt.Sprintf("--from=%s", legacyAddress), + "--fees=1stake") + RequireTxSuccess(t, rsp) + + // 3. Now the account should be existed, query the account Sequence + rsp = cli.CustomQuery("q", "accounts", "query", legacyAddress, "cosmos.accounts.defaults.base.v1.QuerySequence", "{}") + sequence := gjson.Get(rsp, "sequence").Uint() + require.Equal(t, uint64(0), sequence) + + // 4. Execute a transaction using the bank module + + // Check initial balances + legacyBalance := cli.QueryBalance(legacyAddress, "stake") + receiverBalance := cli.QueryBalance(receiverAddress, "stake") + require.Equal(t, int64(19999999), legacyBalance) // 20000000 - 1 (fee for migration) + require.Equal(t, int64(1000000), receiverBalance) + + transferAmount := "1000000" + rsp = cli.RunAndWait("tx", "bank", "send", + legacyAddress, + receiverAddress, + transferAmount+"stake", + fmt.Sprintf("--from=%s", legacyAddress), + "--fees=1stake") + RequireTxSuccess(t, rsp) + + // Verify the balances after the transaction + newLegacyBalance := cli.QueryBalance(legacyAddress, "stake") + newReceiverBalance := cli.QueryBalance(receiverAddress, "stake") + + expectedLegacyBalance := int64(19999999 - 1000000 - 1) // Initial balance - transferred amount - fee + expectedReceiverBalance := int64(1000000 + 1000000) // Initial balance + transferred amount + + require.Equal(t, expectedLegacyBalance, newLegacyBalance, "Legacy account balance is incorrect after transfer") + require.Equal(t, expectedReceiverBalance, newReceiverBalance, "Receiver account balance is incorrect after transfer") + + // 5. Test swapKey functionality + newKeyName := "new-key" + newKeyAddress := cli.AddKey(newKeyName) + require.NotEmpty(t, newKeyAddress) + + newPubKey := cli.GetPubKeyByCustomField(newKeyAddress, "address") + require.NotEmpty(t, newPubKey, "Public key for new-key not found") + + swapKeyMsg := fmt.Sprintf(`{ + "new_pub_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "%s" + } + }`, newPubKey) + + rsp = cli.RunAndWait("tx", "accounts", "execute", legacyAddress, "cosmos.accounts.defaults.base.v1.MsgSwapPubKey", swapKeyMsg, + fmt.Sprintf("--from=%s", legacyAddress), + "--fees=1stake") + RequireTxSuccess(t, rsp) +} diff --git a/tests/systemtests/cli.go b/tests/systemtests/cli.go index 6c8dffc4bbd5..571a872494a8 100644 --- a/tests/systemtests/cli.go +++ b/tests/systemtests/cli.go @@ -322,6 +322,23 @@ func (c CLIWrapper) GetKeyAddrPrefix(name, prefix string) string { return addr } +// GetPubKeyByCustomField returns pubkey in base64 by custom field +func (c CLIWrapper) GetPubKeyByCustomField(addr, field string) string { + keysListOutput := c.Keys("keys", "list") + keysList := gjson.Parse(keysListOutput) + + var pubKeyValue string + keysList.ForEach(func(_, value gjson.Result) bool { + if value.Get(field).String() == addr { + pubKeyJSON := gjson.Parse(value.Get("pubkey").String()) + pubKeyValue = pubKeyJSON.Get("key").String() + return false + } + return true + }) + return pubKeyValue +} + const defaultSrcAddr = "node0" // FundAddress sends the token amount to the destination address From 24103093a61bd21a13ee1d2149181538d11ad2c4 Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Mon, 21 Oct 2024 12:36:14 +0200 Subject: [PATCH 2/8] update module.go --- x/accounts/module.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/x/accounts/module.go b/x/accounts/module.go index 1ed89d87d8dd..e3d43408d38b 100644 --- a/x/accounts/module.go +++ b/x/accounts/module.go @@ -2,8 +2,9 @@ package accounts import ( "context" + basev1 "cosmossdk.io/api/cosmos/accounts/defaults/base/v1" + coretransaction "cosmossdk.io/core/transaction" "encoding/json" - "github.com/spf13/cobra" "google.golang.org/grpc" @@ -42,21 +43,29 @@ type AppModule struct { k Keeper } -func (m AppModule) IsAppModule() {} +func (AppModule) IsAppModule() {} // Name returns the module's name. // Deprecated: kept for legacy reasons. -func (AppModule) Name() string { return ModuleName } +func (am AppModule) Name() string { return ModuleName } + +func (AppModule) RegisterInterfaces(registrar registry.InterfaceRegistrar) { + registrar.RegisterImplementations((*coretransaction.Msg)(nil), + &basev1.MsgInit{}, + &basev1.MsgSwapPubKey{}, + &basev1.MsgSwapPubKeyResponse{}, + &basev1.QuerySequence{}, + &basev1.QuerySequenceResponse{}, + ) -func (m AppModule) RegisterInterfaces(registrar registry.InterfaceRegistrar) { msgservice.RegisterMsgServiceDesc(registrar, v1.MsgServiceDesc()) } // App module services -func (m AppModule) RegisterServices(registar grpc.ServiceRegistrar) error { - v1.RegisterQueryServer(registar, NewQueryServer(m.k)) - v1.RegisterMsgServer(registar, NewMsgServer(m.k)) +func (am AppModule) RegisterServices(registrar grpc.ServiceRegistrar) error { + v1.RegisterQueryServer(registrar, NewQueryServer(am.k)) + v1.RegisterMsgServer(registrar, NewMsgServer(am.k)) return nil } From 2a44357e79a1dea95de1a2fa8533d9afa30243dd Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Mon, 21 Oct 2024 12:42:37 +0200 Subject: [PATCH 3/8] linting issues --- x/accounts/module.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x/accounts/module.go b/x/accounts/module.go index e3d43408d38b..3a1c5c421e29 100644 --- a/x/accounts/module.go +++ b/x/accounts/module.go @@ -2,14 +2,15 @@ package accounts import ( "context" - basev1 "cosmossdk.io/api/cosmos/accounts/defaults/base/v1" - coretransaction "cosmossdk.io/core/transaction" "encoding/json" + "github.com/spf13/cobra" "google.golang.org/grpc" + basev1 "cosmossdk.io/api/cosmos/accounts/defaults/base/v1" "cosmossdk.io/core/appmodule" "cosmossdk.io/core/registry" + coretransaction "cosmossdk.io/core/transaction" "cosmossdk.io/x/accounts/cli" v1 "cosmossdk.io/x/accounts/v1" From a6c8bc11919141410e723d03007ad953f93defc2 Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Tue, 22 Oct 2024 12:26:39 +0200 Subject: [PATCH 4/8] minor fix --- tests/systemtests/account_test.go | 4 ++-- x/accounts/module.go | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/systemtests/account_test.go b/tests/systemtests/account_test.go index 5645826cb351..d0bb67c677c1 100644 --- a/tests/systemtests/account_test.go +++ b/tests/systemtests/account_test.go @@ -109,8 +109,8 @@ func TestAccountsMigration(t *testing.T) { // 3. Now the account should be existed, query the account Sequence rsp = cli.CustomQuery("q", "accounts", "query", legacyAddress, "cosmos.accounts.defaults.base.v1.QuerySequence", "{}") - sequence := gjson.Get(rsp, "sequence").Uint() - require.Equal(t, uint64(0), sequence) + sequence := gjson.Get(rsp, "sequence").Exists() + require.True(t, sequence, "Sequence field should exist") // 4. Execute a transaction using the bank module diff --git a/x/accounts/module.go b/x/accounts/module.go index 3a1c5c421e29..f7958240b7b5 100644 --- a/x/accounts/module.go +++ b/x/accounts/module.go @@ -7,10 +7,8 @@ import ( "github.com/spf13/cobra" "google.golang.org/grpc" - basev1 "cosmossdk.io/api/cosmos/accounts/defaults/base/v1" "cosmossdk.io/core/appmodule" "cosmossdk.io/core/registry" - coretransaction "cosmossdk.io/core/transaction" "cosmossdk.io/x/accounts/cli" v1 "cosmossdk.io/x/accounts/v1" @@ -51,14 +49,6 @@ func (AppModule) IsAppModule() {} func (am AppModule) Name() string { return ModuleName } func (AppModule) RegisterInterfaces(registrar registry.InterfaceRegistrar) { - registrar.RegisterImplementations((*coretransaction.Msg)(nil), - &basev1.MsgInit{}, - &basev1.MsgSwapPubKey{}, - &basev1.MsgSwapPubKeyResponse{}, - &basev1.QuerySequence{}, - &basev1.QuerySequenceResponse{}, - ) - msgservice.RegisterMsgServiceDesc(registrar, v1.MsgServiceDesc()) } From 05b118a37299969852817a16bad6f547183f646a Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Tue, 22 Oct 2024 16:46:16 +0200 Subject: [PATCH 5/8] fix accounts inject --- simapp/simd/cmd/root_di.go | 9 +++++++++ x/accounts/keeper.go | 1 + 2 files changed, 10 insertions(+) diff --git a/simapp/simd/cmd/root_di.go b/simapp/simd/cmd/root_di.go index 7182fe4c9bf9..ea6e70f37a99 100644 --- a/simapp/simd/cmd/root_di.go +++ b/simapp/simd/cmd/root_di.go @@ -16,6 +16,9 @@ import ( "cosmossdk.io/depinject" "cosmossdk.io/log" "cosmossdk.io/simapp" + basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject" + lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject" + multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" @@ -42,6 +45,12 @@ func NewRootCmd() *cobra.Command { depinject.Supply(log.NewNopLogger()), depinject.Provide( ProvideClientContext, + multisigdepinject.ProvideAccount, + basedepinject.ProvideAccount, + lockupdepinject.ProvideAllLockupAccounts, + + // provide base account options + basedepinject.ProvideSecp256K1PubKey, ), ), &autoCliOpts, diff --git a/x/accounts/keeper.go b/x/accounts/keeper.go index fee356a7736f..003e55715fb0 100644 --- a/x/accounts/keeper.go +++ b/x/accounts/keeper.go @@ -10,6 +10,7 @@ import ( gogoproto "github.com/cosmos/gogoproto/proto" + _ "cosmossdk.io/api/cosmos/accounts/defaults/base/v1" // import for side-effects "cosmossdk.io/collections" "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" From 73d13f673071206b199e592c3b3313629f0d65fa Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Tue, 22 Oct 2024 17:16:09 +0200 Subject: [PATCH 6/8] minor fix --- tests/systemtests/account_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/systemtests/account_test.go b/tests/systemtests/account_test.go index d0bb67c677c1..67c3d3c0e6b1 100644 --- a/tests/systemtests/account_test.go +++ b/tests/systemtests/account_test.go @@ -109,7 +109,7 @@ func TestAccountsMigration(t *testing.T) { // 3. Now the account should be existed, query the account Sequence rsp = cli.CustomQuery("q", "accounts", "query", legacyAddress, "cosmos.accounts.defaults.base.v1.QuerySequence", "{}") - sequence := gjson.Get(rsp, "sequence").Exists() + sequence := gjson.Get(rsp, "response.sequence").Exists() require.True(t, sequence, "Sequence field should exist") // 4. Execute a transaction using the bank module From 49641b73a0b3a035d8d4a89fd3c1f54499bde9b8 Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Wed, 23 Oct 2024 00:46:46 +0200 Subject: [PATCH 7/8] simplify test --- tests/systemtests/account_test.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/systemtests/account_test.go b/tests/systemtests/account_test.go index 67c3d3c0e6b1..db4fed5c7126 100644 --- a/tests/systemtests/account_test.go +++ b/tests/systemtests/account_test.go @@ -57,18 +57,12 @@ func TestAccountsMigration(t *testing.T) { sut.ResetChain(t) cli := NewCLIWrapper(t, sut, verbose) - // Create legacy-account with some tokens - legacyName := "legacy-account" - legacyAddress := cli.AddKey(legacyName) - require.NotEmpty(t, legacyAddress) - + legacyAddress := cli.GetKeyAddr(defaultSrcAddr) // Create a receiver account receiverName := "receiver-account" receiverAddress := cli.AddKey(receiverName) require.NotEmpty(t, receiverAddress) - sut.ModifyGenesisCLI(t, - []string{"genesis", "add-genesis-account", legacyAddress, "20000000stake"}, []string{"genesis", "add-genesis-account", receiverAddress, "1000000stake"}, ) @@ -117,7 +111,7 @@ func TestAccountsMigration(t *testing.T) { // Check initial balances legacyBalance := cli.QueryBalance(legacyAddress, "stake") receiverBalance := cli.QueryBalance(receiverAddress, "stake") - require.Equal(t, int64(19999999), legacyBalance) // 20000000 - 1 (fee for migration) + require.Equal(t, int64(399999999), legacyBalance) // 20000000 - 1 (fee for migration) require.Equal(t, int64(1000000), receiverBalance) transferAmount := "1000000" @@ -133,8 +127,8 @@ func TestAccountsMigration(t *testing.T) { newLegacyBalance := cli.QueryBalance(legacyAddress, "stake") newReceiverBalance := cli.QueryBalance(receiverAddress, "stake") - expectedLegacyBalance := int64(19999999 - 1000000 - 1) // Initial balance - transferred amount - fee - expectedReceiverBalance := int64(1000000 + 1000000) // Initial balance + transferred amount + expectedLegacyBalance := legacyBalance - 1000000 - 1 // Initial balance - transferred amount - fee + expectedReceiverBalance := receiverBalance + 1000000 // Initial balance + transferred amount require.Equal(t, expectedLegacyBalance, newLegacyBalance, "Legacy account balance is incorrect after transfer") require.Equal(t, expectedReceiverBalance, newReceiverBalance, "Receiver account balance is incorrect after transfer") From 3179d6541c1239affdc8977194fa0b692839531a Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Wed, 23 Oct 2024 03:08:34 +0200 Subject: [PATCH 8/8] fix v2 injects --- simapp/v2/simdv2/cmd/root_di.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/simapp/v2/simdv2/cmd/root_di.go b/simapp/v2/simdv2/cmd/root_di.go index 6b13b7201342..a43ce3bca8c3 100644 --- a/simapp/v2/simdv2/cmd/root_di.go +++ b/simapp/v2/simdv2/cmd/root_di.go @@ -14,6 +14,9 @@ import ( "cosmossdk.io/log" "cosmossdk.io/runtime/v2" "cosmossdk.io/simapp/v2" + basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject" + lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject" + multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" @@ -36,7 +39,15 @@ func NewRootCmd[T transaction.Tx]() *cobra.Command { if err := depinject.Inject( depinject.Configs( simapp.AppConfig(), - depinject.Provide(ProvideClientContext), + depinject.Provide( + ProvideClientContext, + // inject desired account types: + multisigdepinject.ProvideAccount, + basedepinject.ProvideAccount, + lockupdepinject.ProvideAllLockupAccounts, + + // provide base account options + basedepinject.ProvideSecp256K1PubKey), depinject.Supply(log.NewNopLogger()), ), &autoCliOpts,