Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add chain-initiator tool to use mainnet snapshot in localnet #3435

Merged
merged 10 commits into from
Dec 13, 2023
38 changes: 38 additions & 0 deletions scripts/chain-initiator/account-unmarshal-json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"encoding/json"
"fmt"
)

func (a *Account) UnmarshalJSON(data []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}

// Set the Type field from the raw data
typeStr, ok := raw["@type"].(string)
if !ok {
return fmt.Errorf("type field is missing or invalid")
}
a.Type = typeStr

switch a.Type {
case "/cosmos.auth.v1beta1.BaseAccount":
var ba BaseAccount
if err := json.Unmarshal(data, &ba); err != nil {
return err
}
a.BaseAccount = &ba
case "/cosmos.auth.v1beta1.ModuleAccount":
var ma ModuleAccount
if err := json.Unmarshal(data, &ma); err != nil {
return err
}
a.ModuleAccount = &ma
default:
return fmt.Errorf("unknown account type: %s", a.Type)
}
return nil
}
19 changes: 19 additions & 0 deletions scripts/chain-initiator/add-genesis-account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"log"
"os/exec"
)

func addGenesisAccount(cmdPath, address, balance, homePath string) {
// Command and arguments
args := []string{"add-genesis-account", address, balance + "rowan", "--home", homePath}

// Execute the command
if err := exec.Command(cmdPath, args...).Run(); err != nil {
log.Fatalf(Red+"Command execution failed: %v", err) // nolint: goconst
}

// If execution reaches here, the command was successful
log.Printf(Yellow+"add genesis account with address %s, balance: %s and home path %s successfully", address, balance, homePath)
}
29 changes: 29 additions & 0 deletions scripts/chain-initiator/add-key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"encoding/json"
"log"
"os/exec"
)

func addKey(cmdPath, name, homePath, keyringBackend string) string {
// Command and arguments
args := []string{"keys", "add", name, "--home", homePath, "--keyring-backend", keyringBackend, "--output", "json"}

// Execute the command
output, err := exec.Command(cmdPath, args...).CombinedOutput()
if err != nil {
log.Fatalf(Red+"Command execution failed: %v", err)
}

// Unmarshal the JSON output
var keyOutput KeyOutput
if err := json.Unmarshal(output, &keyOutput); err != nil {
log.Fatalf(Red+"Failed to unmarshal JSON output: %v", err)
}

// Log the address
log.Printf(Yellow+"add key with name %s, home path: %s, keyring backend %s and address %s successfully", name, homePath, keyringBackend, keyOutput.Address)

return keyOutput.Address
}
19 changes: 19 additions & 0 deletions scripts/chain-initiator/collect-gentxs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"log"
"os/exec"
)

func collectGentxs(cmdPath, homePath string) {
// Command and arguments
args := []string{"collect-gentxs", "--home", homePath}

// Execute the command
if err := exec.Command(cmdPath, args...).Run(); err != nil {
log.Fatalf(Red+"Command execution failed: %v", err)
}

// If execution reaches here, the command was successful
log.Printf(Yellow+"collect gen txs with home path %s successfully", homePath)
}
114 changes: 114 additions & 0 deletions scripts/chain-initiator/download-and-run-version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// nolint: nakedret
package main

import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
)

func isURL(str string) bool {
return strings.HasPrefix(str, "http://") || strings.HasPrefix(str, "https://")
}

func downloadAndRunVersion(binaryPathOrURL string, skipDownload bool) (path string, version string, err error) {
if !isURL(binaryPathOrURL) {
// If the input is a local path
path = binaryPathOrURL

// Check if the path exists
if _, err = os.Stat(path); os.IsNotExist(err) {
err = errors.New(fmt.Sprintf("binary file does not exist at the specified path: %v", path))
return
}

// Run the command 'binary version'
cmd := exec.Command(path, "version")
var versionOutput []byte
versionOutput, err = cmd.CombinedOutput()
if err != nil {
return
}
version = strings.TrimSpace(string(versionOutput))

return
}

if skipDownload {
// Extract version from the URL
re := regexp.MustCompile(`v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?`)
versionMatches := re.FindStringSubmatch(binaryPathOrURL)
if len(versionMatches) == 0 {
err = errors.New("no version found in URL")
return
}
version = versionMatches[0]

// Remove the "v" prefix if present
if strings.HasPrefix(version, "v") {
version = strings.TrimPrefix(version, "v")
}

// Set the binary path based on the version
path = "/tmp/sifnoded-" + version

// Check if the path exists
if _, err = os.Stat(path); os.IsNotExist(err) {
err = errors.New(fmt.Sprintf("binary file does not exist at the specified path: %v", path))
}

return
}

// Download the binary
resp, err := http.Get(binaryPathOrURL) // nolint: gosec
if err != nil {
return
}
defer resp.Body.Close()

// Create a temporary file
tmpFile, err := ioutil.TempFile("", "binary-*")
if err != nil {
return
}
tmpFilePath := tmpFile.Name()
defer os.Remove(tmpFilePath) // Clean up

// Write the downloaded content to the file
_, err = io.Copy(tmpFile, resp.Body)
tmpFile.Close()
if err != nil {
return
}

// Make the file executable
err = os.Chmod(tmpFilePath, 0755)
if err != nil {
return
}

// Run the command 'binary version'
cmd := exec.Command(tmpFilePath, "version")
versionOutput, err := cmd.CombinedOutput()
if err != nil {
return
}
version = strings.TrimSpace(string(versionOutput))

// Rename the temporary file
newFilePath := "/tmp/sifnoded-" + version
err = os.Rename(tmpFilePath, newFilePath)
if err != nil {
return
}
path = newFilePath

return
}
26 changes: 26 additions & 0 deletions scripts/chain-initiator/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"io/ioutil"
"log"
"os/exec"
)

func export(cmdPath, homePath, genesisFilePath string) {
// Command and arguments
args := []string{"export", "--home", homePath}

// Execute the command and capture the output
output, err := exec.Command(cmdPath, args...).CombinedOutput()
if err != nil {
log.Fatalf(Red+"Command execution failed: %v", err)
}

// Write the output to the specified file
err = ioutil.WriteFile(genesisFilePath, output, 0644) // nolint: gosec
if err != nil {
log.Fatalf(Red+"Failed to write output to file: %v", err)
}

log.Printf(Yellow+"Output successfully written to %s", genesisFilePath)
}
17 changes: 17 additions & 0 deletions scripts/chain-initiator/filter-accounts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

func filterAccounts(accounts []Account, filterAddresses []string) []Account {
filterMap := make(map[string]struct{})
for _, addr := range filterAddresses {
filterMap[addr] = struct{}{}
}

newAccounts := []Account{}
for _, account := range accounts {
if shouldFilterAccount(account, filterMap) {
continue
}
newAccounts = append(newAccounts, account)
}
return newAccounts
}
24 changes: 24 additions & 0 deletions scripts/chain-initiator/filter-balances.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

func filterBalances(balances []banktypes.Balance, filterAddresses []string) ([]banktypes.Balance, sdk.Coins) {
filterMap := make(map[string]struct{})
for _, addr := range filterAddresses {
filterMap[addr] = struct{}{}
}

newBalances := []banktypes.Balance{}
var coinsToRemove sdk.Coins
for _, balance := range balances {
if _, exists := filterMap[balance.Address]; exists {
coinsToRemove = coinsToRemove.Add(balance.Coins...)
continue
}
newBalances = append(newBalances, balance)
}
return newBalances, coinsToRemove
}
19 changes: 19 additions & 0 deletions scripts/chain-initiator/gen-tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"log"
"os/exec"
)

func genTx(cmdPath, name, amount, chainId, homePath, keyringBackend string) {
// Command and arguments
args := []string{"gentx", name, amount + "rowan", "--chain-id", chainId, "--home", homePath, "--keyring-backend", keyringBackend}

// Execute the command
if err := exec.Command(cmdPath, args...).Run(); err != nil {
log.Fatalf(Red+"Command execution failed: %v", err)
}

// If execution reaches here, the command was successful
log.Printf(Yellow+"gen tx with name %s, amount: %s, chain id %s, home path %s and keyring backend %s successfully", name, amount, chainId, homePath, keyringBackend)
}
24 changes: 24 additions & 0 deletions scripts/chain-initiator/get-args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"log"
)

func getArgs(args []string) (snapshotUrl, oldBinaryUrl, newBinaryUrl string) {
snapshotUrl = args[0] // https://snapshots.polkachu.com/snapshots/sifchain/sifchain_15048938.tar.lz4
if snapshotUrl == "" {
log.Fatalf(Red + "snapshot url is required")
}

oldBinaryUrl = args[1] // https://github.com/Sifchain/sifnode/releases/download/v1.2.0-beta/sifnoded-v1.2.0-beta-darwin-arm64
if oldBinaryUrl == "" {
log.Fatalf(Red + "old binary url is required")
}

newBinaryUrl = args[2] // https://github.com/Sifchain/sifnode/releases/download/v1.3.0-beta/sifnoded-v1.3.0-beta-darwin-arm64
if newBinaryUrl == "" {
log.Fatalf(Red + "new binary url is required")
}

return
}
Loading
Loading