-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into MinimumStake
- Loading branch information
Showing
198 changed files
with
7,402 additions
and
5,206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,96 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"path/filepath" | ||
|
||
cli "github.com/jawher/mow.cli" | ||
"github.com/pactus-project/pactus/cmd" | ||
"github.com/pactus-project/pactus/genesis" | ||
"github.com/pactus-project/pactus/util" | ||
"github.com/pactus-project/pactus/wallet" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// Init initializes a node for the Pactus blockchain. | ||
func Init() func(c *cli.Cmd) { | ||
return func(c *cli.Cmd) { | ||
workingDirOpt := c.String(cli.StringOpt{ | ||
Name: "w working-dir", | ||
Desc: "A path to the working directory to save the wallet and node files", | ||
Value: cmd.PactusHomeDir(), | ||
}) | ||
testnetOpt := c.Bool(cli.BoolOpt{ | ||
Name: "testnet", | ||
Desc: "Initialize working directory for joining the testnet", | ||
Value: true, // TODO: make it false after mainnet launch | ||
}) | ||
localnetOpt := c.Bool(cli.BoolOpt{ | ||
Name: "localnet", | ||
Desc: "Initialize working directory for localnet (for developers)", | ||
Value: false, | ||
}) | ||
restoreOpt := c.String(cli.StringOpt{ | ||
Name: "restore", | ||
Desc: "Restore the default_wallet using a mnemonic (seed phrase)", | ||
Value: "", | ||
}) | ||
// BuildInitCmd builds the init command for the Pactus blockchain. | ||
func buildInitCmd(parentCmd *cobra.Command) { | ||
var initCmd = &cobra.Command{ | ||
Use: "init", | ||
Short: "Initialize the Pactus blockchain", | ||
} | ||
parentCmd.AddCommand(initCmd) | ||
workingDirOpt := initCmd.Flags().StringP("working-dir", "w", | ||
cmd.PactusHomeDir(), "A path to the working directory to save the wallet and node files") | ||
|
||
c.LongDesc = "Initializing the working directory" | ||
c.Before = func() { fmt.Println(cmd.Pactus) } | ||
c.Action = func() { | ||
workingDir, _ := filepath.Abs(*workingDirOpt) | ||
if !util.IsDirNotExistsOrEmpty(workingDir) { | ||
cmd.PrintErrorMsg("The working directory is not empty: %s", workingDir) | ||
return | ||
} | ||
mnemonic := "" | ||
if len(*restoreOpt) == 0 { | ||
mnemonic = wallet.GenerateMnemonic(128) | ||
cmd.PrintLine() | ||
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 | ||
} | ||
} else { | ||
mnemonic = *restoreOpt | ||
err := wallet.CheckMnemonic(*restoreOpt) | ||
cmd.FatalErrorCheck(err) | ||
} | ||
cmd.PrintLine() | ||
cmd.PrintInfoMsg("Enter a password for wallet") | ||
password := cmd.PromptPassword("Password", true) | ||
testnetOpt := initCmd.Flags().Bool("testnet", true, | ||
"Initialize working directory for joining the testnet") // TODO: make it false after mainnet launch | ||
|
||
cmd.PrintLine() | ||
cmd.PrintInfoMsgBold("How many validators do you want to create?") | ||
cmd.PrintInfoMsg("Each node can run up to 32 validators, and each validator can hold up to 1000 staked coins.") | ||
cmd.PrintInfoMsg("You can define validators based on the amount of coins you want to stake.") | ||
numValidators := cmd.PromptInputWithRange("Number of Validators", 7, 1, 32) | ||
localnetOpt := initCmd.Flags().Bool("localnet", false, | ||
"Initialize working directory for localnet (for developers)") | ||
|
||
chain := genesis.Mainnet | ||
// The order of checking the network (chain type) matters here. | ||
if *testnetOpt { | ||
chain = genesis.Testnet | ||
} | ||
if *localnetOpt { | ||
chain = genesis.Localnet | ||
} | ||
validatorAddrs, rewardAddrs, err := cmd.CreateNode(numValidators, chain, workingDir, mnemonic, password) | ||
cmd.FatalErrorCheck(err) | ||
restoreOpt := initCmd.Flags().String("restore", "", "Restore the default_wallet using a mnemonic (seed phrase)") | ||
|
||
initCmd.Run = func(_ *cobra.Command, _ []string) { | ||
workingDir, _ := filepath.Abs(*workingDirOpt) | ||
if !util.IsDirNotExistsOrEmpty(workingDir) { | ||
cmd.PrintErrorMsg("The working directory is not empty: %s", workingDir) | ||
return | ||
} | ||
mnemonic := "" | ||
if len(*restoreOpt) == 0 { | ||
mnemonic = wallet.GenerateMnemonic(128) | ||
cmd.PrintLine() | ||
cmd.PrintInfoMsgBold("Validator addresses:") | ||
for i, addr := range validatorAddrs { | ||
cmd.PrintInfoMsg("%v- %s", i+1, addr) | ||
} | ||
cmd.PrintInfoMsg("Your wallet seed is:") | ||
cmd.PrintInfoMsgBold(" " + mnemonic) | ||
cmd.PrintLine() | ||
|
||
cmd.PrintInfoMsgBold("Reward addresses:") | ||
for i, addr := range rewardAddrs { | ||
cmd.PrintInfoMsg("%v- %s", i+1, addr) | ||
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 | ||
} | ||
} else { | ||
mnemonic = *restoreOpt | ||
err := wallet.CheckMnemonic(*restoreOpt) | ||
cmd.FatalErrorCheck(err) | ||
} | ||
cmd.PrintLine() | ||
cmd.PrintInfoMsg("Enter a password for wallet") | ||
password := cmd.PromptPassword("Password", true) | ||
|
||
cmd.PrintLine() | ||
cmd.PrintInfoMsgBold("Network: %v", chain.String()) | ||
cmd.PrintLine() | ||
cmd.PrintSuccessMsg("A pactus node is successfully initialized at %v", workingDir) | ||
cmd.PrintLine() | ||
cmd.PrintInfoMsg("You can start the node by running this command:") | ||
cmd.PrintInfoMsg("./pactus-daemon start -w %v", workingDir) | ||
cmd.PrintLine() | ||
cmd.PrintInfoMsgBold("How many validators do you want to create?") | ||
cmd.PrintInfoMsg("Each node can run up to 32 validators, and each validator can hold up to 1000 staked coins.") | ||
cmd.PrintInfoMsg("You can define validators based on the amount of coins you want to stake.") | ||
numValidators := cmd.PromptInputWithRange("Number of Validators", 7, 1, 32) | ||
|
||
chain := genesis.Mainnet | ||
// The order of checking the network (chain type) matters here. | ||
if *testnetOpt { | ||
chain = genesis.Testnet | ||
} | ||
if *localnetOpt { | ||
chain = genesis.Localnet | ||
} | ||
validatorAddrs, rewardAddrs, err := cmd.CreateNode(numValidators, chain, workingDir, mnemonic, password) | ||
cmd.FatalErrorCheck(err) | ||
|
||
cmd.PrintLine() | ||
cmd.PrintInfoMsgBold("Validator addresses:") | ||
for i, addr := range validatorAddrs { | ||
cmd.PrintInfoMsg("%v- %s", i+1, addr) | ||
} | ||
cmd.PrintLine() | ||
|
||
cmd.PrintInfoMsgBold("Reward addresses:") | ||
for i, addr := range rewardAddrs { | ||
cmd.PrintInfoMsg("%v- %s", i+1, addr) | ||
} | ||
|
||
cmd.PrintLine() | ||
cmd.PrintInfoMsgBold("Network: %v", chain.String()) | ||
cmd.PrintLine() | ||
cmd.PrintSuccessMsg("A pactus node is successfully initialized at %v", workingDir) | ||
cmd.PrintLine() | ||
cmd.PrintInfoMsg("You can start the node by running this command:") | ||
cmd.PrintInfoMsg("./pactus-daemon start -w %v", workingDir) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,25 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"fmt" | ||
|
||
cli "github.com/jawher/mow.cli" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func main() { | ||
app := cli.App("pactus-daemon", "Pactus daemon") | ||
|
||
app.Command("init", "Initialize the Pactus blockchain", Init()) | ||
app.Command("start", "Start the Pactus blockchain", Start()) | ||
app.Command("version", "Print the Pactus version", Version()) | ||
var rootCmd = &cobra.Command{ | ||
Use: "pactus-daemon", | ||
Short: "Pactus daemon", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
fmt.Println("use --help") | ||
}, | ||
} | ||
|
||
if err := app.Run(os.Args); err != nil { | ||
buildVersionCmd(rootCmd) | ||
buildInitCmd(rootCmd) | ||
buildStartCmd(rootCmd) | ||
err := rootCmd.Execute() | ||
if err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,74 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
_ "net/http/pprof" // #nosec | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
cli "github.com/jawher/mow.cli" | ||
"github.com/pactus-project/pactus/cmd" | ||
"github.com/pactus-project/pactus/wallet" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// Start starts the pactus node. | ||
func Start() func(c *cli.Cmd) { | ||
return func(c *cli.Cmd) { | ||
workingDirOpt := c.String(cli.StringOpt{ | ||
Name: "w working-dir", | ||
Desc: "A path to the working directory to read the wallet and node files", | ||
Value: cmd.PactusHomeDir(), | ||
}) | ||
passwordOpt := c.String(cli.StringOpt{ | ||
Name: "p password", | ||
Desc: "The wallet password", | ||
}) | ||
pprofOpt := c.String(cli.StringOpt{ | ||
Name: "pprof", | ||
Desc: "debug pprof server address(not recommended to expose to internet)", | ||
}) | ||
func buildStartCmd(parentCmd *cobra.Command) { | ||
var startCmd = &cobra.Command{ | ||
Use: "start", | ||
Short: "Start the Pactus blockchain", | ||
} | ||
|
||
c.LongDesc = "Starting the node from working directory" | ||
c.Before = func() { fmt.Println(cmd.Pactus) } | ||
c.Action = func() { | ||
workingDir, _ := filepath.Abs(*workingDirOpt) | ||
// change working directory | ||
err := os.Chdir(workingDir) | ||
cmd.FatalErrorCheck(err) | ||
parentCmd.AddCommand(startCmd) | ||
|
||
if *pprofOpt != "" { | ||
cmd.PrintWarnMsg("Starting Debug pprof server on: http://%s/debug/pprof/", *pprofOpt) | ||
server := &http.Server{ | ||
Addr: *pprofOpt, | ||
ReadHeaderTimeout: 3 * time.Second, | ||
} | ||
go func() { | ||
err := server.ListenAndServe() | ||
cmd.FatalErrorCheck(err) | ||
}() | ||
} | ||
workingDirOpt := startCmd.Flags().StringP("working-dir", "w", | ||
cmd.PactusHomeDir(), "A path to the working directory to read the wallet and node files") | ||
|
||
passwordOpt := startCmd.Flags().StringP("password", "p", "", "The wallet password") | ||
|
||
pprofOpt := startCmd.Flags().String("pprof", "", "debug pprof server address(not recommended to expose to internet)") | ||
|
||
passwordFetcher := func(wallet *wallet.Wallet) (string, bool) { | ||
if !wallet.IsEncrypted() { | ||
return "", true | ||
} | ||
startCmd.Run = func(_ *cobra.Command, _ []string) { | ||
workingDir, _ := filepath.Abs(*workingDirOpt) | ||
// change working directory | ||
err := os.Chdir(workingDir) | ||
cmd.FatalErrorCheck(err) | ||
|
||
var password string | ||
if *passwordOpt != "" { | ||
password = *passwordOpt | ||
} else { | ||
password = cmd.PromptPassword("Wallet password", false) | ||
} | ||
return password, true | ||
if *pprofOpt != "" { | ||
cmd.PrintWarnMsg("Starting Debug pprof server on: http://%s/debug/pprof/", *pprofOpt) | ||
server := &http.Server{ | ||
Addr: *pprofOpt, | ||
ReadHeaderTimeout: 3 * time.Second, | ||
} | ||
node, _, err := cmd.StartNode( | ||
workingDir, passwordFetcher) | ||
cmd.FatalErrorCheck(err) | ||
go func() { | ||
err := server.ListenAndServe() | ||
cmd.FatalErrorCheck(err) | ||
}() | ||
} | ||
|
||
cmd.TrapSignal(func() { | ||
node.Stop() | ||
cmd.PrintInfoMsg("Exiting ...") | ||
}) | ||
passwordFetcher := func(wallet *wallet.Wallet) (string, bool) { | ||
if !wallet.IsEncrypted() { | ||
return "", true | ||
} | ||
|
||
// run forever (the node will not be returned) | ||
select {} | ||
var password string | ||
if *passwordOpt != "" { | ||
password = *passwordOpt | ||
} else { | ||
password = cmd.PromptPassword("Wallet password", false) | ||
} | ||
return password, true | ||
} | ||
node, _, err := cmd.StartNode( | ||
workingDir, passwordFetcher) | ||
cmd.FatalErrorCheck(err) | ||
|
||
cmd.TrapSignal(func() { | ||
node.Stop() | ||
cmd.PrintInfoMsg("Exiting ...") | ||
}) | ||
|
||
// run forever (the node will not be returned) | ||
select {} | ||
} | ||
} |
Oops, something went wrong.