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: supporting multiple consensus instances #450

Merged
merged 7 commits into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func PromptConfirm(label string) bool {
return false
}

// Promptlabel prompts for an input string.
// PromptInput prompts for an input string.
func PromptInput(label string) string {
prompt := promptui.Prompt{
Label: label,
Expand All @@ -94,55 +94,65 @@ func PromptInput(label string) string {
return result
}

// Promptlabel prompts for an input string with a suggestion.
// PromptInputWithSuggestion prompts for an input string with a suggestion.
func PromptInputWithSuggestion(label, suggestion string) string {
prompt := promptui.Prompt{
Label: label,
Default: suggestion,
}
result, err := prompt.Run()
if err != nil {
PrintErrorMsg("prompt error: %v", err)
os.Exit(1)
}
FatalErrorCheck(err)

return result
}

func PrintDangerMsg(format string, a ...interface{}) {
if terminalSupported() {
format = fmt.Sprintf("\033[31m%s\033[0m\n", format)
func FatalErrorCheck(err error) {
if err != nil {
if terminalSupported() {
fmt.Printf("\033[31m%s\033[0m\n", err.Error())
} else {
fmt.Printf("%s\n", err.Error())
}

os.Exit(1)
}
fmt.Printf(format, a...)
}

func PrintErrorMsg(format string, a ...interface{}) {
if terminalSupported() {
// Print error msg with red color
format = fmt.Sprintf("\033[31m[ERROR] %s\033[0m\n", format)
format = fmt.Sprintf("\033[31m[ERROR] %s\033[0m", format)
}
fmt.Printf(format, a...)
fmt.Printf(format+"\n", a...)
}

func PrintSuccessMsg(format string, a ...interface{}) {
if terminalSupported() {
// Print successful msg with green color
format = fmt.Sprintf("\033[32m%s\033[0m\n", format)
format = fmt.Sprintf("\033[32m%s\033[0m", format)
}
fmt.Printf(format, a...)
fmt.Printf(format+"\n", a...)
}

func PrintWarnMsg(format string, a ...interface{}) {
if terminalSupported() {
// Print warning msg with yellow color
format = fmt.Sprintf("\033[33m%s\033[0m\n", format)
format = fmt.Sprintf("\033[33m%s\033[0m", format)
}
fmt.Printf(format, a...)
fmt.Printf(format+"\n", a...)
}

func PrintInfoMsg(format string, a ...interface{}) {
fmt.Printf(format+"\n", a...)
}

func PrintInfoMsgBold(format string, a ...interface{}) {
if terminalSupported() {
format = fmt.Sprintf("\033[1m%s\033[0m", format)
}
fmt.Printf(format+"\n", a...)
}

func PrintLine() {
fmt.Println()
}
Expand Down
116 changes: 64 additions & 52 deletions cmd/daemon/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"path/filepath"
"strconv"

cli "github.com/jawher/mow.cli"
"github.com/pactus-project/pactus/cmd"
Expand All @@ -17,7 +18,7 @@ import (
"github.com/pactus-project/pactus/wallet"
)

// Init initializes a node for pactus blockchain.
// Init initializes a node for the Pactus blockchain.
func Init() func(c *cli.Cmd) {
return func(c *cli.Cmd) {
workingDirOpt := c.String(cli.StringOpt{
Expand All @@ -44,72 +45,93 @@ func Init() func(c *cli.Cmd) {
cmd.PrintErrorMsg("The working directory is not empty: %s", workingDir)
return
}

cmd.PrintInfoMsg("Creating wallet...")
mnemonic := wallet.GenerateMnemonic(128)
cmd.PrintLine()
cmd.PrintInfoMsg("Your wallet seed:")
cmd.PrintInfoMsg("\"" + mnemonic + "\"")
cmd.PrintWarnMsg("Write down your 12 word mnemonic on a piece of paper to recover your validator key in future.")
cmd.PrintInfoMsg("Your wallet seed is:")
cmd.PrintInfoMsgBold(" " + mnemonic)
cmd.PrintLine()
cmd.PrintWarnMsg("Write down this seed on a piece of paper to recover your validator key in future.")
cmd.PrintLine()
confirmed := cmd.PromptConfirm("Do you want to continue")
if !confirmed {
return
}

cmd.PrintLine()
cmd.PrintInfoMsg("Please enter a password for wallet")
cmd.PrintInfoMsg("Enter a password for wallet")
password := cmd.PromptPassword("Password", true)
walletPath := cmd.PactusDefaultWalletPath(workingDir)

cmd.PrintLine()
cmd.PrintInfoMsg("How many validators do you want to create?")
cmd.PrintInfoMsg("Enter a number between 1 to 32, default is 7.")
numValidatorsStr := cmd.PromptInputWithSuggestion("Number of Validators", "7")
numValidators, err := strconv.Atoi(numValidatorsStr)
cmd.FatalErrorCheck(err)

if numValidators < 1 || numValidators > 32 {
cmd.PrintErrorMsg("Invalid validator number")
return
}

cmd.PrintLine()
cmd.PrintInfoMsg("Creating wallet...")

// To make process faster, we update the password
// after creating the addresses
network := wallet.NetworkMainNet
if *testnetOpt {
network = wallet.NetworkTestNet
}
wallet, err := wallet.Create(walletPath, mnemonic, "", network)
if err != nil {
cmd.PrintErrorMsg("Failed to create wallet: %v", err)
return
}
cmd.PrintInfoMsg("Wallet created successfully")
valAddrStr, err := wallet.DeriveNewAddress("Validator address")
if err != nil {
cmd.PrintErrorMsg("Failed to create validator address: %v", err)
return
cmd.FatalErrorCheck(err)

cmd.PrintLine()
cmd.PrintSuccessMsg("Wallet created successfully at %s.", walletPath)
cmd.PrintLine()
cmd.PrintInfoMsg("Generating keys...")
cmd.PrintLine()
cmd.PrintInfoMsgBold("Validator addresses:")
for i := 0; i < numValidators; i++ {
valAddrStr, err := wallet.DeriveNewAddress(fmt.Sprintf("Validator address %v", i+1))
cmd.FatalErrorCheck(err)

cmd.PrintInfoMsg("%v- %s", i+1, valAddrStr)
}
rewardAddrStr, err := wallet.DeriveNewAddress("Reward address")
if err != nil {
cmd.PrintErrorMsg("Failed to create reward address: %v", err)
return
cmd.PrintLine()

cmd.PrintInfoMsgBold("Reward addresses:")
for i := 0; i < numValidators; i++ {
rewardAddrStr, err := wallet.DeriveNewAddress(fmt.Sprintf("Reward address %v", i+1))
cmd.FatalErrorCheck(err)

cmd.PrintInfoMsg("%v- %s", i+1, rewardAddrStr)
}
cmd.PrintLine()
cmd.PrintInfoMsg("Initializing node...")
cmd.PrintLine()

var gen *genesis.Genesis
confFile := cmd.PactusConfigPath(workingDir)

if *testnetOpt {
cmd.PrintInfoMsg("Network: Testnet")

gen = genesis.Testnet()

// Save config for testnet
if err := config.SaveTestnetConfig(confFile, rewardAddrStr); err != nil {
cmd.PrintErrorMsg("Failed to write config file: %v", err)
return
}
err := config.SaveTestnetConfig(confFile, numValidators)
cmd.FatalErrorCheck(err)
} else if *localnetOpt {
info := wallet.AddressInfo(valAddrStr)
if info == nil {
cmd.PrintErrorMsg("Failed to get validator public key")
return
}
cmd.PrintInfoMsg("Network: Localnet")

info := wallet.AddressInfo(wallet.AddressLabels()[0].Address)
valPub := info.Pub.(*bls.PublicKey)
gen = makeLocalGenesis(valPub)

// Save config for localnet
if err := config.SaveLocalnetConfig(confFile, rewardAddrStr); err != nil {
cmd.PrintErrorMsg("Failed to write config file: %v", err)
return
}
err := config.SaveLocalnetConfig(confFile)
cmd.FatalErrorCheck(err)
} else {
panic("not yet!")
// gen = genesis.Mainnet()
Expand All @@ -121,38 +143,26 @@ func Init() func(c *cli.Cmd) {
// }
}

// Save genesis file
genFile := cmd.PactusGenesisPath(workingDir)
if err := gen.SaveToFile(genFile); err != nil {
cmd.PrintErrorMsg("Failed to write genesis file: %v", err)
return
}
err = gen.SaveToFile(genFile)
cmd.FatalErrorCheck(err)

err = wallet.UpdatePassword("", password)
if err != nil {
cmd.PrintErrorMsg("Failed to update wallet password: %v", err)
return
}
cmd.FatalErrorCheck(err)

// Save wallet
err = wallet.Save()
if err != nil {
cmd.PrintErrorMsg("Failed to save wallet: %v", err)
return
}
cmd.PrintLine()
cmd.FatalErrorCheck(err)

cmd.PrintLine()
cmd.PrintSuccessMsg("A pactus node is successfully initialized at %v", workingDir)
cmd.PrintInfoMsg("You validator address is: %v", valAddrStr)
cmd.PrintInfoMsg("You reward address is: %v", rewardAddrStr)
cmd.PrintLine()
cmd.PrintInfoMsg("You can start the node by running this command:")
cmd.PrintInfoMsg("./pactus-daemon start -w %v", workingDir)
}
}
}

// makeLocalGenesis makes genisis file for the local network.
// makeLocalGenesis makes genesis file for the local network.
func makeLocalGenesis(pub *bls.PublicKey) *genesis.Genesis {
// Treasury account
acc := account.NewAccount(crypto.TreasuryAddress, 0)
Expand All @@ -163,6 +173,8 @@ func makeLocalGenesis(pub *bls.PublicKey) *genesis.Genesis {
vals := []*validator.Validator{val}

// create genesis
gen := genesis.MakeGenesis(util.RoundNow(60), accs, vals, param.DefaultParams())
params := param.DefaultParams()
params.BlockVersion = 63
gen := genesis.MakeGenesis(util.RoundNow(60), accs, vals, params)
return gen
}
Loading