diff options
Diffstat (limited to 'mobile/geth.go')
-rw-r--r-- | mobile/geth.go | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/mobile/geth.go b/mobile/geth.go new file mode 100644 index 000000000..cb421868c --- /dev/null +++ b/mobile/geth.go @@ -0,0 +1,188 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +// Contains all the wrappers from the node package to support client side node +// management on mobile platforms. + +package geth + +import ( + "fmt" + "math/big" + "path/filepath" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/whisper" +) + +// NodeConfig represents the collection of configuration values to fine tune the Geth +// node embedded into a mobile process. The available values are a subset of the +// entire API provided by go-ethereum to reduce the maintenance surface and dev +// complexity. +type NodeConfig struct { + // Bootstrap nodes used to establish connectivity with the rest of the network. + BootstrapNodes *Enodes + + // MaxPeers is the maximum number of peers that can be connected. If this is + // set to zero, then only the configured static and trusted peers can connect. + MaxPeers int + + // EthereumEnabled specifies whether the node should run the Ethereum protocol. + EthereumEnabled bool + + // EthereumNetworkID is the network identifier used by the Ethereum protocol to + // decide if remote peers should be accepted or not. + EthereumNetworkID int + + // EthereumChainConfig is the default parameters of the blockchain to use. If no + // configuration is specified, it defaults to the main network. + EthereumChainConfig *ChainConfig + + // EthereumGenesis is the genesis JSON to use to seed the blockchain with. An + // empty genesis state is equivalent to using the mainnet's state. + EthereumGenesis string + + // EthereumTestnetNonces specifies whether to use account nonces from the testnet + // range (2^20) or from the mainnet one (0). + EthereumTestnetNonces bool + + // EthereumDatabaseCache is the system memory in MB to allocate for database caching. + // A minimum of 16MB is always reserved. + EthereumDatabaseCache int + + // WhisperEnabled specifies whether the node should run the Whisper protocol. + WhisperEnabled bool +} + +// defaultNodeConfig contains the default node configuration values to use if all +// or some fields are missing from the user's specified list. +var defaultNodeConfig = &NodeConfig{ + BootstrapNodes: MainnetBootnodes(), + MaxPeers: 25, + EthereumEnabled: true, + EthereumNetworkID: 1, + EthereumChainConfig: MainnetChainConfig, + EthereumDatabaseCache: 16, +} + +// NewNodeConfig creates a new node option set, initialized to the default values. +func NewNodeConfig() *NodeConfig { + config := *defaultNodeConfig + return &config +} + +// Node represents a Geth Ethereum node instance. +type Node struct { + node *node.Node +} + +// NewNode creates and configures a new Geth node. +func NewNode(datadir string, config *NodeConfig) (*Node, error) { + // If no or partial configurations were specified, use defaults + if config == nil { + config = NewNodeConfig() + } + if config.MaxPeers == 0 { + config.MaxPeers = defaultNodeConfig.MaxPeers + } + // Create the empty networking stack + nodeConf := &node.Config{ + DataDir: datadir, + KeyStoreDir: filepath.Join(datadir, "keystore"), // Mobile should never use internal keystores! + Name: common.MakeName(clientIdentifier, utils.Version), + BootstrapNodes: config.BootstrapNodes.nodes, + ListenAddr: ":0", + NAT: nat.Any(), + MaxPeers: config.MaxPeers, + } + stack, err := node.New(nodeConf) + if err != nil { + return nil, err + } + // Register the Ethereum protocol if requested + if config.EthereumEnabled { + ethConf := ð.Config{ + ChainConfig: &core.ChainConfig{ + HomesteadBlock: big.NewInt(config.EthereumChainConfig.HomesteadBlock), + DAOForkBlock: big.NewInt(config.EthereumChainConfig.DAOForkBlock), + DAOForkSupport: config.EthereumChainConfig.DAOForkSupport, + }, + Genesis: config.EthereumGenesis, + FastSync: true, + DatabaseCache: config.EthereumDatabaseCache, + NetworkId: config.EthereumNetworkID, + GasPrice: new(big.Int).Mul(big.NewInt(20), common.Shannon), + GpoMinGasPrice: new(big.Int).Mul(big.NewInt(20), common.Shannon), + GpoMaxGasPrice: new(big.Int).Mul(big.NewInt(500), common.Shannon), + GpoFullBlockRatio: 80, + GpobaseStepDown: 10, + GpobaseStepUp: 100, + GpobaseCorrectionFactor: 110, + } + if config.EthereumTestnetNonces { + state.StartingNonce = 1048576 // (2**20) + } + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + return eth.New(ctx, ethConf) + }); err != nil { + return nil, fmt.Errorf("ethereum init: %v", err) + } + } + // Register the Whisper protocol if requested + if config.WhisperEnabled { + if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { + return nil, fmt.Errorf("whisper init: %v", err) + } + } + return &Node{stack}, nil +} + +// Start creates a live P2P node and starts running it. +func (n *Node) Start() error { + return n.node.Start() +} + +// Stop terminates a running node along with all it's services. In the node was +// not started, an error is returned. +func (n *Node) Stop() error { + return n.node.Stop() +} + +// GetEthereumClient retrieves a client to access the Ethereum subsystem. +func (n *Node) GetEthereumClient() (*EthereumClient, error) { + rpc, err := n.node.Attach() + if err != nil { + return nil, err + } + return &EthereumClient{ethclient.NewClient(rpc)}, nil +} + +// GetNodeInfo gathers and returns a collection of metadata known about the host. +func (n *Node) GetNodeInfo() *NodeInfo { + return &NodeInfo{n.node.Server().NodeInfo()} +} + +// GetPeersInfo returns an array of metadata objects describing connected peers. +func (n *Node) GetPeersInfo() *PeerInfos { + return &PeerInfos{n.node.Server().PeersInfo()} +} |