diff --git a/cmd/fetchd/cmd/gen_asi_upgrade_manifest.go b/cmd/fetchd/cmd/gen_asi_upgrade_manifest.go new file mode 100644 index 00000000..6527c083 --- /dev/null +++ b/cmd/fetchd/cmd/gen_asi_upgrade_manifest.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "github.com/cosmos/cosmos-sdk/types" + config2 "github.com/tendermint/tendermint/config" + "os" + "path" +) + +type ASIUpgradeTransfer struct { + From string `json:"from"` + Amount types.Coins `json:"amount"` +} + +type ASIUpgradeTransfers struct { + Transfer []ASIUpgradeTransfer `json:"transfer"` + To string `json:"to"` +} + +type ASIUpgradeManifest struct { + IBC *ASIUpgradeTransfers `json:"ibc,omitempty"` + Reconciliation *ASIUpgradeTransfers `json:"reconciliation,omitempty"` +} + +func SaveASIManifest(manifest *ASIUpgradeManifest, config *config2.Config) error { + var serialisedManifest []byte + var err error + if serialisedManifest, err = json.MarshalIndent(manifest, "", "\t"); err != nil { + return fmt.Errorf("failed to marshal manifest: %w", err) + } + + var f *os.File + const manifestFilename = "asi_upgrade_manifest.json" + genesisFilePath := config.GenesisFile() + manifestFilePath := path.Join(path.Dir(genesisFilePath), manifestFilename) + if f, err = os.Create(manifestFilePath); err != nil { + return fmt.Errorf("failed to create file \"%s\": %w", manifestFilePath, err) + } + defer f.Close() + + if _, err = f.Write(serialisedManifest); err != nil { + return fmt.Errorf("failed to write manifest to the \"%s\" file : %w", manifestFilePath, err) + } + + return nil +} diff --git a/cmd/fetchd/cmd/genasiupgrade.go b/cmd/fetchd/cmd/genasiupgrade.go index 41744b2d..fbfd6f53 100644 --- a/cmd/fetchd/cmd/genasiupgrade.go +++ b/cmd/fetchd/cmd/genasiupgrade.go @@ -125,14 +125,16 @@ func ASIGenesisUpgradeCmd(defaultNodeHome string) *cobra.Command { ASIGenesisUpgradeReplaceBridgeAdmin(jsonData, networkConfig) } + manifest := ASIUpgradeManifest{} + // withdraw balances from IBC channels - if err = ASIGenesisUpgradeWithdrawIBCChannelsBalances(jsonData, networkConfig); err != nil { + if err = ASIGenesisUpgradeWithdrawIBCChannelsBalances(jsonData, networkConfig, &manifest); err != nil { return err } // withdraw balances from reconciliation addresses if networkConfig.ReconciliationTargetAddr != nil { - if err = ASIGenesisUpgradeWithdrawReconciliationBalances(jsonData, networkConfig); err != nil { + if err = ASIGenesisUpgradeWithdrawReconciliationBalances(jsonData, networkConfig, &manifest); err != nil { return err } } @@ -146,6 +148,10 @@ func ASIGenesisUpgradeCmd(defaultNodeHome string) *cobra.Command { // replace addresses across the genesis file ASIGenesisUpgradeReplaceAddresses(jsonData, networkConfig) + if err = SaveASIManifest(&manifest, config); err != nil { + return err + } + var encodedAppState []byte if encodedAppState, err = json.Marshal(jsonData); err != nil { return err @@ -287,12 +293,16 @@ func replaceAddresses(addressTypePrefix string, jsonData map[string]interface{}, }) } -func ASIGenesisUpgradeWithdrawIBCChannelsBalances(jsonData map[string]interface{}, networkInfo NetworkConfig) error { +func ASIGenesisUpgradeWithdrawIBCChannelsBalances(jsonData map[string]interface{}, networkInfo NetworkConfig, manifest *ASIUpgradeManifest) error { bank := jsonData[banktypes.ModuleName].(map[string]interface{}) balances := bank["balances"].([]interface{}) balanceMap := getGenesisBalancesMap(balances) ibcWithdrawalAddress := networkInfo.IbcTargetAddr + manifest.IBC = &ASIUpgradeTransfers{ + Transfer: []ASIUpgradeTransfer{}, + To: ibcWithdrawAddress, + } withdrawalBalanceIdx, ok := (*balanceMap)[ibcWithdrawalAddress] if !ok { fmt.Println("failed to find Ibc withdrawal address in genesis balances - have addresses already been converted?") @@ -322,6 +332,8 @@ func ASIGenesisUpgradeWithdrawIBCChannelsBalances(jsonData map[string]interface{ channelBalanceCoins := getCoinsFromInterfaceSlice(balances[balanceIdx]) withdrawalBalanceCoins := getCoinsFromInterfaceSlice(balances[withdrawalBalanceIdx]) + manifest.IBC.Transfer = append(manifest.IBC.Transfer, ASIUpgradeTransfer{From: channelAddr, Amount: channelBalanceCoins}) + // add channel balance to withdrawal balance newWithdrawalBalanceCoins := withdrawalBalanceCoins.Add(channelBalanceCoins...) balances[withdrawalBalanceIdx].(map[string]interface{})["coins"] = getInterfaceSliceFromCoins(newWithdrawalBalanceCoins) @@ -358,7 +370,7 @@ func getGenesisAccountSequenceMap(accounts []interface{}) *map[string]int { return &accountMap } -func ASIGenesisUpgradeWithdrawReconciliationBalances(jsonData map[string]interface{}, networkInfo NetworkConfig) error { +func ASIGenesisUpgradeWithdrawReconciliationBalances(jsonData map[string]interface{}, networkInfo NetworkConfig, manifest *ASIUpgradeManifest) error { bank := jsonData[banktypes.ModuleName].(map[string]interface{}) balances := bank["balances"].([]interface{}) reconciliationWithdrawAddress := networkInfo.ReconciliationTargetAddr @@ -381,6 +393,11 @@ func ASIGenesisUpgradeWithdrawReconciliationBalances(jsonData map[string]interfa return fmt.Errorf("no match in genesis for reconciliation address: %s", *reconciliationWithdrawAddress) } + manifest.Reconciliation = &ASIUpgradeTransfers{ + Transfer: []ASIUpgradeTransfer{}, + To: ReconciliationWithdrawAddress, + } + for _, row := range items { addr := row[2] @@ -411,6 +428,8 @@ func ASIGenesisUpgradeWithdrawReconciliationBalances(jsonData map[string]interfa newReconciliationBalanceCoins := reconciliationBalanceCoins.Add(accBalanceCoins...) reconciliationBalance.(map[string]interface{})["coins"] = getInterfaceSliceFromCoins(newReconciliationBalanceCoins) + manifest.Reconciliation.Transfer = append(manifest.Reconciliation.Transfer, ASIUpgradeTransfer{From: addr, Amount: accBalanceCoins}) + // zero out the reconciliation account balance balances[balanceIdx].(map[string]interface{})["coins"] = []interface{}{} }