add some parameters to suppport non-interactive mode

This commit is contained in:
Ubuntu 2020-02-12 13:36:10 +00:00
parent 34bb132b10
commit 37d670069b
4 changed files with 192 additions and 73 deletions

View file

@ -42,6 +42,31 @@ func main() {
Value: 3,
Usage: "log level to emit to the screen",
},
cli.StringFlag{
Name: "consensusType",
Usage: "Which consensus engine to use? (default = null)\n \t\t1. Ethash - proof-of-work\n \t\t2. Clique - proof-of-authority",
},
cli.IntFlag{
Name: "blocksTime",
Usage: "log level to emit to the screen",
},
cli.StringFlag{
Name: "sealAccounts",
Usage: "Which accounts are allowed to seal? (mandatory at least one)",
},
cli.StringFlag{
Name: "preFundedAccounts",
Usage: "Which accounts should be pre-funded? (advisable at least one)",
},
cli.StringFlag{
Name: "preCmpAddressWithOneWei",
Usage: "Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei?",
},
cli.Uint64Flag{
Name: "networkID",
Value: 0,
Usage: "Specify your chain/network ID if you want an explicit one (default = random)",
},
}
app.Before = func(c *cli.Context) error {
// Set up the logger to print everything and the random generator
@ -60,6 +85,15 @@ func runWizard(c *cli.Context) error {
if strings.Contains(network, " ") || strings.Contains(network, "-") || strings.ToLower(network) != network {
log.Crit("No spaces, hyphens or capital letters allowed in network name")
}
makeWizard(c.String("network")).run()
consensusType := c.String("consensusType")
blocksTime := uint64(c.Int("blocksTime"))
sealAccounts := c.String("sealAccounts")
preFundedAccounts := c.String("preFundedAccounts")
preCmpAddOneWei := c.String("preCmpAddressWithOneWei")
networkID := c.Uint64("networkID")
nonInteract := network != "" && consensusType != "" && blocksTime > 0 && sealAccounts != "" && preFundedAccounts != "" && preCmpAddOneWei != "" && networkID > 0
makeWizard(network, consensusType, blocksTime, sealAccounts, preFundedAccounts, preCmpAddOneWei, networkID, nonInteract).run()
return nil
}

View file

@ -78,6 +78,13 @@ type wizard struct {
in *bufio.Reader // Wrapper around stdin to allow reading user input
lock sync.Mutex // Lock to protect configs during concurrent service discovery
consensusType string
blocksTime uint64
sealAccounts string
preFundedAccounts string
preCmpAddOneWei string
networkID uint64
nonInteract bool
}
// read reads a single line from stdin, trimming if from spaces.
@ -109,6 +116,9 @@ func (w *wizard) readString() string {
// an empty line is entered, the default value is returned.
func (w *wizard) readDefaultString(def string) string {
fmt.Printf("> ")
if w.nonInteract {
return def
}
text, err := w.in.ReadString('\n')
if err != nil {
log.Crit("Failed to read user input", "err", err)
@ -305,6 +315,29 @@ func (w *wizard) readAddress() *common.Address {
}
}
// readAddress reads a single line from stdin, trimming if from spaces and converts
// it to an Ethereum address.
func (w *wizard) processAddress(address string) []common.Address {
// process the address from the string
var signers []common.Address
signerArray := strings.Split(address, ",")
for i := 0; i < len(signerArray); i++ {
text := strings.TrimSpace(signerArray[i])
if text == "" {
continue
}
// Make sure it looks ok and return it if so
if len(text) != 40 {
log.Error("Invalid address length, please retry")
continue
}
bigaddr, _ := new(big.Int).SetString(text, 16)
address := common.BigToAddress(bigaddr)
signers = append(signers, address)
}
return signers
}
// readDefaultAddress reads a single line from stdin, trimming if from spaces and
// converts it to an Ethereum address. If an empty line is entered, the default
// value is returned.

View file

@ -60,7 +60,13 @@ func (w *wizard) makeGenesis() {
fmt.Println(" 1. Ethash - proof-of-work")
fmt.Println(" 2. Clique - proof-of-authority")
choice := w.read()
var choice string
if w.consensusType != "" {
choice = w.consensusType
fmt.Println(w.consensusType)
}else{
choice = w.read()
}
switch {
case choice == "1":
// In case of ethash, we're pretty much done
@ -76,13 +82,20 @@ func (w *wizard) makeGenesis() {
}
fmt.Println()
fmt.Println("How many seconds should blocks take? (default = 15)")
if w.blocksTime > 0 {
genesis.Config.Clique.Period = w.blocksTime
}else{
genesis.Config.Clique.Period = uint64(w.readDefaultInt(15))
}
// We also need the initial list of signers
fmt.Println()
fmt.Println("Which accounts are allowed to seal? (mandatory at least one)")
var signers []common.Address
if w.sealAccounts != "" {
signers = w.processAddress(w.sealAccounts)
} else {
for {
if address := w.readAddress(); address != nil {
signers = append(signers, *address)
@ -92,6 +105,7 @@ func (w *wizard) makeGenesis() {
break
}
}
}
// Sort the signers and embed into the extra-data section
for i := 0; i < len(signers); i++ {
for j := i + 1; j < len(signers); j++ {
@ -111,6 +125,15 @@ func (w *wizard) makeGenesis() {
// Consensus all set, just ask for initial funds and go
fmt.Println()
fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
if w.preFundedAccounts != "" {
preFunedAccounts := w.processAddress(w.preFundedAccounts)
for _, preFunedAccount := range preFunedAccounts {
genesis.Alloc[preFunedAccount] = core.GenesisAccount{
Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
}
continue
}
}else{
for {
// Read the address of the account to fund
if address := w.readAddress(); address != nil {
@ -121,18 +144,30 @@ func (w *wizard) makeGenesis() {
}
break
}
}
fmt.Println()
fmt.Println("Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)")
if w.preCmpAddOneWei == "true" {
for i := int64(0); i < 256; i++ {
genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)}
}
} else if w.preCmpAddOneWei == "" {
if w.readDefaultYesNo(true) {
// Add a batch of precompile balances to avoid them getting deleted
for i := int64(0); i < 256; i++ {
genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)}
}
}
}
// Query the user for some custom extras
fmt.Println()
fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
if w.networkID != 0 {
genesis.Config.ChainID = new(big.Int).SetUint64(w.networkID)
fmt.Println(w.networkID)
} else {
genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
}
// All done, store the genesis and flush to disk
log.Info("Configured new genesis block")
@ -197,7 +232,12 @@ func (w *wizard) manageGenesis() {
fmt.Println(" 2. Export genesis configurations")
fmt.Println(" 3. Remove genesis configuration")
choice := w.read()
var choice string
if w.nonInteract {
choice = "2"
} else {
choice = w.read()
}
switch choice {
case "1":
// Fork rule updating requested, iterate over each fork

View file

@ -30,7 +30,7 @@ import (
)
// makeWizard creates and returns a new puppeth wizard.
func makeWizard(network string) *wizard {
func makeWizard(network string, consensusType string, blocksTime uint64, sealAccounts string, preFundedAccounts string, preCmpAddOneWei string, networkID uint64, nonInteract bool) *wizard {
return &wizard{
network: network,
conf: config{
@ -39,6 +39,13 @@ func makeWizard(network string) *wizard {
servers: make(map[string]*sshClient),
services: make(map[string][]string),
in: bufio.NewReader(os.Stdin),
consensusType: consensusType,
blocksTime: blocksTime,
sealAccounts: sealAccounts,
preFundedAccounts: preFundedAccounts,
preCmpAddOneWei: preCmpAddOneWei,
networkID: networkID,
nonInteract: nonInteract,
}
}
@ -104,6 +111,10 @@ func (w *wizard) run() {
w.networkStats()
}
// Basics done, loop ad infinitum about what to do
if w.nonInteract {
w.makeGenesis()
w.manageGenesis()
} else {
for {
fmt.Println()
fmt.Println("What would you like to do? (default = stats)")
@ -167,3 +178,4 @@ func (w *wizard) run() {
}
}
}
}