Skip to content

Commit

Permalink
feat: chain-initiator include submit software upgrade proposal logic
Browse files Browse the repository at this point in the history
  • Loading branch information
snobbee committed Dec 8, 2023
1 parent 18bf261 commit 4f0d1c8
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 79 deletions.
6 changes: 3 additions & 3 deletions scripts/chain-initiator/gen-tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import (
"os/exec"
)

func genTx(cmdPath, name, balance, chainId, homePath, keyringBackend string) {
func genTx(cmdPath, name, amount, chainId, homePath, keyringBackend string) {
// Command and arguments
args := []string{"gentx", name, balance + "rowan", "--chain-id", chainId, "--home", homePath, "--keyring-backend", keyringBackend}
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("Command execution failed: %v", err)
}

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

import (
"log"
)

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

newVersion = args[1] // v0.1.0
if newVersion == "" {
log.Fatalf("new version is required")
}

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

import (
"log"

"github.com/spf13/cobra"
)

const (
flagHome = "home"
flagCmd = "cmd"
)

func getFlags(cmd *cobra.Command) (homePath, cmdPath string) {
homePath, _ = cmd.Flags().GetString(flagHome)
if homePath == "" {
log.Fatalf("home path is required")
}

cmdPath, _ = cmd.Flags().GetString(flagCmd)
if cmdPath == "" {
log.Fatalf("cmd path is required")
}

return
}
107 changes: 36 additions & 71 deletions scripts/chain-initiator/initiator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@ package main

import (
"log"
"os"

app "github.com/Sifchain/sifnode/app"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/spf13/cobra"
)

const (
moniker = "node"
chainId = "sifchain-1"
keyringBackend = "test"
validatorKeyName = "validator"
validatorBalance = "4000000000000000000000000000"
genesisFilePath = "/tmp/genesis.json"
moniker = "node"
chainId = "sifchain-1"
keyringBackend = "test"
validatorKeyName = "validator"
validatorBalance = "4000000000000000000000000000"
validatorSelfDelegation = "1000000000000000000000000000"
genesisFilePath = "/tmp/genesis.json"
node = "tcp://localhost:26657"
broadcastMode = "block"
)

func main() {
var rootCmd = &cobra.Command{
Use: "initiator [cmd_path] [home_path] [snapshot_url]]",
Short: "Chain Initiator is a tool for modifying genesis files",
Long: `A tool for performing various operations on genesis files of a blockchain setup.`,
Args: cobra.ExactArgs(3), // Expect exactly two arguments
Use: "initiator [snapshot_url] [new_version] [flags]",
Short: "Chain Initiator is a tool for running a chain from a snapshot.",
Long: `A tool for running a chain from a snapshot.`,
Args: cobra.ExactArgs(2), // Expect exactly 1 argument
Run: func(cmd *cobra.Command, args []string) {
cmdPath := args[0] // sifnoded
homePath := args[1] // /tmp/node
snapshotUrl := args[2] // https://snapshots.polkachu.com/snapshots/sifchain/sifchain_15048938.tar.lz4
snapshotUrl, newVersion := getArgs(args)
_ = snapshotUrl
homePath, cmdPath := getFlags(cmd)

// set address prefix
app.SetConfig(false)
Expand Down Expand Up @@ -57,77 +59,40 @@ func main() {
addGenesisAccount(cmdPath, validatorAddress, validatorBalance, homePath)

// generate genesis tx
genTx(cmdPath, validatorKeyName, validatorBalance, chainId, homePath, keyringBackend)
genTx(cmdPath, validatorKeyName, validatorSelfDelegation, chainId, homePath, keyringBackend)

// collect genesis txs
collectGentxs(cmdPath, homePath)

// validate genesis
validateGenesis(cmdPath, homePath)

genesis, err := readGenesisFile(genesisFilePath)
if err != nil {
log.Fatalf("Error reading genesis file: %v", err)
}
// update genesis
updateGenesis(validatorBalance, homePath)

genesisInitFilePath := homePath + "/config/genesis.json"
genesisInit, err := readGenesisFile(genesisInitFilePath)
if err != nil {
log.Fatalf("Error reading initial genesis file: %v", err)
}

filterAccountAddresses := []string{
"sif1harggtyrlukcfrtmpgjzptsnaedcdh38qqknp2", // multisig account with missing pubkeys
}
filterBalanceAddresses := []string{
"sif1harggtyrlukcfrtmpgjzptsnaedcdh38qqknp2",
authtypes.NewModuleAddress("distribution").String(),
authtypes.NewModuleAddress("bonded_tokens_pool").String(),
authtypes.NewModuleAddress("not_bonded_tokens_pool").String(),
}

var coinsToRemove sdk.Coins

genesis.AppState.Auth.Accounts = filterAccounts(genesis.AppState.Auth.Accounts, filterAccountAddresses)
genesis.AppState.Bank.Balances, coinsToRemove = filterBalances(genesis.AppState.Bank.Balances, filterBalanceAddresses)

newValidatorBalance, ok := sdk.NewIntFromString("4000000000000000000000000000")
if !ok {
panic("invalid number")
}
newValidatorBalanceCoin := sdk.NewCoin("rowan", newValidatorBalance)

// update supply
genesis.AppState.Bank.Supply = genesis.AppState.Bank.Supply.Sub(coinsToRemove).Add(newValidatorBalanceCoin)

// Add new validator account and balance
genesis.AppState.Auth.Accounts = append(genesis.AppState.Auth.Accounts, genesisInit.AppState.Auth.Accounts[0])
genesis.AppState.Bank.Balances = append(genesis.AppState.Bank.Balances, genesisInit.AppState.Bank.Balances[0])

// reset staking data
stakingParams := genesis.AppState.Staking.Params
genesis.AppState.Staking = genesisInit.AppState.Staking
genesis.AppState.Staking.Params = stakingParams

// reset slashing data
genesis.AppState.Slashing = genesisInit.AppState.Slashing
// start chain
startCmd := start(cmdPath, homePath)

// reset distribution data
genesis.AppState.Distribution = genesisInit.AppState.Distribution
// wait for node to start
waitForNodeToStart(node)

// set genutil from genesisInit
genesis.AppState.Genutil = genesisInit.AppState.Genutil
// query and calculate upgrade block height
upgradeBlockHeight := queryAndCalcUpgradeBlockHeight(cmdPath, node)

outputFilePath := homePath + "/config/genesis.json"
if err := writeGenesisFile(outputFilePath, genesis); err != nil {
log.Fatalf("Error writing genesis file: %v", err)
}
// submit upgrade proposal
submitUpgradeProposal(cmdPath, validatorKeyName, newVersion, upgradeBlockHeight, homePath, keyringBackend, chainId, node, broadcastMode)

// start chain
start(cmdPath, homePath)
// listen for signals
listenForSignals(startCmd)
},
}

// get HOME environment variable
homeEnv, _ := os.LookupEnv("HOME")

rootCmd.PersistentFlags().String(flagCmd, homeEnv+"/go/bin/sifnoded", "path to sifnoded")
rootCmd.PersistentFlags().String(flagHome, homeEnv+"/.sifnoded", "home directory")

if err := rootCmd.Execute(); err != nil {
log.Fatalf("Error executing command: %v", err)
}
Expand Down
30 changes: 30 additions & 0 deletions scripts/chain-initiator/is-node-running.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"net"
"net/http"
"strings"
)

func isNodeRunning(node string) bool {
// Remove the "tcp://" prefix if present
if strings.HasPrefix(node, "tcp://") {
node = strings.TrimPrefix(node, "tcp://")
}

// Attempt to make a TCP connection
conn, err := net.Dial("tcp", node)
if err == nil {
conn.Close()
return true
}

// If TCP connection fails, attempt an HTTP GET request
resp, err := http.Get("http://" + node)
if err == nil {
resp.Body.Close()
return resp.StatusCode == http.StatusOK
}

return false
}
27 changes: 27 additions & 0 deletions scripts/chain-initiator/listen-for-signals.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"log"
"os"
"os/exec"
"os/signal"
"syscall"
)

func listenForSignals(cmd *exec.Cmd) {
// Set up channel to listen for signals
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

// Block until a signal is received
<-sigChan

// Stop the process when a signal is received
if cmd != nil && cmd.Process != nil {
err := cmd.Process.Kill()
if err != nil {
log.Fatalf("Failed to kill process: %v", err)
}
log.Println("Process killed successfully")
}
}
23 changes: 23 additions & 0 deletions scripts/chain-initiator/query-and-calc-upgrade-block-height.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"log"
"strconv"
)

func queryAndCalcUpgradeBlockHeight(cmdPath, node string) string {
// query block height
blockHeight := queryBlockHeight(cmdPath, node)

// Convert blockHeight from string to int
blockHeightInt, err := strconv.Atoi(blockHeight)
if err != nil {
log.Fatalf("Failed to convert blockHeight to integer: %v", err)
}

// set upgrade block height
upgradeBlockHeight := blockHeightInt + 100

// return upgrade block height as a string
return strconv.Itoa(upgradeBlockHeight)
}
26 changes: 26 additions & 0 deletions scripts/chain-initiator/query-block-height.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

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

func queryBlockHeight(cmdPath, node string) string {
// Command and arguments
args := []string{"status", "--node", node}

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

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

return statusOutput.SyncInfo.LatestBlockHeight
}
14 changes: 9 additions & 5 deletions scripts/chain-initiator/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os/exec"
)

func start(cmdPath, homePath string) {
func start(cmdPath, homePath string) *exec.Cmd {
// Command and arguments
args := []string{"start", "--home", homePath}

Expand All @@ -17,8 +17,12 @@ func start(cmdPath, homePath string) {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

// Execute the command and stream the output
if err := cmd.Run(); err != nil {
log.Fatalf("Command execution failed: %v", err)
}
// Execute the command and stream the output in a goroutine to avoid blocking
go func() {
if err := cmd.Run(); err != nil {
log.Fatalf("Command execution failed: %v", err)
}
}()

return cmd
}
Loading

0 comments on commit 4f0d1c8

Please sign in to comment.