mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
Add the rest of the flags
This commit is contained in:
parent
e98379679f
commit
a421570dc0
4 changed files with 914 additions and 109 deletions
|
|
@ -3,6 +3,7 @@ package flagset
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -46,10 +47,6 @@ func (f *Flagset) Args() []string {
|
|||
return f.set.Args()
|
||||
}
|
||||
|
||||
func (f *Flagset) BoolVar() {
|
||||
|
||||
}
|
||||
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
|
|
@ -95,6 +92,56 @@ func (f *Flagset) IntFlag(i *IntFlag) {
|
|||
f.set.IntVar(i.Value, i.Name, i.Default, i.Usage)
|
||||
}
|
||||
|
||||
type Uint64Flag struct {
|
||||
Name string
|
||||
Usage string
|
||||
Default uint64
|
||||
Value *uint64
|
||||
}
|
||||
|
||||
func (f *Flagset) Uint64Flag(i *Uint64Flag) {
|
||||
f.addFlag(&FlagVar{
|
||||
Name: i.Name,
|
||||
Usage: i.Usage,
|
||||
})
|
||||
f.set.Uint64Var(i.Value, i.Name, i.Default, i.Usage)
|
||||
}
|
||||
|
||||
type BigIntFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
Default *big.Int
|
||||
Value *big.Int
|
||||
}
|
||||
|
||||
func (b *BigIntFlag) String() string {
|
||||
return b.Value.String()
|
||||
}
|
||||
|
||||
func (b *BigIntFlag) Set(value string) error {
|
||||
num := new(big.Int)
|
||||
|
||||
var ok bool
|
||||
if strings.HasPrefix(value, "0x") {
|
||||
num, ok = num.SetString(value[2:], 16)
|
||||
} else {
|
||||
num, ok = num.SetString(value, 10)
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to set big int")
|
||||
}
|
||||
b.Value = num
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Flagset) BigIntFlag(b *BigIntFlag) {
|
||||
f.addFlag(&FlagVar{
|
||||
Name: b.Name,
|
||||
Usage: b.Usage,
|
||||
})
|
||||
f.set.Var(b, b.Name, b.Usage)
|
||||
}
|
||||
|
||||
type SliceStringFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
|
|
@ -102,7 +149,7 @@ type SliceStringFlag struct {
|
|||
}
|
||||
|
||||
func (i *SliceStringFlag) String() string {
|
||||
return ""
|
||||
return strings.Join(i.Value, ",")
|
||||
}
|
||||
|
||||
func (i *SliceStringFlag) Set(value string) error {
|
||||
|
|
@ -124,9 +171,75 @@ type DurationFlag struct {
|
|||
Value *time.Duration
|
||||
}
|
||||
|
||||
func (d *DurationFlag) String() string {
|
||||
return d.Value.String()
|
||||
}
|
||||
|
||||
func (d *DurationFlag) Set(value string) error {
|
||||
v, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Value = &v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Flagset) DurationFlag(d *DurationFlag) {
|
||||
f.addFlag(&FlagVar{
|
||||
Name: d.Name,
|
||||
Usage: d.Usage,
|
||||
})
|
||||
f.set.Var(d, d.Name, d.Usage)
|
||||
}
|
||||
|
||||
type MapStringFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
Value *map[string]string
|
||||
}
|
||||
|
||||
func (m *MapStringFlag) String() string {
|
||||
ls := []string{}
|
||||
for k, v := range *m.Value {
|
||||
ls = append(ls, k+"="+v)
|
||||
}
|
||||
return strings.Join(ls, ",")
|
||||
}
|
||||
|
||||
func (m *MapStringFlag) Set(value string) error {
|
||||
if m.Value == nil {
|
||||
m.Value = &map[string]string{}
|
||||
}
|
||||
for _, t := range strings.Split(value, ",") {
|
||||
if t != "" {
|
||||
kv := strings.Split(t, "=")
|
||||
|
||||
if len(kv) == 2 {
|
||||
(*m.Value)[kv[0]] = kv[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Flagset) MapStringFlag(m *MapStringFlag) {
|
||||
f.addFlag(&FlagVar{
|
||||
Name: m.Name,
|
||||
Usage: m.Usage,
|
||||
})
|
||||
f.set.Var(m, m.Name, m.Usage)
|
||||
}
|
||||
|
||||
type Float64Flag struct {
|
||||
Name string
|
||||
Usage string
|
||||
Value *float64
|
||||
}
|
||||
|
||||
func (f *Flagset) Float64Flag(i *Float64Flag) {
|
||||
f.addFlag(&FlagVar{
|
||||
Name: i.Name,
|
||||
Usage: i.Usage,
|
||||
})
|
||||
f.set.Float64Var(i.Value, i.Name, *i.Value, "")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,12 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||
"github.com/ethereum/go-ethereum/ethstats"
|
||||
"github.com/ethereum/go-ethereum/graphql"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/metrics/influxdb"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
|
|
@ -57,89 +60,136 @@ func (c *Command) Run(args []string) int {
|
|||
// read config file
|
||||
config := DefaultConfig()
|
||||
if c.configFile != "" {
|
||||
c, err := readConfigFile(c.configFile)
|
||||
cfg, err := readConfigFile(c.configFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
if err := config.Merge(cfg); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
config.Merge(c)
|
||||
}
|
||||
config.Merge(c.cliConfig)
|
||||
if err := config.Merge(c.cliConfig); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
// start the logger
|
||||
setupLogger(*config.LogLevel)
|
||||
|
||||
// load the chain genesis
|
||||
if err := config.loadChain(); err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
// create the node/stack
|
||||
nodeCfg, err := config.buildNode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
stack, err := node.New(nodeCfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
c.node = stack
|
||||
|
||||
// TODO: MakeChain?
|
||||
// TODO: Metrics
|
||||
// TODO: apis
|
||||
// TODO: Graphql
|
||||
|
||||
// register the ethereum backend
|
||||
ethCfg, err := config.buildEth()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
backend, err := eth.New(stack, ethCfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
// This is the tracers api, not sure if this should be here, i do not think so.
|
||||
// c.node.RegisterAPIs(tracers.APIs(backend.APIBackend))
|
||||
// debug tracing is enabled by default
|
||||
stack.RegisterAPIs(tracers.APIs(backend.APIBackend))
|
||||
|
||||
// graphql is started from another place
|
||||
if *config.JsonRPC.Graphql.Enabled {
|
||||
if err := graphql.New(stack, backend.APIBackend, config.JsonRPC.Cors, config.JsonRPC.Modules); err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Failed to register the GraphQL service: %v", err))
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// register ethash service
|
||||
if config.EthStats != nil {
|
||||
if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), *config.EthStats); err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// setup account manager (only keystore)
|
||||
{
|
||||
keydir := stack.KeyStoreDir()
|
||||
scryptN := keystore.StandardScryptN
|
||||
scryptP := keystore.StandardScryptP
|
||||
|
||||
stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP))
|
||||
n, p := keystore.StandardScryptN, keystore.StandardScryptP
|
||||
if *config.UseLightweightKDF {
|
||||
n, p = keystore.LightScryptN, keystore.LightScryptP
|
||||
}
|
||||
stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p))
|
||||
}
|
||||
|
||||
// sealing (if enabled)
|
||||
if *config.Sealer.Enabled {
|
||||
if err := backend.StartMining(1); err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
c.setupMetrics()
|
||||
if err := c.setupMetrics(config.Metrics); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
// start the node
|
||||
if err := c.node.Start(); err != nil {
|
||||
panic(err)
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
return c.handleSignals()
|
||||
}
|
||||
|
||||
func (c *Command) setupMetrics() error {
|
||||
func (c *Command) setupMetrics(config *MetricsConfig) error {
|
||||
metrics.Enabled = *config.Enabled
|
||||
metrics.EnabledExpensive = *config.Expensive
|
||||
|
||||
if !metrics.Enabled {
|
||||
// metrics are globally disabled
|
||||
// metrics are disabled, do not set up any sink
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("Enabling metrics collection")
|
||||
|
||||
// influxdb
|
||||
if v1Enabled, v2Enabled := (*config.InfluxDB.V1Enabled), (*config.InfluxDB.V2Enabled); v1Enabled || v2Enabled {
|
||||
if v1Enabled && v2Enabled {
|
||||
return fmt.Errorf("both influx v1 and influx v2 cannot be enabled")
|
||||
}
|
||||
|
||||
cfg := config.InfluxDB
|
||||
tags := *cfg.Tags
|
||||
endpoint := *cfg.Endpoint
|
||||
|
||||
if v1Enabled {
|
||||
log.Info("Enabling metrics export to InfluxDB (v1)")
|
||||
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, *cfg.Database, *cfg.Username, *cfg.Password, "geth.", tags)
|
||||
}
|
||||
if v2Enabled {
|
||||
log.Info("Enabling metrics export to InfluxDB (v2)")
|
||||
go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, *cfg.Token, *cfg.Bucket, *cfg.Organization, "geth.", tags)
|
||||
}
|
||||
}
|
||||
|
||||
// Start system runtime metrics collection
|
||||
go metrics.CollectProcessMetrics(3 * time.Second)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,29 +4,44 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
godebug "runtime/debug"
|
||||
|
||||
"github.com/ethereum/go-ethereum/command/server/chains"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/fdlimit"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/imdario/mergo"
|
||||
gopsutil "github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
func mapStrPtr(m map[string]string) *map[string]string {
|
||||
return &m
|
||||
}
|
||||
|
||||
func stringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
func float64Ptr(f float64) *float64 {
|
||||
return &f
|
||||
}
|
||||
|
||||
func uint64Ptr(i uint64) *uint64 {
|
||||
return &i
|
||||
}
|
||||
|
|
@ -42,28 +57,39 @@ func durPtr(d time.Duration) *time.Duration {
|
|||
type Config struct {
|
||||
chain *chains.Chain
|
||||
|
||||
Chain *string
|
||||
Debug *bool
|
||||
LogLevel *string
|
||||
DataDir *string
|
||||
P2P *P2PConfig
|
||||
SyncMode *string
|
||||
EthStats *string
|
||||
TxPool *TxPoolConfig
|
||||
Sealer *SealerConfig
|
||||
JsonRPC *JsonRPCConfig
|
||||
Chain *string
|
||||
Debug *bool
|
||||
Whitelist *map[string]string
|
||||
UseLightweightKDF *bool
|
||||
LogLevel *string
|
||||
DataDir *string
|
||||
P2P *P2PConfig
|
||||
SyncMode *string
|
||||
GcMode *string
|
||||
Snapshot *bool
|
||||
EthStats *string
|
||||
Heimdall *HeimdallConfig
|
||||
TxPool *TxPoolConfig
|
||||
Sealer *SealerConfig
|
||||
JsonRPC *JsonRPCConfig
|
||||
Gpo *GpoConfig
|
||||
Ethstats *string
|
||||
Metrics *MetricsConfig
|
||||
Cache *CacheConfig
|
||||
}
|
||||
|
||||
type P2PConfig struct {
|
||||
MaxPeers *uint64
|
||||
Bind *string
|
||||
Port *uint64
|
||||
NoDiscover *bool
|
||||
V5Disc *bool
|
||||
Discovery *P2PDiscovery
|
||||
MaxPeers *uint64
|
||||
MaxPendPeers *uint64
|
||||
Bind *string
|
||||
Port *uint64
|
||||
NoDiscover *bool
|
||||
NAT *string
|
||||
Discovery *P2PDiscovery
|
||||
}
|
||||
|
||||
type P2PDiscovery struct {
|
||||
V5Enabled *bool
|
||||
Bootnodes []string
|
||||
BootnodesV4 []string
|
||||
BootnodesV5 []string
|
||||
|
|
@ -72,6 +98,11 @@ type P2PDiscovery struct {
|
|||
DNS []string
|
||||
}
|
||||
|
||||
type HeimdallConfig struct {
|
||||
URL *string
|
||||
Without *bool
|
||||
}
|
||||
|
||||
type TxPoolConfig struct {
|
||||
Locals []string
|
||||
NoLocals *bool
|
||||
|
|
@ -95,21 +126,84 @@ type SealerConfig struct {
|
|||
}
|
||||
|
||||
type JsonRPCConfig struct {
|
||||
IPCDisable *bool
|
||||
IPCPath *string
|
||||
|
||||
Modules []string
|
||||
VHost []string
|
||||
Cors []string
|
||||
Bind *string
|
||||
|
||||
GasCap *uint64
|
||||
TxFeeCap *float64
|
||||
|
||||
Http *APIConfig
|
||||
Ws *APIConfig
|
||||
Graphql *APIConfig
|
||||
}
|
||||
|
||||
type APIConfig struct {
|
||||
Enabled *bool
|
||||
Port *uint64
|
||||
Prefix *string
|
||||
}
|
||||
|
||||
type GpoConfig struct {
|
||||
Blocks *uint64
|
||||
Percentile *uint64
|
||||
MaxPrice *big.Int
|
||||
IgnorePrice *big.Int
|
||||
}
|
||||
|
||||
type MetricsConfig struct {
|
||||
Enabled *bool
|
||||
Expensive *bool
|
||||
InfluxDB *InfluxDBConfig
|
||||
}
|
||||
|
||||
type InfluxDBConfig struct {
|
||||
V1Enabled *bool
|
||||
Endpoint *string
|
||||
Database *string
|
||||
Username *string
|
||||
Password *string
|
||||
Tags *map[string]string
|
||||
V2Enabled *bool
|
||||
Token *string
|
||||
Bucket *string
|
||||
Organization *string
|
||||
}
|
||||
|
||||
type CacheConfig struct {
|
||||
Cache *uint64
|
||||
PercGc *uint64
|
||||
PercSnapshot *uint64
|
||||
PercDatabase *uint64
|
||||
PercTrie *uint64
|
||||
Journal *string
|
||||
Rejournal *time.Duration
|
||||
NoPrefetch *bool
|
||||
Preimages *bool
|
||||
TxLookupLimit *uint64
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Chain: stringPtr("mainnet"),
|
||||
Debug: boolPtr(false),
|
||||
LogLevel: stringPtr("INFO"),
|
||||
DataDir: stringPtr(""),
|
||||
Chain: stringPtr("mainnet"),
|
||||
Debug: boolPtr(false),
|
||||
UseLightweightKDF: boolPtr(false),
|
||||
Whitelist: mapStrPtr(map[string]string{}),
|
||||
LogLevel: stringPtr("INFO"),
|
||||
DataDir: stringPtr(node.DefaultDataDir()),
|
||||
P2P: &P2PConfig{
|
||||
MaxPeers: uint64Ptr(30),
|
||||
Bind: stringPtr("0.0.0.0"),
|
||||
Port: uint64Ptr(30303),
|
||||
NoDiscover: boolPtr(false),
|
||||
V5Disc: boolPtr(false),
|
||||
MaxPeers: uint64Ptr(30),
|
||||
MaxPendPeers: uint64Ptr(50),
|
||||
Bind: stringPtr("0.0.0.0"),
|
||||
Port: uint64Ptr(30303),
|
||||
NoDiscover: boolPtr(false),
|
||||
NAT: stringPtr("any"),
|
||||
Discovery: &P2PDiscovery{
|
||||
V5Enabled: boolPtr(false),
|
||||
Bootnodes: []string{},
|
||||
BootnodesV4: []string{},
|
||||
BootnodesV5: []string{},
|
||||
|
|
@ -118,7 +212,13 @@ func DefaultConfig() *Config {
|
|||
DNS: []string{},
|
||||
},
|
||||
},
|
||||
Heimdall: &HeimdallConfig{
|
||||
URL: stringPtr("http://localhost:1317"),
|
||||
Without: boolPtr(false),
|
||||
},
|
||||
SyncMode: stringPtr("fast"),
|
||||
GcMode: stringPtr("full"),
|
||||
Snapshot: boolPtr(true),
|
||||
EthStats: stringPtr(""),
|
||||
TxPool: &TxPoolConfig{
|
||||
Locals: []string{},
|
||||
|
|
@ -134,9 +234,66 @@ func DefaultConfig() *Config {
|
|||
LifeTime: durPtr(3 * time.Hour),
|
||||
},
|
||||
Sealer: &SealerConfig{
|
||||
Enabled: boolPtr(false),
|
||||
GasCeil: uint64Ptr(8000000),
|
||||
GasPrice: big.NewInt(params.GWei),
|
||||
Enabled: boolPtr(false),
|
||||
GasCeil: uint64Ptr(8000000),
|
||||
GasPrice: big.NewInt(params.GWei),
|
||||
ExtraData: stringPtr(""),
|
||||
},
|
||||
Gpo: &GpoConfig{
|
||||
Blocks: uint64Ptr(20),
|
||||
Percentile: uint64Ptr(60),
|
||||
MaxPrice: gasprice.DefaultMaxPrice,
|
||||
IgnorePrice: gasprice.DefaultIgnorePrice,
|
||||
},
|
||||
JsonRPC: &JsonRPCConfig{
|
||||
IPCDisable: boolPtr(false),
|
||||
Modules: []string{"web3", "net"},
|
||||
Cors: []string{"*"},
|
||||
VHost: []string{"*"},
|
||||
GasCap: uint64Ptr(ethconfig.Defaults.RPCGasCap),
|
||||
TxFeeCap: float64Ptr(ethconfig.Defaults.RPCTxFeeCap),
|
||||
Http: &APIConfig{
|
||||
Enabled: boolPtr(false),
|
||||
Port: uint64Ptr(8545),
|
||||
Prefix: stringPtr(""),
|
||||
},
|
||||
Ws: &APIConfig{
|
||||
Enabled: boolPtr(false),
|
||||
Port: uint64Ptr(8546),
|
||||
Prefix: stringPtr(""),
|
||||
},
|
||||
Graphql: &APIConfig{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
},
|
||||
Ethstats: stringPtr(""),
|
||||
Metrics: &MetricsConfig{
|
||||
Enabled: boolPtr(false),
|
||||
Expensive: boolPtr(false),
|
||||
InfluxDB: &InfluxDBConfig{
|
||||
V1Enabled: boolPtr(false),
|
||||
Endpoint: stringPtr(""),
|
||||
Database: stringPtr(""),
|
||||
Username: stringPtr(""),
|
||||
Password: stringPtr(""),
|
||||
Tags: mapStrPtr(map[string]string{}),
|
||||
V2Enabled: boolPtr(false),
|
||||
Token: stringPtr(""),
|
||||
Bucket: stringPtr(""),
|
||||
Organization: stringPtr(""),
|
||||
},
|
||||
},
|
||||
Cache: &CacheConfig{
|
||||
Cache: uint64Ptr(1024),
|
||||
PercDatabase: uint64Ptr(50),
|
||||
PercTrie: uint64Ptr(15),
|
||||
PercGc: uint64Ptr(25),
|
||||
PercSnapshot: uint64Ptr(10),
|
||||
Journal: stringPtr("triecache"),
|
||||
Rejournal: durPtr(60 * time.Minute),
|
||||
NoPrefetch: boolPtr(false),
|
||||
Preimages: boolPtr(false),
|
||||
TxLookupLimit: uint64Ptr(2350000),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -163,13 +320,22 @@ func (c *Config) loadChain() error {
|
|||
}
|
||||
c.chain = chain
|
||||
|
||||
// preload some default values that are on the chain file
|
||||
// preload some default values that depend on the chain file
|
||||
|
||||
// the genesis files defines default bootnodes
|
||||
if c.P2P.Discovery.Bootnodes == nil {
|
||||
c.P2P.Discovery.Bootnodes = c.chain.Bootnodes
|
||||
}
|
||||
if c.P2P.Discovery.DNS == nil {
|
||||
c.P2P.Discovery.DNS = c.chain.DNS
|
||||
}
|
||||
|
||||
// depending on the chain we have different cache values
|
||||
if *c.Chain != "mainnet" {
|
||||
c.Cache.Cache = uint64Ptr(4096)
|
||||
} else {
|
||||
c.Cache.Cache = uint64Ptr(1024)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -184,25 +350,30 @@ func (c *Config) buildEth() (*ethconfig.Config, error) {
|
|||
|
||||
// txpool options
|
||||
{
|
||||
cfg := n.TxPool
|
||||
cfg.NoLocals = *c.TxPool.NoLocals
|
||||
cfg.Journal = *c.TxPool.Journal
|
||||
cfg.Rejournal = *c.TxPool.Rejournal
|
||||
cfg.PriceLimit = *c.TxPool.PriceLimit
|
||||
cfg.PriceBump = *c.TxPool.PriceBump
|
||||
cfg.AccountSlots = *c.TxPool.AccountSlots
|
||||
cfg.GlobalSlots = *c.TxPool.GlobalSlots
|
||||
cfg.AccountQueue = *c.TxPool.AccountQueue
|
||||
cfg.GlobalQueue = *c.TxPool.GlobalQueue
|
||||
cfg.Lifetime = *c.TxPool.LifeTime
|
||||
n.TxPool.NoLocals = *c.TxPool.NoLocals
|
||||
n.TxPool.Journal = *c.TxPool.Journal
|
||||
n.TxPool.Rejournal = *c.TxPool.Rejournal
|
||||
n.TxPool.PriceLimit = *c.TxPool.PriceLimit
|
||||
n.TxPool.PriceBump = *c.TxPool.PriceBump
|
||||
n.TxPool.AccountSlots = *c.TxPool.AccountSlots
|
||||
n.TxPool.GlobalSlots = *c.TxPool.GlobalSlots
|
||||
n.TxPool.AccountQueue = *c.TxPool.AccountQueue
|
||||
n.TxPool.GlobalQueue = *c.TxPool.GlobalQueue
|
||||
n.TxPool.Lifetime = *c.TxPool.LifeTime
|
||||
}
|
||||
|
||||
// miner options
|
||||
{
|
||||
cfg := n.Miner
|
||||
cfg.Etherbase = common.HexToAddress(*c.Sealer.Etherbase)
|
||||
cfg.GasPrice = c.Sealer.GasPrice
|
||||
cfg.GasCeil = *c.Sealer.GasCeil
|
||||
n.Miner.GasPrice = c.Sealer.GasPrice
|
||||
n.Miner.GasCeil = *c.Sealer.GasCeil
|
||||
n.Miner.ExtraData = []byte(*c.Sealer.ExtraData)
|
||||
|
||||
if etherbase := c.Sealer.Etherbase; etherbase != nil {
|
||||
if !common.IsHexAddress(*etherbase) {
|
||||
return nil, fmt.Errorf("etherbase is not an address: %s", *etherbase)
|
||||
}
|
||||
n.Miner.Etherbase = common.HexToAddress(*etherbase)
|
||||
}
|
||||
}
|
||||
|
||||
// discovery (this params should be in node.Config)
|
||||
|
|
@ -211,16 +382,106 @@ func (c *Config) buildEth() (*ethconfig.Config, error) {
|
|||
n.SnapDiscoveryURLs = c.P2P.Discovery.DNS
|
||||
}
|
||||
|
||||
var syncMode downloader.SyncMode
|
||||
// whitelist
|
||||
{
|
||||
n.Whitelist = map[uint64]common.Hash{}
|
||||
for k, v := range *c.Whitelist {
|
||||
number, err := strconv.ParseUint(k, 0, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid whitelist block number %s: %v", k, err)
|
||||
}
|
||||
var hash common.Hash
|
||||
if err = hash.UnmarshalText([]byte(v)); err != nil {
|
||||
return nil, fmt.Errorf("invalid whitelist hash %s: %v", v, err)
|
||||
}
|
||||
n.Whitelist[number] = hash
|
||||
}
|
||||
}
|
||||
|
||||
// cache
|
||||
{
|
||||
cache := *c.Cache.Cache
|
||||
calcPerc := func(val *uint64) int {
|
||||
return int(cache * (*val) / 100)
|
||||
}
|
||||
|
||||
// Cap the cache allowance
|
||||
mem, err := gopsutil.VirtualMemory()
|
||||
if err == nil {
|
||||
if 32<<(^uintptr(0)>>63) == 32 && mem.Total > 2*1024*1024*1024 {
|
||||
log.Warn("Lowering memory allowance on 32bit arch", "available", mem.Total/1024/1024, "addressable", 2*1024)
|
||||
mem.Total = 2 * 1024 * 1024 * 1024
|
||||
}
|
||||
allowance := uint64(mem.Total / 1024 / 1024 / 3)
|
||||
if cache > allowance {
|
||||
log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
|
||||
cache = allowance
|
||||
}
|
||||
}
|
||||
// Tune the garbage collector
|
||||
gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024)))
|
||||
|
||||
log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
|
||||
godebug.SetGCPercent(int(gogc))
|
||||
|
||||
n.TrieCleanCacheJournal = *c.Cache.Journal
|
||||
n.TrieCleanCacheRejournal = *c.Cache.Rejournal
|
||||
n.DatabaseCache = calcPerc(c.Cache.PercDatabase)
|
||||
n.SnapshotCache = calcPerc(c.Cache.PercSnapshot)
|
||||
n.TrieCleanCache = calcPerc(c.Cache.PercTrie)
|
||||
n.TrieDirtyCache = calcPerc(c.Cache.PercGc)
|
||||
n.NoPrefetch = *c.Cache.NoPrefetch
|
||||
n.Preimages = *c.Cache.Preimages
|
||||
n.TxLookupLimit = *c.Cache.TxLookupLimit
|
||||
}
|
||||
|
||||
n.RPCGasCap = *c.JsonRPC.GasCap
|
||||
if n.RPCGasCap != 0 {
|
||||
log.Info("Set global gas cap", "cap", n.RPCGasCap)
|
||||
} else {
|
||||
log.Info("Global gas cap disabled")
|
||||
}
|
||||
n.RPCTxFeeCap = *c.JsonRPC.TxFeeCap
|
||||
|
||||
// sync mode. It can either be "fast", "full" or "snap". We disable
|
||||
// for now the "light" mode.
|
||||
switch *c.SyncMode {
|
||||
case "fast":
|
||||
syncMode = downloader.FastSync
|
||||
n.SyncMode = downloader.FastSync
|
||||
case "full":
|
||||
n.SyncMode = downloader.FullSync
|
||||
case "snap":
|
||||
n.SyncMode = downloader.SnapSync
|
||||
default:
|
||||
return nil, fmt.Errorf("sync mode '%s' not found", syncMode)
|
||||
return nil, fmt.Errorf("sync mode '%s' not found", *c.SyncMode)
|
||||
}
|
||||
n.SyncMode = syncMode
|
||||
n.DatabaseHandles = dbHandles
|
||||
|
||||
// archive mode. It can either be "archive" or "full".
|
||||
switch *c.GcMode {
|
||||
case "full":
|
||||
n.NoPruning = false
|
||||
case "archive":
|
||||
n.NoPruning = true
|
||||
if !n.Preimages {
|
||||
n.Preimages = true
|
||||
log.Info("Enabling recording of key preimages since archive mode is used")
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("gcmode '%s' not found", *c.GcMode)
|
||||
}
|
||||
|
||||
// snapshot disable check
|
||||
if *c.Snapshot {
|
||||
if n.SyncMode == downloader.SnapSync {
|
||||
log.Info("Snap sync requested, enabling --snapshot")
|
||||
} else {
|
||||
// disable snapshot
|
||||
n.TrieCleanCache += n.SnapshotCache
|
||||
n.SnapshotCache = 0
|
||||
}
|
||||
}
|
||||
|
||||
n.DatabaseHandles = dbHandles
|
||||
return &n, nil
|
||||
}
|
||||
|
||||
|
|
@ -231,24 +492,55 @@ var (
|
|||
)
|
||||
|
||||
func (c *Config) buildNode() (*node.Config, error) {
|
||||
cfg := &node.Config{
|
||||
Name: clientIdentifier,
|
||||
DataDir: *c.DataDir,
|
||||
Version: params.VersionWithCommit(gitCommit, gitDate),
|
||||
IPCPath: clientIdentifier + ".ipc",
|
||||
P2P: p2p.Config{
|
||||
MaxPeers: int(*c.P2P.MaxPeers),
|
||||
ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)),
|
||||
},
|
||||
/*
|
||||
HTTPHost: *c.BindAddr,
|
||||
HTTPPort: int(*c.Ports.HTTP),
|
||||
HTTPVirtualHosts: []string{"*"},
|
||||
WSHost: *c.BindAddr,
|
||||
WSPort: int(*c.Ports.Websocket),
|
||||
*/
|
||||
ipcPath := ""
|
||||
if !*c.JsonRPC.IPCDisable {
|
||||
ipcPath = clientIdentifier + ".ipc"
|
||||
if c.JsonRPC.IPCPath != nil {
|
||||
ipcPath = *c.JsonRPC.IPCPath
|
||||
}
|
||||
}
|
||||
|
||||
cfg := &node.Config{
|
||||
Name: clientIdentifier,
|
||||
DataDir: *c.DataDir,
|
||||
UseLightweightKDF: *c.UseLightweightKDF,
|
||||
Version: params.VersionWithCommit(gitCommit, gitDate),
|
||||
IPCPath: ipcPath,
|
||||
P2P: p2p.Config{
|
||||
MaxPeers: int(*c.P2P.MaxPeers),
|
||||
MaxPendingPeers: int(*c.P2P.MaxPendPeers),
|
||||
ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)),
|
||||
DiscoveryV5: *c.P2P.Discovery.V5Enabled,
|
||||
},
|
||||
HTTPModules: c.JsonRPC.Modules,
|
||||
HTTPCors: c.JsonRPC.Cors,
|
||||
HTTPVirtualHosts: c.JsonRPC.VHost,
|
||||
HTTPPathPrefix: *c.JsonRPC.Http.Prefix,
|
||||
WSModules: c.JsonRPC.Modules,
|
||||
WSOrigins: c.JsonRPC.Cors,
|
||||
WSPathPrefix: *c.JsonRPC.Ws.Prefix,
|
||||
GraphQLCors: c.JsonRPC.Cors,
|
||||
GraphQLVirtualHosts: c.JsonRPC.VHost,
|
||||
}
|
||||
|
||||
// enable jsonrpc endpoints
|
||||
{
|
||||
if *c.JsonRPC.Http.Enabled {
|
||||
cfg.HTTPHost = *c.JsonRPC.Bind
|
||||
cfg.HTTPPort = int(*c.JsonRPC.Http.Port)
|
||||
}
|
||||
if *c.JsonRPC.Ws.Enabled {
|
||||
cfg.WSHost = *c.JsonRPC.Bind
|
||||
cfg.WSPort = int(*c.JsonRPC.Ws.Port)
|
||||
}
|
||||
}
|
||||
|
||||
natif, err := nat.Parse(*c.P2P.NAT)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wrong 'nat' flag: %v", err)
|
||||
}
|
||||
cfg.P2P.NAT = natif
|
||||
|
||||
// setup private key for DevP2P if not found
|
||||
devP2PPrivKey, err := readDevP2PKey(*c.DataDir)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,65 +1,415 @@
|
|||
package server
|
||||
|
||||
import "github.com/ethereum/go-ethereum/command/flagset"
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/command/flagset"
|
||||
)
|
||||
|
||||
func (c *Command) Flags() *flagset.Flagset {
|
||||
c.cliConfig = DefaultConfig()
|
||||
|
||||
f := flagset.NewFlagSet("")
|
||||
f := flagset.NewFlagSet("server")
|
||||
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "debug",
|
||||
Value: c.cliConfig.Debug,
|
||||
Usage: "Path of the file to apply",
|
||||
Value: c.cliConfig.Debug,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "chain",
|
||||
Value: c.cliConfig.Chain,
|
||||
Usage: "Name of the chain to sync",
|
||||
Value: c.cliConfig.Chain,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "log-level",
|
||||
Value: c.cliConfig.LogLevel,
|
||||
Usage: "Set log level for the server",
|
||||
Value: c.cliConfig.LogLevel,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "data-dir",
|
||||
Value: c.cliConfig.DataDir,
|
||||
Name: "datadir",
|
||||
Usage: "Path of the data directory to store information",
|
||||
Value: c.cliConfig.DataDir,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "config",
|
||||
Value: &c.configFile,
|
||||
Usage: "File for the config file",
|
||||
Value: &c.configFile,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "syncmode",
|
||||
Usage: `Blockchain sync mode ("fast", "full", "snap" or "light")`,
|
||||
Value: c.cliConfig.SyncMode,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "gcmode",
|
||||
Usage: `Blockchain garbage collection mode ("full", "archive")`,
|
||||
Value: c.cliConfig.GcMode,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "lightkdf",
|
||||
Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength",
|
||||
Value: c.cliConfig.UseLightweightKDF,
|
||||
})
|
||||
f.MapStringFlag(&flagset.MapStringFlag{
|
||||
Name: "whitelist",
|
||||
Usage: "Comma separated block number-to-hash mappings to enforce (<number>=<hash>)",
|
||||
Value: c.cliConfig.Whitelist,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "snapshot",
|
||||
Usage: `Enables snapshot-database mode (default = enable)`,
|
||||
Value: c.cliConfig.Snapshot,
|
||||
})
|
||||
|
||||
// heimdall
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "bor.heimdall",
|
||||
Usage: "URL of Heimdall service",
|
||||
Value: c.cliConfig.Heimdall.URL,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "bor.withoutheimdall",
|
||||
Usage: "Run without Heimdall service (for testing purpose)",
|
||||
Value: c.cliConfig.Heimdall.Without,
|
||||
})
|
||||
|
||||
// txpool options
|
||||
f.SliceStringFlag(&flagset.SliceStringFlag{
|
||||
Name: "txpool.locals",
|
||||
Value: c.cliConfig.TxPool.Locals,
|
||||
Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)",
|
||||
Value: c.cliConfig.TxPool.Locals,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "txpool.nolocals",
|
||||
Value: c.cliConfig.TxPool.NoLocals,
|
||||
Usage: "Disables price exemptions for locally submitted transactions",
|
||||
Value: c.cliConfig.TxPool.NoLocals,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "txpool.journal",
|
||||
Usage: "Disk journal for local transaction to survive node restarts",
|
||||
Value: c.cliConfig.TxPool.Journal,
|
||||
})
|
||||
f.DurationFlag(&flagset.DurationFlag{
|
||||
Name: "txpool.rejournal",
|
||||
Usage: "Time interval to regenerate the local transaction journal",
|
||||
Value: c.cliConfig.TxPool.Rejournal,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txpool.pricelimit",
|
||||
Usage: "Minimum gas price limit to enforce for acceptance into the pool",
|
||||
Value: c.cliConfig.TxPool.PriceLimit,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txpool.pricebump",
|
||||
Usage: "Price bump percentage to replace an already existing transaction",
|
||||
Value: c.cliConfig.TxPool.PriceBump,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txpool.accountslots",
|
||||
Usage: "Minimum number of executable transaction slots guaranteed per account",
|
||||
Value: c.cliConfig.TxPool.AccountSlots,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txpool.globalslots",
|
||||
Usage: "Maximum number of executable transaction slots for all accounts",
|
||||
Value: c.cliConfig.TxPool.GlobalSlots,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txpool.accountqueue",
|
||||
Usage: "Maximum number of non-executable transaction slots permitted per account",
|
||||
Value: c.cliConfig.TxPool.AccountQueue,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txpool.globalqueue",
|
||||
Usage: "Maximum number of non-executable transaction slots for all accounts",
|
||||
Value: c.cliConfig.TxPool.GlobalQueue,
|
||||
})
|
||||
f.DurationFlag(&flagset.DurationFlag{
|
||||
Name: "txpool.lifetime",
|
||||
Usage: "Maximum amount of time non-executable transaction are queued",
|
||||
Value: c.cliConfig.TxPool.LifeTime,
|
||||
})
|
||||
|
||||
// sealer options
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "mine",
|
||||
Usage: "Enable mining",
|
||||
Value: c.cliConfig.Sealer.Enabled,
|
||||
Usage: "",
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "miner.etherbase",
|
||||
Usage: "Public address for block mining rewards (default = first account)",
|
||||
Value: c.cliConfig.Sealer.Etherbase,
|
||||
Usage: "",
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "miner.extradata",
|
||||
Usage: "Block extra data set by the miner (default = client version)",
|
||||
Value: c.cliConfig.Sealer.ExtraData,
|
||||
Usage: "",
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "miner.gaslimit",
|
||||
Usage: "Target gas ceiling for mined blocks",
|
||||
Value: c.cliConfig.Sealer.GasCeil,
|
||||
})
|
||||
f.BigIntFlag(&flagset.BigIntFlag{
|
||||
Name: "miner.gasprice",
|
||||
Usage: "Minimum gas price for mining a transaction",
|
||||
Value: c.cliConfig.Sealer.GasPrice,
|
||||
})
|
||||
|
||||
// ethstats
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "ethstats",
|
||||
Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)",
|
||||
Value: c.cliConfig.Ethstats,
|
||||
})
|
||||
|
||||
// gas price oracle
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "gpo.blocks",
|
||||
Usage: "Number of recent blocks to check for gas prices",
|
||||
Value: c.cliConfig.Gpo.Blocks,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "gpo.percentile",
|
||||
Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
|
||||
Value: c.cliConfig.Gpo.Percentile,
|
||||
})
|
||||
f.BigIntFlag(&flagset.BigIntFlag{
|
||||
Name: "gpo.maxprice",
|
||||
Usage: "Maximum gas price will be recommended by gpo",
|
||||
Value: c.cliConfig.Gpo.MaxPrice,
|
||||
})
|
||||
f.BigIntFlag(&flagset.BigIntFlag{
|
||||
Name: "gpo.ignoreprice",
|
||||
Usage: "Gas price below which gpo will ignore transactions",
|
||||
Value: c.cliConfig.Gpo.IgnorePrice,
|
||||
})
|
||||
|
||||
// cache options
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "cache",
|
||||
Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node)",
|
||||
Value: c.cliConfig.Cache.Cache,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "cache.database",
|
||||
Usage: "Percentage of cache memory allowance to use for database io",
|
||||
Value: c.cliConfig.Cache.PercDatabase,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "cache.trie",
|
||||
Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)",
|
||||
Value: c.cliConfig.Cache.PercTrie,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "cache.trie.journal",
|
||||
Usage: "Disk journal directory for trie cache to survive node restarts",
|
||||
Value: c.cliConfig.Cache.Journal,
|
||||
})
|
||||
f.DurationFlag(&flagset.DurationFlag{
|
||||
Name: "cache.trie.rejournal",
|
||||
Usage: "Time interval to regenerate the trie cache journal",
|
||||
Value: c.cliConfig.Cache.Rejournal,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "cache.gc",
|
||||
Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)",
|
||||
Value: c.cliConfig.Cache.PercGc,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "cache.snapshot",
|
||||
Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode)",
|
||||
Value: c.cliConfig.Cache.PercSnapshot,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "cache.noprefetch",
|
||||
Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)",
|
||||
Value: c.cliConfig.Cache.NoPrefetch,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "cache.preimages",
|
||||
Usage: "Enable recording the SHA3/keccak preimages of trie keys",
|
||||
Value: c.cliConfig.Cache.Preimages,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "txlookuplimit",
|
||||
Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)",
|
||||
Value: c.cliConfig.Cache.TxLookupLimit,
|
||||
})
|
||||
|
||||
// rpc options
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "rpc.gascap",
|
||||
Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)",
|
||||
Value: c.cliConfig.JsonRPC.GasCap,
|
||||
})
|
||||
f.Float64Flag(&flagset.Float64Flag{
|
||||
Name: "rpc.txfeecap",
|
||||
Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)",
|
||||
Value: c.cliConfig.JsonRPC.TxFeeCap,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "ipcdisable",
|
||||
Usage: "Disable the IPC-RPC server",
|
||||
Value: c.cliConfig.JsonRPC.IPCDisable,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "ipcpath",
|
||||
Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)",
|
||||
Value: c.cliConfig.JsonRPC.IPCPath,
|
||||
})
|
||||
f.SliceStringFlag(&flagset.SliceStringFlag{
|
||||
Name: "rpc.corsdomain",
|
||||
Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
|
||||
Value: c.cliConfig.JsonRPC.Cors,
|
||||
})
|
||||
f.SliceStringFlag(&flagset.SliceStringFlag{
|
||||
Name: "rpc.vhosts",
|
||||
Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
|
||||
Value: c.cliConfig.JsonRPC.VHost,
|
||||
})
|
||||
// http options
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "http",
|
||||
Usage: "Enable the HTTP-RPC server",
|
||||
Value: c.cliConfig.JsonRPC.Http.Enabled,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "http.port",
|
||||
Usage: "HTTP-RPC server listening port",
|
||||
Value: c.cliConfig.JsonRPC.Http.Port,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "http.rpcprefix",
|
||||
Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.",
|
||||
Value: c.cliConfig.JsonRPC.Http.Prefix,
|
||||
})
|
||||
// ws options
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "ws",
|
||||
Usage: "Enable the WS-RPC server",
|
||||
Value: c.cliConfig.JsonRPC.Ws.Enabled,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "ws.port",
|
||||
Usage: "WS-RPC server listening port",
|
||||
Value: c.cliConfig.JsonRPC.Ws.Port,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "ws.rpcprefix",
|
||||
Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.",
|
||||
Value: c.cliConfig.JsonRPC.Ws.Prefix,
|
||||
})
|
||||
// graphql options
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "graphql",
|
||||
Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.",
|
||||
Value: c.cliConfig.JsonRPC.Graphql.Enabled,
|
||||
})
|
||||
|
||||
// p2p options
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "bind",
|
||||
Usage: "Network binding address",
|
||||
Value: c.cliConfig.P2P.Bind,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "port",
|
||||
Usage: "Network listening port",
|
||||
Value: c.cliConfig.P2P.Port,
|
||||
})
|
||||
f.SliceStringFlag(&flagset.SliceStringFlag{
|
||||
Name: "bootnodes",
|
||||
Usage: "Comma separated enode URLs for P2P discovery bootstrap",
|
||||
Value: c.cliConfig.P2P.Discovery.Bootnodes,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "maxpeers",
|
||||
Usage: "Maximum number of network peers (network disabled if set to 0)",
|
||||
Value: c.cliConfig.P2P.MaxPeers,
|
||||
})
|
||||
f.Uint64Flag(&flagset.Uint64Flag{
|
||||
Name: "maxpendpeers",
|
||||
Usage: "Maximum number of pending connection attempts (defaults used if set to 0)",
|
||||
Value: c.cliConfig.P2P.MaxPendPeers,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "nat",
|
||||
Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
|
||||
Value: c.cliConfig.P2P.NAT,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "nodiscover",
|
||||
Usage: "Disables the peer discovery mechanism (manual peer addition)",
|
||||
Value: c.cliConfig.P2P.NoDiscover,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "v5disc",
|
||||
Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism",
|
||||
Value: c.cliConfig.P2P.Discovery.V5Enabled,
|
||||
})
|
||||
|
||||
// metrics
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "metrics",
|
||||
Usage: "Enable metrics collection and reporting",
|
||||
Value: c.cliConfig.Metrics.Enabled,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "metrics.expensive",
|
||||
Usage: "Enable expensive metrics collection and reporting",
|
||||
Value: c.cliConfig.Metrics.Expensive,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "metrics.influxdb",
|
||||
Usage: "Enable metrics export/push to an external InfluxDB database (v1)",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.V1Enabled,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.endpoint",
|
||||
Usage: "InfluxDB API endpoint to report metrics to",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Endpoint,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.database",
|
||||
Usage: "InfluxDB database name to push reported metrics to",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Database,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.username",
|
||||
Usage: "Username to authorize access to the database",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Username,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.password",
|
||||
Usage: "Password to authorize access to the database",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Password,
|
||||
})
|
||||
f.MapStringFlag(&flagset.MapStringFlag{
|
||||
Name: "metrics.influxdb.tags",
|
||||
Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Tags,
|
||||
})
|
||||
// influx db v2
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "metrics.influxdbv2",
|
||||
Usage: "Enable metrics export/push to an external InfluxDB v2 database",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.V2Enabled,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.token",
|
||||
Usage: "Token to authorize access to the database (v2 only)",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Token,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.bucket",
|
||||
Usage: "InfluxDB bucket name to push reported metrics to (v2 only)",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Bucket,
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "metrics.influxdb.organization",
|
||||
Usage: "InfluxDB organization name (v2 only)",
|
||||
Value: c.cliConfig.Metrics.InfluxDB.Organization,
|
||||
})
|
||||
|
||||
return f
|
||||
|
|
|
|||
Loading…
Reference in a new issue