github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/cmd/burrow/commands/config_options.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "net" 6 "strings" 7 8 "github.com/hyperledger/burrow/config" 9 "github.com/hyperledger/burrow/crypto" 10 cli "github.com/jawher/mow.cli" 11 ) 12 13 type configOptions struct { 14 configFileOpt *string 15 genesisFileOpt *string 16 validatorIndexOpt *int 17 accountIndexOpt *int 18 initAddressOpt *string 19 initPassphraseOpt *string 20 initMonikerOpt *string 21 externalAddressOpt *string 22 grpcAddressOpt *string 23 } 24 25 const configFileSpec = "[--config=<config file>]" 26 27 var configFileOption = cli.StringOpt{ 28 Name: "c config", 29 Desc: "Use the specified burrow config file", 30 EnvVar: "BURROW_CONFIG_FILE", 31 } 32 33 const genesisFileSpec = "[--genesis=<genesis json file>]" 34 35 var genesisFileOption = cli.StringOpt{ 36 Name: "g genesis", 37 Desc: "Use the specified genesis JSON file rather than a key in the main config, use - to read from STDIN", 38 EnvVar: "BURROW_GENESIS_FILE", 39 } 40 41 func addConfigOptions(cmd *cli.Cmd) *configOptions { 42 spec := "[--moniker=<human readable moniker>] " + 43 "[--index=<index of account in GenesisDoc> " + 44 "|--validator=<index of validator in GenesisDoc> " + 45 "|--address=<address of signing key>] " + 46 "[--passphrase=<secret passphrase to unlock key>] " + 47 "[--external-address=<hostname:port>] " + 48 "[--grpc-address=<hostname:port>] " + 49 configFileSpec + " " + genesisFileSpec 50 51 cmd.Spec = strings.Join([]string{cmd.Spec, spec}, " ") 52 return &configOptions{ 53 accountIndexOpt: cmd.Int(cli.IntOpt{ 54 Name: "i index", 55 Desc: "Account index (in accounts list - GenesisSpec or GenesisDoc) from which to set Address", 56 Value: -1, 57 EnvVar: "BURROW_ACCOUNT_INDEX", 58 }), 59 60 validatorIndexOpt: cmd.Int(cli.IntOpt{ 61 Name: "v validator", 62 Desc: "Validator index (in validators list - GenesisSpec or GenesisDoc) from which to set Address", 63 Value: -1, 64 EnvVar: "BURROW_VALIDATOR_INDEX", 65 }), 66 67 initAddressOpt: cmd.String(cli.StringOpt{ 68 Name: "a address", 69 Desc: "The address of the signing key of this node", 70 EnvVar: "BURROW_ADDRESS", 71 }), 72 73 initPassphraseOpt: cmd.String(cli.StringOpt{ 74 Name: "p passphrase", 75 Desc: "The passphrase of the signing key of this node (currently unimplemented but planned for future version of our KeyClient interface)", 76 EnvVar: "BURROW_PASSPHRASE", 77 }), 78 79 initMonikerOpt: cmd.String(cli.StringOpt{ 80 Name: "m moniker", 81 Desc: "An optional human-readable moniker to identify this node amongst Tendermint peers in logs and status queries", 82 EnvVar: "BURROW_NODE_MONIKER", 83 }), 84 85 externalAddressOpt: cmd.String(cli.StringOpt{ 86 Name: "x external-address", 87 Desc: "An external address or host name provided with the port that this node will broadcast over gossip in order for other nodes to connect", 88 EnvVar: "BURROW_EXTERNAL_ADDRESS", 89 }), 90 91 grpcAddressOpt: cmd.String(cli.StringOpt{ 92 Name: "grpc-address", 93 Desc: "GRPC listen address", 94 EnvVar: "BURROW_GRPC_ADDRESS", 95 }), 96 97 configFileOpt: cmd.String(configFileOption), 98 99 genesisFileOpt: cmd.String(genesisFileOption), 100 } 101 } 102 103 func (opts *configOptions) obtainBurrowConfig() (*config.BurrowConfig, error) { 104 conf, err := obtainDefaultConfig(*opts.configFileOpt, *opts.genesisFileOpt) 105 if err != nil { 106 return nil, err 107 } 108 // Which account am I? 109 conf.ValidatorAddress, err = accountAddress(conf, *opts.initAddressOpt, *opts.accountIndexOpt, *opts.validatorIndexOpt) 110 if err != nil { 111 return nil, err 112 } 113 if *opts.initPassphraseOpt != "" { 114 conf.Passphrase = opts.initPassphraseOpt 115 } 116 if *opts.initMonikerOpt == "" { 117 chainIDHeader := "" 118 if conf.GenesisDoc != nil && conf.GenesisDoc.GetChainID() != "" { 119 chainIDHeader = conf.GenesisDoc.GetChainID() + "_" 120 } 121 if conf.ValidatorAddress != nil { 122 // Set a default moniker... since we can at this stage of config completion and it is required for start 123 conf.Tendermint.Moniker = fmt.Sprintf("%sNode_%s", chainIDHeader, conf.ValidatorAddress) 124 } 125 } else { 126 conf.Tendermint.Moniker = *opts.initMonikerOpt 127 } 128 if *opts.externalAddressOpt != "" { 129 conf.Tendermint.ExternalAddress = *opts.externalAddressOpt 130 } 131 if *opts.grpcAddressOpt != "" { 132 host, port, err := net.SplitHostPort(*opts.grpcAddressOpt) 133 if err != nil { 134 return nil, fmt.Errorf("could not parse GRPC listen addres: %w", err) 135 } 136 conf.RPC.GRPC.ListenHost = host 137 conf.RPC.GRPC.ListenPort = port 138 } 139 return conf, nil 140 } 141 142 // address is sourced in the following order: 143 // 1. explicitly from cli 144 // 2. genesis accounts (by index) 145 // 3. genesis validators (by index) 146 // 4. config 147 // 5. genesis validator (if only one) 148 func accountAddress(conf *config.BurrowConfig, addressIn string, accIndex, valIndex int) (*crypto.Address, error) { 149 if addressIn != "" { 150 address, err := crypto.AddressFromHexString(addressIn) 151 if err != nil { 152 return nil, fmt.Errorf("could not read address for account in '%s': %v", addressIn, err) 153 } 154 return &address, nil 155 } else if accIndex > -1 { 156 if conf.GenesisDoc == nil { 157 return nil, fmt.Errorf("unable to set Address from provided index since no " + 158 "GenesisDoc/GenesisSpec provided") 159 } 160 if accIndex >= len(conf.GenesisDoc.Accounts) { 161 return nil, fmt.Errorf("index of %v given but only %v accounts specified in GenesisDoc", 162 accIndex, len(conf.GenesisDoc.Accounts)) 163 } 164 return &conf.GenesisDoc.Accounts[accIndex].Address, nil 165 } else if valIndex > -1 { 166 if conf.GenesisDoc == nil { 167 return nil, fmt.Errorf("unable to set Address from provided validator since no " + 168 "GenesisDoc/GenesisSpec provided") 169 } 170 if valIndex >= len(conf.GenesisDoc.Validators) { 171 return nil, fmt.Errorf("validator index of %v given but only %v validators specified in GenesisDoc", 172 valIndex, len(conf.GenesisDoc.Validators)) 173 } 174 return &conf.GenesisDoc.Validators[valIndex].Address, nil 175 } else if conf.ValidatorAddress != nil { 176 return conf.ValidatorAddress, nil 177 } else if conf.GenesisDoc != nil && len(conf.GenesisDoc.Validators) == 1 { 178 return &conf.GenesisDoc.Validators[0].Address, nil 179 } 180 return nil, nil 181 }