diff --git a/cmd/fetchd/cmd/genasiupgrade.go b/cmd/fetchd/cmd/genasiupgrade.go index 18016d71..05321877 100644 --- a/cmd/fetchd/cmd/genasiupgrade.go +++ b/cmd/fetchd/cmd/genasiupgrade.go @@ -1,14 +1,18 @@ package cmd import ( + "encoding/json" "fmt" + "github.com/btcsuite/btcutil/bech32" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/spf13/cobra" "github.com/tendermint/tendermint/types" + "regexp" ) const ( @@ -59,8 +63,23 @@ func ASIGenesisUpgradeCmd(defaultNodeHome string) *cobra.Command { return fmt.Errorf("failed to unmarshal genesis state: %w", err) } + var jsonData map[string]interface{} + if err = json.Unmarshal(genDoc.AppState, &jsonData); err != nil { + return fmt.Errorf("failed to unmarshal app state: %w", err) + } + + // replace addresses across the genesis file + ASIGenesisUpgradeReplaceAddresses(jsonData) + // replace chain-id ASIGenesisUpgradeReplaceChainID(genDoc) + + var encodedAppState []byte + if encodedAppState, err = json.Marshal(jsonData); err != nil { + return err + } + + genDoc.AppState = encodedAppState return genutil.ExportGenesisFile(genDoc, genFile) }, } @@ -81,8 +100,73 @@ func ASIGenesisUpgradeReplaceChainID(genesisData *types.GenesisDoc) { func ASIGenesisUpgradeReplaceDenom() {} -func ASIGenesisUpgradeReplaceAddresses() {} +func ASIGenesisUpgradeReplaceAddresses(jsonData map[string]interface{}) { + // account addresses + replaceAddresses(AccAddressPrefix, jsonData, AddrDataLength+AddrChecksumLength) + // validator addresses + replaceAddresses(ValAddressPrefix, jsonData, AddrDataLength+AddrChecksumLength) + // consensus addresses + replaceAddresses(ConsAddressPrefix, jsonData, AddrDataLength+AddrChecksumLength) + // contract addresses + replaceAddresses(AccAddressPrefix, jsonData, WasmDataLength+AddrChecksumLength) +} + +func replaceAddresses(addressTypePrefix string, jsonData map[string]interface{}, dataLength int) { + re := regexp.MustCompile(fmt.Sprintf(`^%s%s1([%s]{%d})$`, OldAddrPrefix, addressTypePrefix, Bech32Chars, dataLength)) + + crawlJson(nil, jsonData, func(key interface{}, value interface{}) interface{} { + if str, ok := value.(string); ok { + if !re.MatchString(str) { + return value + } + newAddress, err := convertAddressToASI(str, addressTypePrefix) + if err != nil { + panic(err) + } + + return newAddress + } + return value + }) +} func ASIGenesisUpgradeWithdrawIBCChannelsBalances() {} func ASIGenesisUpgradeWithdrawReconciliationBalances() {} + +func crawlJson(key interface{}, value interface{}, strHandler func(interface{}, interface{}) interface{}) interface{} { + switch val := value.(type) { + case string: + if strHandler != nil { + return strHandler(key, val) + } + case []interface{}: + for i := range val { + val[i] = crawlJson(nil, val[i], strHandler) + } + case map[string]interface{}: + for k, v := range val { + val[k] = crawlJson(k, v, strHandler) + } + } + return value +} + +func convertAddressToASI(addr string, addressTypePrefix string) (string, error) { + _, decodedAddrData, err := bech32.Decode(addr) + if err != nil { + return "", fmt.Errorf("failed to decode address: %w", err) + } + + err = sdk.VerifyAddressFormat(decodedAddrData) + if err != nil { + return "", fmt.Errorf("failed to verify address format: %w", err) + } + + newAddress, err := bech32.Encode(NewAddrPrefix+addressTypePrefix, decodedAddrData) + if err != nil { + return "", fmt.Errorf("failed to encode new address: %w", err) + } + + return newAddress, nil +} diff --git a/go.mod b/go.mod index 32d3950a..b446d809 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,8 @@ require ( github.com/tendermint/tm-db v0.6.7 ) +require github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce + require ( filippo.io/edwards25519 v1.0.0-beta.2 // indirect github.com/99designs/keyring v1.1.6 // indirect diff --git a/go.sum b/go.sum index a83afb2d..6467bd8d 100644 --- a/go.sum +++ b/go.sum @@ -122,6 +122,7 @@ github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+q github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=