aboutsummaryrefslogblamecommitdiffstats
path: root/mobile/geth.go
blob: af0054cdcd034c9a18e30012a24f3f9f8a928d45 (plain) (tree)

























                                                                                  
                                                

                                                   
                                                  
                                             

                                                 
                                                
                                                           




























                                                                                        



                                                                                             





                                                                                    






                                                                                     
                                                     


                                    
                                                    














                                                                                  
                                                                         






                                                                       


                                                                              

                                            
                                                   
                                                 








                                                                                                                    
         
                                           





                                                      
                                                         
                                                                                               






                                                                                                      

                                                                        
                                                      









                                                                                                   
                                                                                                  
                                                    


                                                                        

                                                            
                                                                                                          







                                                                                          


                                                     
                                                                                                                                           


                                                                       
                                   













                                                                               
                                                                      















                                                                                 
// 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/common"
    "github.com/ethereum/go-ethereum/eth"
    "github.com/ethereum/go-ethereum/ethclient"
    "github.com/ethereum/go-ethereum/ethstats"
    "github.com/ethereum/go-ethereum/les"
    "github.com/ethereum/go-ethereum/node"
    "github.com/ethereum/go-ethereum/p2p/nat"
    "github.com/ethereum/go-ethereum/params"
    "github.com/ethereum/go-ethereum/whisper/whisperv2"
)

// 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

    // EthereumDatabaseCache is the system memory in MB to allocate for database caching.
    // A minimum of 16MB is always reserved.
    EthereumDatabaseCache int

    // EthereumNetStats is a netstats connection string to use to report various
    // chain, transaction and node stats to a monitoring server.
    //
    // It has the form "nodename:secret@host:port"
    EthereumNetStats string

    // 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:        FoundationBootnodes(),
    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) (stack *Node, _ error) {
    // If no or partial configurations were specified, use defaults
    if config == nil {
        config = NewNodeConfig()
    }
    if config.MaxPeers == 0 {
        config.MaxPeers = defaultNodeConfig.MaxPeers
    }
    if config.BootstrapNodes == nil || config.BootstrapNodes.Size() == 0 {
        config.BootstrapNodes = defaultNodeConfig.BootstrapNodes
    }
    // Create the empty networking stack
    nodeConf := &node.Config{
        Name:             clientIdentifier,
        Version:          params.Version,
        DataDir:          datadir,
        KeyStoreDir:      filepath.Join(datadir, "keystore"), // Mobile should never use internal keystores!
        NoDiscovery:      true,
        DiscoveryV5:      true,
        DiscoveryV5Addr:  ":0",
        BootstrapNodesV5: config.BootstrapNodes.nodes,
        ListenAddr:       ":0",
        NAT:              nat.Any(),
        MaxPeers:         config.MaxPeers,
    }
    rawStack, err := node.New(nodeConf)
    if err != nil {
        return nil, err
    }
    // Register the Ethereum protocol if requested
    if config.EthereumEnabled {
        ethConf := &eth.Config{
            ChainConfig: &params.ChainConfig{
                ChainId:        big.NewInt(config.EthereumChainConfig.ChainID),
                HomesteadBlock: big.NewInt(config.EthereumChainConfig.HomesteadBlock),
                DAOForkBlock:   big.NewInt(config.EthereumChainConfig.DAOForkBlock),
                DAOForkSupport: config.EthereumChainConfig.DAOForkSupport,
                EIP150Block:    big.NewInt(config.EthereumChainConfig.EIP150Block),
                EIP150Hash:     config.EthereumChainConfig.EIP150Hash.hash,
                EIP155Block:    big.NewInt(config.EthereumChainConfig.EIP155Block),
                EIP158Block:    big.NewInt(config.EthereumChainConfig.EIP158Block),
            },
            Genesis:                 config.EthereumGenesis,
            LightMode:               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 err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
            return les.New(ctx, ethConf)
        }); err != nil {
            return nil, fmt.Errorf("ethereum init: %v", err)
        }
        // If netstats reporting is requested, do it
        if config.EthereumNetStats != "" {
            if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
                var lesServ *les.LightEthereum
                ctx.Service(&lesServ)

                return ethstats.New(config.EthereumNetStats, nil, lesServ)
            }); err != nil {
                return nil, fmt.Errorf("netstats init: %v", err)
            }
        }
    }
    // Register the Whisper protocol if requested
    if config.WhisperEnabled {
        if err := rawStack.Register(func(*node.ServiceContext) (node.Service, error) { return whisperv2.New(), nil }); err != nil {
            return nil, fmt.Errorf("whisper init: %v", err)
        }
    }
    return &Node{rawStack}, 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() (client *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()}
}