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, ðConf) 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