aboutsummaryrefslogtreecommitdiffstats
path: root/mobile/geth.go
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/geth.go')
-rw-r--r--mobile/geth.go188
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 := &eth.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()}
+}