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 }