Skip to content

Commit 299ab46

Browse files
robert-zarembamergify-bot
authored andcommitted
fix: x/bank/044 migrateDenomMetadata (#10239)
* fix: x/bank/044 migrateDenomMetadata * adding changelog entry * comment update * fix tests (cherry picked from commit 16a953c) # Conflicts: # CHANGELOG.md # x/bank/migrations/v044/keys.go # x/bank/migrations/v044/store.go # x/bank/migrations/v044/store_test.go # x/bank/types/key.go
1 parent 37f5069 commit 299ab46

File tree

6 files changed

+336
-0
lines changed

6 files changed

+336
-0
lines changed

CHANGELOG.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,57 @@ Ref: https://keepachangelog.com/en/1.0.0/
4646

4747
### Bug Fixes
4848

49+
<<<<<<< HEAD
4950
* [\#9969](https://github.com/cosmos/cosmos-sdk/pull/9969) fix: use keyring in config for add-genesis-account cmd.
5051
* (x/genutil) [#10104](https://github.com/cosmos/cosmos-sdk/pull/10104) Ensure the `init` command reads the `--home` flag value correctly.
5152
* (x/feegrant) [\#10049](https://github.com/cosmos/cosmos-sdk/issues/10049) Fixed the error message when `period` or `period-limit` flag is not set on a feegrant grant transaction.
53+
=======
54+
* [\#9695](https://github.com/cosmos/cosmos-sdk/pull/9695) Migrate keys from `Info` -> `Record`
55+
* Add new `codec.Codec` argument in:
56+
* `keyring.NewInMemory`
57+
* `keyring.New`
58+
* Rename:
59+
* `SavePubKey` to `SaveOfflineKey`.
60+
* `NewMultiInfo`, `NewLedgerInfo` to `NewLegacyMultiInfo`, `newLegacyLedgerInfo` respectively. Move them into `legacy_info.go`.
61+
* `NewOfflineInfo` to `newLegacyOfflineInfo` and move it to `migration_test.go`.
62+
* Return:
63+
*`keyring.Record, error` in `SaveOfflineKey`, `SaveLedgerKey`, `SaveMultiSig`, `Key` and `KeyByAddress`.
64+
*`keyring.Record` instead of `Info` in `NewMnemonic` and `List`.
65+
* Remove `algo` argument from :
66+
* `SaveOfflineKey`
67+
* Take `keyring.Record` instead of `Info` as first argument in:
68+
* `MkConsKeyOutput`
69+
* `MkValKeyOutput`
70+
* `MkAccKeyOutput`
71+
* [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance.
72+
* [\#10022](https://github.com/cosmos/cosmos-sdk/pull/10022) `AuthKeeper` interface in `x/auth` now includes a function `HasAccount`.
73+
* [\#9759](https://github.com/cosmos/cosmos-sdk/pull/9759) `NewAccountKeeeper` in `x/auth` now takes an additional `bech32Prefix` argument that represents `sdk.Bech32MainPrefix`.
74+
* [\#9628](https://github.com/cosmos/cosmos-sdk/pull/9628) Rename `x/{mod}/legacy` to `x/{mod}/migrations`.
75+
* [\#9571](https://github.com/cosmos/cosmos-sdk/pull/9571) Implemented error handling for staking hooks, which now return an error on failure.
76+
* [\#9427](https://github.com/cosmos/cosmos-sdk/pull/9427) Move simapp `FundAccount` and `FundModuleAccount` to `x/bank/testutil`
77+
* (client/tx) [\#9421](https://github.com/cosmos/cosmos-sdk/pull/9421/) `BuildUnsignedTx`, `BuildSimTx`, `PrintUnsignedStdTx` functions are moved to
78+
the Tx Factory as methods.
79+
* (client/keys) [\#9407](https://github.com/cosmos/cosmos-sdk/pull/9601) Added `keys rename` CLI command and `Keyring.Rename` interface method to rename a key in the keyring.
80+
* (x/slashing) [\#9458](https://github.com/cosmos/cosmos-sdk/pull/9458) Coins burned from slashing is now returned from Slash function and included in Slash event.
81+
* [\#9246](https://github.com/cosmos/cosmos-sdk/pull/9246) The `New` method for the network package now returns an error.
82+
* [\#9519](https://github.com/cosmos/cosmos-sdk/pull/9519) `DeleteDeposits` renamed to `DeleteAndBurnDeposits`, `RefundDeposits` renamed to `RefundAndDeleteDeposits`
83+
* (codec) [\#9521](https://github.com/cosmos/cosmos-sdk/pull/9521) Removed deprecated `clientCtx.JSONCodec` from `client.Context`.
84+
* (codec) [\#9521](https://github.com/cosmos/cosmos-sdk/pull/9521) Rename `EncodingConfig.Marshaler` to `Codec`.
85+
* [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) `RESTHandlerFn` argument is removed from the `gov/NewProposalHandler`.
86+
* [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) `types/rest` package moved to `testutil/rest`.
87+
* [\#9432](https://github.com/cosmos/cosmos-sdk/pull/9432) `ConsensusParamsKeyTable` moved from `params/keeper` to `params/types`
88+
* [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to `sdkerrors.QueryResult` when enabled
89+
* [\#9650](https://github.com/cosmos/cosmos-sdk/pull/9650) Removed deprecated message handler implementation from the SDK modules.
90+
* [\#10248](https://github.com/cosmos/cosmos-sdk/pull/10248) Remove unused `KeyPowerReduction` variable from x/staking types.
91+
* (x/bank) [\#9832] (https://github.com/cosmos/cosmos-sdk/pull/9832) `AddressFromBalancesStore` renamed to `AddressAndDenomFromBalancesStore`.
92+
* (tests) [\#9938](https://github.com/cosmos/cosmos-sdk/pull/9938) `simapp.Setup` accepts additional `testing.T` argument.
93+
* (baseapp) [\#9920](https://github.com/cosmos/cosmos-sdk/pull/9920) BaseApp `{Check,Deliver,Simulate}Tx` methods are now replaced by a middleware stack.
94+
* Replace the Antehandler interface with the `tx.Handler` and `tx.Middleware` interfaces.
95+
* Replace `baseapp.SetAnteHandler` with `baseapp.SetTxHandler`.
96+
* Move Msg routers from BaseApp to middlewares.
97+
* Move Baseapp panic recovery into a middleware.
98+
* Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}`.
99+
>>>>>>> 16a953cc9 (fix: x/bank/044 migrateDenomMetadata (#10239))
52100
53101
### Client Breaking Changes
54102

@@ -64,7 +112,31 @@ Ref: https://keepachangelog.com/en/1.0.0/
64112

65113
* (deps) [\#9956](https://github.com/cosmos/cosmos-sdk/pull/9956) Bump Tendermint to [v0.34.12](https://github.com/tendermint/tendermint/releases/tag/v0.34.12).
66114

115+
<<<<<<< HEAD
67116
### Deprecated
117+
=======
118+
### Bug Fixes
119+
* [#10180](https://github.com/cosmos/cosmos-sdk/issues/10180) Documentation: make references to Cosmos SDK consistent
120+
* (store) [#10218](https://github.com/cosmos/cosmos-sdk/pull/10218) Charge gas even when there are no entries while seeking.
121+
* (x/genutil) [#10104](https://github.com/cosmos/cosmos-sdk/pull/10104) Ensure the `init` command reads the `--home` flag value correctly.
122+
* [\#9651](https://github.com/cosmos/cosmos-sdk/pull/9651) Change inconsistent limit of `0` to `MaxUint64` on InfiniteGasMeter and add GasRemaining func to GasMeter.
123+
* [\#9639](https://github.com/cosmos/cosmos-sdk/pull/9639) Check store keys length before accessing them by making sure that `key` is of length `m+1` (for `key[n:m]`)
124+
* (types) [\#9627](https://github.com/cosmos/cosmos-sdk/pull/9627) Fix nil pointer panic on `NewBigIntFromInt`
125+
* (x/genutil) [\#9574](https://github.com/cosmos/cosmos-sdk/pull/9575) Actually use the `gentx` client tx flags (like `--keyring-dir`)
126+
* (x/distribution) [\#9599](https://github.com/cosmos/cosmos-sdk/pull/9599) Withdraw rewards event now includes a value attribute even if there are 0 rewards (due to situations like 100% commission).
127+
* (x/genutil) [\#9638](https://github.com/cosmos/cosmos-sdk/pull/9638) Added missing validator key save when recovering from mnemonic
128+
* [\#9762](https://github.com/cosmos/cosmos-sdk/pull/9762) The init command uses the chain-id from the client config if --chain-id is not provided
129+
* [\#9854](https://github.com/cosmos/cosmos-sdk/pull/9854) Fixed the `make proto-gen` to get dynamic container name based on project name for the cosmos based sdks.
130+
* [\#9829](https://github.com/cosmos/cosmos-sdk/pull/9829) Fixed Coin denom sorting not being checked during `Balance.Validate` check. Refactored the Validation logic to use `Coins.Validate` for `Balance.Coins`.
131+
+ [\#9965](https://github.com/cosmos/cosmos-sdk/pull/9965) Fixed `simd version` command output to report the right release tag.
132+
+ [\#9980](https://github.com/cosmos/cosmos-sdk/pull/9980) Returning the error when the invalid argument is passed to bank query total supply cli.
133+
+ [\#10061](https://github.com/cosmos/cosmos-sdk/pull/10061) Ensure that `LegacyAminoPubKey` struct correctly unmarshals from JSON
134+
* (server) [#10016](https://github.com/cosmos/cosmos-sdk/issues/10016) Fix marshaling of index-events into server config file.
135+
* (x/feegrant) [\#10049](https://github.com/cosmos/cosmos-sdk/issues/10049) Fixed the error message when `period` or `period-limit` flag is not set on a feegrant grant transaction.
136+
* [\#10184](https://github.com/cosmos/cosmos-sdk/pull/10184) Fixed CLI tx commands to no longer explicitly require the chain-id flag as this value can come from a user config.
137+
* [\#10239](https://github.com/cosmos/cosmos-sdk/pull/10239) Fixed x/bank/044 migrateDenomMetadata.
138+
* (x/upgrade) [\#10189](https://github.com/cosmos/cosmos-sdk/issues/10189) Removed potential sources of non-determinism in upgrades
139+
>>>>>>> 16a953cc9 (fix: x/bank/044 migrateDenomMetadata (#10239))
68140
69141
* (x/upgrade) [\#9906](https://github.com/cosmos/cosmos-sdk/pull/9906) Deprecate `UpgradeConsensusState` gRPC query since this functionality is only used for IBC, which now has its own [IBC replacement](https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54)
70142

x/bank/migrations/v044/keys.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package v044
2+
3+
var (
4+
DenomAddressPrefix = []byte{0x03}
5+
)
6+
7+
// CreateDenomAddressPrefix creates a prefix for a reverse index of denomination
8+
// to account balance for that denomination.
9+
func CreateDenomAddressPrefix(denom string) []byte {
10+
// we add a "zero" byte at the end - null byte terminator, to allow prefix denom prefix
11+
// scan. Setting it is not needed (key[last] = 0) - because this is the default.
12+
key := make([]byte, len(DenomAddressPrefix)+len(denom)+1)
13+
copy(key, DenomAddressPrefix)
14+
copy(key[len(DenomAddressPrefix):], denom)
15+
return key
16+
}

x/bank/migrations/v044/store.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package v044
2+
3+
import (
4+
"github.com/cosmos/cosmos-sdk/codec"
5+
"github.com/cosmos/cosmos-sdk/store/prefix"
6+
sdk "github.com/cosmos/cosmos-sdk/types"
7+
"github.com/cosmos/cosmos-sdk/types/address"
8+
v043 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v043"
9+
"github.com/cosmos/cosmos-sdk/x/bank/types"
10+
)
11+
12+
// MigrateStore performs in-place store migrations from v0.43 to v0.44. The
13+
// migration includes:
14+
//
15+
// - Migrate coin storage to save only amount.
16+
// - Add an additional reverse index from denomination to address.
17+
// - Remove duplicate denom from denom metadata store key.
18+
func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error {
19+
store := ctx.KVStore(storeKey)
20+
err := addDenomReverseIndex(store, cdc)
21+
if err != nil {
22+
return err
23+
}
24+
25+
return migrateDenomMetadata(store)
26+
}
27+
28+
func addDenomReverseIndex(store sdk.KVStore, cdc codec.BinaryCodec) error {
29+
oldBalancesStore := prefix.NewStore(store, v043.BalancesPrefix)
30+
31+
oldBalancesIter := oldBalancesStore.Iterator(nil, nil)
32+
defer oldBalancesIter.Close()
33+
34+
denomPrefixStores := make(map[string]prefix.Store) // memoize prefix stores
35+
36+
for ; oldBalancesIter.Valid(); oldBalancesIter.Next() {
37+
var balance sdk.Coin
38+
if err := cdc.Unmarshal(oldBalancesIter.Value(), &balance); err != nil {
39+
return err
40+
}
41+
42+
addr, err := v043.AddressFromBalancesStore(oldBalancesIter.Key())
43+
if err != nil {
44+
return err
45+
}
46+
47+
var coin sdk.DecCoin
48+
if err := cdc.Unmarshal(oldBalancesIter.Value(), &coin); err != nil {
49+
return err
50+
}
51+
52+
bz, err := coin.Amount.Marshal()
53+
if err != nil {
54+
return err
55+
}
56+
57+
newStore := prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr))
58+
newStore.Set([]byte(coin.Denom), bz)
59+
60+
denomPrefixStore, ok := denomPrefixStores[balance.Denom]
61+
if !ok {
62+
denomPrefixStore = prefix.NewStore(store, CreateDenomAddressPrefix(balance.Denom))
63+
denomPrefixStores[balance.Denom] = denomPrefixStore
64+
}
65+
66+
// Store a reverse index from denomination to account address with a
67+
// sentinel value.
68+
denomPrefixStore.Set(address.MustLengthPrefix(addr), []byte{0})
69+
}
70+
71+
return nil
72+
}
73+
74+
func migrateDenomMetadata(store sdk.KVStore) error {
75+
oldDenomMetaDataStore := prefix.NewStore(store, v043.DenomMetadataPrefix)
76+
77+
oldDenomMetaDataIter := oldDenomMetaDataStore.Iterator(nil, nil)
78+
defer oldDenomMetaDataIter.Close()
79+
80+
for ; oldDenomMetaDataIter.Valid(); oldDenomMetaDataIter.Next() {
81+
oldKey := oldDenomMetaDataIter.Key()
82+
l := len(oldKey)/2 + 1
83+
84+
var newKey = make([]byte, len(types.DenomMetadataPrefix)+l)
85+
// old key: prefix_bytes | denom_bytes | denom_bytes
86+
copy(newKey, types.DenomMetadataPrefix)
87+
copy(newKey[len(types.DenomMetadataPrefix):], oldKey[:l])
88+
store.Set(newKey, oldDenomMetaDataIter.Value())
89+
oldDenomMetaDataStore.Delete(oldKey)
90+
}
91+
92+
return nil
93+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package v044_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/cosmos/cosmos-sdk/simapp"
9+
"github.com/cosmos/cosmos-sdk/store/prefix"
10+
"github.com/cosmos/cosmos-sdk/testutil"
11+
sdk "github.com/cosmos/cosmos-sdk/types"
12+
"github.com/cosmos/cosmos-sdk/types/address"
13+
v043 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v043"
14+
v044 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v044"
15+
"github.com/cosmos/cosmos-sdk/x/bank/types"
16+
)
17+
18+
func TestMigrateStore(t *testing.T) {
19+
encCfg := simapp.MakeTestEncodingConfig()
20+
bankKey := sdk.NewKVStoreKey("bank")
21+
ctx := testutil.DefaultContext(bankKey, sdk.NewTransientStoreKey("transient_test"))
22+
store := ctx.KVStore(bankKey)
23+
24+
addr := sdk.AccAddress([]byte("addr________________"))
25+
prefixAccStore := prefix.NewStore(store, v043.CreateAccountBalancesPrefix(addr))
26+
27+
balances := sdk.NewCoins(
28+
sdk.NewCoin("foo", sdk.NewInt(10000)),
29+
sdk.NewCoin("bar", sdk.NewInt(20000)),
30+
)
31+
32+
for _, b := range balances {
33+
bz, err := encCfg.Codec.Marshal(&b)
34+
require.NoError(t, err)
35+
36+
prefixAccStore.Set([]byte(b.Denom), bz)
37+
}
38+
39+
require.NoError(t, v044.MigrateStore(ctx, bankKey, encCfg.Codec))
40+
41+
for _, b := range balances {
42+
addrPrefixStore := prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr))
43+
bz := addrPrefixStore.Get([]byte(b.Denom))
44+
var expected sdk.Int
45+
require.NoError(t, expected.Unmarshal(bz))
46+
require.Equal(t, expected, b.Amount)
47+
}
48+
49+
for _, b := range balances {
50+
denomPrefixStore := prefix.NewStore(store, v044.CreateDenomAddressPrefix(b.Denom))
51+
bz := denomPrefixStore.Get(address.MustLengthPrefix(addr))
52+
require.NotNil(t, bz)
53+
}
54+
}
55+
56+
func TestMigrateDenomMetaData(t *testing.T) {
57+
encCfg := simapp.MakeTestEncodingConfig()
58+
bankKey := sdk.NewKVStoreKey("bank")
59+
ctx := testutil.DefaultContext(bankKey, sdk.NewTransientStoreKey("transient_test"))
60+
store := ctx.KVStore(bankKey)
61+
metaData := []types.Metadata{
62+
{
63+
Name: "Cosmos Hub Atom",
64+
Symbol: "ATOM",
65+
Description: "The native staking token of the Cosmos Hub.",
66+
DenomUnits: []*types.DenomUnit{
67+
{"uatom", uint32(0), []string{"microatom"}},
68+
{"matom", uint32(3), []string{"milliatom"}},
69+
{"atom", uint32(6), nil},
70+
},
71+
Base: "uatom",
72+
Display: "atom",
73+
},
74+
{
75+
Name: "Token",
76+
Symbol: "TOKEN",
77+
Description: "The native staking token of the Token Hub.",
78+
DenomUnits: []*types.DenomUnit{
79+
{"1token", uint32(5), []string{"decitoken"}},
80+
{"2token", uint32(4), []string{"centitoken"}},
81+
{"3token", uint32(7), []string{"dekatoken"}},
82+
},
83+
Base: "utoken",
84+
Display: "token",
85+
},
86+
}
87+
denomMetadataStore := prefix.NewStore(store, v043.DenomMetadataPrefix)
88+
89+
for i := range []int{0, 1} {
90+
key := append(v043.DenomMetadataPrefix, []byte(metaData[i].Base)...)
91+
// keys before 0.44 had denom two times in the key
92+
key = append(key, []byte(metaData[i].Base)...)
93+
bz, err := encCfg.Codec.Marshal(&metaData[i])
94+
require.NoError(t, err)
95+
denomMetadataStore.Set(key, bz)
96+
}
97+
98+
require.NoError(t, v044.MigrateStore(ctx, bankKey, encCfg.Codec))
99+
100+
denomMetadataStore = prefix.NewStore(store, v043.DenomMetadataPrefix)
101+
denomMetadataIter := denomMetadataStore.Iterator(nil, nil)
102+
defer denomMetadataIter.Close()
103+
for i := 0; denomMetadataIter.Valid(); denomMetadataIter.Next() {
104+
var result types.Metadata
105+
newKey := denomMetadataIter.Key()
106+
107+
// make sure old entry is deleted
108+
oldKey := append(newKey, newKey[1:]...)
109+
bz := denomMetadataStore.Get(oldKey)
110+
require.Nil(t, bz)
111+
112+
require.Equal(t, string(newKey)[1:], metaData[i].Base, "idx: %d", i)
113+
bz = denomMetadataStore.Get(denomMetadataIter.Key())
114+
require.NotNil(t, bz)
115+
err := encCfg.Codec.Unmarshal(bz, &result)
116+
require.NoError(t, err)
117+
assertMetaDataEqual(t, metaData[i], result)
118+
i++
119+
}
120+
}
121+
122+
func assertMetaDataEqual(t *testing.T, expected, actual types.Metadata) {
123+
require.Equal(t, expected.GetBase(), actual.GetBase())
124+
require.Equal(t, expected.GetDisplay(), actual.GetDisplay())
125+
require.Equal(t, expected.GetDescription(), actual.GetDescription())
126+
require.Equal(t, expected.GetDenomUnits()[1].GetDenom(), actual.GetDenomUnits()[1].GetDenom())
127+
require.Equal(t, expected.GetDenomUnits()[1].GetExponent(), actual.GetDenomUnits()[1].GetExponent())
128+
require.Equal(t, expected.GetDenomUnits()[1].GetAliases(), actual.GetDenomUnits()[1].GetAliases())
129+
}

x/bank/types/key.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,17 @@ func AddressFromBalancesStore(key []byte) (sdk.AccAddress, error) {
5555
func CreateAccountBalancesPrefix(addr []byte) []byte {
5656
return append(BalancesPrefix, address.MustLengthPrefix(addr)...)
5757
}
58+
<<<<<<< HEAD
59+
=======
60+
61+
// CreateDenomAddressPrefix creates a prefix for a reverse index of denomination
62+
// to account balance for that denomination.
63+
func CreateDenomAddressPrefix(denom string) []byte {
64+
// we add a "zero" byte at the end - null byte terminator, to allow prefix denom prefix
65+
// scan. Setting it is not needed (key[last] = 0) - because this is the default.
66+
key := make([]byte, len(DenomAddressPrefix)+len(denom)+1)
67+
copy(key, DenomAddressPrefix)
68+
copy(key[len(DenomAddressPrefix):], denom)
69+
return key
70+
}
71+
>>>>>>> 16a953cc9 (fix: x/bank/044 migrateDenomMetadata (#10239))

x/bank/types/key_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,15 @@ func TestAddressFromBalancesStore(t *testing.T) {
5555
})
5656
}
5757
}
58+
59+
func TestCreateDenomAddressPrefix(t *testing.T) {
60+
require := require.New(t)
61+
62+
key := types.CreateDenomAddressPrefix("")
63+
require.Len(key, len(types.DenomAddressPrefix)+1)
64+
require.Equal(append(types.DenomAddressPrefix, 0), key)
65+
66+
key = types.CreateDenomAddressPrefix("abc")
67+
require.Len(key, len(types.DenomAddressPrefix)+4)
68+
require.Equal(append(types.DenomAddressPrefix, 'a', 'b', 'c', 0), key)
69+
}

0 commit comments

Comments
 (0)