github.com/murrekatt/go-ethereum@v1.5.8-0.20170123175102-fc52f2c007fb/mobile/geth.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Contains all the wrappers from the node package to support client side node 18 // management on mobile platforms. 19 20 package geth 21 22 import ( 23 "fmt" 24 "math/big" 25 "path/filepath" 26 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/eth" 29 "github.com/ethereum/go-ethereum/ethclient" 30 "github.com/ethereum/go-ethereum/ethstats" 31 "github.com/ethereum/go-ethereum/les" 32 "github.com/ethereum/go-ethereum/node" 33 "github.com/ethereum/go-ethereum/p2p/nat" 34 "github.com/ethereum/go-ethereum/params" 35 "github.com/ethereum/go-ethereum/whisper/whisperv2" 36 ) 37 38 // NodeConfig represents the collection of configuration values to fine tune the Geth 39 // node embedded into a mobile process. The available values are a subset of the 40 // entire API provided by go-ethereum to reduce the maintenance surface and dev 41 // complexity. 42 type NodeConfig struct { 43 // Bootstrap nodes used to establish connectivity with the rest of the network. 44 BootstrapNodes *Enodes 45 46 // MaxPeers is the maximum number of peers that can be connected. If this is 47 // set to zero, then only the configured static and trusted peers can connect. 48 MaxPeers int 49 50 // EthereumEnabled specifies whether the node should run the Ethereum protocol. 51 EthereumEnabled bool 52 53 // EthereumNetworkID is the network identifier used by the Ethereum protocol to 54 // decide if remote peers should be accepted or not. 55 EthereumNetworkID int 56 57 // EthereumChainConfig is the default parameters of the blockchain to use. If no 58 // configuration is specified, it defaults to the main network. 59 EthereumChainConfig *ChainConfig 60 61 // EthereumGenesis is the genesis JSON to use to seed the blockchain with. An 62 // empty genesis state is equivalent to using the mainnet's state. 63 EthereumGenesis string 64 65 // EthereumDatabaseCache is the system memory in MB to allocate for database caching. 66 // A minimum of 16MB is always reserved. 67 EthereumDatabaseCache int 68 69 // EthereumNetStats is a netstats connection string to use to report various 70 // chain, transaction and node stats to a monitoring server. 71 // 72 // It has the form "nodename:secret@host:port" 73 EthereumNetStats string 74 75 // WhisperEnabled specifies whether the node should run the Whisper protocol. 76 WhisperEnabled bool 77 } 78 79 // defaultNodeConfig contains the default node configuration values to use if all 80 // or some fields are missing from the user's specified list. 81 var defaultNodeConfig = &NodeConfig{ 82 BootstrapNodes: FoundationBootnodes(), 83 MaxPeers: 25, 84 EthereumEnabled: true, 85 EthereumNetworkID: 1, 86 EthereumChainConfig: MainnetChainConfig(), 87 EthereumDatabaseCache: 16, 88 } 89 90 // NewNodeConfig creates a new node option set, initialized to the default values. 91 func NewNodeConfig() *NodeConfig { 92 config := *defaultNodeConfig 93 return &config 94 } 95 96 // Node represents a Geth Ethereum node instance. 97 type Node struct { 98 node *node.Node 99 } 100 101 // NewNode creates and configures a new Geth node. 102 func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) { 103 // If no or partial configurations were specified, use defaults 104 if config == nil { 105 config = NewNodeConfig() 106 } 107 if config.MaxPeers == 0 { 108 config.MaxPeers = defaultNodeConfig.MaxPeers 109 } 110 if config.BootstrapNodes == nil || config.BootstrapNodes.Size() == 0 { 111 config.BootstrapNodes = defaultNodeConfig.BootstrapNodes 112 } 113 // Create the empty networking stack 114 nodeConf := &node.Config{ 115 Name: clientIdentifier, 116 Version: params.Version, 117 DataDir: datadir, 118 KeyStoreDir: filepath.Join(datadir, "keystore"), // Mobile should never use internal keystores! 119 NoDiscovery: true, 120 DiscoveryV5: true, 121 DiscoveryV5Addr: ":0", 122 BootstrapNodesV5: config.BootstrapNodes.nodes, 123 ListenAddr: ":0", 124 NAT: nat.Any(), 125 MaxPeers: config.MaxPeers, 126 } 127 rawStack, err := node.New(nodeConf) 128 if err != nil { 129 return nil, err 130 } 131 // Register the Ethereum protocol if requested 132 if config.EthereumEnabled { 133 ethConf := ð.Config{ 134 ChainConfig: ¶ms.ChainConfig{ 135 ChainId: big.NewInt(config.EthereumChainConfig.ChainID), 136 HomesteadBlock: big.NewInt(config.EthereumChainConfig.HomesteadBlock), 137 DAOForkBlock: big.NewInt(config.EthereumChainConfig.DAOForkBlock), 138 DAOForkSupport: config.EthereumChainConfig.DAOForkSupport, 139 EIP150Block: big.NewInt(config.EthereumChainConfig.EIP150Block), 140 EIP150Hash: config.EthereumChainConfig.EIP150Hash.hash, 141 EIP155Block: big.NewInt(config.EthereumChainConfig.EIP155Block), 142 EIP158Block: big.NewInt(config.EthereumChainConfig.EIP158Block), 143 }, 144 Genesis: config.EthereumGenesis, 145 LightMode: true, 146 DatabaseCache: config.EthereumDatabaseCache, 147 NetworkId: config.EthereumNetworkID, 148 GasPrice: new(big.Int).Mul(big.NewInt(20), common.Shannon), 149 GpoMinGasPrice: new(big.Int).Mul(big.NewInt(20), common.Shannon), 150 GpoMaxGasPrice: new(big.Int).Mul(big.NewInt(500), common.Shannon), 151 GpoFullBlockRatio: 80, 152 GpobaseStepDown: 10, 153 GpobaseStepUp: 100, 154 GpobaseCorrectionFactor: 110, 155 } 156 if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) { 157 return les.New(ctx, ethConf) 158 }); err != nil { 159 return nil, fmt.Errorf("ethereum init: %v", err) 160 } 161 // If netstats reporting is requested, do it 162 if config.EthereumNetStats != "" { 163 if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) { 164 var lesServ *les.LightEthereum 165 ctx.Service(&lesServ) 166 167 return ethstats.New(config.EthereumNetStats, nil, lesServ) 168 }); err != nil { 169 return nil, fmt.Errorf("netstats init: %v", err) 170 } 171 } 172 } 173 // Register the Whisper protocol if requested 174 if config.WhisperEnabled { 175 if err := rawStack.Register(func(*node.ServiceContext) (node.Service, error) { return whisperv2.New(), nil }); err != nil { 176 return nil, fmt.Errorf("whisper init: %v", err) 177 } 178 } 179 return &Node{rawStack}, nil 180 } 181 182 // Start creates a live P2P node and starts running it. 183 func (n *Node) Start() error { 184 return n.node.Start() 185 } 186 187 // Stop terminates a running node along with all it's services. In the node was 188 // not started, an error is returned. 189 func (n *Node) Stop() error { 190 return n.node.Stop() 191 } 192 193 // GetEthereumClient retrieves a client to access the Ethereum subsystem. 194 func (n *Node) GetEthereumClient() (client *EthereumClient, _ error) { 195 rpc, err := n.node.Attach() 196 if err != nil { 197 return nil, err 198 } 199 return &EthereumClient{ethclient.NewClient(rpc)}, nil 200 } 201 202 // GetNodeInfo gathers and returns a collection of metadata known about the host. 203 func (n *Node) GetNodeInfo() *NodeInfo { 204 return &NodeInfo{n.node.Server().NodeInfo()} 205 } 206 207 // GetPeersInfo returns an array of metadata objects describing connected peers. 208 func (n *Node) GetPeersInfo() *PeerInfos { 209 return &PeerInfos{n.node.Server().PeersInfo()} 210 }