mobile: initial wrappers for mobile support
This commit is contained in:
188
mobile/geth.go
Normal file
188
mobile/geth.go
Normal file
@ -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()}
|
||||
}
|
Reference in New Issue
Block a user