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