mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
add some parameters to suppport non-interactive mode
This commit is contained in:
parent
34bb132b10
commit
37d670069b
4 changed files with 192 additions and 73 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,20 +82,28 @@ func (w *wizard) makeGenesis() {
|
|||
}
|
||||
fmt.Println()
|
||||
fmt.Println("How many seconds should blocks take? (default = 15)")
|
||||
genesis.Config.Clique.Period = uint64(w.readDefaultInt(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
|
||||
for {
|
||||
if address := w.readAddress(); address != nil {
|
||||
signers = append(signers, *address)
|
||||
continue
|
||||
}
|
||||
if len(signers) > 0 {
|
||||
break
|
||||
if w.sealAccounts != "" {
|
||||
signers = w.processAddress(w.sealAccounts)
|
||||
} else {
|
||||
for {
|
||||
if address := w.readAddress(); address != nil {
|
||||
signers = append(signers, *address)
|
||||
continue
|
||||
}
|
||||
if len(signers) > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort the signers and embed into the extra-data section
|
||||
|
|
@ -111,28 +125,49 @@ 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)")
|
||||
for {
|
||||
// Read the address of the account to fund
|
||||
if address := w.readAddress(); address != nil {
|
||||
genesis.Alloc[*address] = core.GenesisAccount{
|
||||
Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
|
||||
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
|
||||
}
|
||||
continue
|
||||
}else{
|
||||
for {
|
||||
// Read the address of the account to fund
|
||||
if address := w.readAddress(); address != nil {
|
||||
genesis.Alloc[*address] = core.GenesisAccount{
|
||||
Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println("Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)")
|
||||
if w.readDefaultYesNo(true) {
|
||||
// Add a batch of precompile balances to avoid them getting deleted
|
||||
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)")
|
||||
genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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,66 +111,71 @@ func (w *wizard) run() {
|
|||
w.networkStats()
|
||||
}
|
||||
// Basics done, loop ad infinitum about what to do
|
||||
for {
|
||||
fmt.Println()
|
||||
fmt.Println("What would you like to do? (default = stats)")
|
||||
fmt.Println(" 1. Show network stats")
|
||||
if w.conf.Genesis == nil {
|
||||
fmt.Println(" 2. Configure new genesis")
|
||||
} else {
|
||||
fmt.Println(" 2. Manage existing genesis")
|
||||
}
|
||||
if len(w.servers) == 0 {
|
||||
fmt.Println(" 3. Track new remote server")
|
||||
} else {
|
||||
fmt.Println(" 3. Manage tracked machines")
|
||||
}
|
||||
if len(w.services) == 0 {
|
||||
fmt.Println(" 4. Deploy network components")
|
||||
} else {
|
||||
fmt.Println(" 4. Manage network components")
|
||||
}
|
||||
|
||||
choice := w.read()
|
||||
switch {
|
||||
case choice == "" || choice == "1":
|
||||
w.networkStats()
|
||||
|
||||
case choice == "2":
|
||||
if w.nonInteract {
|
||||
w.makeGenesis()
|
||||
w.manageGenesis()
|
||||
} else {
|
||||
for {
|
||||
fmt.Println()
|
||||
fmt.Println("What would you like to do? (default = stats)")
|
||||
fmt.Println(" 1. Show network stats")
|
||||
if w.conf.Genesis == nil {
|
||||
fmt.Println()
|
||||
fmt.Println("What would you like to do? (default = create)")
|
||||
fmt.Println(" 1. Create new genesis from scratch")
|
||||
fmt.Println(" 2. Import already existing genesis")
|
||||
|
||||
choice := w.read()
|
||||
switch {
|
||||
case choice == "" || choice == "1":
|
||||
w.makeGenesis()
|
||||
case choice == "2":
|
||||
w.importGenesis()
|
||||
default:
|
||||
log.Error("That's not something I can do")
|
||||
}
|
||||
fmt.Println(" 2. Configure new genesis")
|
||||
} else {
|
||||
w.manageGenesis()
|
||||
fmt.Println(" 2. Manage existing genesis")
|
||||
}
|
||||
case choice == "3":
|
||||
if len(w.servers) == 0 {
|
||||
if w.makeServer() != "" {
|
||||
w.networkStats()
|
||||
}
|
||||
fmt.Println(" 3. Track new remote server")
|
||||
} else {
|
||||
w.manageServers()
|
||||
fmt.Println(" 3. Manage tracked machines")
|
||||
}
|
||||
case choice == "4":
|
||||
if len(w.services) == 0 {
|
||||
w.deployComponent()
|
||||
fmt.Println(" 4. Deploy network components")
|
||||
} else {
|
||||
w.manageComponents()
|
||||
fmt.Println(" 4. Manage network components")
|
||||
}
|
||||
|
||||
choice := w.read()
|
||||
switch {
|
||||
case choice == "" || choice == "1":
|
||||
w.networkStats()
|
||||
|
||||
case choice == "2":
|
||||
if w.conf.Genesis == nil {
|
||||
fmt.Println()
|
||||
fmt.Println("What would you like to do? (default = create)")
|
||||
fmt.Println(" 1. Create new genesis from scratch")
|
||||
fmt.Println(" 2. Import already existing genesis")
|
||||
|
||||
choice := w.read()
|
||||
switch {
|
||||
case choice == "" || choice == "1":
|
||||
w.makeGenesis()
|
||||
case choice == "2":
|
||||
w.importGenesis()
|
||||
default:
|
||||
log.Error("That's not something I can do")
|
||||
}
|
||||
} else {
|
||||
w.manageGenesis()
|
||||
}
|
||||
case choice == "3":
|
||||
if len(w.servers) == 0 {
|
||||
if w.makeServer() != "" {
|
||||
w.networkStats()
|
||||
}
|
||||
} else {
|
||||
w.manageServers()
|
||||
}
|
||||
case choice == "4":
|
||||
if len(w.services) == 0 {
|
||||
w.deployComponent()
|
||||
} else {
|
||||
w.manageComponents()
|
||||
}
|
||||
default:
|
||||
log.Error("That's not something I can do")
|
||||
}
|
||||
default:
|
||||
log.Error("That's not something I can do")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue