github.com/Finschia/finschia-sdk@v0.48.1/x/bank/types/balance.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "sort" 7 8 "github.com/Finschia/finschia-sdk/codec" 9 sdk "github.com/Finschia/finschia-sdk/types" 10 "github.com/Finschia/finschia-sdk/x/bank/exported" 11 ) 12 13 var _ exported.GenesisBalance = (*Balance)(nil) 14 15 // GetAddress returns the account address of the Balance object. 16 func (b Balance) GetAddress() sdk.AccAddress { 17 return sdk.MustAccAddressFromBech32(b.Address) 18 } 19 20 // GetCoins returns the account coins of the Balance object. 21 func (b Balance) GetCoins() sdk.Coins { 22 return b.Coins 23 } 24 25 // Validate checks for address and coins correctness. 26 func (b Balance) Validate() error { 27 if _, err := sdk.AccAddressFromBech32(b.Address); err != nil { 28 return err 29 } 30 31 if err := b.Coins.Validate(); err != nil { 32 return err 33 } 34 35 return nil 36 } 37 38 type balanceByAddress struct { 39 addresses []sdk.AccAddress 40 balances []Balance 41 } 42 43 func (b balanceByAddress) Len() int { return len(b.addresses) } 44 func (b balanceByAddress) Less(i, j int) bool { 45 return bytes.Compare(b.addresses[i], b.addresses[j]) < 0 46 } 47 48 func (b balanceByAddress) Swap(i, j int) { 49 b.addresses[i], b.addresses[j] = b.addresses[j], b.addresses[i] 50 b.balances[i], b.balances[j] = b.balances[j], b.balances[i] 51 } 52 53 // SanitizeGenesisBalances sorts addresses and coin sets. 54 func SanitizeGenesisBalances(balances []Balance) []Balance { 55 // Given that this function sorts balances, using the standard library's 56 // Quicksort based algorithms, we have algorithmic complexities of: 57 // * Best case: O(nlogn) 58 // * Worst case: O(n^2) 59 // The comparator used MUST be cheap to use lest we incur expenses like we had 60 // before whereby sdk.AccAddressFromBech32, which is a very expensive operation 61 // compared n * n elements yet discarded computations each time, as per: 62 // https://github.com/cosmos/cosmos-sdk/issues/7766#issuecomment-786671734 63 64 // 1. Retrieve the address equivalents for each Balance's address. 65 addresses := make([]sdk.AccAddress, len(balances)) 66 for i := range balances { 67 addr := sdk.MustAccAddressFromBech32(balances[i].Address) 68 addresses[i] = addr 69 } 70 71 // 2. Sort balances. 72 sort.Sort(balanceByAddress{addresses: addresses, balances: balances}) 73 74 return balances 75 } 76 77 // GenesisBalancesIterator implements genesis account iteration. 78 type GenesisBalancesIterator struct{} 79 80 // IterateGenesisBalances iterates over all the genesis balances found in 81 // appGenesis and invokes a callback on each genesis account. If any call 82 // returns true, iteration stops. 83 func (GenesisBalancesIterator) IterateGenesisBalances( 84 cdc codec.JSONCodec, appState map[string]json.RawMessage, cb func(exported.GenesisBalance) (stop bool), 85 ) { 86 for _, balance := range GetGenesisStateFromAppState(cdc, appState).Balances { 87 if cb(balance) { 88 break 89 } 90 } 91 }