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