github.com/Finschia/finschia-sdk@v0.48.1/x/bank/legacy/v043/store.go (about) 1 package v043 2 3 import ( 4 "github.com/Finschia/finschia-sdk/codec" 5 "github.com/Finschia/finschia-sdk/store/prefix" 6 sdk "github.com/Finschia/finschia-sdk/types" 7 v040auth "github.com/Finschia/finschia-sdk/x/auth/legacy/v040" 8 v040bank "github.com/Finschia/finschia-sdk/x/bank/legacy/v040" 9 "github.com/Finschia/finschia-sdk/x/bank/types" 10 ) 11 12 // migrateSupply migrates the supply to be stored by denom key instead in a 13 // single blob. 14 // ref: https://github.com/cosmos/cosmos-sdk/issues/7092 15 func migrateSupply(store sdk.KVStore, cdc codec.BinaryCodec) error { 16 // Old supply was stored as a single blob under the SupplyKey. 17 var oldSupplyI v040bank.SupplyI 18 err := cdc.UnmarshalInterface(store.Get(v040bank.SupplyKey), &oldSupplyI) 19 if err != nil { 20 return err 21 } 22 23 // We delete the single key holding the whole blob. 24 store.Delete(v040bank.SupplyKey) 25 26 if oldSupplyI == nil { 27 return nil 28 } 29 30 // We add a new key for each denom 31 supplyStore := prefix.NewStore(store, types.SupplyKey) 32 33 // We're sure that SupplyI is a Supply struct, there's no other 34 // implementation. 35 oldSupply := oldSupplyI.(*types.Supply) //nolint:staticcheck 36 for i := range oldSupply.Total { 37 coin := oldSupply.Total[i] 38 coinBz, err := coin.Amount.Marshal() 39 if err != nil { 40 return err 41 } 42 43 supplyStore.Set([]byte(coin.Denom), coinBz) 44 } 45 46 return nil 47 } 48 49 // migrateBalanceKeys migrate the balances keys to cater for variable-length 50 // addresses. 51 func migrateBalanceKeys(store sdk.KVStore) { 52 // old key is of format: 53 // prefix ("balances") || addrBytes (20 bytes) || denomBytes 54 // new key is of format 55 // prefix (0x02) || addrLen (1 byte) || addrBytes || denomBytes 56 oldStore := prefix.NewStore(store, v040bank.BalancesPrefix) 57 58 oldStoreIter := oldStore.Iterator(nil, nil) 59 defer oldStoreIter.Close() 60 61 for ; oldStoreIter.Valid(); oldStoreIter.Next() { 62 addr := v040bank.AddressFromBalancesStore(oldStoreIter.Key()) 63 denom := oldStoreIter.Key()[v040auth.AddrLen:] 64 newStoreKey := types.CreatePrefixedAccountStoreKey(addr, denom) 65 66 // Set new key on store. Values don't change. 67 store.Set(newStoreKey, oldStoreIter.Value()) 68 oldStore.Delete(oldStoreIter.Key()) 69 } 70 } 71 72 // MigrateStore performs in-place store migrations from v0.40 to v0.43. The 73 // migration includes: 74 // 75 // - Change addresses to be length-prefixed. 76 // - Change balances prefix to 1 byte 77 // - Change supply to be indexed by denom 78 // - Prune balances & supply with zero coins (ref: https://github.com/cosmos/cosmos-sdk/pull/9229) 79 func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error { 80 store := ctx.KVStore(storeKey) 81 migrateBalanceKeys(store) 82 83 if err := pruneZeroBalances(store, cdc); err != nil { 84 return err 85 } 86 87 if err := migrateSupply(store, cdc); err != nil { 88 return err 89 } 90 91 return pruneZeroSupply(store) 92 } 93 94 // pruneZeroBalances removes the zero balance addresses from balances store. 95 func pruneZeroBalances(store sdk.KVStore, cdc codec.BinaryCodec) error { 96 balancesStore := prefix.NewStore(store, BalancesPrefix) 97 iterator := balancesStore.Iterator(nil, nil) 98 defer iterator.Close() 99 100 for ; iterator.Valid(); iterator.Next() { 101 var balance sdk.Coin 102 if err := cdc.Unmarshal(iterator.Value(), &balance); err != nil { 103 return err 104 } 105 106 if balance.IsZero() { 107 balancesStore.Delete(iterator.Key()) 108 } 109 } 110 return nil 111 } 112 113 // pruneZeroSupply removes zero balance denom from supply store. 114 func pruneZeroSupply(store sdk.KVStore) error { 115 supplyStore := prefix.NewStore(store, SupplyKey) 116 iterator := supplyStore.Iterator(nil, nil) 117 defer iterator.Close() 118 119 for ; iterator.Valid(); iterator.Next() { 120 var amount sdk.Int 121 if err := amount.Unmarshal(iterator.Value()); err != nil { 122 return err 123 } 124 125 if amount.IsZero() { 126 supplyStore.Delete(iterator.Key()) 127 } 128 } 129 130 return nil 131 }