github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/simulations/adapters/inproc.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2017 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package adapters
    26  
    27  import (
    28  	"errors"
    29  	"fmt"
    30  	"math"
    31  	"net"
    32  	"sync"
    33  
    34  	"github.com/ethereum/go-ethereum/event"
    35  	"github.com/ethereum/go-ethereum/log"
    36  	"github.com/ethereum/go-ethereum/node"
    37  	"github.com/ethereum/go-ethereum/p2p"
    38  	"github.com/ethereum/go-ethereum/p2p/discover"
    39  	"github.com/ethereum/go-ethereum/p2p/simulations/pipes"
    40  	"github.com/ethereum/go-ethereum/rpc"
    41  )
    42  
    43  //Simadapter是一个节点适配器,用于创建内存中的模拟节点和
    44  //使用net.pipe连接它们
    45  type SimAdapter struct {
    46  	pipe     func() (net.Conn, net.Conn, error)
    47  	mtx      sync.RWMutex
    48  	nodes    map[discover.NodeID]*SimNode
    49  	services map[string]ServiceFunc
    50  }
    51  
    52  //newsimadapter创建一个能够在内存中运行的simadapter
    53  //运行任何给定服务(运行在
    54  //特定节点将传递给nodeconfig中的newnode函数)
    55  //适配器使用net.pipe进行内存中模拟的网络连接
    56  func NewSimAdapter(services map[string]ServiceFunc) *SimAdapter {
    57  	return &SimAdapter{
    58  		pipe:     pipes.NetPipe,
    59  		nodes:    make(map[discover.NodeID]*SimNode),
    60  		services: services,
    61  	}
    62  }
    63  
    64  func NewTCPAdapter(services map[string]ServiceFunc) *SimAdapter {
    65  	return &SimAdapter{
    66  		pipe:     pipes.TCPPipe,
    67  		nodes:    make(map[discover.NodeID]*SimNode),
    68  		services: services,
    69  	}
    70  }
    71  
    72  //name返回用于日志记录的适配器的名称
    73  func (s *SimAdapter) Name() string {
    74  	return "sim-adapter"
    75  }
    76  
    77  //newnode使用给定的配置返回新的simnode
    78  func (s *SimAdapter) NewNode(config *NodeConfig) (Node, error) {
    79  	s.mtx.Lock()
    80  	defer s.mtx.Unlock()
    81  
    82  //检查ID为的节点是否已存在
    83  	id := config.ID
    84  	if _, exists := s.nodes[id]; exists {
    85  		return nil, fmt.Errorf("node already exists: %s", id)
    86  	}
    87  
    88  //检查服务是否有效
    89  	if len(config.Services) == 0 {
    90  		return nil, errors.New("node must have at least one service")
    91  	}
    92  	for _, service := range config.Services {
    93  		if _, exists := s.services[service]; !exists {
    94  			return nil, fmt.Errorf("unknown node service %q", service)
    95  		}
    96  	}
    97  
    98  	n, err := node.New(&node.Config{
    99  		P2P: p2p.Config{
   100  			PrivateKey:      config.PrivateKey,
   101  			MaxPeers:        math.MaxInt32,
   102  			NoDiscovery:     true,
   103  			Dialer:          s,
   104  			EnableMsgEvents: config.EnableMsgEvents,
   105  		},
   106  		NoUSB:  true,
   107  		Logger: log.New("node.id", id.String()),
   108  	})
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	simNode := &SimNode{
   114  		ID:      id,
   115  		config:  config,
   116  		node:    n,
   117  		adapter: s,
   118  		running: make(map[string]node.Service),
   119  	}
   120  	s.nodes[id] = simNode
   121  	return simNode, nil
   122  }
   123  
   124  //拨号通过使用连接到节点来实现p2p.nodeadialer接口。
   125  //内存中的net.pipe
   126  func (s *SimAdapter) Dial(dest *discover.Node) (conn net.Conn, err error) {
   127  	node, ok := s.GetNode(dest.ID)
   128  	if !ok {
   129  		return nil, fmt.Errorf("unknown node: %s", dest.ID)
   130  	}
   131  	srv := node.Server()
   132  	if srv == nil {
   133  		return nil, fmt.Errorf("node not running: %s", dest.ID)
   134  	}
   135  //simadapter.pipe是net.pipe(newsimadapter)
   136  	pipe1, pipe2, err := s.pipe()
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  //这是模拟的“倾听”
   141  //异步调用拨号目的地节点的P2P服务器
   142  //在“监听”端建立连接
   143  	go srv.SetupConn(pipe1, 0, nil)
   144  	return pipe2, nil
   145  }
   146  
   147  //dialrpc通过创建内存中的rpc来实现rpcdialer接口
   148  //给定节点的客户端
   149  func (s *SimAdapter) DialRPC(id discover.NodeID) (*rpc.Client, error) {
   150  	node, ok := s.GetNode(id)
   151  	if !ok {
   152  		return nil, fmt.Errorf("unknown node: %s", id)
   153  	}
   154  	handler, err := node.node.RPCHandler()
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	return rpc.DialInProc(handler), nil
   159  }
   160  
   161  //getnode返回具有给定ID的节点(如果存在)
   162  func (s *SimAdapter) GetNode(id discover.NodeID) (*SimNode, bool) {
   163  	s.mtx.RLock()
   164  	defer s.mtx.RUnlock()
   165  	node, ok := s.nodes[id]
   166  	return node, ok
   167  }
   168  
   169  //Simnode是一个内存中的模拟节点,它使用
   170  //net.pipe(参见simadapter.dial),直接在上面运行devp2p协议
   171  //管
   172  type SimNode struct {
   173  	lock         sync.RWMutex
   174  	ID           discover.NodeID
   175  	config       *NodeConfig
   176  	adapter      *SimAdapter
   177  	node         *node.Node
   178  	running      map[string]node.Service
   179  	client       *rpc.Client
   180  	registerOnce sync.Once
   181  }
   182  
   183  //addr返回节点的发现地址
   184  func (sn *SimNode) Addr() []byte {
   185  	return []byte(sn.Node().String())
   186  }
   187  
   188  //node返回表示simnode的discover.node
   189  func (sn *SimNode) Node() *discover.Node {
   190  	return discover.NewNode(sn.ID, net.IP{127, 0, 0, 1}, 30303, 30303)
   191  }
   192  
   193  //客户端返回一个rpc.client,可用于与
   194  //基础服务(节点启动后设置)
   195  func (sn *SimNode) Client() (*rpc.Client, error) {
   196  	sn.lock.RLock()
   197  	defer sn.lock.RUnlock()
   198  	if sn.client == nil {
   199  		return nil, errors.New("node not started")
   200  	}
   201  	return sn.client, nil
   202  }
   203  
   204  //serverpc通过创建一个
   205  //节点的RPC服务器的内存中客户端
   206  func (sn *SimNode) ServeRPC(conn net.Conn) error {
   207  	handler, err := sn.node.RPCHandler()
   208  	if err != nil {
   209  		return err
   210  	}
   211  	handler.ServeCodec(rpc.NewJSONCodec(conn), rpc.OptionMethodInvocation|rpc.OptionSubscriptions)
   212  	return nil
   213  }
   214  
   215  //快照通过调用
   216  //模拟快照RPC方法
   217  func (sn *SimNode) Snapshots() (map[string][]byte, error) {
   218  	sn.lock.RLock()
   219  	services := make(map[string]node.Service, len(sn.running))
   220  	for name, service := range sn.running {
   221  		services[name] = service
   222  	}
   223  	sn.lock.RUnlock()
   224  	if len(services) == 0 {
   225  		return nil, errors.New("no running services")
   226  	}
   227  	snapshots := make(map[string][]byte)
   228  	for name, service := range services {
   229  		if s, ok := service.(interface {
   230  			Snapshot() ([]byte, error)
   231  		}); ok {
   232  			snap, err := s.Snapshot()
   233  			if err != nil {
   234  				return nil, err
   235  			}
   236  			snapshots[name] = snap
   237  		}
   238  	}
   239  	return snapshots, nil
   240  }
   241  
   242  //start注册服务并启动底层devp2p节点
   243  func (sn *SimNode) Start(snapshots map[string][]byte) error {
   244  	newService := func(name string) func(ctx *node.ServiceContext) (node.Service, error) {
   245  		return func(nodeCtx *node.ServiceContext) (node.Service, error) {
   246  			ctx := &ServiceContext{
   247  				RPCDialer:   sn.adapter,
   248  				NodeContext: nodeCtx,
   249  				Config:      sn.config,
   250  			}
   251  			if snapshots != nil {
   252  				ctx.Snapshot = snapshots[name]
   253  			}
   254  			serviceFunc := sn.adapter.services[name]
   255  			service, err := serviceFunc(ctx)
   256  			if err != nil {
   257  				return nil, err
   258  			}
   259  			sn.running[name] = service
   260  			return service, nil
   261  		}
   262  	}
   263  
   264  //确保在节点的情况下只注册一次服务
   265  //停止然后重新启动
   266  	var regErr error
   267  	sn.registerOnce.Do(func() {
   268  		for _, name := range sn.config.Services {
   269  			if err := sn.node.Register(newService(name)); err != nil {
   270  				regErr = err
   271  				break
   272  			}
   273  		}
   274  	})
   275  	if regErr != nil {
   276  		return regErr
   277  	}
   278  
   279  	if err := sn.node.Start(); err != nil {
   280  		return err
   281  	}
   282  
   283  //创建进程内RPC客户端
   284  	handler, err := sn.node.RPCHandler()
   285  	if err != nil {
   286  		return err
   287  	}
   288  
   289  	sn.lock.Lock()
   290  	sn.client = rpc.DialInProc(handler)
   291  	sn.lock.Unlock()
   292  
   293  	return nil
   294  }
   295  
   296  //stop关闭RPC客户端并停止底层devp2p节点
   297  func (sn *SimNode) Stop() error {
   298  	sn.lock.Lock()
   299  	if sn.client != nil {
   300  		sn.client.Close()
   301  		sn.client = nil
   302  	}
   303  	sn.lock.Unlock()
   304  	return sn.node.Stop()
   305  }
   306  
   307  //服务按名称返回正在运行的服务
   308  func (sn *SimNode) Service(name string) node.Service {
   309  	sn.lock.RLock()
   310  	defer sn.lock.RUnlock()
   311  	return sn.running[name]
   312  }
   313  
   314  //服务返回基础服务的副本
   315  func (sn *SimNode) Services() []node.Service {
   316  	sn.lock.RLock()
   317  	defer sn.lock.RUnlock()
   318  	services := make([]node.Service, 0, len(sn.running))
   319  	for _, service := range sn.running {
   320  		services = append(services, service)
   321  	}
   322  	return services
   323  }
   324  
   325  //ServiceMap按基础服务的名称返回映射
   326  func (sn *SimNode) ServiceMap() map[string]node.Service {
   327  	sn.lock.RLock()
   328  	defer sn.lock.RUnlock()
   329  	services := make(map[string]node.Service, len(sn.running))
   330  	for name, service := range sn.running {
   331  		services[name] = service
   332  	}
   333  	return services
   334  }
   335  
   336  //服务器返回基础p2p.server
   337  func (sn *SimNode) Server() *p2p.Server {
   338  	return sn.node.Server()
   339  }
   340  
   341  //subscribeEvents订阅来自
   342  //底层p2p.server
   343  func (sn *SimNode) SubscribeEvents(ch chan *p2p.PeerEvent) event.Subscription {
   344  	srv := sn.Server()
   345  	if srv == nil {
   346  		panic("node not running")
   347  	}
   348  	return srv.SubscribeEvents(ch)
   349  }
   350  
   351  //nodeinfo返回有关节点的信息
   352  func (sn *SimNode) NodeInfo() *p2p.NodeInfo {
   353  	server := sn.Server()
   354  	if server == nil {
   355  		return &p2p.NodeInfo{
   356  			ID:    sn.ID.String(),
   357  			Enode: sn.Node().String(),
   358  		}
   359  	}
   360  	return server.NodeInfo()
   361  }
   362  
   363  func setSocketBuffer(conn net.Conn, socketReadBuffer int, socketWriteBuffer int) error {
   364  	if v, ok := conn.(*net.UnixConn); ok {
   365  		err := v.SetReadBuffer(socketReadBuffer)
   366  		if err != nil {
   367  			return err
   368  		}
   369  		err = v.SetWriteBuffer(socketWriteBuffer)
   370  		if err != nil {
   371  			return err
   372  		}
   373  	}
   374  	return nil
   375  }