Skip to content

Commit

Permalink
feat: add chain-initiator tool to use mainnet snapshot in localnet (#…
Browse files Browse the repository at this point in the history
…3435)

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

* test: linter

* feat: chain-initiator uses snapshot url and export genesis file from there

* test: lint

* feat: chain-initiator include submit software upgrade proposal logic

* fix: improved stability

* feat: improved chain initiator

* test: fix lint

* feat: binary url can be remote url or local path
  • Loading branch information
snobbee committed Dec 13, 2023
1 parent 32352c8 commit 0698422
Show file tree
Hide file tree
Showing 33 changed files with 1,562 additions and 0 deletions.
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

0 comments on commit 0698422

Please sign in to comment.