2015-07-07 03:54:22 +03:00
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
2015-07-22 19:48:40 +03:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2015-07-07 03:54:22 +03:00
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
2015-07-22 19:48:40 +03:00
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
2015-07-07 03:54:22 +03:00
2015-03-06 04:00:41 +02:00
package utils
import (
"crypto/ecdsa"
2015-04-20 18:45:37 +03:00
"fmt"
"log"
2015-10-07 18:21:13 +03:00
"math"
2015-05-09 13:00:51 +03:00
"math/big"
2015-08-07 10:56:49 +03:00
"net"
2015-04-20 18:45:37 +03:00
"net/http"
2015-03-10 00:00:27 +02:00
"os"
2015-05-12 15:24:11 +03:00
"path/filepath"
2015-05-12 16:20:53 +03:00
"runtime"
2015-07-07 11:32:05 +03:00
"strconv"
2015-05-12 15:24:11 +03:00
2015-03-06 04:00:41 +02:00
"github.com/codegangsta/cli"
2015-04-13 11:13:52 +03:00
"github.com/ethereum/ethash"
2015-03-07 13:39:52 +02:00
"github.com/ethereum/go-ethereum/accounts"
2015-03-18 09:44:58 +02:00
"github.com/ethereum/go-ethereum/common"
2015-03-06 04:00:41 +02:00
"github.com/ethereum/go-ethereum/core"
2015-08-07 10:56:49 +03:00
"github.com/ethereum/go-ethereum/core/vm"
2015-03-06 04:00:41 +02:00
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
2015-04-03 18:09:01 +03:00
"github.com/ethereum/go-ethereum/logger/glog"
2015-08-07 10:56:49 +03:00
"github.com/ethereum/go-ethereum/metrics"
2015-03-06 04:00:41 +02:00
"github.com/ethereum/go-ethereum/p2p/nat"
2015-10-07 18:21:13 +03:00
"github.com/ethereum/go-ethereum/params"
2015-06-08 12:01:02 +03:00
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/codec"
2015-06-15 17:48:59 +03:00
"github.com/ethereum/go-ethereum/rpc/comms"
2015-08-07 10:56:49 +03:00
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/rpc/useragent"
2015-06-15 17:48:59 +03:00
"github.com/ethereum/go-ethereum/xeth"
2015-03-06 04:00:41 +02:00
)
2015-03-10 17:44:48 +02:00
func init ( ) {
cli . AppHelpTemplate = ` { { . Name } } { { if . Flags } } [ global options ] { { end } } command { { if . Flags } } [ command options ] { { end } } [ arguments ... ]
VERSION :
{ { . Version } }
COMMANDS :
{ { range . Commands } } { { . Name } } { { with . ShortName } } , { { . } } { { end } } { { "\t" } } { { . Usage } }
{ { end } } { { if . Flags } }
GLOBAL OPTIONS :
{ { range . Flags } } { { . } }
{ { end } } { { end } }
`
cli . CommandHelpTemplate = ` { { . Name } } { { if . Subcommands } } command { { end } } { { if . Flags } } [ command options ] { { end } } [ arguments ... ]
{ { if . Description } } { { . Description } }
{ { end } } { { if . Subcommands } }
SUBCOMMANDS :
{ { range . Subcommands } } { { . Name } } { { with . ShortName } } , { { . } } { { end } } { { "\t" } } { { . Usage } }
{ { end } } { { end } } { { if . Flags } }
OPTIONS :
{ { range . Flags } } { { . } }
{ { end } } { { end } }
`
}
2015-03-09 23:51:50 +02:00
// NewApp creates an app with sane defaults.
func NewApp ( version , usage string ) * cli . App {
app := cli . NewApp ( )
2015-05-12 15:24:11 +03:00
app . Name = filepath . Base ( os . Args [ 0 ] )
2015-03-09 23:51:50 +02:00
app . Author = ""
2015-03-26 02:03:03 +02:00
//app.Authors = nil
2015-03-09 23:51:50 +02:00
app . Email = ""
app . Version = version
app . Usage = usage
return app
}
2015-03-06 04:00:41 +02:00
// These are all the command line flags we support.
// If you add to this list, please remember to include the
// flag in the appropriate command definition.
//
// The flags are defined here so their names and help texts
// are the same for all commands.
var (
// General settings
2015-04-08 16:43:55 +03:00
DataDirFlag = DirectoryFlag {
2015-03-06 04:00:41 +02:00
Name : "datadir" ,
Usage : "Data directory to be used" ,
2015-04-08 16:43:55 +03:00
Value : DirectoryString { common . DefaultDataDir ( ) } ,
2015-03-06 04:00:41 +02:00
}
2015-03-18 09:44:58 +02:00
NetworkIdFlag = cli . IntFlag {
Name : "networkid" ,
2015-04-22 02:41:34 +03:00
Usage : "Network Id (integer)" ,
2015-03-18 09:44:58 +02:00
Value : eth . NetworkId ,
}
2015-04-13 11:13:52 +03:00
BlockchainVersionFlag = cli . IntFlag {
Name : "blockchainversion" ,
2015-04-22 02:41:34 +03:00
Usage : "Blockchain version (integer)" ,
2015-04-13 11:13:52 +03:00
Value : core . BlockChainVersion ,
}
2015-06-08 13:12:13 +03:00
GenesisNonceFlag = cli . IntFlag {
Name : "genesisnonce" ,
Usage : "Sets the genesis nonce" ,
Value : 42 ,
}
2015-07-10 15:29:40 +03:00
GenesisFileFlag = cli . StringFlag {
Name : "genesis" ,
Usage : "Inserts/Overwrites the genesis block (json format)" ,
}
2015-09-06 16:46:54 +03:00
DevModeFlag = cli . BoolFlag {
Name : "dev" ,
Usage : "Developer mode. This mode creates a private network and sets several debugging flags" ,
}
2015-10-05 14:01:34 +03:00
TestNetFlag = cli . BoolFlag {
Name : "testnet" ,
Usage : "Testnet mode. This enables your node to operate on the testnet" ,
}
2015-04-19 00:53:30 +03:00
IdentityFlag = cli . StringFlag {
Name : "identity" ,
2015-04-22 02:41:34 +03:00
Usage : "Custom node name" ,
2015-04-19 00:53:30 +03:00
}
2015-04-08 14:22:31 +03:00
NatspecEnabledFlag = cli . BoolFlag {
Name : "natspec" ,
Usage : "Enable NatSpec confirmation notice" ,
}
2015-07-22 13:46:20 +03:00
CacheFlag = cli . IntFlag {
Name : "cache" ,
Usage : "Megabytes of memory allocated to internal caching" ,
Value : 0 ,
}
2015-08-03 18:48:24 +03:00
OlympicFlag = cli . BoolFlag {
Name : "olympic" ,
Usage : "Use olympic style protocol" ,
}
2015-10-09 18:36:31 +03:00
FastSyncFlag = cli . BoolFlag {
Name : "fast" ,
Usage : "Enables fast syncing through state downloads" ,
2015-07-02 19:55:18 +03:00
}
2015-03-18 09:44:58 +02:00
// miner settings
2015-06-12 08:45:23 +03:00
// TODO: refactor CPU vs GPU mining flags
MiningGPUFlag = cli . StringFlag {
Name : "minegpu" ,
Usage : "Mine with given GPUs. '--minegpu 0,1' will mine with the first two GPUs found." ,
}
2015-03-06 04:00:41 +02:00
MinerThreadsFlag = cli . IntFlag {
Name : "minerthreads" ,
Usage : "Number of miner threads" ,
Value : runtime . NumCPU ( ) ,
}
MiningEnabledFlag = cli . BoolFlag {
Name : "mine" ,
Usage : "Enable mining" ,
}
2015-05-20 18:56:17 +03:00
AutoDAGFlag = cli . BoolFlag {
Name : "autodag" ,
Usage : "Enable automatic DAG pregeneration" ,
}
2015-03-26 23:49:22 +02:00
EtherbaseFlag = cli . StringFlag {
2015-03-27 13:14:00 +02:00
Name : "etherbase" ,
2015-07-07 11:32:05 +03:00
Usage : "Public address for block mining rewards. By default the address first created is used" ,
Value : "0" ,
2015-03-26 23:49:22 +02:00
}
2015-05-09 13:00:51 +03:00
GasPriceFlag = cli . StringFlag {
Name : "gasprice" ,
Usage : "Sets the minimal gasprice when mining transactions" ,
2015-08-03 03:46:34 +03:00
Value : new ( big . Int ) . Mul ( big . NewInt ( 50 ) , common . Shannon ) . String ( ) ,
2015-05-09 13:00:51 +03:00
}
2015-09-22 11:34:58 +03:00
ExtraDataFlag = cli . StringFlag {
Name : "extradata" ,
Usage : "Extra data for the miner" ,
}
2015-03-18 09:44:58 +02:00
UnlockedAccountFlag = cli . StringFlag {
Name : "unlock" ,
2015-06-18 18:20:00 +03:00
Usage : "Unlock the account given until this program exits (prompts for password). '--unlock n' unlocks the n-th account in order or creation." ,
2015-03-23 15:00:06 +02:00
Value : "" ,
}
PasswordFileFlag = cli . StringFlag {
Name : "password" ,
2015-04-22 02:41:34 +03:00
Usage : "Path to password file to use with options and subcommands needing a password" ,
2015-03-23 15:00:06 +02:00
Value : "" ,
2015-03-18 09:44:58 +02:00
}
2015-03-06 04:00:41 +02:00
2015-07-18 00:09:36 +03:00
// vm flags
VMDebugFlag = cli . BoolFlag {
Name : "vmdebug" ,
Usage : "Virtual Machine debug output" ,
}
VMForceJitFlag = cli . BoolFlag {
Name : "forcejit" ,
Usage : "Force the JIT VM to take precedence" ,
}
VMJitCacheFlag = cli . IntFlag {
Name : "jitcache" ,
Usage : "Amount of cached JIT VM programs" ,
Value : 64 ,
}
VMEnableJitFlag = cli . BoolFlag {
Name : "jitvm" ,
Usage : "Enable the JIT VM" ,
}
2015-03-18 09:44:58 +02:00
// logging and debug settings
2015-03-06 04:00:41 +02:00
LogFileFlag = cli . StringFlag {
Name : "logfile" ,
Usage : "Send log output to a file" ,
}
2015-05-09 13:00:51 +03:00
VerbosityFlag = cli . IntFlag {
Name : "verbosity" ,
2015-04-22 02:41:34 +03:00
Usage : "Logging verbosity: 0-6 (0=silent, 1=error, 2=warn, 3=info, 4=core, 5=debug, 6=debug detail)" ,
2015-03-06 04:00:41 +02:00
Value : int ( logger . InfoLevel ) ,
}
2015-03-21 11:20:47 +02:00
LogJSONFlag = cli . StringFlag {
Name : "logjson" ,
Usage : "Send json structured log output to a file or '-' for standard output (default: no json output)" ,
Value : "" ,
2015-03-06 04:00:41 +02:00
}
2015-04-20 18:45:37 +03:00
LogToStdErrFlag = cli . BoolFlag {
Name : "logtostderr" ,
Usage : "Logs are written to standard error instead of to files." ,
}
LogVModuleFlag = cli . GenericFlag {
Name : "vmodule" ,
2015-04-22 02:41:34 +03:00
Usage : "The syntax of the argument is a comma-separated list of pattern=N, where pattern is a literal file name (minus the \".go\" suffix) or \"glob\" pattern and N is a log verbosity level." ,
2015-04-20 18:45:37 +03:00
Value : glog . GetVModule ( ) ,
}
BacktraceAtFlag = cli . GenericFlag {
Name : "backtrace_at" ,
2015-04-22 02:41:34 +03:00
Usage : "If set to a file and line number (e.g., \"block.go:271\") holding a logging statement, a stack trace will be logged" ,
2015-04-20 18:45:37 +03:00
Value : glog . GetTraceLocation ( ) ,
}
2015-04-20 19:14:49 +03:00
PProfEanbledFlag = cli . BoolFlag {
Name : "pprof" ,
2015-04-22 02:41:34 +03:00
Usage : "Enable the profiling server on localhost" ,
2015-04-20 18:45:37 +03:00
}
PProfPortFlag = cli . IntFlag {
Name : "pprofport" ,
Usage : "Port on which the profiler should listen" ,
Value : 6060 ,
}
2015-06-29 16:11:01 +03:00
MetricsEnabledFlag = cli . BoolFlag {
Name : metrics . MetricsEnabledFlag ,
Usage : "Enables metrics collection and reporting" ,
}
2015-03-06 04:00:41 +02:00
// RPC settings
RPCEnabledFlag = cli . BoolFlag {
Name : "rpc" ,
2015-04-22 02:41:34 +03:00
Usage : "Enable the JSON-RPC server" ,
2015-03-06 04:00:41 +02:00
}
RPCListenAddrFlag = cli . StringFlag {
Name : "rpcaddr" ,
Usage : "Listening address for the JSON-RPC server" ,
Value : "127.0.0.1" ,
}
RPCPortFlag = cli . IntFlag {
Name : "rpcport" ,
Usage : "Port on which the JSON-RPC server should listen" ,
Value : 8545 ,
}
2015-03-29 22:21:14 +03:00
RPCCORSDomainFlag = cli . StringFlag {
Name : "rpccorsdomain" ,
Usage : "Domain on which to send Access-Control-Allow-Origin header" ,
Value : "" ,
}
2015-06-16 14:30:53 +03:00
RpcApiFlag = cli . StringFlag {
Name : "rpcapi" ,
Usage : "Specify the API's which are offered over the HTTP RPC interface" ,
2015-06-17 17:22:35 +03:00
Value : comms . DefaultHttpRpcApis ,
2015-06-16 14:30:53 +03:00
}
2015-06-08 12:01:02 +03:00
IPCDisabledFlag = cli . BoolFlag {
Name : "ipcdisable" ,
Usage : "Disable the IPC-RPC server" ,
}
IPCApiFlag = cli . StringFlag {
Name : "ipcapi" ,
2015-06-16 14:30:53 +03:00
Usage : "Specify the API's which are offered over the IPC interface" ,
2015-06-17 17:22:35 +03:00
Value : comms . DefaultIpcApis ,
2015-06-08 12:01:02 +03:00
}
IPCPathFlag = DirectoryFlag {
Name : "ipcpath" ,
Usage : "Filename for IPC socket/pipe" ,
Value : DirectoryString { common . DefaultIpcPath ( ) } ,
}
2015-06-19 15:04:18 +03:00
ExecFlag = cli . StringFlag {
Name : "exec" ,
Usage : "Execute javascript statement (only in combination with console/attach)" ,
}
2015-03-06 04:00:41 +02:00
// Network Settings
MaxPeersFlag = cli . IntFlag {
Name : "maxpeers" ,
2015-04-22 02:41:34 +03:00
Usage : "Maximum number of network peers (network disabled if set to 0)" ,
2015-05-08 17:01:31 +03:00
Value : 25 ,
2015-03-06 04:00:41 +02:00
}
2015-05-04 17:35:49 +03:00
MaxPendingPeersFlag = cli . IntFlag {
Name : "maxpendpeers" ,
Usage : "Maximum number of pending connection attempts (defaults used if set to 0)" ,
Value : 0 ,
}
2015-03-06 04:00:41 +02:00
ListenPortFlag = cli . IntFlag {
Name : "port" ,
Usage : "Network listening port" ,
Value : 30303 ,
}
BootnodesFlag = cli . StringFlag {
Name : "bootnodes" ,
2015-04-24 14:46:53 +03:00
Usage : "Space-separated enode URLs for p2p discovery bootstrap" ,
2015-03-06 04:00:41 +02:00
Value : "" ,
}
NodeKeyFileFlag = cli . StringFlag {
Name : "nodekey" ,
Usage : "P2P node key file" ,
}
NodeKeyHexFlag = cli . StringFlag {
Name : "nodekeyhex" ,
Usage : "P2P node key as hex (for testing)" ,
}
NATFlag = cli . StringFlag {
Name : "nat" ,
2015-04-22 02:41:34 +03:00
Usage : "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)" ,
2015-03-06 04:00:41 +02:00
Value : "any" ,
}
2015-05-26 19:07:24 +03:00
NoDiscoverFlag = cli . BoolFlag {
Name : "nodiscover" ,
Usage : "Disables the peer discovery mechanism (manual peer addition)" ,
}
2015-04-20 18:45:37 +03:00
WhisperEnabledFlag = cli . BoolFlag {
Name : "shh" ,
2015-04-22 02:41:34 +03:00
Usage : "Enable whisper" ,
2015-04-20 18:45:37 +03:00
}
2015-04-23 01:11:11 +03:00
// ATM the url is left to the user and deployment to
2015-03-15 08:31:40 +02:00
JSpathFlag = cli . StringFlag {
Name : "jspath" ,
2015-09-22 11:34:58 +03:00
Usage : "JS root path for loadScript and document root for admin.httpGet" ,
2015-03-15 08:31:40 +02:00
Value : "." ,
}
2015-04-23 01:11:11 +03:00
SolcPathFlag = cli . StringFlag {
Name : "solc" ,
Usage : "solidity compiler to be used" ,
Value : "solc" ,
}
2015-05-26 15:17:43 +03:00
GpoMinGasPriceFlag = cli . StringFlag {
Name : "gpomin" ,
Usage : "Minimum suggested gas price" ,
2015-08-03 03:46:34 +03:00
Value : new ( big . Int ) . Mul ( big . NewInt ( 50 ) , common . Shannon ) . String ( ) ,
2015-05-26 15:17:43 +03:00
}
GpoMaxGasPriceFlag = cli . StringFlag {
Name : "gpomax" ,
Usage : "Maximum suggested gas price" ,
2015-08-03 03:46:34 +03:00
Value : new ( big . Int ) . Mul ( big . NewInt ( 500 ) , common . Shannon ) . String ( ) ,
2015-05-26 15:17:43 +03:00
}
GpoFullBlockRatioFlag = cli . IntFlag {
Name : "gpofull" ,
Usage : "Full block threshold for gas price calculation (%)" ,
Value : 80 ,
}
GpobaseStepDownFlag = cli . IntFlag {
Name : "gpobasedown" ,
Usage : "Suggested gas price base step down ratio (1/1000)" ,
Value : 10 ,
}
GpobaseStepUpFlag = cli . IntFlag {
Name : "gpobaseup" ,
Usage : "Suggested gas price base step up ratio (1/1000)" ,
Value : 100 ,
}
GpobaseCorrectionFactorFlag = cli . IntFlag {
Name : "gpobasecf" ,
Usage : "Suggested gas price base correction factor (%)" ,
Value : 110 ,
}
2015-03-06 04:00:41 +02:00
)
2015-05-27 15:50:31 +03:00
// MakeNAT creates a port mapper from set command line flags.
func MakeNAT ( ctx * cli . Context ) nat . Interface {
2015-03-06 04:00:41 +02:00
natif , err := nat . Parse ( ctx . GlobalString ( NATFlag . Name ) )
if err != nil {
Fatalf ( "Option %s: %v" , NATFlag . Name , err )
}
return natif
}
2015-05-27 15:50:31 +03:00
// MakeNodeKey creates a node key from set command line flags.
func MakeNodeKey ( ctx * cli . Context ) ( key * ecdsa . PrivateKey ) {
2015-03-06 04:00:41 +02:00
hex , file := ctx . GlobalString ( NodeKeyHexFlag . Name ) , ctx . GlobalString ( NodeKeyFileFlag . Name )
var err error
switch {
case file != "" && hex != "" :
Fatalf ( "Options %q and %q are mutually exclusive" , NodeKeyFileFlag . Name , NodeKeyHexFlag . Name )
case file != "" :
if key , err = crypto . LoadECDSA ( file ) ; err != nil {
Fatalf ( "Option %q: %v" , NodeKeyFileFlag . Name , err )
}
case hex != "" :
if key , err = crypto . HexToECDSA ( hex ) ; err != nil {
Fatalf ( "Option %q: %v" , NodeKeyHexFlag . Name , err )
}
}
return key
}
2015-05-27 15:50:31 +03:00
// MakeEthConfig creates ethereum options from set command line flags.
2015-03-13 19:30:45 +02:00
func MakeEthConfig ( clientID , version string , ctx * cli . Context ) * eth . Config {
2015-04-19 00:53:30 +03:00
customName := ctx . GlobalString ( IdentityFlag . Name )
if len ( customName ) > 0 {
clientID += "/" + customName
}
2015-07-07 11:32:05 +03:00
am := MakeAccountManager ( ctx )
2015-07-07 13:53:36 +03:00
etherbase , err := ParamToAddress ( ctx . GlobalString ( EtherbaseFlag . Name ) , am )
if err != nil {
glog . V ( logger . Error ) . Infoln ( "WARNING: No etherbase set and no accounts found as default" )
}
2015-09-01 17:35:14 +03:00
// Assemble the entire eth configuration and return
2015-09-06 16:46:54 +03:00
cfg := & eth . Config {
2015-05-26 15:17:43 +03:00
Name : common . MakeName ( clientID , version ) ,
2015-09-29 17:16:00 +03:00
DataDir : MustDataDir ( ctx ) ,
2015-05-26 15:17:43 +03:00
GenesisNonce : ctx . GlobalInt ( GenesisNonceFlag . Name ) ,
2015-07-10 15:29:40 +03:00
GenesisFile : ctx . GlobalString ( GenesisFileFlag . Name ) ,
2015-10-09 18:36:31 +03:00
FastSync : ctx . GlobalBool ( FastSyncFlag . Name ) ,
2015-05-26 15:17:43 +03:00
BlockChainVersion : ctx . GlobalInt ( BlockchainVersionFlag . Name ) ,
2015-07-22 13:46:20 +03:00
DatabaseCache : ctx . GlobalInt ( CacheFlag . Name ) ,
2015-05-26 15:17:43 +03:00
SkipBcVersionCheck : false ,
NetworkId : ctx . GlobalInt ( NetworkIdFlag . Name ) ,
LogFile : ctx . GlobalString ( LogFileFlag . Name ) ,
Verbosity : ctx . GlobalInt ( VerbosityFlag . Name ) ,
LogJSON : ctx . GlobalString ( LogJSONFlag . Name ) ,
2015-07-07 13:53:36 +03:00
Etherbase : common . HexToAddress ( etherbase ) ,
2015-05-26 15:17:43 +03:00
MinerThreads : ctx . GlobalInt ( MinerThreadsFlag . Name ) ,
2015-07-07 11:32:05 +03:00
AccountManager : am ,
2015-05-26 15:17:43 +03:00
VmDebug : ctx . GlobalBool ( VMDebugFlag . Name ) ,
MaxPeers : ctx . GlobalInt ( MaxPeersFlag . Name ) ,
MaxPendingPeers : ctx . GlobalInt ( MaxPendingPeersFlag . Name ) ,
Port : ctx . GlobalString ( ListenPortFlag . Name ) ,
2015-08-03 18:48:24 +03:00
Olympic : ctx . GlobalBool ( OlympicFlag . Name ) ,
2015-05-26 15:17:43 +03:00
NAT : MakeNAT ( ctx ) ,
NatSpec : ctx . GlobalBool ( NatspecEnabledFlag . Name ) ,
Discovery : ! ctx . GlobalBool ( NoDiscoverFlag . Name ) ,
NodeKey : MakeNodeKey ( ctx ) ,
Shh : ctx . GlobalBool ( WhisperEnabledFlag . Name ) ,
Dial : true ,
BootNodes : ctx . GlobalString ( BootnodesFlag . Name ) ,
GasPrice : common . String2Big ( ctx . GlobalString ( GasPriceFlag . Name ) ) ,
GpoMinGasPrice : common . String2Big ( ctx . GlobalString ( GpoMinGasPriceFlag . Name ) ) ,
GpoMaxGasPrice : common . String2Big ( ctx . GlobalString ( GpoMaxGasPriceFlag . Name ) ) ,
GpoFullBlockRatio : ctx . GlobalInt ( GpoFullBlockRatioFlag . Name ) ,
GpobaseStepDown : ctx . GlobalInt ( GpobaseStepDownFlag . Name ) ,
GpobaseStepUp : ctx . GlobalInt ( GpobaseStepUpFlag . Name ) ,
GpobaseCorrectionFactor : ctx . GlobalInt ( GpobaseCorrectionFactorFlag . Name ) ,
SolcPath : ctx . GlobalString ( SolcPathFlag . Name ) ,
AutoDAG : ctx . GlobalBool ( AutoDAGFlag . Name ) || ctx . GlobalBool ( MiningEnabledFlag . Name ) ,
2015-03-13 19:30:45 +02:00
}
2015-09-06 16:46:54 +03:00
2015-10-05 14:01:34 +03:00
if ctx . GlobalBool ( DevModeFlag . Name ) && ctx . GlobalBool ( TestNetFlag . Name ) {
glog . Fatalf ( "%s and %s are mutually exclusive\n" , DevModeFlag . Name , TestNetFlag . Name )
}
if ctx . GlobalBool ( TestNetFlag . Name ) {
// testnet is always stored in the testnet folder
cfg . DataDir += "/testnet"
cfg . NetworkId = 2
cfg . TestNet = true
}
2015-10-07 00:39:43 +03:00
if ctx . GlobalBool ( VMEnableJitFlag . Name ) {
cfg . Name += "/JIT"
}
2015-09-06 16:46:54 +03:00
if ctx . GlobalBool ( DevModeFlag . Name ) {
if ! ctx . GlobalIsSet ( VMDebugFlag . Name ) {
cfg . VmDebug = true
}
if ! ctx . GlobalIsSet ( MaxPeersFlag . Name ) {
cfg . MaxPeers = 0
}
if ! ctx . GlobalIsSet ( GasPriceFlag . Name ) {
cfg . GasPrice = new ( big . Int )
}
if ! ctx . GlobalIsSet ( ListenPortFlag . Name ) {
cfg . Port = "0" // auto port
}
if ! ctx . GlobalIsSet ( WhisperEnabledFlag . Name ) {
cfg . Shh = true
}
if ! ctx . GlobalIsSet ( DataDirFlag . Name ) {
cfg . DataDir = os . TempDir ( ) + "/ethereum_dev_mode"
}
cfg . PowTest = true
cfg . DevMode = true
glog . V ( logger . Info ) . Infoln ( "dev mode enabled" )
}
return cfg
2015-03-06 04:00:41 +02:00
}
2015-05-27 14:29:34 +03:00
// SetupLogger configures glog from the logging-related command line flags.
func SetupLogger ( ctx * cli . Context ) {
glog . SetV ( ctx . GlobalInt ( VerbosityFlag . Name ) )
glog . CopyStandardLogTo ( "INFO" )
glog . SetToStderr ( true )
glog . SetLogDir ( ctx . GlobalString ( LogFileFlag . Name ) )
}
2015-04-13 11:13:52 +03:00
2015-10-07 18:21:13 +03:00
// SetupNetwork configures the system for either the main net or some test network.
func SetupNetwork ( ctx * cli . Context ) {
switch {
case ctx . GlobalBool ( OlympicFlag . Name ) :
params . DurationLimit = big . NewInt ( 8 )
params . GenesisGasLimit = big . NewInt ( 3141592 )
params . MinGasLimit = big . NewInt ( 125000 )
params . MaximumExtraDataSize = big . NewInt ( 1024 )
NetworkIdFlag . Value = 0
core . BlockReward = big . NewInt ( 1.5e+18 )
core . ExpDiffPeriod = big . NewInt ( math . MaxInt64 )
}
}
2015-07-18 00:09:36 +03:00
// SetupVM configured the VM package's global settings
func SetupVM ( ctx * cli . Context ) {
2015-08-11 01:27:30 +03:00
vm . EnableJit = ctx . GlobalBool ( VMEnableJitFlag . Name )
2015-07-18 00:09:36 +03:00
vm . ForceJit = ctx . GlobalBool ( VMForceJitFlag . Name )
vm . SetJITCacheSize ( ctx . GlobalInt ( VMJitCacheFlag . Name ) )
}
2015-05-27 15:50:31 +03:00
// MakeChain creates a chain manager from set command line flags.
2015-08-31 18:09:50 +03:00
func MakeChain ( ctx * cli . Context ) ( chain * core . BlockChain , chainDb ethdb . Database ) {
2015-09-29 17:16:00 +03:00
datadir := MustDataDir ( ctx )
2015-07-22 13:46:20 +03:00
cache := ctx . GlobalInt ( CacheFlag . Name )
2015-05-27 14:29:34 +03:00
var err error
2015-08-06 20:57:39 +03:00
if chainDb , err = ethdb . NewLDBDatabase ( filepath . Join ( datadir , "chaindata" ) , cache ) ; err != nil {
2015-04-13 11:13:52 +03:00
Fatalf ( "Could not open database: %v" , err )
}
2015-08-03 18:48:24 +03:00
if ctx . GlobalBool ( OlympicFlag . Name ) {
2015-08-06 20:57:39 +03:00
_ , err := core . WriteTestNetGenesisBlock ( chainDb , 42 )
2015-08-03 18:48:24 +03:00
if err != nil {
glog . Fatalln ( err )
}
}
2015-04-13 11:13:52 +03:00
eventMux := new ( event . TypeMux )
2015-05-05 09:24:15 +03:00
pow := ethash . New ( )
2015-07-10 15:29:40 +03:00
//genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
2015-08-31 18:09:50 +03:00
chain , err = core . NewBlockChain ( chainDb , pow , eventMux )
2015-06-08 13:12:13 +03:00
if err != nil {
Fatalf ( "Could not start chainmanager: %v" , err )
}
2015-08-06 20:57:39 +03:00
proc := core . NewBlockProcessor ( chainDb , pow , chain , eventMux )
2015-05-27 14:29:34 +03:00
chain . SetProcessor ( proc )
2015-08-06 20:57:39 +03:00
return chain , chainDb
2015-03-06 04:00:41 +02:00
}
2015-03-07 13:39:52 +02:00
2015-05-27 15:50:31 +03:00
// MakeChain creates an account manager from set command line flags.
func MakeAccountManager ( ctx * cli . Context ) * accounts . Manager {
2015-09-29 17:16:00 +03:00
dataDir := MustDataDir ( ctx )
2015-10-05 14:01:34 +03:00
if ctx . GlobalBool ( TestNetFlag . Name ) {
dataDir += "/testnet"
}
2015-05-12 19:33:04 +03:00
ks := crypto . NewKeyStorePassphrase ( filepath . Join ( dataDir , "keystore" ) )
2015-03-10 01:09:39 +02:00
return accounts . NewManager ( ks )
2015-03-07 13:39:52 +02:00
}
2015-03-10 00:00:27 +02:00
2015-09-29 17:16:00 +03:00
// MustDataDir retrieves the currently requested data directory, terminating if
// none (or the empty string) is specified.
func MustDataDir ( ctx * cli . Context ) string {
if path := ctx . GlobalString ( DataDirFlag . Name ) ; path != "" {
return path
}
Fatalf ( "Cannot determine default data directory, please set manually (--datadir)" )
return ""
}
2015-06-12 10:32:37 +03:00
func IpcSocketPath ( ctx * cli . Context ) ( ipcpath string ) {
2015-08-06 17:15:36 +03:00
if runtime . GOOS == "windows" {
2015-06-12 10:32:37 +03:00
ipcpath = common . DefaultIpcPath ( )
2015-07-02 18:20:58 +03:00
if ctx . GlobalIsSet ( IPCPathFlag . Name ) {
2015-06-12 10:32:37 +03:00
ipcpath = ctx . GlobalString ( IPCPathFlag . Name )
}
} else {
ipcpath = common . DefaultIpcPath ( )
2015-07-02 18:20:58 +03:00
if ctx . GlobalIsSet ( DataDirFlag . Name ) {
2015-06-12 10:32:37 +03:00
ipcpath = filepath . Join ( ctx . GlobalString ( DataDirFlag . Name ) , "geth.ipc" )
}
2015-07-02 18:20:58 +03:00
if ctx . GlobalIsSet ( IPCPathFlag . Name ) {
ipcpath = ctx . GlobalString ( IPCPathFlag . Name )
}
2015-06-12 10:32:37 +03:00
}
return
}
2015-06-08 12:01:02 +03:00
func StartIPC ( eth * eth . Ethereum , ctx * cli . Context ) error {
config := comms . IpcConfig {
2015-06-12 10:32:37 +03:00
Endpoint : IpcSocketPath ( ctx ) ,
2015-06-08 12:01:02 +03:00
}
2015-08-07 10:56:49 +03:00
initializer := func ( conn net . Conn ) ( shared . EthereumApi , error ) {
fe := useragent . NewRemoteFrontend ( conn , eth . AccountManager ( ) )
xeth := xeth . New ( eth , fe )
codec := codec . JSON
2015-06-08 12:01:02 +03:00
2015-09-22 11:34:58 +03:00
apis , err := api . ParseApiString ( ctx . GlobalString ( IPCApiFlag . Name ) , codec , xeth , eth , ctx . GlobalString ( JSpathFlag . Name ) )
2015-08-07 10:56:49 +03:00
if err != nil {
return nil , err
}
return api . Merge ( apis ... ) , nil
2015-06-08 12:01:02 +03:00
}
2015-08-07 10:56:49 +03:00
return comms . StartIpc ( config , codec . JSON , initializer )
2015-06-08 12:01:02 +03:00
}
2015-04-22 02:47:17 +03:00
func StartRPC ( eth * eth . Ethereum , ctx * cli . Context ) error {
2015-06-16 14:30:53 +03:00
config := comms . HttpConfig {
2015-03-29 22:26:47 +03:00
ListenAddress : ctx . GlobalString ( RPCListenAddrFlag . Name ) ,
ListenPort : uint ( ctx . GlobalInt ( RPCPortFlag . Name ) ) ,
CorsDomain : ctx . GlobalString ( RPCCORSDomainFlag . Name ) ,
2015-03-10 00:00:27 +02:00
}
2015-03-29 22:26:47 +03:00
xeth := xeth . New ( eth , nil )
2015-06-16 14:30:53 +03:00
codec := codec . JSON
2015-09-22 11:34:58 +03:00
apis , err := api . ParseApiString ( ctx . GlobalString ( RpcApiFlag . Name ) , codec , xeth , eth , ctx . GlobalString ( JSpathFlag . Name ) )
2015-06-16 14:30:53 +03:00
if err != nil {
return err
}
2015-06-22 13:47:32 +03:00
return comms . StartHttp ( config , codec , api . Merge ( apis ... ) )
2015-03-10 00:00:27 +02:00
}
2015-04-20 18:45:37 +03:00
func StartPProf ( ctx * cli . Context ) {
address := fmt . Sprintf ( "localhost:%d" , ctx . GlobalInt ( PProfPortFlag . Name ) )
go func ( ) {
log . Println ( http . ListenAndServe ( address , nil ) )
} ( )
}
2015-07-07 11:32:05 +03:00
2015-07-07 13:53:36 +03:00
func ParamToAddress ( addr string , am * accounts . Manager ) ( addrHex string , err error ) {
2015-07-07 11:32:05 +03:00
if ! ( ( len ( addr ) == 40 ) || ( len ( addr ) == 42 ) ) { // with or without 0x
index , err := strconv . Atoi ( addr )
if err != nil {
Fatalf ( "Invalid account address '%s'" , addr )
}
addrHex , err = am . AddressByIndex ( index )
if err != nil {
2015-07-07 13:53:36 +03:00
return "" , err
2015-07-07 11:32:05 +03:00
}
} else {
addrHex = addr
}
return
}