From 0be6e3d99a1d2b2d20e197c6e8dffb0182981c2b Mon Sep 17 00:00:00 2001 From: Jiri Vestfal <45360788+MissingNO57@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:19:14 +0200 Subject: [PATCH] feat: Cudos config verification command (#393) --- app/app.go | 8 +- app/upgrade_cudos.go | 222 ++++++++++++++------------- app/upgrade_cudos_distribution.go | 110 ++++++------- app/upgrade_v_11_4_network_config.go | 32 ++-- app/utils.go | 22 +++ cmd/fetchd/cmd/cudos_merge.go | 145 +++++++++++++++++ cmd/fetchd/cmd/util.go | 1 + 7 files changed, 360 insertions(+), 180 deletions(-) diff --git a/app/app.go b/app/app.go index 6ea835c1..f5b8b117 100644 --- a/app/app.go +++ b/app/app.go @@ -734,7 +734,7 @@ func getNetworkInfo(app *App, ctx sdk.Context, manifest *UpgradeManifest, expect if app.cudosMigrationConfigPath != "" { app.Logger().Info("cudos merge: loading network config", "file", app.cudosMigrationConfigPath, "expected sha256", app.cudosMigrationConfigSha256) - networkInfo, err = LoadNetworkConfigFromFile(app.cudosMigrationConfigPath, &app.cudosMigrationConfigSha256) + networkInfo, err = LoadAndVerifyNetworkConfigFromFile(app.cudosMigrationConfigPath, &app.cudosMigrationConfigSha256) if err != nil { return nil, err } @@ -776,7 +776,7 @@ func LoadAndParseMergeSourceInputFiles(app *App, ctx sdk.Context, manifest *Upgr cudosConfig := NewCudosMergeConfig(networkInfo.CudosMerge) - genesisData, err := parseGenesisData(app, ctx, *cudosJsonData, cudosGenDoc, cudosConfig, manifest) + genesisData, err := ParseGenesisData(*cudosJsonData, cudosGenDoc, cudosConfig, manifest) if err != nil { return nil, nil, fmt.Errorf("failed to parse genesis data: %w", err) } @@ -798,8 +798,8 @@ func (app *App) RegisterUpgradeHandlers(cfg module.Configurator) { return nil, fmt.Errorf("cudos merge: %w", err) } - manifest.DestinationChainBlockHeight = cudosGenesisData.blockHeight - manifest.DestinationChainID = cudosGenesisData.chainId + manifest.DestinationChainBlockHeight = cudosGenesisData.BlockHeight + manifest.DestinationChainID = cudosGenesisData.ChainId manifest.SourceChainBlockHeight = ctx.BlockHeight() manifest.MergeSourceChainID = ctx.ChainID() diff --git a/app/upgrade_cudos.go b/app/upgrade_cudos.go index 03cbe1b7..0d292f7b 100644 --- a/app/upgrade_cudos.go +++ b/app/upgrade_cudos.go @@ -79,7 +79,7 @@ func convertAddressPrefix(addr string, newPrefix string) (string, error) { func ensureCudosconvertAddressToRaw(addr string, genesisData *GenesisData) (sdk.AccAddress, error) { prefix, decodedAddrData, err := bech32.DecodeAndConvert(addr) - if prefix != genesisData.prefix { + if prefix != genesisData.Prefix { return nil, fmt.Errorf("unknown prefix: %s", prefix) } @@ -104,26 +104,26 @@ const ( ) type GenesisData struct { - totalSupply sdk.Coins - blockHeight int64 - chainId string - prefix string - bondDenom string + TotalSupply sdk.Coins + BlockHeight int64 + ChainId string + Prefix string + BondDenom string - accounts *OrderedMap[string, *AccountInfo] - contracts *OrderedMap[string, *ContractInfo] - ibcAccounts *OrderedMap[string, *IBCInfo] - delegations *OrderedMap[string, *OrderedMap[string, sdk.Int]] + Accounts *OrderedMap[string, *AccountInfo] + Contracts *OrderedMap[string, *ContractInfo] + IbcAccounts *OrderedMap[string, *IBCInfo] + Delegations *OrderedMap[string, *OrderedMap[string, sdk.Int]] - validators *OrderedMap[string, *ValidatorInfo] - bondedPoolAddress string - notBondedPoolAddress string + Validators *OrderedMap[string, *ValidatorInfo] + BondedPoolAddress string + NotBondedPoolAddress string - distributionInfo *DistributionInfo + DistributionInfo *DistributionInfo - gravityModuleAccountAddress string + GravityModuleAccountAddress string - collisionMap *OrderedMap[string, string] + CollisionMap *OrderedMap[string, string] } func LoadCudosGenesis(app *App, manifest *UpgradeManifest) (*map[string]interface{}, *tmtypes.GenesisDoc, error) { @@ -215,7 +215,7 @@ func CudosMergeUpgradeHandler(app *App, ctx sdk.Context, cudosCfg *CudosMergeCon return nil } -func getAccPrefix(jsonData map[string]interface{}) (string, error) { +func GetAccPrefix(jsonData map[string]interface{}) (string, error) { // Map to verify that account exists in auth module auth := jsonData[authtypes.ModuleName].(map[string]interface{}) accounts := auth["accounts"].([]interface{}) @@ -249,7 +249,7 @@ func getAccPrefix(jsonData map[string]interface{}) (string, error) { return "", fmt.Errorf("failed to get prefix: %w", lastErr) } -func getBondDenom(jsonData map[string]interface{}) (string, error) { +func GetBondDenom(jsonData map[string]interface{}) (string, error) { staking, ok := jsonData["staking"].(map[string]interface{}) if !ok { return "", fmt.Errorf("staking module data not found in genesis") @@ -268,7 +268,7 @@ func getBondDenom(jsonData map[string]interface{}) (string, error) { return bondDenom, nil } -func parseGenesisData(app *App, ctx sdk.Context, jsonData map[string]interface{}, genDoc *tmtypes.GenesisDoc, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) (*GenesisData, error) { +func ParseGenesisData(jsonData map[string]interface{}, genDoc *tmtypes.GenesisDoc, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) (*GenesisData, error) { genesisData := GenesisData{} var err error @@ -276,71 +276,71 @@ func parseGenesisData(app *App, ctx sdk.Context, jsonData map[string]interface{} if err != nil { return nil, fmt.Errorf("failed to get total supply: %w", err) } - genesisData.totalSupply = totalSupply - genesisData.blockHeight = genDoc.InitialHeight - genesisData.chainId = genDoc.ChainID + genesisData.TotalSupply = totalSupply + genesisData.BlockHeight = genDoc.InitialHeight + genesisData.ChainId = genDoc.ChainID - genesisData.prefix, err = getAccPrefix(jsonData) + genesisData.Prefix, err = GetAccPrefix(jsonData) if err != nil { return nil, fmt.Errorf("failed to get prefix: %w", err) } - genesisData.bondDenom, err = getBondDenom(jsonData) + genesisData.BondDenom, err = GetBondDenom(jsonData) if err != nil { return nil, fmt.Errorf("failed to get staking denom: %w", err) } - genesisData.contracts, err = parseGenesisWasmContracts(jsonData) + genesisData.Contracts, err = parseGenesisWasmContracts(jsonData) if err != nil { return nil, fmt.Errorf("failed to get contracts: %w", err) } - genesisData.ibcAccounts, err = parseGenesisIBCAccounts(jsonData, cudosCfg, genesisData.prefix) + genesisData.IbcAccounts, err = parseGenesisIBCAccounts(jsonData, cudosCfg, genesisData.Prefix) if err != nil { return nil, fmt.Errorf("failed to get ibc accounts: %w", err) } // Get all accounts and balances into map - genesisData.accounts, err = parseGenesisAccounts(app, ctx, jsonData, genesisData.contracts, genesisData.ibcAccounts, cudosCfg, manifest) + genesisData.Accounts, err = parseGenesisAccounts(jsonData, genesisData.Contracts, genesisData.IbcAccounts, cudosCfg, manifest) if err != nil { return nil, fmt.Errorf("failed to get accounts map: %w", err) } // Staking module - bondedPoolAddress, err := GetAddressByName(genesisData.accounts, BondedPoolAccName) + bondedPoolAddress, err := GetAddressByName(genesisData.Accounts, BondedPoolAccName) if err != nil { return nil, fmt.Errorf("failed to get bonded pool account: %w", err) } - genesisData.bondedPoolAddress = bondedPoolAddress + genesisData.BondedPoolAddress = bondedPoolAddress - genesisData.notBondedPoolAddress, err = GetAddressByName(genesisData.accounts, NotBondedPoolAccName) + genesisData.NotBondedPoolAddress, err = GetAddressByName(genesisData.Accounts, NotBondedPoolAccName) if err != nil { return nil, fmt.Errorf("failed to get not-bonded pool account: %w", err) } - genesisData.validators, err = parseGenesisValidators(jsonData) + genesisData.Validators, err = parseGenesisValidators(jsonData) if err != nil { return nil, fmt.Errorf("failed to get validators map: %w", err) } - genesisData.delegations, err = parseGenesisDelegations(genesisData.bondDenom, genesisData.validators, genesisData.contracts, cudosCfg) + genesisData.Delegations, err = parseGenesisDelegations(genesisData.Validators, genesisData.Contracts, cudosCfg) if err != nil { return nil, fmt.Errorf("failed to get delegations map: %w", err) } - distributionInfo, err := parseGenesisDistribution(jsonData, genesisData.accounts) + distributionInfo, err := parseGenesisDistribution(jsonData, genesisData.Accounts) if err != nil { return nil, fmt.Errorf("failed to get distribution module map: %w", err) } - genesisData.distributionInfo = distributionInfo + genesisData.DistributionInfo = distributionInfo - gravityModuleAccountAddress, err := GetAddressByName(genesisData.accounts, GravityAccName) + gravityModuleAccountAddress, err := GetAddressByName(genesisData.Accounts, GravityAccName) if err != nil { return nil, fmt.Errorf("failed to get gravity module account: %w", err) } - genesisData.gravityModuleAccountAddress = gravityModuleAccountAddress + genesisData.GravityModuleAccountAddress = gravityModuleAccountAddress - genesisData.collisionMap = NewOrderedMap[string, string]() + genesisData.CollisionMap = NewOrderedMap[string, string]() return &genesisData, nil } @@ -537,7 +537,7 @@ func parseGenesisAccount(accMap map[string]interface{}) (*AccountInfo, error) { return &accountInfo, nil } -func parseGenesisAccounts(app *App, ctx sdk.Context, jsonData map[string]interface{}, contractAccountMap *OrderedMap[string, *ContractInfo], IBCAccountsMap *OrderedMap[string, *IBCInfo], cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) (*OrderedMap[string, *AccountInfo], error) { +func parseGenesisAccounts(jsonData map[string]interface{}, contractAccountMap *OrderedMap[string, *ContractInfo], IBCAccountsMap *OrderedMap[string, *IBCInfo], cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) (*OrderedMap[string, *AccountInfo], error) { var err error // Map to verify that account exists in auth module @@ -563,7 +563,7 @@ func parseGenesisAccounts(app *App, ctx sdk.Context, jsonData map[string]interfa } // Add balances to accounts map - err = fillGenesisBalancesToAccountsMap(app, ctx, jsonData, accountMap, cudosCfg, manifest) + err = fillGenesisBalancesToAccountsMap(jsonData, accountMap, cudosCfg, manifest) if err != nil { return nil, err } @@ -571,7 +571,7 @@ func parseGenesisAccounts(app *App, ctx sdk.Context, jsonData map[string]interfa return accountMap, nil } -func parseGenesisDelegations(sourceBondDenom string, validators *OrderedMap[string, *ValidatorInfo], contracts *OrderedMap[string, *ContractInfo], cudosCfg *CudosMergeConfig) (*OrderedMap[string, *OrderedMap[string, sdk.Int]], error) { +func parseGenesisDelegations(validators *OrderedMap[string, *ValidatorInfo], contracts *OrderedMap[string, *ContractInfo], cudosCfg *CudosMergeConfig) (*OrderedMap[string, *OrderedMap[string, sdk.Int]], error) { // Handle delegations delegatedBalanceMap := NewOrderedMap[string, *OrderedMap[string, sdk.Int]]() for i := range validators.Iterate() { @@ -738,22 +738,22 @@ func parseGenesisValidators(jsonData map[string]interface{}) (*OrderedMap[string func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { // Handle delegations - for i := range genesisData.validators.Iterate() { + for i := range genesisData.Validators.Iterate() { validatorOperatorAddress, validator := i.Key, i.Value for j := range validator.delegations.Iterate() { delegatorAddress, delegation := j.Key, j.Value - resolvedDelegatorAddress, err := resolveIfContractAddressWithFallback(delegatorAddress, genesisData.contracts, cudosCfg) + resolvedDelegatorAddress, err := resolveIfContractAddressWithFallback(delegatorAddress, genesisData.Contracts, cudosCfg) if err != nil { return err } - currentValidatorInfo := genesisData.validators.MustGet(validatorOperatorAddress) + currentValidatorInfo := genesisData.Validators.MustGet(validatorOperatorAddress) delegatorTokens := currentValidatorInfo.TokensFromShares(delegation.shares).TruncateInt() // Move balance to delegator address - delegatorBalance := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, delegatorTokens)) + delegatorBalance := sdk.NewCoins(sdk.NewCoin(genesisData.BondDenom, delegatorTokens)) if delegatorTokens.IsZero() { // This happens when number of shares is less than 1 @@ -763,7 +763,7 @@ func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudos // Subtract balance from bonded or not-bonded pool if currentValidatorInfo.status == BondedStatus { // Move balance from bonded pool to delegator - err := moveGenesisBalance(genesisData, genesisData.bondedPoolAddress, resolvedDelegatorAddress, delegatorBalance, "bonded_delegation", manifest, cudosCfg) + err := moveGenesisBalance(genesisData, genesisData.BondedPoolAddress, resolvedDelegatorAddress, delegatorBalance, "bonded_delegation", manifest, cudosCfg) if err != nil { return err } @@ -772,7 +772,7 @@ func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudos // Delegations to unbonded/jailed/tombstoned validators are not re-delegated // Move balance from not-bonded pool to delegator - err := moveGenesisBalance(genesisData, genesisData.notBondedPoolAddress, resolvedDelegatorAddress, delegatorBalance, "not_bonded_delegation", manifest, cudosCfg) + err := moveGenesisBalance(genesisData, genesisData.NotBondedPoolAddress, resolvedDelegatorAddress, delegatorBalance, "not_bonded_delegation", manifest, cudosCfg) if err != nil { return err } @@ -784,16 +784,16 @@ func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudos for j := range validator.unbondingDelegations.Iterate() { delegatorAddress, unbondingDelegation := j.Key, j.Value - resolvedDelegatorAddress, err := resolveIfContractAddressWithFallback(delegatorAddress, genesisData.contracts, cudosCfg) + resolvedDelegatorAddress, err := resolveIfContractAddressWithFallback(delegatorAddress, genesisData.Contracts, cudosCfg) if err != nil { return err } for _, entry := range unbondingDelegation.entries { - unbondingDelegationBalance := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, entry.balance)) + unbondingDelegationBalance := sdk.NewCoins(sdk.NewCoin(genesisData.BondDenom, entry.balance)) // Move unbonding balance from not-bonded pool to delegator address - err := moveGenesisBalance(genesisData, genesisData.notBondedPoolAddress, resolvedDelegatorAddress, unbondingDelegationBalance, "unbonding_delegation", manifest, cudosCfg) + err := moveGenesisBalance(genesisData, genesisData.NotBondedPoolAddress, resolvedDelegatorAddress, unbondingDelegationBalance, "unbonding_delegation", manifest, cudosCfg) if err != nil { return err } @@ -805,7 +805,7 @@ func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudos // Handle remaining pool balances // Handle remaining bonded pool balance - bondedPool := genesisData.accounts.MustGet(genesisData.bondedPoolAddress) + bondedPool := genesisData.Accounts.MustGet(genesisData.BondedPoolAddress) // TODO: Write to manifest? err := checkTolerance(bondedPool.balance, maxToleratedRemainingStakingBalance) @@ -814,13 +814,13 @@ func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudos } app.Logger().Info("cudos merge: remaining bonded pool balance", "amount", bondedPool.balance.String()) - err = moveGenesisBalance(genesisData, genesisData.bondedPoolAddress, cudosCfg.config.RemainingStakingBalanceAddr, bondedPool.balance, "remaining_bonded_pool_balance", manifest, cudosCfg) + err = moveGenesisBalance(genesisData, genesisData.BondedPoolAddress, cudosCfg.config.RemainingStakingBalanceAddr, bondedPool.balance, "remaining_bonded_pool_balance", manifest, cudosCfg) if err != nil { return err } // Handle remaining not-bonded pool balance - notBondedPool := genesisData.accounts.MustGet(genesisData.notBondedPoolAddress) + notBondedPool := genesisData.Accounts.MustGet(genesisData.NotBondedPoolAddress) // TODO: Write to manifest? err = checkTolerance(notBondedPool.balance, maxToleratedRemainingStakingBalance) @@ -829,7 +829,7 @@ func withdrawGenesisStakingDelegations(app *App, genesisData *GenesisData, cudos } app.Logger().Info("cudos merge: remaining not-bonded pool balance", "amount", notBondedPool.balance.String()) - err = moveGenesisBalance(genesisData, genesisData.notBondedPoolAddress, cudosCfg.config.RemainingStakingBalanceAddr, notBondedPool.balance, "remaining_not_bonded_pool_balance", manifest, cudosCfg) + err = moveGenesisBalance(genesisData, genesisData.NotBondedPoolAddress, cudosCfg.config.RemainingStakingBalanceAddr, notBondedPool.balance, "remaining_not_bonded_pool_balance", manifest, cudosCfg) if err != nil { return err } @@ -911,9 +911,9 @@ func createDelegation(ctx sdk.Context, app *App, originalValidator string, newDe func handleCommunityPoolBalance(ctx sdk.Context, app *App, genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { // Get addresses and amounts - RemainingDistributionBalanceAccount := genesisData.accounts.MustGet(cudosCfg.config.RemainingDistributionBalanceAddr) - communityPoolBalance, _ := genesisData.distributionInfo.feePool.communityPool.TruncateDecimal() - convertedCommunityPoolBalance, err := convertBalance(app, ctx, communityPoolBalance, cudosCfg) + RemainingDistributionBalanceAccount := genesisData.Accounts.MustGet(cudosCfg.config.RemainingDistributionBalanceAddr) + communityPoolBalance, _ := genesisData.DistributionInfo.FeePool.CommunityPool.TruncateDecimal() + convertedCommunityPoolBalance, err := convertBalance(app.StakingKeeper.BondDenom(ctx), communityPoolBalance, cudosCfg) if err != nil { return err } @@ -953,8 +953,8 @@ func handleCommunityPoolBalance(ctx sdk.Context, app *App, genesisData *GenesisD func createGenesisDelegations(ctx sdk.Context, app *App, genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { - for _, delegatorAddr := range genesisData.delegations.Keys() { - delegatorAddrMap := genesisData.delegations.MustGet(delegatorAddr) + for _, delegatorAddr := range genesisData.Delegations.Keys() { + delegatorAddrMap := genesisData.Delegations.MustGet(delegatorAddr) // Skip accounts that shouldn't be delegated if cudosCfg.notDelegatedAccounts.Has(delegatorAddr) { @@ -970,13 +970,13 @@ func createGenesisDelegations(ctx sdk.Context, app *App, genesisData *GenesisDat } // Get int amount in native tokens - tokensToDelegate, err := convertAmount(app, ctx, genesisData, delegatedAmount, cudosCfg) + tokensToDelegate, err := convertAmount(app.StakingKeeper.BondDenom(ctx), genesisData, delegatedAmount, cudosCfg) if err != nil { return err } var delegatorRawAddr []byte - if remappedDelegatorAddr, exists := genesisData.collisionMap.Get(delegatorAddr); exists { + if remappedDelegatorAddr, exists := genesisData.CollisionMap.Get(delegatorAddr); exists { // Vesting collision _, delegatorRawAddr, err = bech32.DecodeAndConvert(remappedDelegatorAddr) if err != nil { @@ -1056,13 +1056,13 @@ func getInterfaceSliceFromCoins(coins sdk.Coins) []interface{} { func withdrawGenesisContractBalances(genesisData *GenesisData, manifest *UpgradeManifest, cudosCfg *CudosMergeConfig) error { - for _, contractAddress := range genesisData.contracts.Keys() { - resolvedAddress, err := resolveIfContractAddressWithFallback(contractAddress, genesisData.contracts, cudosCfg) + for _, contractAddress := range genesisData.Contracts.Keys() { + resolvedAddress, err := resolveIfContractAddressWithFallback(contractAddress, genesisData.Contracts, cudosCfg) if err != nil { return err } - contractBalance, contractBalancePresent := genesisData.accounts.Get(contractAddress) + contractBalance, contractBalancePresent := genesisData.Accounts.Get(contractAddress) if contractBalancePresent { err := moveGenesisBalance(genesisData, contractAddress, resolvedAddress, contractBalance.balance, "contract_balance", manifest, cudosCfg) if err != nil { @@ -1074,23 +1074,23 @@ func withdrawGenesisContractBalances(genesisData *GenesisData, manifest *Upgrade return nil } -func convertAmount(app *App, ctx sdk.Context, genesisData *GenesisData, amount sdk.Int, cudosCfg *CudosMergeConfig) (sdk.Int, error) { - balance := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, amount)) - convertedBalance, err := convertBalance(app, ctx, balance, cudosCfg) +func convertAmount(outputDenom string, genesisData *GenesisData, amount sdk.Int, cudosCfg *CudosMergeConfig) (sdk.Int, error) { + balance := sdk.NewCoins(sdk.NewCoin(genesisData.BondDenom, amount)) + convertedBalance, err := convertBalance(outputDenom, balance, cudosCfg) if err != nil { return sdk.ZeroInt(), err } - return convertedBalance.AmountOf(app.StakingKeeper.BondDenom(ctx)), nil + return convertedBalance.AmountOf(outputDenom), nil } -func convertBalance(app *App, ctx sdk.Context, balance sdk.Coins, cudosCfg *CudosMergeConfig) (sdk.Coins, error) { +func convertBalance(outputDenom string, balance sdk.Coins, cudosCfg *CudosMergeConfig) (sdk.Coins, error) { var resBalance sdk.Coins for _, coin := range balance { if conversionConstant, exists := cudosCfg.balanceConversionConstants.Get(coin.Denom); exists { newAmount := coin.Amount.ToDec().Quo(conversionConstant).TruncateInt() - sdkCoin := sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), newAmount) + sdkCoin := sdk.NewCoin(outputDenom, newAmount) resBalance = resBalance.Add(sdkCoin) } // Denominations that are not in conversion constant map are ignored @@ -1128,7 +1128,7 @@ func ensureAccount(addrStr string, genesisAccountsMap *OrderedMap[string, *Accou return nil } -func fillGenesisBalancesToAccountsMap(app *App, ctx sdk.Context, jsonData map[string]interface{}, genesisAccountsMap *OrderedMap[string, *AccountInfo], cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { +func fillGenesisBalancesToAccountsMap(jsonData map[string]interface{}, genesisAccountsMap *OrderedMap[string, *AccountInfo], cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { bank := jsonData[banktypes.ModuleName].(map[string]interface{}) balances := bank["balances"].([]interface{}) @@ -1147,12 +1147,14 @@ func fillGenesisBalancesToAccountsMap(app *App, ctx sdk.Context, jsonData map[st return err } - convertedBalance, err := convertBalance(app, ctx, sdkBalance, cudosCfg) + // We don't care about name of output denom, just checking if there is anything to convert + dummyDenom := "dummy" + convertedDummyBalance, err := convertBalance(dummyDenom, sdkBalance, cudosCfg) if err != nil { return err } - if !convertedBalance.IsZero() { + if !convertedDummyBalance.IsZero() { // Create new account if it doesn't exist err := ensureAccount(addrStr, genesisAccountsMap, "bank_balance_no_auth_acc", manifest) if err != nil { @@ -1178,10 +1180,10 @@ func genesisUpgradeWithdrawIBCChannelsBalances(genesisData *GenesisData, cudosCf To: ibcWithdrawalAddress, } - for _, IBCaccountAddress := range genesisData.ibcAccounts.Keys() { + for _, IBCaccountAddress := range genesisData.IbcAccounts.Keys() { - IBCaccount, IBCAccountExists := genesisData.accounts.Get(IBCaccountAddress) - IBCinfo := genesisData.ibcAccounts.MustGet(IBCaccountAddress) + IBCaccount, IBCAccountExists := genesisData.Accounts.Get(IBCaccountAddress) + IBCinfo := genesisData.IbcAccounts.MustGet(IBCaccountAddress) var channelBalance sdk.Coins if IBCAccountExists { @@ -1470,7 +1472,7 @@ func migrateToAccount(ctx sdk.Context, app *App, fromAddress string, toAddress s } func markAccountAsMigrated(genesisData *GenesisData, accountAddress string) error { - AccountInfoRecord, exists := genesisData.accounts.Get(accountAddress) + AccountInfoRecord, exists := genesisData.Accounts.Get(accountAddress) if !exists { return fmt.Errorf("genesis account %s not found", accountAddress) } @@ -1481,7 +1483,7 @@ func markAccountAsMigrated(genesisData *GenesisData, accountAddress string) erro AccountInfoRecord.migrated = true - genesisData.accounts.Set(accountAddress, AccountInfoRecord) + genesisData.Accounts.Set(accountAddress, AccountInfoRecord) return nil } @@ -1519,7 +1521,7 @@ func registerManifestMoveDelegations(fromAddress, toAddress, validatorAddress st } func getDelegationData(genesisData *GenesisData, DelegatorAddress string, validatorAddress string) (*OrderedMap[string, sdk.Int], *sdk.Int) { - sourceDelegations, exists := genesisData.delegations.Get(DelegatorAddress) + sourceDelegations, exists := genesisData.Delegations.Get(DelegatorAddress) if !exists { return nil, nil } @@ -1556,7 +1558,7 @@ func moveGenesisDelegation(genesisData *GenesisData, fromDelegatorAddress, toDel // No destination delegations newMap := NewOrderedMap[string, sdk.Int]() newMap.Set(toDelegatorAddress, amount) - genesisData.delegations.Set(toDelegatorAddress, newMap) + genesisData.Delegations.Set(toDelegatorAddress, newMap) } else if destinationDelegatedAmount == nil { // No delegations to validator @@ -1597,31 +1599,31 @@ func registerManifestBalanceMovement(fromAddress, toAddress string, amount sdk.C func moveGenesisBalance(genesisData *GenesisData, fromAddress, toAddress string, amount sdk.Coins, memo string, manifest *UpgradeManifest, cudosCfg *CudosMergeConfig) error { // Check if fromAddress exists - if _, ok := genesisData.accounts.Get(fromAddress); !ok { + if _, ok := genesisData.Accounts.Get(fromAddress); !ok { return fmt.Errorf("fromAddress %s does not exist in genesis balances", fromAddress) } // Create to account if it doesn't exist - err := ensureAccount(toAddress, genesisData.accounts, "balance_movement_destination", manifest) + err := ensureAccount(toAddress, genesisData.Accounts, "balance_movement_destination", manifest) if err != nil { return err } - if toAcc := genesisData.accounts.MustGet(toAddress); toAcc.migrated { + if toAcc := genesisData.Accounts.MustGet(toAddress); toAcc.migrated { return fmt.Errorf("genesis account %s already migrated", toAddress) } - if fromAcc := genesisData.accounts.MustGet(fromAddress); fromAcc.migrated { + if fromAcc := genesisData.Accounts.MustGet(fromAddress); fromAcc.migrated { return fmt.Errorf("genesis account %s already migrated", fromAddress) } - genesisToBalance := genesisData.accounts.MustGet(toAddress) - genesisFromBalance := genesisData.accounts.MustGet(fromAddress) + genesisToBalance := genesisData.Accounts.MustGet(toAddress) + genesisFromBalance := genesisData.Accounts.MustGet(fromAddress) genesisToBalance.balance = genesisToBalance.balance.Add(amount...) genesisFromBalance.balance = genesisFromBalance.balance.Sub(amount) - genesisData.accounts.Set(toAddress, genesisToBalance) - genesisData.accounts.Set(fromAddress, genesisFromBalance) + genesisData.Accounts.Set(toAddress, genesisToBalance) + genesisData.Accounts.Set(fromAddress, genesisFromBalance) registerManifestBalanceMovement(fromAddress, toAddress, amount, memo, manifest) @@ -1630,20 +1632,20 @@ func moveGenesisBalance(genesisData *GenesisData, fromAddress, toAddress string, func createGenesisBalance(genesisData *GenesisData, toAddress string, amount sdk.Coins, memo string, manifest *UpgradeManifest) error { // Create to account if it doesn't exist - err := ensureAccount(toAddress, genesisData.accounts, "balance_creation_destination", manifest) + err := ensureAccount(toAddress, genesisData.Accounts, "balance_creation_destination", manifest) if err != nil { return err } - if toAcc := genesisData.accounts.MustGet(toAddress); toAcc.migrated { + if toAcc := genesisData.Accounts.MustGet(toAddress); toAcc.migrated { return fmt.Errorf("genesis account %s already migrated", toAddress) } - genesisToBalance := genesisData.accounts.MustGet(toAddress) + genesisToBalance := genesisData.Accounts.MustGet(toAddress) genesisToBalance.balance = genesisToBalance.balance.Add(amount...) - genesisData.accounts.Set(toAddress, genesisToBalance) + genesisData.Accounts.Set(toAddress, genesisToBalance) registerManifestBalanceMovement("", toAddress, amount, memo, manifest) @@ -1652,18 +1654,18 @@ func createGenesisBalance(genesisData *GenesisData, toAddress string, amount sdk func removeGenesisBalance(genesisData *GenesisData, address string, amount sdk.Coins, memo string, manifest *UpgradeManifest) error { // Check if fromAddress exists - if _, ok := genesisData.accounts.Get(address); !ok { + if _, ok := genesisData.Accounts.Get(address); !ok { return fmt.Errorf("address %s does not exist in genesis balances", address) } - if acc := genesisData.accounts.MustGet(address); acc.migrated { + if acc := genesisData.Accounts.MustGet(address); acc.migrated { return fmt.Errorf("genesis account %s already migrated", address) } - genesisAccount := genesisData.accounts.MustGet(address) + genesisAccount := genesisData.Accounts.MustGet(address) genesisAccount.balance = genesisAccount.balance.Sub(amount) - genesisData.accounts.Set(address, genesisAccount) + genesisData.Accounts.Set(address, genesisAccount) registerManifestBalanceMovement(address, "", amount, memo, manifest) @@ -1695,8 +1697,8 @@ func checkDecTolerance(coins sdk.DecCoins, maxToleratedDiff sdk.Int) error { func withdrawGenesisGravity(genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { - gravityBalance := genesisData.accounts.MustGet(genesisData.gravityModuleAccountAddress).balance - err := moveGenesisBalance(genesisData, genesisData.gravityModuleAccountAddress, cudosCfg.config.RemainingGravityBalanceAddr, gravityBalance, "gravity_balance", manifest, cudosCfg) + gravityBalance := genesisData.Accounts.MustGet(genesisData.GravityModuleAccountAddress).balance + err := moveGenesisBalance(genesisData, genesisData.GravityModuleAccountAddress, cudosCfg.config.RemainingGravityBalanceAddr, gravityBalance, "gravity_balance", manifest, cudosCfg) if err != nil { return err } @@ -1817,7 +1819,7 @@ func doRegularAccountMigration(ctx sdk.Context, app *App, genesisAccount *Accoun func doCollisionMigration(ctx sdk.Context, app *App, genesisData *GenesisData, genesisAccount *AccountInfo, existingAccount authtypes.AccountI, newBalance sdk.Coins, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { // Keep existing account intact and move cudos balance to account specified in config - genesisData.collisionMap.SetNew(genesisAccount.address, cudosCfg.config.VestingCollisionDestAddr) + genesisData.CollisionMap.SetNew(genesisAccount.address, cudosCfg.config.VestingCollisionDestAddr) _, destRawAddr, err := bech32.DecodeAndConvert(cudosCfg.config.VestingCollisionDestAddr) if err != nil { @@ -1838,14 +1840,14 @@ func MigrateGenesisAccounts(genesisData *GenesisData, ctx sdk.Context, app *App, // Mint donor chain total supply totalSupplyToMint := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), cudosCfg.config.TotalFetchSupplyToMint)) - totalCudosSupply := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, cudosCfg.config.TotalCudosSupply)) + totalCudosSupply := sdk.NewCoins(sdk.NewCoin(genesisData.BondDenom, cudosCfg.config.TotalCudosSupply)) err := app.MintKeeper.MintCoins(ctx, totalSupplyToMint) if err != nil { return err } - totalSupplyReducedByCommission, err := convertBalance(app, ctx, totalCudosSupply, cudosCfg) + totalSupplyReducedByCommission, err := convertBalance(app.StakingKeeper.BondDenom(ctx), totalCudosSupply, cudosCfg) if err != nil { return err } @@ -1859,13 +1861,13 @@ func MigrateGenesisAccounts(genesisData *GenesisData, ctx sdk.Context, app *App, err = migrateToAccount(ctx, app, "mint_module", commissionRawAcc, sdk.NewCoins(), totalCommission, "total_commission", manifest) - extraSupplyInCudos := cudosCfg.config.TotalCudosSupply.Sub(genesisData.totalSupply.AmountOf(genesisData.bondDenom)) - extraSupplyCudosAddress, err := convertAddressPrefix(cudosCfg.config.ExtraSupplyFetchAddr, genesisData.prefix) + extraSupplyInCudos := cudosCfg.config.TotalCudosSupply.Sub(genesisData.TotalSupply.AmountOf(genesisData.BondDenom)) + extraSupplyCudosAddress, err := convertAddressPrefix(cudosCfg.config.ExtraSupplyFetchAddr, genesisData.Prefix) if err != nil { return err } - extraSupplyInCudosCoins := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, extraSupplyInCudos)) + extraSupplyInCudosCoins := sdk.NewCoins(sdk.NewCoin(genesisData.BondDenom, extraSupplyInCudos)) err = createGenesisBalance(genesisData, extraSupplyCudosAddress, extraSupplyInCudosCoins, "extra_supply", manifest) if err != nil { @@ -1878,8 +1880,8 @@ func MigrateGenesisAccounts(genesisData *GenesisData, ctx sdk.Context, app *App, } // Mint the rest of the supply - for _, genesisAccountAddress := range genesisData.accounts.Keys() { - genesisAccount := genesisData.accounts.MustGet(genesisAccountAddress) + for _, genesisAccountAddress := range genesisData.Accounts.Keys() { + genesisAccount := genesisData.Accounts.MustGet(genesisAccountAddress) if genesisAccount.accountType == ContractAccountType { // All contracts balance should be handled already @@ -1925,7 +1927,7 @@ func MigrateGenesisAccounts(genesisData *GenesisData, ctx sdk.Context, app *App, } // Get balance to mint - newBalance, err := convertBalance(app, ctx, genesisAccount.balance, cudosCfg) + newBalance, err := convertBalance(app.StakingKeeper.BondDenom(ctx), genesisAccount.balance, cudosCfg) if err != nil { return err } @@ -1982,7 +1984,7 @@ func MigrateGenesisAccounts(genesisData *GenesisData, ctx sdk.Context, app *App, func DoGenesisAccountMovements(genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { for _, accountMovement := range cudosCfg.config.MovedAccounts { - fromAcc, exists := genesisData.accounts.Get(accountMovement.SourceAddress) + fromAcc, exists := genesisData.Accounts.Get(accountMovement.SourceAddress) if !exists { registerManifestBalanceMovement(accountMovement.SourceAddress, accountMovement.DestinationAddress, nil, "non_existing_from_account", manifest) @@ -1994,13 +1996,13 @@ func DoGenesisAccountMovements(genesisData *GenesisData, cudosCfg *CudosMergeCon return nil } - fromAccTokensAmount := fromAcc.balance.AmountOfNoDenomValidation(genesisData.bondDenom) + fromAccTokensAmount := fromAcc.balance.AmountOfNoDenomValidation(genesisData.BondDenom) // Move entire balance if balance to move is 0 or greater than available balance if accountMovement.Amount == nil || fromAccTokensAmount.LT(*accountMovement.Amount) { accountMovement.Amount = &fromAccTokensAmount } - balanceToMove := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, *accountMovement.Amount)) + balanceToMove := sdk.NewCoins(sdk.NewCoin(genesisData.BondDenom, *accountMovement.Amount)) // Handle balance movement err := moveGenesisBalance(genesisData, accountMovement.SourceAddress, accountMovement.DestinationAddress, balanceToMove, "balance_movement", manifest, cudosCfg) @@ -2010,7 +2012,7 @@ func DoGenesisAccountMovements(genesisData *GenesisData, cudosCfg *CudosMergeCon // Handle delegations movement remainingAmountToMove := sdk.NewIntFromBigInt(accountMovement.Amount.BigInt()) - if sourceDelegations, exists := genesisData.delegations.Get(accountMovement.SourceAddress); exists { + if sourceDelegations, exists := genesisData.Delegations.Get(accountMovement.SourceAddress); exists { for i := range sourceDelegations.Iterate() { validatorAddr, delegatedAmount := i.Key, i.Value diff --git a/app/upgrade_cudos_distribution.go b/app/upgrade_cudos_distribution.go index 9659b42d..dd05944a 100644 --- a/app/upgrade_cudos_distribution.go +++ b/app/upgrade_cudos_distribution.go @@ -31,24 +31,24 @@ type ValidatorCurrentReward struct { } type FeePool struct { - communityPool sdk.DecCoins + CommunityPool sdk.DecCoins } type DistributionInfo struct { - feePool *FeePool - outstandingRewards *OrderedMap[string, sdk.DecCoins] + FeePool *FeePool + OutstandingRewards *OrderedMap[string, sdk.DecCoins] // params // previousProposer string - validatorAccumulatedCommissions *OrderedMap[string, sdk.DecCoins] // validator_addr -> validator_accumulated_commissions - validatorCurrentRewards *OrderedMap[string, *ValidatorCurrentReward] // validator_addr -> validator_current_rewards - validatorHistoricalRewards *OrderedMap[string, *OrderedMap[uint64, *ValidatorHistoricalReward]] // validator_addr -> period -> validator_historical_reward + ValidatorAccumulatedCommissions *OrderedMap[string, sdk.DecCoins] // validator_addr -> validator_accumulated_commissions + ValidatorCurrentRewards *OrderedMap[string, *ValidatorCurrentReward] // validator_addr -> validator_current_rewards + ValidatorHistoricalRewards *OrderedMap[string, *OrderedMap[uint64, *ValidatorHistoricalReward]] // validator_addr -> period -> validator_historical_reward - delegatorStartingInfos *OrderedMap[string, *OrderedMap[string, *DelegatorStartingInfo]] // validator_addr -> delegator_addr -> starting_info - delegatorWithdrawInfos *OrderedMap[string, string] // delegator_address -> withdraw_address - validatorSlashEvents *OrderedMap[string, *OrderedMap[uint64, *ValidatorSlashEvent]] // validatior_address -> height -> validator_slash_event - distributionModuleAccountAddress string + DelegatorStartingInfos *OrderedMap[string, *OrderedMap[string, *DelegatorStartingInfo]] // validator_addr -> delegator_addr -> starting_info + DelegatorWithdrawInfos *OrderedMap[string, string] // delegator_address -> withdraw_address + ValidatorSlashEvents *OrderedMap[string, *OrderedMap[uint64, *ValidatorSlashEvent]] // validatior_address -> height -> validator_slash_event + DistributionModuleAccountAddress string } func parseDelegatorStartingInfos(distribution map[string]interface{}) (*OrderedMap[string, *OrderedMap[string, *DelegatorStartingInfo]], error) { @@ -223,7 +223,7 @@ func parseFeePool(distribution map[string]interface{}) (*FeePool, error) { return nil, err } - return &FeePool{communityPool: communityPool}, nil + return &FeePool{CommunityPool: communityPool}, nil } func parseDelegatorWithdrawInfos(distribution map[string]interface{}) (*OrderedMap[string, string], error) { @@ -246,47 +246,47 @@ func parseGenesisDistribution(jsonData map[string]interface{}, genesisAccounts * distributionInfo := DistributionInfo{} var err error - distributionInfo.delegatorStartingInfos, err = parseDelegatorStartingInfos(distribution) + distributionInfo.DelegatorStartingInfos, err = parseDelegatorStartingInfos(distribution) if err != nil { return nil, err } - distributionInfo.validatorHistoricalRewards, err = parseValidatorHistoricalRewards(distribution) + distributionInfo.ValidatorHistoricalRewards, err = parseValidatorHistoricalRewards(distribution) if err != nil { return nil, err } - distributionInfo.validatorCurrentRewards, err = parseValidatorCurrentRewards(distribution) + distributionInfo.ValidatorCurrentRewards, err = parseValidatorCurrentRewards(distribution) if err != nil { return nil, err } - distributionInfo.validatorSlashEvents, err = parseValidatorSlashEvents(distribution) + distributionInfo.ValidatorSlashEvents, err = parseValidatorSlashEvents(distribution) if err != nil { return nil, err } - distributionInfo.outstandingRewards, err = parseOutstandingRewards(distribution) + distributionInfo.OutstandingRewards, err = parseOutstandingRewards(distribution) if err != nil { return nil, err } - distributionInfo.feePool, err = parseFeePool(distribution) + distributionInfo.FeePool, err = parseFeePool(distribution) if err != nil { return nil, err } - distributionInfo.delegatorWithdrawInfos, err = parseDelegatorWithdrawInfos(distribution) + distributionInfo.DelegatorWithdrawInfos, err = parseDelegatorWithdrawInfos(distribution) if err != nil { return nil, err } - distributionInfo.validatorAccumulatedCommissions, err = parseValidatorAccumulatedCommissions(distribution) + distributionInfo.ValidatorAccumulatedCommissions, err = parseValidatorAccumulatedCommissions(distribution) if err != nil { return nil, err } - distributionInfo.distributionModuleAccountAddress, err = GetAddressByName(genesisAccounts, DistributionAccName) + distributionInfo.DistributionModuleAccountAddress, err = GetAddressByName(genesisAccounts, DistributionAccName) if err != nil { return nil, err } @@ -304,10 +304,10 @@ func checkTolerance(coins sdk.Coins, maxToleratedDiff sdk.Int) error { } func verifyOutstandingBalances(genesisData *GenesisData) error { - for i := range genesisData.distributionInfo.outstandingRewards.Iterate() { + for i := range genesisData.DistributionInfo.OutstandingRewards.Iterate() { validatorAddr, validatorOutstandingReward := i.Key, i.Value - validatorAccumulatedCommission := genesisData.distributionInfo.validatorAccumulatedCommissions.MustGet(validatorAddr) + validatorAccumulatedCommission := genesisData.DistributionInfo.ValidatorAccumulatedCommissions.MustGet(validatorAddr) diff := validatorOutstandingReward.Sub(validatorAccumulatedCommission) @@ -326,12 +326,12 @@ func withdrawGenesisDistributionRewards(app *App, genesisData *GenesisData, cudo blockHeight := uint64(math.MaxUint64) // Withdraw all delegation rewards - for _, validatorOpertorAddr := range genesisData.distributionInfo.delegatorStartingInfos.Keys() { - validator := genesisData.validators.MustGet(validatorOpertorAddr) + for _, validatorOpertorAddr := range genesisData.DistributionInfo.DelegatorStartingInfos.Keys() { + validator := genesisData.Validators.MustGet(validatorOpertorAddr) - delegatorStartInfo := genesisData.distributionInfo.delegatorStartingInfos.MustGet(validatorOpertorAddr) + delegatorStartInfo := genesisData.DistributionInfo.DelegatorStartingInfos.MustGet(validatorOpertorAddr) - endingPeriod := updateValidatorData(genesisData.distributionInfo, validator) + endingPeriod := updateValidatorData(genesisData.DistributionInfo, validator) for _, delegatorAddr := range delegatorStartInfo.Keys() { delegation := validator.delegations.MustGet(delegatorAddr) @@ -358,8 +358,8 @@ func withdrawGenesisDistributionRewards(app *App, genesisData *GenesisData, cudo } // Withdraw Community pool balance to address if defined - communityBalance, _ := genesisData.distributionInfo.feePool.communityPool.TruncateDecimal() - distributionModuleAccount := genesisData.accounts.MustGet(genesisData.distributionInfo.distributionModuleAccountAddress) + communityBalance, _ := genesisData.DistributionInfo.FeePool.CommunityPool.TruncateDecimal() + distributionModuleAccount := genesisData.Accounts.MustGet(genesisData.DistributionInfo.DistributionModuleAccountAddress) remainingBalance := distributionModuleAccount.balance.Sub(communityBalance) @@ -372,7 +372,7 @@ func withdrawGenesisDistributionRewards(app *App, genesisData *GenesisData, cudo return fmt.Errorf("remaining distribution balance %s is too high", remainingBalance.String()) } - err = moveGenesisBalance(genesisData, genesisData.distributionInfo.distributionModuleAccountAddress, cudosCfg.config.RemainingDistributionBalanceAddr, distributionModuleAccount.balance, "remaining_distribution_module_balance", manifest, cudosCfg) + err = moveGenesisBalance(genesisData, genesisData.DistributionInfo.DistributionModuleAccountAddress, cudosCfg.config.RemainingDistributionBalanceAddr, distributionModuleAccount.balance, "remaining_distribution_module_balance", manifest, cudosCfg) if err != nil { return err } @@ -382,17 +382,17 @@ func withdrawGenesisDistributionRewards(app *App, genesisData *GenesisData, cudo func withdrawAccumulatedCommissions(genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { - for _, validatorAddress := range genesisData.distributionInfo.validatorAccumulatedCommissions.Keys() { - accumulatedCommission := genesisData.distributionInfo.validatorAccumulatedCommissions.MustGet(validatorAddress) + for _, validatorAddress := range genesisData.DistributionInfo.ValidatorAccumulatedCommissions.Keys() { + accumulatedCommission := genesisData.DistributionInfo.ValidatorAccumulatedCommissions.MustGet(validatorAddress) - accountAddress, err := convertAddressPrefix(validatorAddress, genesisData.prefix) + accountAddress, err := convertAddressPrefix(validatorAddress, genesisData.Prefix) if err != nil { return err } finalRewards, _ := accumulatedCommission.TruncateDecimal() - err = moveGenesisBalance(genesisData, genesisData.distributionInfo.distributionModuleAccountAddress, accountAddress, finalRewards, "accumulated_commission", manifest, cudosCfg) + err = moveGenesisBalance(genesisData, genesisData.DistributionInfo.DistributionModuleAccountAddress, accountAddress, finalRewards, "accumulated_commission", manifest, cudosCfg) if err != nil { return err } @@ -403,17 +403,17 @@ func withdrawAccumulatedCommissions(genesisData *GenesisData, cudosCfg *CudosMer func withdrawValidatorOutstandingRewards(genesisData *GenesisData, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) error { - for _, validatorAddress := range genesisData.distributionInfo.outstandingRewards.Keys() { - outstandingRewards := genesisData.distributionInfo.outstandingRewards.MustGet(validatorAddress) + for _, validatorAddress := range genesisData.DistributionInfo.OutstandingRewards.Keys() { + outstandingRewards := genesisData.DistributionInfo.OutstandingRewards.MustGet(validatorAddress) - accountAddress, err := convertAddressPrefix(validatorAddress, genesisData.prefix) + accountAddress, err := convertAddressPrefix(validatorAddress, genesisData.Prefix) if err != nil { return err } finalRewards, _ := outstandingRewards.TruncateDecimal() - err = moveGenesisBalance(genesisData, genesisData.distributionInfo.distributionModuleAccountAddress, accountAddress, finalRewards, "outstanding_rewards", manifest, cudosCfg) + err = moveGenesisBalance(genesisData, genesisData.DistributionInfo.DistributionModuleAccountAddress, accountAddress, finalRewards, "outstanding_rewards", manifest, cudosCfg) if err != nil { return err } @@ -438,7 +438,7 @@ func calculateDelegationRewardsBetween(distributionInfo *DistributionInfo, val * // return staking * (ending - starting) - operatorRewards := distributionInfo.validatorHistoricalRewards.MustGet(val.operatorAddress) + operatorRewards := distributionInfo.ValidatorHistoricalRewards.MustGet(val.operatorAddress) starting := operatorRewards.MustGet(startingPeriod) ending := operatorRewards.MustGet(endingPeriod) @@ -455,7 +455,7 @@ func calculateDelegationRewardsBetween(distributionInfo *DistributionInfo, val * func IterateValidatorSlashEventsBetween(distributionInfo *DistributionInfo, val string, startingHeight uint64, endingHeight uint64, handler func(height uint64, event *ValidatorSlashEvent) (stop bool, err error), ) error { - slashEvents, exists := distributionInfo.validatorSlashEvents.Get(val) + slashEvents, exists := distributionInfo.ValidatorSlashEvents.Get(val) // No slashing events if !exists { return nil @@ -489,7 +489,7 @@ func IterateValidatorSlashEventsBetween(distributionInfo *DistributionInfo, val // calculate the total rewards accrued by a delegation func calculateDelegationRewards(blockHeight uint64, distributionInfo *DistributionInfo, val *ValidatorInfo, del *DelegationInfo, endingPeriod uint64) (rewards sdk.DecCoins, err error) { // fetch starting info for delegation - delStartingInfo := distributionInfo.delegatorStartingInfos.MustGet(val.operatorAddress) + delStartingInfo := distributionInfo.DelegatorStartingInfos.MustGet(val.operatorAddress) startingInfo := delStartingInfo.MustGet(del.delegatorAddress) if startingInfo.height == blockHeight { @@ -584,7 +584,7 @@ func calculateDelegationRewards(blockHeight uint64, distributionInfo *Distributi // get the delegator withdraw address, defaulting to the delegator address func (d DistributionInfo) GetDelegatorWithdrawAddr(delAddr string) string { - b, exists := d.delegatorWithdrawInfos.Get(delAddr) + b, exists := d.DelegatorWithdrawInfos.Get(delAddr) if !exists { return delAddr } @@ -594,19 +594,19 @@ func (d DistributionInfo) GetDelegatorWithdrawAddr(delAddr string) string { func withdrawDelegationRewards(app *App, genesisData *GenesisData, val *ValidatorInfo, del *DelegationInfo, endingPeriod uint64, blockHeight uint64, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) (sdk.Coins, error) { // check existence of delegator starting info - genesisData.distributionInfo.delegatorStartingInfos.Has(val.operatorAddress) - StartingInfoMap, exists := genesisData.distributionInfo.delegatorStartingInfos.Get(val.operatorAddress) + genesisData.DistributionInfo.DelegatorStartingInfos.Has(val.operatorAddress) + StartingInfoMap, exists := genesisData.DistributionInfo.DelegatorStartingInfos.Get(val.operatorAddress) if !exists || !StartingInfoMap.Has(del.delegatorAddress) { return nil, fmt.Errorf("delegator starting info not found") } // end current period and calculate rewards //endingPeriod := k.IncrementValidatorPeriod(ctx, val) - rewardsRaw, err := calculateDelegationRewards(blockHeight, genesisData.distributionInfo, val, del, endingPeriod) + rewardsRaw, err := calculateDelegationRewards(blockHeight, genesisData.DistributionInfo, val, del, endingPeriod) if err != nil { return nil, err } - outstanding := genesisData.distributionInfo.outstandingRewards.MustGet(val.operatorAddress) + outstanding := genesisData.DistributionInfo.OutstandingRewards.MustGet(val.operatorAddress) // defensive edge case may happen on the very final digits // of the decCoins due to operation order of the distribution mechanism. @@ -626,10 +626,10 @@ func withdrawDelegationRewards(app *App, genesisData *GenesisData, val *Validato // add coins to user account if !finalRewards.IsZero() { - withdrawAddr := genesisData.distributionInfo.GetDelegatorWithdrawAddr(del.delegatorAddress) + withdrawAddr := genesisData.DistributionInfo.GetDelegatorWithdrawAddr(del.delegatorAddress) // SendCoinsFromModuleToAccount - err := moveGenesisBalance(genesisData, genesisData.distributionInfo.distributionModuleAccountAddress, withdrawAddr, finalRewards, "delegation_reward", manifest, cudosCfg) + err := moveGenesisBalance(genesisData, genesisData.DistributionInfo.DistributionModuleAccountAddress, withdrawAddr, finalRewards, "delegation_reward", manifest, cudosCfg) if err != nil { return nil, err } @@ -638,8 +638,8 @@ func withdrawDelegationRewards(app *App, genesisData *GenesisData, val *Validato // update the outstanding rewards and the community pool only if the // transaction was successful - genesisData.distributionInfo.outstandingRewards.Set(val.operatorAddress, outstanding.Sub(rewards)) - genesisData.distributionInfo.feePool.communityPool = genesisData.distributionInfo.feePool.communityPool.Add(remainder...) + genesisData.DistributionInfo.OutstandingRewards.Set(val.operatorAddress, outstanding.Sub(rewards)) + genesisData.DistributionInfo.FeePool.CommunityPool = genesisData.DistributionInfo.FeePool.CommunityPool.Add(remainder...) // decrement reference count of starting period //startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) @@ -656,7 +656,7 @@ func withdrawDelegationRewards(app *App, genesisData *GenesisData, val *Validato baseDenom = cudosCfg.config.OriginalDenom } */ - baseDenom := genesisData.bondDenom + baseDenom := genesisData.BondDenom // Note, we do not call the NewCoins constructor as we do not want the zero // coin removed. @@ -679,7 +679,7 @@ func withdrawDelegationRewards(app *App, genesisData *GenesisData, val *Validato // Code based on IncrementValidatorPeriod func updateValidatorData(distributionInfo *DistributionInfo, val *ValidatorInfo) uint64 { // fetch current rewards - rewards := distributionInfo.validatorCurrentRewards.MustGet(val.operatorAddress) + rewards := distributionInfo.ValidatorCurrentRewards.MustGet(val.operatorAddress) // calculate current ratio var current sdk.DecCoins @@ -688,10 +688,10 @@ func updateValidatorData(distributionInfo *DistributionInfo, val *ValidatorInfo) // can't calculate ratio for zero-token validators // ergo we instead add to the community pool - outstanding := distributionInfo.outstandingRewards.MustGet(val.operatorAddress) - distributionInfo.feePool.communityPool = distributionInfo.feePool.communityPool.Add(rewards.reward...) + outstanding := distributionInfo.OutstandingRewards.MustGet(val.operatorAddress) + distributionInfo.FeePool.CommunityPool = distributionInfo.FeePool.CommunityPool.Add(rewards.reward...) outstanding = outstanding.Sub(rewards.reward) - distributionInfo.outstandingRewards.Set(val.operatorAddress, outstanding) + distributionInfo.OutstandingRewards.Set(val.operatorAddress, outstanding) current = sdk.DecCoins{} } else { @@ -701,7 +701,7 @@ func updateValidatorData(distributionInfo *DistributionInfo, val *ValidatorInfo) // fetch historical rewards for last period //historical := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period-1).CumulativeRewardRatio - historicalValInfo := distributionInfo.validatorHistoricalRewards.MustGet(val.operatorAddress) + historicalValInfo := distributionInfo.ValidatorHistoricalRewards.MustGet(val.operatorAddress) historical := historicalValInfo.MustGet(rewards.period - 1) // decrement reference count diff --git a/app/upgrade_v_11_4_network_config.go b/app/upgrade_v_11_4_network_config.go index eb68409d..7ec3e2b9 100644 --- a/app/upgrade_v_11_4_network_config.go +++ b/app/upgrade_v_11_4_network_config.go @@ -276,24 +276,18 @@ type NetworkConfig struct { CudosMerge *CudosMergeConfigJSON `json:"cudos_merge,omitempty"` } -func LoadNetworkConfigFromFile(configFilePath string, expectedSha256Hex *string) (*NetworkConfig, error) { +func LoadNetworkConfigFromFile(configFilePath string) (*NetworkConfig, *[]byte, error) { // Open the JSON file file, err := os.Open(configFilePath) if err != nil { - return nil, fmt.Errorf("failed to open config file: %v", err) + return nil, nil, fmt.Errorf("failed to open config file: %v", err) } defer file.Close() // Read the file contents byteValue, err := ioutil.ReadAll(file) if err != nil { - return nil, fmt.Errorf("failed to read config file: %v", err) - } - - if isVerified, actualHashHex, err := VerifySha256(byteValue, expectedSha256Hex); err != nil { - return nil, err - } else if !isVerified { - return nil, fmt.Errorf("failed to verify sha256: NetworkConfig file \"%s\" hash \"%s\" does not match expected hash \"%s\"", configFilePath, actualHashHex, *expectedSha256Hex) + return nil, nil, fmt.Errorf("failed to read config file: %v", err) } // Initialize an empty struct to hold the JSON data @@ -302,10 +296,26 @@ func LoadNetworkConfigFromFile(configFilePath string, expectedSha256Hex *string) // Unmarshal the JSON data into the struct err = json.Unmarshal(byteValue, &config) if err != nil { - return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) + return nil, nil, fmt.Errorf("failed to unmarshal JSON: %v", err) + } + + return &config, &byteValue, nil +} + +func LoadAndVerifyNetworkConfigFromFile(configFilePath string, expectedSha256Hex *string) (*NetworkConfig, error) { + config, byteValue, err := LoadNetworkConfigFromFile(configFilePath) + + if err != nil { + return nil, err + } + + if isVerified, actualHashHex, err := VerifySha256(*byteValue, expectedSha256Hex); err != nil { + return nil, err + } else if !isVerified { + return nil, fmt.Errorf("failed to verify sha256: NetworkConfig file \"%s\" hash \"%s\" does not match expected hash \"%s\"", configFilePath, actualHashHex, *expectedSha256Hex) } - return &config, nil + return config, nil } type CudosMergeConfigJSON struct { diff --git a/app/utils.go b/app/utils.go index 0188affd..01781db3 100644 --- a/app/utils.go +++ b/app/utils.go @@ -5,6 +5,7 @@ import ( "crypto/sha256" "encoding/hex" "fmt" + "github.com/cosmos/cosmos-sdk/types/bech32" "io" "os" ) @@ -32,6 +33,14 @@ func GenerateSHA256FromFile(filePath string) (string, error) { return hex.EncodeToString(hashSum), nil } +func GenerateSha256Hex(dataToVerify []byte) (actualHashHex string) { + actualHash32 := sha256.Sum256(dataToVerify) + actualHash := actualHash32[:] + actualHashHex = hex.EncodeToString(actualHash) + + return actualHashHex +} + func VerifySha256(dataToVerify []byte, expectedSha256Hex *string) (isVerified bool, actualHashHex string, err error) { if expectedSha256Hex == nil { return true, "", nil @@ -59,3 +68,16 @@ func VerifySha256(dataToVerify []byte, expectedSha256Hex *string) (isVerified bo } return isVerified, actualHashHex, nil } + +func VerifyAddressPrefix(addr string, expectedPrefix string) error { + prefix, _, err := bech32.DecodeAndConvert(addr) + if err != nil { + return err + } + + if prefix != expectedPrefix { + return fmt.Errorf("invalid address prefix: expected %s, got %s", expectedPrefix, prefix) + } + + return nil +} diff --git a/cmd/fetchd/cmd/cudos_merge.go b/cmd/fetchd/cmd/cudos_merge.go index dca5c7e0..7f5564bf 100644 --- a/cmd/fetchd/cmd/cudos_merge.go +++ b/cmd/fetchd/cmd/cudos_merge.go @@ -1,7 +1,11 @@ package cmd import ( + "encoding/json" "fmt" + "github.com/cosmos/cosmos-sdk/client" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/fetchai/fetchd/app" "github.com/spf13/cobra" ) @@ -40,3 +44,144 @@ func AddCudosFlags(startCmd *cobra.Command) { } } + +func utilNetworkMergeCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "network-merge", + Short: "Network merge commands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmdVerify := &cobra.Command{ + Use: "verify-config [config_json_file_path]", + Short: "Verifies the configuration JSON file", + Long: "This command verifies the structure and content of the configuration JSON file. It checks if all required fields are present and validates their values against predefined rules.", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := client.GetClientContextFromCmd(cmd) + + configFilePath := args[0] + GenesisFilePath := args[1] + + // Read and verify the JSON file + var err error + if err = VerifyConfigFile(configFilePath, GenesisFilePath, ctx); err != nil { + return err + } + + return ctx.PrintString("Configuration is valid.\n") + }, + } + + cmd.AddCommand(cmdVerify) + return cmd +} + +// VerifyConfigFile validates the content of a JSON configuration file. +func VerifyConfigFile(configFilePath string, GenesisFilePath string, ctx client.Context) error { + manifest := app.NewUpgradeManifest() + + destinationChainPrefix := "fetch" + + networkInfo, configBytes, err := app.LoadNetworkConfigFromFile(configFilePath) + if err != nil { + return err + } + err = ctx.PrintString(fmt.Sprintf("Config hash: %s\n", app.GenerateSha256Hex(*configBytes))) + if err != nil { + return err + } + + _, GenDoc, err := genutiltypes.GenesisStateFromGenFile(GenesisFilePath) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + + // unmarshal the app state + var cudosJsonData map[string]interface{} + if err = json.Unmarshal(GenDoc.AppState, &cudosJsonData); err != nil { + return fmt.Errorf("failed to unmarshal app state: %w", err) + } + cudosConfig := app.NewCudosMergeConfig(networkInfo.CudosMerge) + + genesisData, err := app.ParseGenesisData(cudosJsonData, GenDoc, cudosConfig, manifest) + if err != nil { + return fmt.Errorf("failed to parse genesis data: %w", err) + } + + if networkInfo.MergeSourceChainID != genesisData.ChainId { + return fmt.Errorf("source chain id %s is different from config chain id %s", networkInfo.MergeSourceChainID, genesisData.ChainId) + } + + // We don't have access to home folder here so we can't check + if networkInfo.DestinationChainID == "" { + return fmt.Errorf("destination chain id is empty") + } + + // Verify addresses + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.IbcTargetAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("ibc targer address error: %v", err) + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.RemainingStakingBalanceAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("remaining staking balance address error: %v", err) + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.RemainingGravityBalanceAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("remaining gravity balance address error: %v", err) + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.RemainingDistributionBalanceAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("remaining distribution balance address error: %v", err) + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.ContractDestinationFallbackAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("contract destination fallback address error: %v", err) + } + + // Community pool address is optional + if networkInfo.CudosMerge.CommunityPoolBalanceDestAddr != "" { + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.CommunityPoolBalanceDestAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("community pool balance destination address error: %v", err) + } + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.CommissionFetchAddr, destinationChainPrefix) + if err != nil { + return fmt.Errorf("comission address error: %v", err) + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.ExtraSupplyFetchAddr, destinationChainPrefix) + if err != nil { + return fmt.Errorf("extra supply address error: %v", err) + } + + err = app.VerifyAddressPrefix(networkInfo.CudosMerge.VestingCollisionDestAddr, genesisData.Prefix) + if err != nil { + return fmt.Errorf("vesting collision destination address error: %v", err) + } + + // Verify extra supply + bondDenomSourceTotalSupply := genesisData.TotalSupply.AmountOf(genesisData.BondDenom) + if networkInfo.CudosMerge.TotalCudosSupply.LT(bondDenomSourceTotalSupply) { + return fmt.Errorf("total supply %s from config is smaller than total supply %s in genesis", networkInfo.CudosMerge.TotalCudosSupply.String(), bondDenomSourceTotalSupply.String()) + } + + if len(networkInfo.CudosMerge.BalanceConversionConstants) == 0 { + return fmt.Errorf("list of conversion constants is empty") + } + + if len(networkInfo.CudosMerge.BackupValidators) == 0 { + return fmt.Errorf("list of backup validators is empty") + } + + return nil +} diff --git a/cmd/fetchd/cmd/util.go b/cmd/fetchd/cmd/util.go index 58adb0d3..8eab40e4 100644 --- a/cmd/fetchd/cmd/util.go +++ b/cmd/fetchd/cmd/util.go @@ -43,6 +43,7 @@ func utilCommand() *cobra.Command { cmd.AddCommand( utilJsonCommand(), utilAddressCommand(), + utilNetworkMergeCommand(), ) return cmd