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