mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
Merge 9015b958a1 into 9422eec554
This commit is contained in:
commit
29c415c3fa
5 changed files with 328 additions and 144 deletions
87
accounts/contract/contract.go
Normal file
87
accounts/contract/contract.go
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
package contract
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Contract struct {
|
||||||
|
backend core.Backend
|
||||||
|
abi.ABI
|
||||||
|
Address common.Address
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAccount(backend core.Backend) *state.StateObject {
|
||||||
|
statedb, _ := state.New(backend.BlockChain().CurrentHeader().Root, backend.ChainDb())
|
||||||
|
accounts, err := backend.AccountManager().Accounts()
|
||||||
|
if err != nil || len(accounts) == 0 {
|
||||||
|
return statedb.GetOrNewStateObject(common.Address{})
|
||||||
|
} else {
|
||||||
|
return statedb.GetOrNewStateObject(accounts[0].Address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(definition string, addr common.Address, backend core.Backend) (*Contract, error) {
|
||||||
|
abi, err := abi.JSON(strings.NewReader(definition))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Contract{
|
||||||
|
backend: backend,
|
||||||
|
ABI: abi,
|
||||||
|
Address: addr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Contract) Call(method string, args ...interface{}) ([]byte, *big.Int, error) {
|
||||||
|
msg := CallMessage{
|
||||||
|
gas: new(big.Int).Set(common.MaxBig),
|
||||||
|
gasPrice: new(big.Int),
|
||||||
|
value: new(big.Int),
|
||||||
|
from: getAccount(c.backend),
|
||||||
|
}
|
||||||
|
return c.CallWithMessage(msg, method, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Contract) CallWithMessage(msg CallMessage, method string, args ...interface{}) ([]byte, *big.Int, error) {
|
||||||
|
input, err := c.ABI.Pack(method, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
msg.data = input
|
||||||
|
msg.to = &c.Address
|
||||||
|
|
||||||
|
header := c.backend.BlockChain().CurrentHeader()
|
||||||
|
statedb, err := state.New(header.Root, c.backend.ChainDb())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
vmenv := core.NewEnv(statedb, c.backend.BlockChain(), msg, header)
|
||||||
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
|
|
||||||
|
return core.ApplyMessage(vmenv, msg, gp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallMessage is the message type used for call transations.
|
||||||
|
type CallMessage struct {
|
||||||
|
from *state.StateObject
|
||||||
|
to *common.Address
|
||||||
|
gas, gasPrice *big.Int
|
||||||
|
value *big.Int
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// accessor boilerplate to implement core.Message
|
||||||
|
func (m CallMessage) From() (common.Address, error) { return m.from.Address(), nil }
|
||||||
|
func (m CallMessage) Nonce() uint64 { return m.from.Nonce() }
|
||||||
|
func (m CallMessage) To() *common.Address { return m.to }
|
||||||
|
func (m CallMessage) GasPrice() *big.Int { return m.gasPrice }
|
||||||
|
func (m CallMessage) Gas() *big.Int { return m.gas }
|
||||||
|
func (m CallMessage) Value() *big.Int { return m.value }
|
||||||
|
func (m CallMessage) Data() []byte { return m.data }
|
||||||
|
|
@ -450,7 +450,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
|
||||||
Discovery: !ctx.GlobalBool(NoDiscoverFlag.Name),
|
Discovery: !ctx.GlobalBool(NoDiscoverFlag.Name),
|
||||||
NodeKey: MakeNodeKey(ctx),
|
NodeKey: MakeNodeKey(ctx),
|
||||||
Shh: ctx.GlobalBool(WhisperEnabledFlag.Name),
|
Shh: ctx.GlobalBool(WhisperEnabledFlag.Name),
|
||||||
Dial: true,
|
|
||||||
BootNodes: ctx.GlobalString(BootnodesFlag.Name),
|
BootNodes: ctx.GlobalString(BootnodesFlag.Name),
|
||||||
GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)),
|
GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)),
|
||||||
GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)),
|
GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)),
|
||||||
|
|
|
||||||
149
eth/backend.go
149
eth/backend.go
|
|
@ -19,10 +19,7 @@ package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/ecdsa"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -40,7 +37,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
|
@ -49,7 +45,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/miner"
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/whisper"
|
"github.com/ethereum/go-ethereum/whisper"
|
||||||
)
|
)
|
||||||
|
|
@ -86,143 +81,6 @@ var (
|
||||||
trustedNodes = "trusted-nodes.json" // Path within <datadir> to search for the trusted node list
|
trustedNodes = "trusted-nodes.json" // Path within <datadir> to search for the trusted node list
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
DevMode bool
|
|
||||||
TestNet bool
|
|
||||||
|
|
||||||
Name string
|
|
||||||
NetworkId int
|
|
||||||
GenesisFile string
|
|
||||||
GenesisBlock *types.Block // used by block tests
|
|
||||||
FastSync bool
|
|
||||||
Olympic bool
|
|
||||||
|
|
||||||
BlockChainVersion int
|
|
||||||
SkipBcVersionCheck bool // e.g. blockchain export
|
|
||||||
DatabaseCache int
|
|
||||||
|
|
||||||
DataDir string
|
|
||||||
LogFile string
|
|
||||||
Verbosity int
|
|
||||||
VmDebug bool
|
|
||||||
NatSpec bool
|
|
||||||
DocRoot string
|
|
||||||
AutoDAG bool
|
|
||||||
PowTest bool
|
|
||||||
ExtraData []byte
|
|
||||||
|
|
||||||
MaxPeers int
|
|
||||||
MaxPendingPeers int
|
|
||||||
Discovery bool
|
|
||||||
Port string
|
|
||||||
|
|
||||||
// Space-separated list of discovery node URLs
|
|
||||||
BootNodes string
|
|
||||||
|
|
||||||
// This key is used to identify the node on the network.
|
|
||||||
// If nil, an ephemeral key is used.
|
|
||||||
NodeKey *ecdsa.PrivateKey
|
|
||||||
|
|
||||||
NAT nat.Interface
|
|
||||||
Shh bool
|
|
||||||
Dial bool
|
|
||||||
|
|
||||||
Etherbase common.Address
|
|
||||||
GasPrice *big.Int
|
|
||||||
MinerThreads int
|
|
||||||
AccountManager *accounts.Manager
|
|
||||||
SolcPath string
|
|
||||||
|
|
||||||
GpoMinGasPrice *big.Int
|
|
||||||
GpoMaxGasPrice *big.Int
|
|
||||||
GpoFullBlockRatio int
|
|
||||||
GpobaseStepDown int
|
|
||||||
GpobaseStepUp int
|
|
||||||
GpobaseCorrectionFactor int
|
|
||||||
|
|
||||||
// NewDB is used to create databases.
|
|
||||||
// If nil, the default is to create leveldb databases on disk.
|
|
||||||
NewDB func(path string) (ethdb.Database, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *Config) parseBootNodes() []*discover.Node {
|
|
||||||
if cfg.BootNodes == "" {
|
|
||||||
if cfg.TestNet {
|
|
||||||
return defaultTestNetBootNodes
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultBootNodes
|
|
||||||
}
|
|
||||||
var ns []*discover.Node
|
|
||||||
for _, url := range strings.Split(cfg.BootNodes, " ") {
|
|
||||||
if url == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
n, err := discover.ParseNode(url)
|
|
||||||
if err != nil {
|
|
||||||
glog.V(logger.Error).Infof("Bootstrap URL %s: %v\n", url, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ns = append(ns, n)
|
|
||||||
}
|
|
||||||
return ns
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseNodes parses a list of discovery node URLs loaded from a .json file.
|
|
||||||
func (cfg *Config) parseNodes(file string) []*discover.Node {
|
|
||||||
// Short circuit if no node config is present
|
|
||||||
path := filepath.Join(cfg.DataDir, file)
|
|
||||||
if _, err := os.Stat(path); err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Load the nodes from the config file
|
|
||||||
blob, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
glog.V(logger.Error).Infof("Failed to access nodes: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
nodelist := []string{}
|
|
||||||
if err := json.Unmarshal(blob, &nodelist); err != nil {
|
|
||||||
glog.V(logger.Error).Infof("Failed to load nodes: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Interpret the list as a discovery node array
|
|
||||||
var nodes []*discover.Node
|
|
||||||
for _, url := range nodelist {
|
|
||||||
if url == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
node, err := discover.ParseNode(url)
|
|
||||||
if err != nil {
|
|
||||||
glog.V(logger.Error).Infof("Node URL %s: %v\n", url, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
nodes = append(nodes, node)
|
|
||||||
}
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *Config) nodeKey() (*ecdsa.PrivateKey, error) {
|
|
||||||
// use explicit key from command line args if set
|
|
||||||
if cfg.NodeKey != nil {
|
|
||||||
return cfg.NodeKey, nil
|
|
||||||
}
|
|
||||||
// use persistent key if present
|
|
||||||
keyfile := filepath.Join(cfg.DataDir, "nodekey")
|
|
||||||
key, err := crypto.LoadECDSA(keyfile)
|
|
||||||
if err == nil {
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
// no persistent key, generate and store a new one
|
|
||||||
if key, err = crypto.GenerateKey(); err != nil {
|
|
||||||
return nil, fmt.Errorf("could not generate server key: %v", err)
|
|
||||||
}
|
|
||||||
if err := crypto.SaveECDSA(keyfile, key); err != nil {
|
|
||||||
glog.V(logger.Error).Infoln("could not persist nodekey: ", err)
|
|
||||||
}
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Ethereum struct {
|
type Ethereum struct {
|
||||||
// Channel for shutting down the ethereum
|
// Channel for shutting down the ethereum
|
||||||
shutdownChan chan bool
|
shutdownChan chan bool
|
||||||
|
|
@ -272,6 +130,11 @@ type Ethereum struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config *Config) (*Ethereum, error) {
|
func New(config *Config) (*Ethereum, error) {
|
||||||
|
if config == nil {
|
||||||
|
config = new(Config)
|
||||||
|
}
|
||||||
|
MakeConfig(config)
|
||||||
|
|
||||||
logger.New(config.DataDir, config.LogFile, config.Verbosity)
|
logger.New(config.DataDir, config.LogFile, config.Verbosity)
|
||||||
|
|
||||||
// Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files)
|
// Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files)
|
||||||
|
|
@ -437,7 +300,7 @@ func New(config *Config) (*Ethereum, error) {
|
||||||
Discovery: config.Discovery,
|
Discovery: config.Discovery,
|
||||||
Protocols: protocols,
|
Protocols: protocols,
|
||||||
NAT: config.NAT,
|
NAT: config.NAT,
|
||||||
NoDial: !config.Dial,
|
NoDial: config.NoDial,
|
||||||
BootstrapNodes: config.parseBootNodes(),
|
BootstrapNodes: config.parseBootNodes(),
|
||||||
StaticNodes: config.parseNodes(staticNodes),
|
StaticNodes: config.parseNodes(staticNodes),
|
||||||
TrustedNodes: config.parseNodes(trustedNodes),
|
TrustedNodes: config.parseNodes(trustedNodes),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -65,3 +68,20 @@ func TestMipmapUpgrade(t *testing.T) {
|
||||||
t.Error("setting-mipmap-version not written to database")
|
t.Error("setting-mipmap-version not written to database")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleNew() {
|
||||||
|
// Setup ethereum stack; initialising the blockchain, transaction pool
|
||||||
|
// and network stack.
|
||||||
|
ethereum, err := New(&Config{Name: "Ghost"})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
// start all services
|
||||||
|
ethereum.Start()
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, os.Interrupt, os.Kill)
|
||||||
|
<-c
|
||||||
|
// stop all services
|
||||||
|
ethereum.Stop()
|
||||||
|
}
|
||||||
|
|
|
||||||
215
eth/config.go
Normal file
215
eth/config.go
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
package eth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is the configuration object which holds information about the various
|
||||||
|
// sub system and ethereum's environment and settings.
|
||||||
|
type Config struct {
|
||||||
|
DevMode bool // Developer mode
|
||||||
|
TestNet bool // Testnet mode
|
||||||
|
|
||||||
|
Name string // Name of the instance (visible through p2p)
|
||||||
|
NetworkId int // The network id used for p2p
|
||||||
|
GenesisFile string // genesis file for initialising the genesis block
|
||||||
|
GenesisBlock *types.Block // used by block tests
|
||||||
|
FastSync bool // enble fast sync
|
||||||
|
Olympic bool // enable olympic settings
|
||||||
|
|
||||||
|
BlockChainVersion int // version of the block chain in database
|
||||||
|
SkipBcVersionCheck bool // e.g. blockchain export
|
||||||
|
DatabaseCache int // Max cache for leveldb
|
||||||
|
|
||||||
|
DataDir string // datadir containing leveldb, node settings, etc.
|
||||||
|
LogFile string // file to which logs are written
|
||||||
|
Verbosity int // the level of verbosity
|
||||||
|
VmDebug bool // log debug output during vm execution
|
||||||
|
NatSpec bool // enable natspec
|
||||||
|
DocRoot string // documentation root for natspec
|
||||||
|
AutoDAG bool // pre-generate dags
|
||||||
|
PowTest bool // enabled pow test
|
||||||
|
ExtraData []byte // default extra data to be used for the miner
|
||||||
|
|
||||||
|
MaxPeers int // maximum amount of peers
|
||||||
|
MaxPendingPeers int // maximum amount of pending peers
|
||||||
|
Discovery bool // enable discovery
|
||||||
|
Port string // port to be used for p2p
|
||||||
|
|
||||||
|
BootNodes string // Space-separated list of discovery node URLs
|
||||||
|
|
||||||
|
// This key is used to identify the node on the network.
|
||||||
|
// If nil, an ephemeral key is used.
|
||||||
|
NodeKey *ecdsa.PrivateKey
|
||||||
|
|
||||||
|
NAT nat.Interface // NAT interface
|
||||||
|
Shh bool // enable shh
|
||||||
|
NoDial bool // disable outgoing dials
|
||||||
|
NoConn bool // disable peers
|
||||||
|
|
||||||
|
AccountManager *accounts.Manager // account manager
|
||||||
|
LightKDF bool // enables light KDF
|
||||||
|
|
||||||
|
Etherbase common.Address // default coinbase
|
||||||
|
GasPrice *big.Int // minimum acceptable gas price (tx relay, mining)
|
||||||
|
MinerThreads int // amount of default miner threads to be used during mining
|
||||||
|
SolcPath string // path to solidity executable
|
||||||
|
|
||||||
|
GpoMinGasPrice *big.Int // GPO minimum gas price
|
||||||
|
GpoMaxGasPrice *big.Int // GPO maximum gas price
|
||||||
|
GpoFullBlockRatio int
|
||||||
|
GpobaseStepDown int
|
||||||
|
GpobaseStepUp int
|
||||||
|
GpobaseCorrectionFactor int
|
||||||
|
|
||||||
|
// NewDB is used to create databases.
|
||||||
|
// If nil, the default is to create leveldb databases on disk.
|
||||||
|
NewDB func(path string) (ethdb.Database, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeConfig sets missing default values
|
||||||
|
func MakeConfig(cfg *Config) {
|
||||||
|
if cfg.BlockChainVersion < 3 {
|
||||||
|
cfg.BlockChainVersion = 3
|
||||||
|
}
|
||||||
|
if len(cfg.Name) == 0 {
|
||||||
|
cfg.Name = "Custom-Ethereum-Client"
|
||||||
|
}
|
||||||
|
if len(cfg.DataDir) == 0 {
|
||||||
|
cfg.DataDir = common.DefaultDataDir()
|
||||||
|
}
|
||||||
|
if cfg.MaxPeers == 0 && !cfg.NoConn {
|
||||||
|
cfg.MaxPeers = 25
|
||||||
|
}
|
||||||
|
if len(cfg.Port) == 0 {
|
||||||
|
cfg.Port = "0" // auto
|
||||||
|
}
|
||||||
|
if cfg.TestNet && cfg.NetworkId == 0 {
|
||||||
|
cfg.NetworkId = 2
|
||||||
|
}
|
||||||
|
if cfg.NAT == nil {
|
||||||
|
cfg.NAT, _ = nat.Parse("any")
|
||||||
|
}
|
||||||
|
if cfg.GasPrice == nil {
|
||||||
|
cfg.GasPrice = new(big.Int).Mul(big.NewInt(10), common.Szabo)
|
||||||
|
}
|
||||||
|
if cfg.GpoMinGasPrice == nil {
|
||||||
|
cfg.GpoMinGasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon)
|
||||||
|
}
|
||||||
|
if cfg.GpoMaxGasPrice == nil {
|
||||||
|
cfg.GpoMaxGasPrice = new(big.Int).Mul(big.NewInt(500), common.Shannon)
|
||||||
|
}
|
||||||
|
if cfg.GpoFullBlockRatio == 0 && cfg.GpobaseStepDown == 0 && cfg.GpobaseStepUp == 0 && cfg.GpobaseCorrectionFactor == 0 {
|
||||||
|
cfg.GpoFullBlockRatio = 80
|
||||||
|
cfg.GpobaseStepDown = 10
|
||||||
|
cfg.GpobaseStepUp = 100
|
||||||
|
cfg.GpobaseCorrectionFactor = 110
|
||||||
|
}
|
||||||
|
if cfg.AccountManager == nil {
|
||||||
|
scryptN := crypto.StandardScryptN
|
||||||
|
scryptP := crypto.StandardScryptP
|
||||||
|
if cfg.LightKDF {
|
||||||
|
scryptN = crypto.LightScryptN
|
||||||
|
scryptP = crypto.LightScryptP
|
||||||
|
}
|
||||||
|
cfg.AccountManager = accounts.NewManager(crypto.NewKeyStorePassphrase(filepath.Join(cfg.DataDir, "keystore"), scryptN, scryptP))
|
||||||
|
}
|
||||||
|
glog.SetV(cfg.Verbosity)
|
||||||
|
glog.CopyStandardLogTo("INFO")
|
||||||
|
glog.SetToStderr(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) parseBootNodes() []*discover.Node {
|
||||||
|
if cfg.BootNodes == "" {
|
||||||
|
if cfg.TestNet {
|
||||||
|
return defaultTestNetBootNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultBootNodes
|
||||||
|
}
|
||||||
|
var ns []*discover.Node
|
||||||
|
for _, url := range strings.Split(cfg.BootNodes, " ") {
|
||||||
|
if url == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n, err := discover.ParseNode(url)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Bootstrap URL %s: %v\n", url, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
return ns
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseNodes parses a list of discovery node URLs loaded from a .json file.
|
||||||
|
func (cfg *Config) parseNodes(file string) []*discover.Node {
|
||||||
|
// Short circuit if no node config is present
|
||||||
|
path := filepath.Join(cfg.DataDir, file)
|
||||||
|
if _, err := os.Stat(path); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Load the nodes from the config file
|
||||||
|
blob, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Failed to access nodes: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
nodelist := []string{}
|
||||||
|
if err := json.Unmarshal(blob, &nodelist); err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Failed to load nodes: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Interpret the list as a discovery node array
|
||||||
|
var nodes []*discover.Node
|
||||||
|
for _, url := range nodelist {
|
||||||
|
if url == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
node, err := discover.ParseNode(url)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Node URL %s: %v\n", url, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
}
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) nodeKey() (*ecdsa.PrivateKey, error) {
|
||||||
|
// use explicit key from command line args if set
|
||||||
|
if cfg.NodeKey != nil {
|
||||||
|
return cfg.NodeKey, nil
|
||||||
|
}
|
||||||
|
// use persistent key if present
|
||||||
|
keyfile := filepath.Join(cfg.DataDir, "nodekey")
|
||||||
|
key, err := crypto.LoadECDSA(keyfile)
|
||||||
|
if err == nil {
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
// no persistent key, generate and store a new one
|
||||||
|
if key, err = crypto.GenerateKey(); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not generate server key: %v", err)
|
||||||
|
}
|
||||||
|
if err := crypto.SaveECDSA(keyfile, key); err != nil {
|
||||||
|
glog.V(logger.Error).Infoln("could not persist nodekey: ", err)
|
||||||
|
}
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue