change config from flag to toml file; fix tag listenaddr

This commit is contained in:
Nguyen Ba Tam 2018-07-11 16:58:08 +07:00 committed by Tuna
parent 80c7b4c01f
commit 564641a1ad
11 changed files with 107 additions and 55 deletions

View file

@ -190,7 +190,7 @@ func initGenesis(ctx *cli.Context) error {
utils.Fatalf("invalid genesis file: %v", err) utils.Fatalf("invalid genesis file: %v", err)
} }
// Open an initialise both full and light databases // Open an initialise both full and light databases
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
for _, name := range []string{"chaindata", "lightchaindata"} { for _, name := range []string{"chaindata", "lightchaindata"} {
chaindb, err := stack.OpenDatabase(name, 0, 0) chaindb, err := stack.OpenDatabase(name, 0, 0)
if err != nil { if err != nil {
@ -209,7 +209,7 @@ func importChain(ctx *cli.Context) error {
if len(ctx.Args()) < 1 { if len(ctx.Args()) < 1 {
utils.Fatalf("This command requires an argument.") utils.Fatalf("This command requires an argument.")
} }
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
chain, chainDb := utils.MakeChain(ctx, stack) chain, chainDb := utils.MakeChain(ctx, stack)
defer chainDb.Close() defer chainDb.Close()
@ -303,7 +303,7 @@ func exportChain(ctx *cli.Context) error {
if len(ctx.Args()) < 1 { if len(ctx.Args()) < 1 {
utils.Fatalf("This command requires an argument.") utils.Fatalf("This command requires an argument.")
} }
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
chain, _ := utils.MakeChain(ctx, stack) chain, _ := utils.MakeChain(ctx, stack)
start := time.Now() start := time.Now()
@ -336,7 +336,7 @@ func importPreimages(ctx *cli.Context) error {
if len(ctx.Args()) < 1 { if len(ctx.Args()) < 1 {
utils.Fatalf("This command requires an argument.") utils.Fatalf("This command requires an argument.")
} }
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase) diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase)
start := time.Now() start := time.Now()
@ -352,7 +352,7 @@ func exportPreimages(ctx *cli.Context) error {
if len(ctx.Args()) < 1 { if len(ctx.Args()) < 1 {
utils.Fatalf("This command requires an argument.") utils.Fatalf("This command requires an argument.")
} }
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase) diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase)
start := time.Now() start := time.Now()
@ -369,7 +369,7 @@ func copyDb(ctx *cli.Context) error {
utils.Fatalf("Source chaindata directory path argument missing") utils.Fatalf("Source chaindata directory path argument missing")
} }
// Initialize a new chain for the running node to sync into // Initialize a new chain for the running node to sync into
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
chain, chainDb := utils.MakeChain(ctx, stack) chain, chainDb := utils.MakeChain(ctx, stack)
syncmode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode) syncmode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode)
@ -441,7 +441,7 @@ func removeDB(ctx *cli.Context) error {
} }
func dump(ctx *cli.Context) error { func dump(ctx *cli.Context) error {
stack := makeFullNode(ctx) stack,_ := makeFullNode(ctx)
chain, chainDb := utils.MakeChain(ctx, stack) chain, chainDb := utils.MakeChain(ctx, stack)
for _, arg := range ctx.Args() { for _, arg := range ctx.Args() {
var block *types.Block var block *types.Block

View file

@ -25,7 +25,7 @@ import (
"reflect" "reflect"
"unicode" "unicode"
cli "gopkg.in/urfave/cli.v1" "gopkg.in/urfave/cli.v1"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/dashboard" "github.com/ethereum/go-ethereum/dashboard"
@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
"github.com/naoina/toml" "github.com/naoina/toml"
"strings"
) )
var ( var (
@ -71,15 +72,21 @@ var tomlSettings = toml.Config{
} }
type ethstatsConfig struct { type ethstatsConfig struct {
URL string `toml:",omitempty"` URL string `toml:"url"`
} }
type account struct {
Unlocks []string `toml:"unlocks"`
Passwords []string `toml:"passwords"`
}
type tomoConfig struct { type tomoConfig struct {
Eth eth.Config Eth eth.Config `toml:"eth"`
Shh whisper.Config Shh whisper.Config `toml:"ssh"`
Node node.Config Node node.Config `toml:"node"`
Ethstats ethstatsConfig Ethstats ethstatsConfig `toml:"ethstats"`
Dashboard dashboard.Config Dashboard dashboard.Config `toml:"dashboard"`
Account account `toml:"account"`
MineEnable bool `toml:"mine"`
} }
func loadConfig(file string, cfg *tomoConfig) error { func loadConfig(file string, cfg *tomoConfig) error {
@ -88,7 +95,6 @@ func loadConfig(file string, cfg *tomoConfig) error {
return err return err
} }
defer f.Close() defer f.Close()
err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg) err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg)
// Add file name to errors that have a line number. // Add file name to errors that have a line number.
if _, ok := err.(*toml.LineError); ok { if _, ok := err.(*toml.LineError); ok {
@ -115,7 +121,6 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, tomoConfig) {
Node: defaultNodeConfig(), Node: defaultNodeConfig(),
Dashboard: dashboard.DefaultConfig, Dashboard: dashboard.DefaultConfig,
} }
// Load config file. // Load config file.
if file := ctx.GlobalString(configFileFlag.Name); file != "" { if file := ctx.GlobalString(configFileFlag.Name); file != "" {
if err := loadConfig(file, &cfg); err != nil { if err := loadConfig(file, &cfg); err != nil {
@ -123,6 +128,21 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, tomoConfig) {
} }
} }
// read passwords from enviroment
passwords := []string{}
for _, env := range cfg.Account.Passwords {
if trimmed := strings.TrimSpace(env); trimmed != "" {
value := os.Getenv(trimmed)
for _, info := range strings.Split(value, ",") {
trimmed2 := strings.TrimSpace(info)
if (trimmed2 != "") {
passwords = append(passwords, trimmed2)
}
}
}
}
cfg.Account.Passwords = passwords
// Apply flags. // Apply flags.
utils.SetNodeConfig(ctx, &cfg.Node) utils.SetNodeConfig(ctx, &cfg.Node)
stack, err := node.New(&cfg.Node) stack, err := node.New(&cfg.Node)
@ -150,7 +170,7 @@ func enableWhisper(ctx *cli.Context) bool {
return false return false
} }
func makeFullNode(ctx *cli.Context) *node.Node { func makeFullNode(ctx *cli.Context) (*node.Node, tomoConfig) {
stack, cfg := makeConfigNode(ctx) stack, cfg := makeConfigNode(ctx)
utils.RegisterEthService(stack, &cfg.Eth) utils.RegisterEthService(stack, &cfg.Eth)
@ -175,7 +195,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
if cfg.Ethstats.URL != "" { if cfg.Ethstats.URL != "" {
utils.RegisterEthStatsService(stack, cfg.Ethstats.URL) utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
} }
return stack return stack, cfg
} }
// dumpConfig is the dumpconfig command. // dumpConfig is the dumpconfig command.

View file

@ -77,8 +77,8 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Cons
// same time. // same time.
func localConsole(ctx *cli.Context) error { func localConsole(ctx *cli.Context) error {
// Create and start the node based on the CLI flags // Create and start the node based on the CLI flags
node := makeFullNode(ctx) node,cfg := makeFullNode(ctx)
startNode(ctx, node) startNode(ctx, node,cfg)
defer node.Stop() defer node.Stop()
// Attach to the newly started node and start the JavaScript console // Attach to the newly started node and start the JavaScript console
@ -130,6 +130,7 @@ func remoteConsole(ctx *cli.Context) error {
} }
endpoint = fmt.Sprintf("%s/tomo.ipc", path) endpoint = fmt.Sprintf("%s/tomo.ipc", path)
} }
client, err := dialRPC(endpoint) client, err := dialRPC(endpoint)
if err != nil { if err != nil {
utils.Fatalf("Unable to attach to remote tomo: %v", err) utils.Fatalf("Unable to attach to remote tomo: %v", err)
@ -178,8 +179,8 @@ func dialRPC(endpoint string) (*rpc.Client, error) {
// everything down. // everything down.
func ephemeralConsole(ctx *cli.Context) error { func ephemeralConsole(ctx *cli.Context) error {
// Create and start the node based on the CLI flags // Create and start the node based on the CLI flags
node := makeFullNode(ctx) node,cfg := makeFullNode(ctx)
startNode(ctx, node) startNode(ctx, node,cfg)
defer node.Stop() defer node.Stop()
// Attach to the newly started node and start the JavaScript console // Attach to the newly started node and start the JavaScript console

View file

@ -213,8 +213,8 @@ func main() {
// It creates a default node based on the command line arguments and runs it in // It creates a default node based on the command line arguments and runs it in
// blocking mode, waiting for it to be shut down. // blocking mode, waiting for it to be shut down.
func tomo(ctx *cli.Context) error { func tomo(ctx *cli.Context) error {
node := makeFullNode(ctx) node,cfg := makeFullNode(ctx)
startNode(ctx, node) startNode(ctx, node,cfg)
node.Wait() node.Wait()
return nil return nil
} }
@ -222,18 +222,18 @@ func tomo(ctx *cli.Context) error {
// startNode boots up the system node and all registered protocols, after which // startNode boots up the system node and all registered protocols, after which
// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
// miner. // miner.
func startNode(ctx *cli.Context, stack *node.Node) { func startNode(ctx *cli.Context, stack *node.Node,cfg tomoConfig) {
// Start up the node itself // Start up the node itself
utils.StartNode(stack) utils.StartNode(stack)
// Unlock any account specifically requested // Unlock any account specifically requested
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
passwords := utils.MakePasswordList(ctx) //passwords := utils.MakePasswordList(ctx)
unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") //unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
for i, account := range unlocks { for i, account := range cfg.Account.Unlocks {
if trimmed := strings.TrimSpace(account); trimmed != "" { if trimmed := strings.TrimSpace(account); trimmed != "" {
unlockAccount(ctx, ks, trimmed, i, passwords) unlockAccount(ctx, ks, trimmed, i, cfg.Account.Passwords)
} }
} }
// Register wallet event handlers to open and auto-derive wallets // Register wallet event handlers to open and auto-derive wallets
@ -278,7 +278,8 @@ func startNode(ctx *cli.Context, stack *node.Node) {
} }
}() }()
// Start auxiliary services if enabled // Start auxiliary services if enabled
if ctx.GlobalBool(utils.StakingEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { //if ctx.GlobalBool(utils.StakingEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
if cfg.MineEnable || ctx.GlobalBool(utils.DeveloperFlag.Name) {
// Mining only makes sense if a full Ethereum node is running // Mining only makes sense if a full Ethereum node is running
if ctx.GlobalBool(utils.LightModeFlag.Name) || ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { if ctx.GlobalBool(utils.LightModeFlag.Name) || ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
utils.Fatalf("Light clients do not support staking") utils.Fatalf("Light clients do not support staking")
@ -305,7 +306,7 @@ func startNode(ctx *cli.Context, stack *node.Node) {
} }
} }
// Set the gas price to the limits from the CLI and start mining // Set the gas price to the limits from the CLI and start mining
ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) ethereum.TxPool().SetGasPrice(cfg.Eth.GasPrice)
if err := ethereum.StartStaking(true); err != nil { if err := ethereum.StartStaking(true); err != nil {
utils.Fatalf("Failed to start staking: %v", err) utils.Fatalf("Failed to start staking: %v", err)
} }
@ -341,7 +342,7 @@ func startNode(ctx *cli.Context, stack *node.Node) {
} }
} }
// Set the gas price to the limits from the CLI and start mining // Set the gas price to the limits from the CLI and start mining
ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) ethereum.TxPool().SetGasPrice(cfg.Eth.GasPrice)
if err := ethereum.StartStaking(true); err != nil { if err := ethereum.StartStaking(true); err != nil {
utils.Fatalf("Failed to start staking: %v", err) utils.Fatalf("Failed to start staking: %v", err)
} }

29
cmd/tomo/testdata/tomo.toml vendored Normal file
View file

@ -0,0 +1,29 @@
mine = true # flag --mine ( true : enable miner , false : disable )
[eth]
NetworkId = 1515 # flag --networkid
SyncMode = "full" # flag --syncmode
GasPrice = 1 # flag --gasprice
[ssh]
[node]
datadir = "node1/" # flag --datadir
http_host = "localhost" # flag --rpcaddr
http_port = 8501 # flag --rpcport
http_modules = ["personal","db","eth","net","web3","txpool","miner"] # flag --rpcapi
[node.p2p]
listenaddr = ":30311" # flag --port
bootnodes = ["enode://a890c5762c406fe046fb93fd307577a8454d571b6bf789f7dbfbf3c559be751f5fa400bc10639691245a9b22be1cfce0bbf82b322a24d06c6dcf29bf7eeb930c@127.0.0.1:30310"]
# flag --bootnodes
[ethstats]
[dashboard]
[account]
unlocks = ["0x12f90a417f41bedd4bbcc99d52971803fb4c3f8b"] # list account slipt in flag --unlock
passwords = ["PWD_DEVNET"] # list password in environment variable (split by ',') : ex : export PWD_DEVNET=123456,123456789

View file

@ -380,12 +380,12 @@ const (
// Config are the configuration parameters of the ethash. // Config are the configuration parameters of the ethash.
type Config struct { type Config struct {
CacheDir string CacheDir string `toml:"cachedir"`
CachesInMem int CachesInMem int `toml:"cachesinmem"`
CachesOnDisk int CachesOnDisk int `toml:"cachesinmem"`
DatasetDir string DatasetDir string `toml:"cachesinmem"`
DatasetsInMem int DatasetsInMem int `toml:"cachesinmem"`
DatasetsOnDisk int DatasetsOnDisk int `toml:"cachesinmem"`
PowMode Mode PowMode Mode
} }

View file

@ -29,13 +29,13 @@ var DefaultConfig = Config{
type Config struct { type Config struct {
// Host is the host interface on which to start the dashboard server. If this // Host is the host interface on which to start the dashboard server. If this
// field is empty, no dashboard will be started. // field is empty, no dashboard will be started.
Host string `toml:",omitempty"` Host string `toml:"host,default=localhost"`
// Port is the TCP port number on which to start the dashboard server. The // Port is the TCP port number on which to start the dashboard server. The
// default zero value is/ valid and will pick a port number randomly (useful // default zero value is/ valid and will pick a port number randomly (useful
// for ephemeral nodes). // for ephemeral nodes).
Port int `toml:",omitempty"` Port int `toml:"port,default=8080"`
// Refresh is the refresh rate of the data updates, the chartEntry will be collected this often. // Refresh is the refresh rate of the data updates, the chartEntry will be collected this often.
Refresh time.Duration `toml:",omitempty"` Refresh time.Duration
} }

View file

@ -79,8 +79,8 @@ type Config struct {
Genesis *core.Genesis `toml:",omitempty"` Genesis *core.Genesis `toml:",omitempty"`
// Protocol options // Protocol options
NetworkId uint64 // Network ID to use for selecting peers to connect to NetworkId uint64 `toml:"NetworkId,default=1"` // Network ID to use for selecting peers to connect to ,default=1
SyncMode downloader.SyncMode SyncMode downloader.SyncMode `toml:"SyncMode,default=FastSync"`
NoPruning bool NoPruning bool
// Light client options // Light client options
@ -98,7 +98,7 @@ type Config struct {
Etherbase common.Address `toml:",omitempty"` Etherbase common.Address `toml:",omitempty"`
MinerThreads int `toml:",omitempty"` MinerThreads int `toml:",omitempty"`
ExtraData []byte `toml:",omitempty"` ExtraData []byte `toml:",omitempty"`
GasPrice *big.Int GasPrice *big.Int `toml:"GasPrice"`
// Ethash options // Ethash options
Ethash ethash.Config Ethash ethash.Config

View file

@ -53,7 +53,7 @@ type Config struct {
Name string `toml:"-"` Name string `toml:"-"`
// UserIdent, if set, is used as an additional component in the devp2p node identifier. // UserIdent, if set, is used as an additional component in the devp2p node identifier.
UserIdent string `toml:",omitempty"` UserIdent string `toml:"identity"`
// Version should be set to the version number of the program. It is used // Version should be set to the version number of the program. It is used
// in the devp2p node identifier. // in the devp2p node identifier.
@ -64,10 +64,10 @@ type Config struct {
// registered services, instead those can use utility methods to create/access // registered services, instead those can use utility methods to create/access
// databases or flat files. This enables ephemeral nodes which can fully reside // databases or flat files. This enables ephemeral nodes which can fully reside
// in memory. // in memory.
DataDir string DataDir string `toml:"datadir"`
// Configuration of peer-to-peer networking. // Configuration of peer-to-peer networking.
P2P p2p.Config P2P p2p.Config `toml:"p2p"`
// KeyStoreDir is the file system folder that contains private keys. The directory can // KeyStoreDir is the file system folder that contains private keys. The directory can
// be specified as a relative path, in which case it is resolved relative to the // be specified as a relative path, in which case it is resolved relative to the
@ -76,11 +76,11 @@ type Config struct {
// If KeyStoreDir is empty, the default location is the "keystore" subdirectory of // If KeyStoreDir is empty, the default location is the "keystore" subdirectory of
// DataDir. If DataDir is unspecified and KeyStoreDir is empty, an ephemeral directory // DataDir. If DataDir is unspecified and KeyStoreDir is empty, an ephemeral directory
// is created by New and destroyed when the node is stopped. // is created by New and destroyed when the node is stopped.
KeyStoreDir string `toml:",omitempty"` KeyStoreDir string `toml:"keystore"`
// UseLightweightKDF lowers the memory and CPU requirements of the key store // UseLightweightKDF lowers the memory and CPU requirements of the key store
// scrypt KDF at the expense of security. // scrypt KDF at the expense of security.
UseLightweightKDF bool `toml:",omitempty"` UseLightweightKDF bool `toml:"lightkdf"`
// NoUSB disables hardware wallet monitoring and connectivity. // NoUSB disables hardware wallet monitoring and connectivity.
NoUSB bool `toml:",omitempty"` NoUSB bool `toml:",omitempty"`
@ -93,12 +93,12 @@ type Config struct {
// HTTPHost is the host interface on which to start the HTTP RPC server. If this // HTTPHost is the host interface on which to start the HTTP RPC server. If this
// field is empty, no HTTP API endpoint will be started. // field is empty, no HTTP API endpoint will be started.
HTTPHost string `toml:",omitempty"` HTTPHost string `toml:"http_host"`
// HTTPPort is the TCP port number on which to start the HTTP RPC server. The // HTTPPort is the TCP port number on which to start the HTTP RPC server. The
// default zero value is/ valid and will pick a port number randomly (useful // default zero value is/ valid and will pick a port number randomly (useful
// for ephemeral nodes). // for ephemeral nodes).
HTTPPort int `toml:",omitempty"` HTTPPort int `toml:"http_port"`
// HTTPCors is the Cross-Origin Resource Sharing header to send to requesting // HTTPCors is the Cross-Origin Resource Sharing header to send to requesting
// clients. Please be aware that CORS is a browser enforced security, it's fully // clients. Please be aware that CORS is a browser enforced security, it's fully
@ -117,7 +117,7 @@ type Config struct {
// HTTPModules is a list of API modules to expose via the HTTP RPC interface. // HTTPModules is a list of API modules to expose via the HTTP RPC interface.
// If the module list is empty, all RPC API endpoints designated public will be // If the module list is empty, all RPC API endpoints designated public will be
// exposed. // exposed.
HTTPModules []string `toml:",omitempty"` HTTPModules []string `toml:"http_modules"`
// WSHost is the host interface on which to start the websocket RPC server. If // WSHost is the host interface on which to start the websocket RPC server. If
// this field is empty, no websocket API endpoint will be started. // this field is empty, no websocket API endpoint will be started.

View file

@ -56,6 +56,7 @@ type Node struct {
addedAt time.Time addedAt time.Time
} }
// NewNode creates a new node. It is mostly meant to be used for // NewNode creates a new node. It is mostly meant to be used for
// testing purposes. // testing purposes.
func NewNode(id NodeID, ip net.IP, udpPort, tcpPort uint16) *Node { func NewNode(id NodeID, ip net.IP, udpPort, tcpPort uint16) *Node {

View file

@ -86,12 +86,12 @@ type Config struct {
// BootstrapNodes are used to establish connectivity // BootstrapNodes are used to establish connectivity
// with the rest of the network. // with the rest of the network.
BootstrapNodes []*discover.Node BootstrapNodes []*discover.Node `toml:"bootnodes"`
// BootstrapNodesV5 are used to establish connectivity // BootstrapNodesV5 are used to establish connectivity
// with the rest of the network using the V5 discovery // with the rest of the network using the V5 discovery
// protocol. // protocol.
BootstrapNodesV5 []*discv5.Node `toml:",omitempty"` BootstrapNodesV5 []*discv5.Node `toml:"bootnodes_v5"`
// Static nodes are used as pre-configured connections which are always // Static nodes are used as pre-configured connections which are always
// maintained and re-connected on disconnects. // maintained and re-connected on disconnects.
@ -121,7 +121,7 @@ type Config struct {
// If the port is zero, the operating system will pick a port. The // If the port is zero, the operating system will pick a port. The
// ListenAddr field will be updated with the actual address when // ListenAddr field will be updated with the actual address when
// the server is started. // the server is started.
ListenAddr string ListenAddr string `toml:"listenaddr,default=30303"`
// If set to a non-nil value, the given NAT port mapper // If set to a non-nil value, the given NAT port mapper
// is used to make the listening port available to the // is used to make the listening port available to the