github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/node/api.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 19:16:40</date> 10 //</624450101963657216> 11 12 13 package node 14 15 import ( 16 "context" 17 "fmt" 18 "strings" 19 "time" 20 21 "github.com/ethereum/go-ethereum/common/hexutil" 22 "github.com/ethereum/go-ethereum/crypto" 23 "github.com/ethereum/go-ethereum/metrics" 24 "github.com/ethereum/go-ethereum/p2p" 25 "github.com/ethereum/go-ethereum/p2p/enode" 26 "github.com/ethereum/go-ethereum/rpc" 27 ) 28 29 //privateAdminAPI是仅公开的管理API方法的集合 30 //通过安全的RPC通道。 31 type PrivateAdminAPI struct { 32 node *Node //此API接口的节点 33 } 34 35 //new private admin api为私有管理方法创建新的api定义 36 //节点本身的。 37 func NewPrivateAdminAPI(node *Node) *PrivateAdminAPI { 38 return &PrivateAdminAPI{node: node} 39 } 40 41 //addpeer请求连接到远程节点,并维护新的 42 //随时连接,即使丢失也要重新连接。 43 func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) { 44 //确保服务器正在运行,否则会失败。 45 server := api.node.Server() 46 if server == nil { 47 return false, ErrNodeStopped 48 } 49 //尝试将URL添加为静态对等,然后返回 50 node, err := enode.ParseV4(url) 51 if err != nil { 52 return false, fmt.Errorf("invalid enode: %v", err) 53 } 54 server.AddPeer(node) 55 return true, nil 56 } 57 58 //如果存在连接,则removepeer从远程节点断开连接 59 func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) { 60 //确保服务器正在运行,否则会失败。 61 server := api.node.Server() 62 if server == nil { 63 return false, ErrNodeStopped 64 } 65 //尝试删除静态对等的URL并返回 66 node, err := enode.ParseV4(url) 67 if err != nil { 68 return false, fmt.Errorf("invalid enode: %v", err) 69 } 70 server.RemovePeer(node) 71 return true, nil 72 } 73 74 //addtrustedpeer允许远程节点始终连接,即使插槽已满 75 func (api *PrivateAdminAPI) AddTrustedPeer(url string) (bool, error) { 76 //确保服务器正在运行,否则会失败。 77 server := api.node.Server() 78 if server == nil { 79 return false, ErrNodeStopped 80 } 81 node, err := enode.ParseV4(url) 82 if err != nil { 83 return false, fmt.Errorf("invalid enode: %v", err) 84 } 85 server.AddTrustedPeer(node) 86 return true, nil 87 } 88 89 //removeTrustedPeer从受信任的对等机集中删除远程节点,但它 90 //不会自动断开。 91 func (api *PrivateAdminAPI) RemoveTrustedPeer(url string) (bool, error) { 92 //确保服务器正在运行,否则会失败。 93 server := api.node.Server() 94 if server == nil { 95 return false, ErrNodeStopped 96 } 97 node, err := enode.ParseV4(url) 98 if err != nil { 99 return false, fmt.Errorf("invalid enode: %v", err) 100 } 101 server.RemoveTrustedPeer(node) 102 return true, nil 103 } 104 105 //PeerEvents创建一个RPC订阅,该订阅从 106 //节点的P2P服务器 107 func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) { 108 //确保服务器正在运行,否则会失败。 109 server := api.node.Server() 110 if server == nil { 111 return nil, ErrNodeStopped 112 } 113 114 //创建订阅 115 notifier, supported := rpc.NotifierFromContext(ctx) 116 if !supported { 117 return nil, rpc.ErrNotificationsUnsupported 118 } 119 rpcSub := notifier.CreateSubscription() 120 121 go func() { 122 events := make(chan *p2p.PeerEvent) 123 sub := server.SubscribeEvents(events) 124 defer sub.Unsubscribe() 125 126 for { 127 select { 128 case event := <-events: 129 notifier.Notify(rpcSub.ID, event) 130 case <-sub.Err(): 131 return 132 case <-rpcSub.Err(): 133 return 134 case <-notifier.Closed(): 135 return 136 } 137 } 138 }() 139 140 return rpcSub, nil 141 } 142 143 //StartRPC启动HTTP RPC API服务器。 144 func (api *PrivateAdminAPI) StartRPC(host *string, port *int, cors *string, apis *string, vhosts *string) (bool, error) { 145 api.node.lock.Lock() 146 defer api.node.lock.Unlock() 147 148 if api.node.httpHandler != nil { 149 return false, fmt.Errorf("HTTP RPC already running on %s", api.node.httpEndpoint) 150 } 151 152 if host == nil { 153 h := DefaultHTTPHost 154 if api.node.config.HTTPHost != "" { 155 h = api.node.config.HTTPHost 156 } 157 host = &h 158 } 159 if port == nil { 160 port = &api.node.config.HTTPPort 161 } 162 163 allowedOrigins := api.node.config.HTTPCors 164 if cors != nil { 165 allowedOrigins = nil 166 for _, origin := range strings.Split(*cors, ",") { 167 allowedOrigins = append(allowedOrigins, strings.TrimSpace(origin)) 168 } 169 } 170 171 allowedVHosts := api.node.config.HTTPVirtualHosts 172 if vhosts != nil { 173 allowedVHosts = nil 174 for _, vhost := range strings.Split(*host, ",") { 175 allowedVHosts = append(allowedVHosts, strings.TrimSpace(vhost)) 176 } 177 } 178 179 modules := api.node.httpWhitelist 180 if apis != nil { 181 modules = nil 182 for _, m := range strings.Split(*apis, ",") { 183 modules = append(modules, strings.TrimSpace(m)) 184 } 185 } 186 187 if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, allowedOrigins, allowedVHosts, api.node.config.HTTPTimeouts); err != nil { 188 return false, err 189 } 190 return true, nil 191 } 192 193 //StopRPC终止已在运行的HTTP RPC API终结点。 194 func (api *PrivateAdminAPI) StopRPC() (bool, error) { 195 api.node.lock.Lock() 196 defer api.node.lock.Unlock() 197 198 if api.node.httpHandler == nil { 199 return false, fmt.Errorf("HTTP RPC not running") 200 } 201 api.node.stopHTTP() 202 return true, nil 203 } 204 205 //startws启动WebSocket RPC API服务器。 206 func (api *PrivateAdminAPI) StartWS(host *string, port *int, allowedOrigins *string, apis *string) (bool, error) { 207 api.node.lock.Lock() 208 defer api.node.lock.Unlock() 209 210 if api.node.wsHandler != nil { 211 return false, fmt.Errorf("WebSocket RPC already running on %s", api.node.wsEndpoint) 212 } 213 214 if host == nil { 215 h := DefaultWSHost 216 if api.node.config.WSHost != "" { 217 h = api.node.config.WSHost 218 } 219 host = &h 220 } 221 if port == nil { 222 port = &api.node.config.WSPort 223 } 224 225 origins := api.node.config.WSOrigins 226 if allowedOrigins != nil { 227 origins = nil 228 for _, origin := range strings.Split(*allowedOrigins, ",") { 229 origins = append(origins, strings.TrimSpace(origin)) 230 } 231 } 232 233 modules := api.node.config.WSModules 234 if apis != nil { 235 modules = nil 236 for _, m := range strings.Split(*apis, ",") { 237 modules = append(modules, strings.TrimSpace(m)) 238 } 239 } 240 241 if err := api.node.startWS(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, origins, api.node.config.WSExposeAll); err != nil { 242 return false, err 243 } 244 return true, nil 245 } 246 247 //stopws终止已在运行的WebSocket RPC API终结点。 248 func (api *PrivateAdminAPI) StopWS() (bool, error) { 249 api.node.lock.Lock() 250 defer api.node.lock.Unlock() 251 252 if api.node.wsHandler == nil { 253 return false, fmt.Errorf("WebSocket RPC not running") 254 } 255 api.node.stopWS() 256 return true, nil 257 } 258 259 //publicAdminAPI是在 260 //安全和不安全的RPC通道。 261 type PublicAdminAPI struct { 262 node *Node //此API接口的节点 263 } 264 265 //NewPublicAdminAPI为公共管理方法创建新的API定义 266 //节点本身的。 267 func NewPublicAdminAPI(node *Node) *PublicAdminAPI { 268 return &PublicAdminAPI{node: node} 269 } 270 271 //对等端检索我们知道的有关每个对等端的所有信息 272 //协议粒度。 273 func (api *PublicAdminAPI) Peers() ([]*p2p.PeerInfo, error) { 274 server := api.node.Server() 275 if server == nil { 276 return nil, ErrNodeStopped 277 } 278 return server.PeersInfo(), nil 279 } 280 281 //nodeinfo检索我们知道的有关主机节点的所有信息 282 //协议粒度。 283 func (api *PublicAdminAPI) NodeInfo() (*p2p.NodeInfo, error) { 284 server := api.node.Server() 285 if server == nil { 286 return nil, ErrNodeStopped 287 } 288 return server.NodeInfo(), nil 289 } 290 291 //datadir检索节点使用的当前数据目录。 292 func (api *PublicAdminAPI) Datadir() string { 293 return api.node.DataDir() 294 } 295 296 //publicDebugAPI是在 297 //安全和不安全的RPC通道。 298 type PublicDebugAPI struct { 299 node *Node //此API接口的节点 300 } 301 302 //NewPublicDebugGapi为公共调试方法创建新的API定义 303 //节点本身的。 304 func NewPublicDebugAPI(node *Node) *PublicDebugAPI { 305 return &PublicDebugAPI{node: node} 306 } 307 308 //度量检索节点收集的所有已知系统度量。 309 func (api *PublicDebugAPI) Metrics(raw bool) (map[string]interface{}, error) { 310 //创建速率格式化程序 311 units := []string{"", "K", "M", "G", "T", "E", "P"} 312 round := func(value float64, prec int) string { 313 unit := 0 314 for value >= 1000 { 315 unit, value, prec = unit+1, value/1000, 2 316 } 317 return fmt.Sprintf(fmt.Sprintf("%%.%df%s", prec, units[unit]), value) 318 } 319 format := func(total float64, rate float64) string { 320 return fmt.Sprintf("%s (%s/s)", round(total, 0), round(rate, 2)) 321 } 322 //迭代所有度量,现在只转储 323 counters := make(map[string]interface{}) 324 metrics.DefaultRegistry.Each(func(name string, metric interface{}) { 325 //创建或检索此度量的计数器层次结构 326 root, parts := counters, strings.Split(name, "/") 327 for _, part := range parts[:len(parts)-1] { 328 if _, ok := root[part]; !ok { 329 root[part] = make(map[string]interface{}) 330 } 331 root = root[part].(map[string]interface{}) 332 } 333 name = parts[len(parts)-1] 334 335 //在计数器中填入度量详细信息,如果需要,请格式化。 336 if raw { 337 switch metric := metric.(type) { 338 case metrics.Counter: 339 root[name] = map[string]interface{}{ 340 "Overall": float64(metric.Count()), 341 } 342 343 case metrics.Meter: 344 root[name] = map[string]interface{}{ 345 "AvgRate01Min": metric.Rate1(), 346 "AvgRate05Min": metric.Rate5(), 347 "AvgRate15Min": metric.Rate15(), 348 "MeanRate": metric.RateMean(), 349 "Overall": float64(metric.Count()), 350 } 351 352 case metrics.Timer: 353 root[name] = map[string]interface{}{ 354 "AvgRate01Min": metric.Rate1(), 355 "AvgRate05Min": metric.Rate5(), 356 "AvgRate15Min": metric.Rate15(), 357 "MeanRate": metric.RateMean(), 358 "Overall": float64(metric.Count()), 359 "Percentiles": map[string]interface{}{ 360 "5": metric.Percentile(0.05), 361 "20": metric.Percentile(0.2), 362 "50": metric.Percentile(0.5), 363 "80": metric.Percentile(0.8), 364 "95": metric.Percentile(0.95), 365 }, 366 } 367 368 case metrics.ResettingTimer: 369 t := metric.Snapshot() 370 ps := t.Percentiles([]float64{5, 20, 50, 80, 95}) 371 root[name] = map[string]interface{}{ 372 "Measurements": len(t.Values()), 373 "Mean": t.Mean(), 374 "Percentiles": map[string]interface{}{ 375 "5": ps[0], 376 "20": ps[1], 377 "50": ps[2], 378 "80": ps[3], 379 "95": ps[4], 380 }, 381 } 382 383 default: 384 root[name] = "Unknown metric type" 385 } 386 } else { 387 switch metric := metric.(type) { 388 case metrics.Counter: 389 root[name] = map[string]interface{}{ 390 "Overall": float64(metric.Count()), 391 } 392 393 case metrics.Meter: 394 root[name] = map[string]interface{}{ 395 "Avg01Min": format(metric.Rate1()*60, metric.Rate1()), 396 "Avg05Min": format(metric.Rate5()*300, metric.Rate5()), 397 "Avg15Min": format(metric.Rate15()*900, metric.Rate15()), 398 "Overall": format(float64(metric.Count()), metric.RateMean()), 399 } 400 401 case metrics.Timer: 402 root[name] = map[string]interface{}{ 403 "Avg01Min": format(metric.Rate1()*60, metric.Rate1()), 404 "Avg05Min": format(metric.Rate5()*300, metric.Rate5()), 405 "Avg15Min": format(metric.Rate15()*900, metric.Rate15()), 406 "Overall": format(float64(metric.Count()), metric.RateMean()), 407 "Maximum": time.Duration(metric.Max()).String(), 408 "Minimum": time.Duration(metric.Min()).String(), 409 "Percentiles": map[string]interface{}{ 410 "5": time.Duration(metric.Percentile(0.05)).String(), 411 "20": time.Duration(metric.Percentile(0.2)).String(), 412 "50": time.Duration(metric.Percentile(0.5)).String(), 413 "80": time.Duration(metric.Percentile(0.8)).String(), 414 "95": time.Duration(metric.Percentile(0.95)).String(), 415 }, 416 } 417 418 case metrics.ResettingTimer: 419 t := metric.Snapshot() 420 ps := t.Percentiles([]float64{5, 20, 50, 80, 95}) 421 root[name] = map[string]interface{}{ 422 "Measurements": len(t.Values()), 423 "Mean": time.Duration(t.Mean()).String(), 424 "Percentiles": map[string]interface{}{ 425 "5": time.Duration(ps[0]).String(), 426 "20": time.Duration(ps[1]).String(), 427 "50": time.Duration(ps[2]).String(), 428 "80": time.Duration(ps[3]).String(), 429 "95": time.Duration(ps[4]).String(), 430 }, 431 } 432 433 default: 434 root[name] = "Unknown metric type" 435 } 436 } 437 }) 438 return counters, nil 439 } 440 441 //publicWeb3API提供helper实用程序 442 type PublicWeb3API struct { 443 stack *Node 444 } 445 446 //NewPublicWeb3API创建新的Web3Service实例 447 func NewPublicWeb3API(stack *Node) *PublicWeb3API { 448 return &PublicWeb3API{stack} 449 } 450 451 //clientversion返回节点名 452 func (s *PublicWeb3API) ClientVersion() string { 453 return s.stack.Server().Name 454 } 455 456 //sha3对输入应用ethereum sha3实现。 457 //它假定输入是十六进制编码的。 458 func (s *PublicWeb3API) Sha3(input hexutil.Bytes) hexutil.Bytes { 459 return crypto.Keccak256(input) 460 } 461