github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/mobile/geth.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:43</date>
    10  //</624342653860843520>
    11  
    12  
    13  //包含节点包中支持客户端节点的所有包装器
    14  //移动平台管理。
    15  
    16  package geth
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  	"path/filepath"
    22  
    23  	"github.com/ethereum/go-ethereum/core"
    24  	"github.com/ethereum/go-ethereum/eth"
    25  	"github.com/ethereum/go-ethereum/eth/downloader"
    26  	"github.com/ethereum/go-ethereum/ethclient"
    27  	"github.com/ethereum/go-ethereum/ethstats"
    28  	"github.com/ethereum/go-ethereum/internal/debug"
    29  	"github.com/ethereum/go-ethereum/les"
    30  	"github.com/ethereum/go-ethereum/node"
    31  	"github.com/ethereum/go-ethereum/p2p"
    32  	"github.com/ethereum/go-ethereum/p2p/nat"
    33  	"github.com/ethereum/go-ethereum/params"
    34  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
    35  )
    36  
    37  //nodeconfig表示对geth进行微调的配置值集合。
    38  //嵌入到移动进程中的节点。可用值是
    39  //Go Ethereum提供的整个API,以减少维护面和开发
    40  //复杂性。
    41  type NodeConfig struct {
    42  //引导节点用于建立与网络其余部分的连接。
    43  	BootstrapNodes *Enodes
    44  
    45  //MaxPeers是可以连接的最大对等数。如果这是
    46  //设置为零,则只有配置的静态和受信任对等方可以连接。
    47  	MaxPeers int
    48  
    49  //ethereumenabled指定节点是否应运行ethereum协议。
    50  	EthereumEnabled bool
    51  
    52  //ethereumnetworkid是以太坊协议用于
    53  //决定是否接受远程对等。
    54  EthereumNetworkID int64 //UIT64实际上是,但Java不能处理…
    55  
    56  //以太坊是用来为区块链播种的Genesis JSON。安
    57  //空的genesis状态相当于使用mainnet的状态。
    58  	EthereumGenesis string
    59  
    60  //ethereumdatabasecache是以MB为单位分配给数据库缓存的系统内存。
    61  //始终保留至少16MB。
    62  	EthereumDatabaseCache int
    63  
    64  //ethereumnetstats是一个netstats连接字符串,用于报告各种
    65  //链、事务和节点状态到监控服务器。
    66  //
    67  //格式为“nodename:secret@host:port”
    68  	EthereumNetStats string
    69  
    70  //WhisperEnabled指定节点是否应运行Whisper协议。
    71  	WhisperEnabled bool
    72  
    73  //pprof服务器的侦听地址。
    74  	PprofAddress string
    75  }
    76  
    77  //defaultnodeconfig包含默认节点配置值(如果全部使用)
    78  //或者用户指定列表中缺少某些字段。
    79  var defaultNodeConfig = &NodeConfig{
    80  	BootstrapNodes:        FoundationBootnodes(),
    81  	MaxPeers:              25,
    82  	EthereumEnabled:       true,
    83  	EthereumNetworkID:     1,
    84  	EthereumDatabaseCache: 16,
    85  }
    86  
    87  //newnodeconfig创建一个新的节点选项集,初始化为默认值。
    88  func NewNodeConfig() *NodeConfig {
    89  	config := *defaultNodeConfig
    90  	return &config
    91  }
    92  
    93  //节点表示一个geth-ethereum节点实例。
    94  type Node struct {
    95  	node *node.Node
    96  }
    97  
    98  //new node创建和配置新的geth节点。
    99  func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) {
   100  //如果未指定或未指定部分配置,请使用默认值
   101  	if config == nil {
   102  		config = NewNodeConfig()
   103  	}
   104  	if config.MaxPeers == 0 {
   105  		config.MaxPeers = defaultNodeConfig.MaxPeers
   106  	}
   107  	if config.BootstrapNodes == nil || config.BootstrapNodes.Size() == 0 {
   108  		config.BootstrapNodes = defaultNodeConfig.BootstrapNodes
   109  	}
   110  
   111  	if config.PprofAddress != "" {
   112  		debug.StartPProf(config.PprofAddress)
   113  	}
   114  
   115  //创建空的网络堆栈
   116  	nodeConf := &node.Config{
   117  		Name:        clientIdentifier,
   118  		Version:     params.VersionWithMeta,
   119  		DataDir:     datadir,
   120  KeyStoreDir: filepath.Join(datadir, "keystore"), //手机不应使用内部密钥库!
   121  		P2P: p2p.Config{
   122  			NoDiscovery:      true,
   123  			DiscoveryV5:      true,
   124  			BootstrapNodesV5: config.BootstrapNodes.nodes,
   125  			ListenAddr:       ":0",
   126  			NAT:              nat.Any(),
   127  			MaxPeers:         config.MaxPeers,
   128  		},
   129  	}
   130  	rawStack, err := node.New(nodeConf)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  
   135  	debug.Memsize.Add("node", rawStack)
   136  
   137  	var genesis *core.Genesis
   138  	if config.EthereumGenesis != "" {
   139  //分析用户提供的Genesis规范(如果不是Mainnet)
   140  		genesis = new(core.Genesis)
   141  		if err := json.Unmarshal([]byte(config.EthereumGenesis), genesis); err != nil {
   142  			return nil, fmt.Errorf("invalid genesis spec: %v", err)
   143  		}
   144  //如果我们有了测试网,那么也要对链配置进行硬编码。
   145  		if config.EthereumGenesis == TestnetGenesis() {
   146  			genesis.Config = params.TestnetChainConfig
   147  			if config.EthereumNetworkID == 1 {
   148  				config.EthereumNetworkID = 3
   149  			}
   150  		}
   151  	}
   152  //如果需要,注册以太坊协议
   153  	if config.EthereumEnabled {
   154  		ethConf := eth.DefaultConfig
   155  		ethConf.Genesis = genesis
   156  		ethConf.SyncMode = downloader.LightSync
   157  		ethConf.NetworkId = uint64(config.EthereumNetworkID)
   158  		ethConf.DatabaseCache = config.EthereumDatabaseCache
   159  		if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
   160  			return les.New(ctx, &ethConf)
   161  		}); err != nil {
   162  			return nil, fmt.Errorf("ethereum init: %v", err)
   163  		}
   164  //如果请求Netstats报告,请执行此操作
   165  		if config.EthereumNetStats != "" {
   166  			if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
   167  				var lesServ *les.LightEthereum
   168  				ctx.Service(&lesServ)
   169  
   170  				return ethstats.New(config.EthereumNetStats, nil, lesServ)
   171  			}); err != nil {
   172  				return nil, fmt.Errorf("netstats init: %v", err)
   173  			}
   174  		}
   175  	}
   176  //如有要求,注册窃听协议
   177  	if config.WhisperEnabled {
   178  		if err := rawStack.Register(func(*node.ServiceContext) (node.Service, error) {
   179  			return whisper.New(&whisper.DefaultConfig), nil
   180  		}); err != nil {
   181  			return nil, fmt.Errorf("whisper init: %v", err)
   182  		}
   183  	}
   184  	return &Node{rawStack}, nil
   185  }
   186  
   187  //start创建一个活动的p2p节点并开始运行它。
   188  func (n *Node) Start() error {
   189  	return n.node.Start()
   190  }
   191  
   192  //stop终止正在运行的节点及其所有服务。如果节点是
   193  //未启动,返回错误。
   194  func (n *Node) Stop() error {
   195  	return n.node.Stop()
   196  }
   197  
   198  //getethereumclient检索客户端以访问ethereum子系统。
   199  func (n *Node) GetEthereumClient() (client *EthereumClient, _ error) {
   200  	rpc, err := n.node.Attach()
   201  	if err != nil {
   202  		return nil, err
   203  	}
   204  	return &EthereumClient{ethclient.NewClient(rpc)}, nil
   205  }
   206  
   207  //getnodeinfo收集并返回有关主机的已知元数据集合。
   208  func (n *Node) GetNodeInfo() *NodeInfo {
   209  	return &NodeInfo{n.node.Server().NodeInfo()}
   210  }
   211  
   212  //GetPeerSinfo返回描述已连接对等端的元数据对象数组。
   213  func (n *Node) GetPeersInfo() *PeerInfos {
   214  	return &PeerInfos{n.node.Server().PeersInfo()}
   215  }
   216