github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/network/p2p/simulations/network.go (about) 1 package simulations 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "io" 9 "sync" 10 "time" 11 12 "github.com/neatlab/neatio/chain/log" 13 "github.com/neatlab/neatio/network/p2p" 14 "github.com/neatlab/neatio/network/p2p/discover" 15 "github.com/neatlab/neatio/network/p2p/simulations/adapters" 16 "github.com/neatlab/neatio/utilities/event" 17 ) 18 19 var dialBanTimeout = 200 * time.Millisecond 20 21 type NetworkConfig struct { 22 ID string `json:"id"` 23 DefaultService string `json:"default_service,omitempty"` 24 } 25 26 type Network struct { 27 NetworkConfig 28 29 Nodes []*Node `json:"nodes"` 30 nodeMap map[discover.NodeID]int 31 32 Conns []*Conn `json:"conns"` 33 connMap map[string]int 34 35 nodeAdapter adapters.NodeAdapter 36 events event.Feed 37 lock sync.RWMutex 38 quitc chan struct{} 39 } 40 41 func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network { 42 return &Network{ 43 NetworkConfig: *conf, 44 nodeAdapter: nodeAdapter, 45 nodeMap: make(map[discover.NodeID]int), 46 connMap: make(map[string]int), 47 quitc: make(chan struct{}), 48 } 49 } 50 51 func (self *Network) Events() *event.Feed { 52 return &self.events 53 } 54 55 func (self *Network) NewNode() (*Node, error) { 56 conf := adapters.RandomNodeConfig() 57 conf.Services = []string{self.DefaultService} 58 return self.NewNodeWithConfig(conf) 59 } 60 61 func (self *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) { 62 self.lock.Lock() 63 defer self.lock.Unlock() 64 65 if conf.ID == (discover.NodeID{}) { 66 c := adapters.RandomNodeConfig() 67 conf.ID = c.ID 68 conf.PrivateKey = c.PrivateKey 69 } 70 id := conf.ID 71 if conf.Reachable == nil { 72 conf.Reachable = func(otherID discover.NodeID) bool { 73 _, err := self.InitConn(conf.ID, otherID) 74 return err == nil 75 } 76 } 77 78 if conf.Name == "" { 79 conf.Name = fmt.Sprintf("node%02d", len(self.Nodes)+1) 80 } 81 82 if node := self.getNode(id); node != nil { 83 return nil, fmt.Errorf("node with ID %q already exists", id) 84 } 85 if node := self.getNodeByName(conf.Name); node != nil { 86 return nil, fmt.Errorf("node with name %q already exists", conf.Name) 87 } 88 89 if len(conf.Services) == 0 { 90 conf.Services = []string{self.DefaultService} 91 } 92 93 adapterNode, err := self.nodeAdapter.NewNode(conf) 94 if err != nil { 95 return nil, err 96 } 97 node := &Node{ 98 Node: adapterNode, 99 Config: conf, 100 } 101 log.Trace(fmt.Sprintf("node %v created", id)) 102 self.nodeMap[id] = len(self.Nodes) 103 self.Nodes = append(self.Nodes, node) 104 105 self.events.Send(ControlEvent(node)) 106 107 return node, nil 108 } 109 110 func (self *Network) Config() *NetworkConfig { 111 return &self.NetworkConfig 112 } 113 114 func (self *Network) StartAll() error { 115 for _, node := range self.Nodes { 116 if node.Up { 117 continue 118 } 119 if err := self.Start(node.ID()); err != nil { 120 return err 121 } 122 } 123 return nil 124 } 125 126 func (self *Network) StopAll() error { 127 for _, node := range self.Nodes { 128 if !node.Up { 129 continue 130 } 131 if err := self.Stop(node.ID()); err != nil { 132 return err 133 } 134 } 135 return nil 136 } 137 138 func (self *Network) Start(id discover.NodeID) error { 139 return self.startWithSnapshots(id, nil) 140 } 141 142 func (self *Network) startWithSnapshots(id discover.NodeID, snapshots map[string][]byte) error { 143 node := self.GetNode(id) 144 if node == nil { 145 return fmt.Errorf("node %v does not exist", id) 146 } 147 if node.Up { 148 return fmt.Errorf("node %v already up", id) 149 } 150 log.Trace(fmt.Sprintf("starting node %v: %v using %v", id, node.Up, self.nodeAdapter.Name())) 151 if err := node.Start(snapshots); err != nil { 152 log.Warn(fmt.Sprintf("start up failed: %v", err)) 153 return err 154 } 155 node.Up = true 156 log.Info(fmt.Sprintf("started node %v: %v", id, node.Up)) 157 158 self.events.Send(NewEvent(node)) 159 160 client, err := node.Client() 161 if err != nil { 162 return fmt.Errorf("error getting rpc client for node %v: %s", id, err) 163 } 164 events := make(chan *p2p.PeerEvent) 165 sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") 166 if err != nil { 167 return fmt.Errorf("error getting peer events for node %v: %s", id, err) 168 } 169 go self.watchPeerEvents(id, events, sub) 170 return nil 171 } 172 173 func (self *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEvent, sub event.Subscription) { 174 defer func() { 175 sub.Unsubscribe() 176 177 self.lock.Lock() 178 node := self.getNode(id) 179 node.Up = false 180 self.lock.Unlock() 181 self.events.Send(NewEvent(node)) 182 }() 183 for { 184 select { 185 case event, ok := <-events: 186 if !ok { 187 return 188 } 189 peer := event.Peer 190 switch event.Type { 191 192 case p2p.PeerEventTypeAdd: 193 self.DidConnect(id, peer) 194 195 case p2p.PeerEventTypeDrop: 196 self.DidDisconnect(id, peer) 197 198 case p2p.PeerEventTypeMsgSend: 199 self.DidSend(id, peer, event.Protocol, *event.MsgCode) 200 201 case p2p.PeerEventTypeMsgRecv: 202 self.DidReceive(peer, id, event.Protocol, *event.MsgCode) 203 204 } 205 206 case err := <-sub.Err(): 207 if err != nil { 208 log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err) 209 } 210 return 211 } 212 } 213 } 214 215 func (self *Network) Stop(id discover.NodeID) error { 216 node := self.GetNode(id) 217 if node == nil { 218 return fmt.Errorf("node %v does not exist", id) 219 } 220 if !node.Up { 221 return fmt.Errorf("node %v already down", id) 222 } 223 if err := node.Stop(); err != nil { 224 return err 225 } 226 node.Up = false 227 log.Info(fmt.Sprintf("stop node %v: %v", id, node.Up)) 228 229 self.events.Send(ControlEvent(node)) 230 return nil 231 } 232 233 func (self *Network) Connect(oneID, otherID discover.NodeID) error { 234 log.Debug(fmt.Sprintf("connecting %s to %s", oneID, otherID)) 235 conn, err := self.InitConn(oneID, otherID) 236 if err != nil { 237 return err 238 } 239 client, err := conn.one.Client() 240 if err != nil { 241 return err 242 } 243 self.events.Send(ControlEvent(conn)) 244 return client.Call(nil, "admin_addPeer", string(conn.other.Addr())) 245 } 246 247 func (self *Network) Disconnect(oneID, otherID discover.NodeID) error { 248 conn := self.GetConn(oneID, otherID) 249 if conn == nil { 250 return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID) 251 } 252 if !conn.Up { 253 return fmt.Errorf("%v and %v already disconnected", oneID, otherID) 254 } 255 client, err := conn.one.Client() 256 if err != nil { 257 return err 258 } 259 self.events.Send(ControlEvent(conn)) 260 return client.Call(nil, "admin_removePeer", string(conn.other.Addr())) 261 } 262 263 func (self *Network) DidConnect(one, other discover.NodeID) error { 264 conn, err := self.GetOrCreateConn(one, other) 265 if err != nil { 266 return fmt.Errorf("connection between %v and %v does not exist", one, other) 267 } 268 if conn.Up { 269 return fmt.Errorf("%v and %v already connected", one, other) 270 } 271 conn.Up = true 272 self.events.Send(NewEvent(conn)) 273 return nil 274 } 275 276 func (self *Network) DidDisconnect(one, other discover.NodeID) error { 277 conn := self.GetConn(one, other) 278 if conn == nil { 279 return fmt.Errorf("connection between %v and %v does not exist", one, other) 280 } 281 if !conn.Up { 282 return fmt.Errorf("%v and %v already disconnected", one, other) 283 } 284 conn.Up = false 285 conn.initiated = time.Now().Add(-dialBanTimeout) 286 self.events.Send(NewEvent(conn)) 287 return nil 288 } 289 290 func (self *Network) DidSend(sender, receiver discover.NodeID, proto string, code uint64) error { 291 msg := &Msg{ 292 One: sender, 293 Other: receiver, 294 Protocol: proto, 295 Code: code, 296 Received: false, 297 } 298 self.events.Send(NewEvent(msg)) 299 return nil 300 } 301 302 func (self *Network) DidReceive(sender, receiver discover.NodeID, proto string, code uint64) error { 303 msg := &Msg{ 304 One: sender, 305 Other: receiver, 306 Protocol: proto, 307 Code: code, 308 Received: true, 309 } 310 self.events.Send(NewEvent(msg)) 311 return nil 312 } 313 314 func (self *Network) GetNode(id discover.NodeID) *Node { 315 self.lock.Lock() 316 defer self.lock.Unlock() 317 return self.getNode(id) 318 } 319 320 func (self *Network) GetNodeByName(name string) *Node { 321 self.lock.Lock() 322 defer self.lock.Unlock() 323 return self.getNodeByName(name) 324 } 325 326 func (self *Network) getNode(id discover.NodeID) *Node { 327 i, found := self.nodeMap[id] 328 if !found { 329 return nil 330 } 331 return self.Nodes[i] 332 } 333 334 func (self *Network) getNodeByName(name string) *Node { 335 for _, node := range self.Nodes { 336 if node.Config.Name == name { 337 return node 338 } 339 } 340 return nil 341 } 342 343 func (self *Network) GetNodes() (nodes []*Node) { 344 self.lock.Lock() 345 defer self.lock.Unlock() 346 347 nodes = append(nodes, self.Nodes...) 348 return nodes 349 } 350 351 func (self *Network) GetConn(oneID, otherID discover.NodeID) *Conn { 352 self.lock.Lock() 353 defer self.lock.Unlock() 354 return self.getConn(oneID, otherID) 355 } 356 357 func (self *Network) GetOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) { 358 self.lock.Lock() 359 defer self.lock.Unlock() 360 return self.getOrCreateConn(oneID, otherID) 361 } 362 363 func (self *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) { 364 if conn := self.getConn(oneID, otherID); conn != nil { 365 return conn, nil 366 } 367 368 one := self.getNode(oneID) 369 if one == nil { 370 return nil, fmt.Errorf("node %v does not exist", oneID) 371 } 372 other := self.getNode(otherID) 373 if other == nil { 374 return nil, fmt.Errorf("node %v does not exist", otherID) 375 } 376 conn := &Conn{ 377 One: oneID, 378 Other: otherID, 379 one: one, 380 other: other, 381 } 382 label := ConnLabel(oneID, otherID) 383 self.connMap[label] = len(self.Conns) 384 self.Conns = append(self.Conns, conn) 385 return conn, nil 386 } 387 388 func (self *Network) getConn(oneID, otherID discover.NodeID) *Conn { 389 label := ConnLabel(oneID, otherID) 390 i, found := self.connMap[label] 391 if !found { 392 return nil 393 } 394 return self.Conns[i] 395 } 396 397 func (self *Network) InitConn(oneID, otherID discover.NodeID) (*Conn, error) { 398 self.lock.Lock() 399 defer self.lock.Unlock() 400 if oneID == otherID { 401 return nil, fmt.Errorf("refusing to connect to self %v", oneID) 402 } 403 conn, err := self.getOrCreateConn(oneID, otherID) 404 if err != nil { 405 return nil, err 406 } 407 if time.Since(conn.initiated) < dialBanTimeout { 408 return nil, fmt.Errorf("connection between %v and %v recently attempted", oneID, otherID) 409 } 410 if conn.Up { 411 return nil, fmt.Errorf("%v and %v already connected", oneID, otherID) 412 } 413 err = conn.nodesUp() 414 if err != nil { 415 return nil, fmt.Errorf("nodes not up: %v", err) 416 } 417 conn.initiated = time.Now() 418 return conn, nil 419 } 420 421 func (self *Network) Shutdown() { 422 for _, node := range self.Nodes { 423 log.Debug(fmt.Sprintf("stopping node %s", node.ID().TerminalString())) 424 if err := node.Stop(); err != nil { 425 log.Warn(fmt.Sprintf("error stopping node %s", node.ID().TerminalString()), "err", err) 426 } 427 428 if closer, ok := node.Node.(io.Closer); ok { 429 if err := closer.Close(); err != nil { 430 log.Warn("Can't close node", "id", node.ID(), "err", err) 431 } 432 } 433 } 434 close(self.quitc) 435 } 436 437 func (self *Network) Reset() { 438 self.lock.Lock() 439 defer self.lock.Unlock() 440 441 self.connMap = make(map[string]int) 442 self.nodeMap = make(map[discover.NodeID]int) 443 444 self.Nodes = nil 445 self.Conns = nil 446 } 447 448 type Node struct { 449 adapters.Node `json:"-"` 450 451 Config *adapters.NodeConfig `json:"config"` 452 453 Up bool `json:"up"` 454 } 455 456 func (self *Node) ID() discover.NodeID { 457 return self.Config.ID 458 } 459 460 func (self *Node) String() string { 461 return fmt.Sprintf("Node %v", self.ID().TerminalString()) 462 } 463 464 func (self *Node) NodeInfo() *p2p.NodeInfo { 465 466 if self.Node == nil { 467 return nil 468 } 469 info := self.Node.NodeInfo() 470 info.Name = self.Config.Name 471 return info 472 } 473 474 func (self *Node) MarshalJSON() ([]byte, error) { 475 return json.Marshal(struct { 476 Info *p2p.NodeInfo `json:"info,omitempty"` 477 Config *adapters.NodeConfig `json:"config,omitempty"` 478 Up bool `json:"up"` 479 }{ 480 Info: self.NodeInfo(), 481 Config: self.Config, 482 Up: self.Up, 483 }) 484 } 485 486 type Conn struct { 487 One discover.NodeID `json:"one"` 488 489 Other discover.NodeID `json:"other"` 490 491 Up bool `json:"up"` 492 493 initiated time.Time 494 495 one *Node 496 other *Node 497 } 498 499 func (self *Conn) nodesUp() error { 500 if !self.one.Up { 501 return fmt.Errorf("one %v is not up", self.One) 502 } 503 if !self.other.Up { 504 return fmt.Errorf("other %v is not up", self.Other) 505 } 506 return nil 507 } 508 509 func (self *Conn) String() string { 510 return fmt.Sprintf("Conn %v->%v", self.One.TerminalString(), self.Other.TerminalString()) 511 } 512 513 type Msg struct { 514 One discover.NodeID `json:"one"` 515 Other discover.NodeID `json:"other"` 516 Protocol string `json:"protocol"` 517 Code uint64 `json:"code"` 518 Received bool `json:"received"` 519 } 520 521 func (self *Msg) String() string { 522 return fmt.Sprintf("Msg(%d) %v->%v", self.Code, self.One.TerminalString(), self.Other.TerminalString()) 523 } 524 525 func ConnLabel(source, target discover.NodeID) string { 526 var first, second discover.NodeID 527 if bytes.Compare(source.Bytes(), target.Bytes()) > 0 { 528 first = target 529 second = source 530 } else { 531 first = source 532 second = target 533 } 534 return fmt.Sprintf("%v-%v", first, second) 535 } 536 537 type Snapshot struct { 538 Nodes []NodeSnapshot `json:"nodes,omitempty"` 539 Conns []Conn `json:"conns,omitempty"` 540 } 541 542 type NodeSnapshot struct { 543 Node Node `json:"node,omitempty"` 544 545 Snapshots map[string][]byte `json:"snapshots,omitempty"` 546 } 547 548 func (self *Network) Snapshot() (*Snapshot, error) { 549 self.lock.Lock() 550 defer self.lock.Unlock() 551 snap := &Snapshot{ 552 Nodes: make([]NodeSnapshot, len(self.Nodes)), 553 Conns: make([]Conn, len(self.Conns)), 554 } 555 for i, node := range self.Nodes { 556 snap.Nodes[i] = NodeSnapshot{Node: *node} 557 if !node.Up { 558 continue 559 } 560 snapshots, err := node.Snapshots() 561 if err != nil { 562 return nil, err 563 } 564 snap.Nodes[i].Snapshots = snapshots 565 } 566 for i, conn := range self.Conns { 567 snap.Conns[i] = *conn 568 } 569 return snap, nil 570 } 571 572 func (self *Network) Load(snap *Snapshot) error { 573 for _, n := range snap.Nodes { 574 if _, err := self.NewNodeWithConfig(n.Node.Config); err != nil { 575 return err 576 } 577 if !n.Node.Up { 578 continue 579 } 580 if err := self.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil { 581 return err 582 } 583 } 584 for _, conn := range snap.Conns { 585 586 if !self.GetNode(conn.One).Up || !self.GetNode(conn.Other).Up { 587 588 continue 589 } 590 if err := self.Connect(conn.One, conn.Other); err != nil { 591 return err 592 } 593 } 594 return nil 595 } 596 597 func (self *Network) Subscribe(events chan *Event) { 598 for { 599 select { 600 case event, ok := <-events: 601 if !ok { 602 return 603 } 604 if event.Control { 605 self.executeControlEvent(event) 606 } 607 case <-self.quitc: 608 return 609 } 610 } 611 } 612 613 func (self *Network) executeControlEvent(event *Event) { 614 log.Trace("execute control event", "type", event.Type, "event", event) 615 switch event.Type { 616 case EventTypeNode: 617 if err := self.executeNodeEvent(event); err != nil { 618 log.Error("error executing node event", "event", event, "err", err) 619 } 620 case EventTypeConn: 621 if err := self.executeConnEvent(event); err != nil { 622 log.Error("error executing conn event", "event", event, "err", err) 623 } 624 case EventTypeMsg: 625 log.Warn("ignoring control msg event") 626 } 627 } 628 629 func (self *Network) executeNodeEvent(e *Event) error { 630 if !e.Node.Up { 631 return self.Stop(e.Node.ID()) 632 } 633 634 if _, err := self.NewNodeWithConfig(e.Node.Config); err != nil { 635 return err 636 } 637 return self.Start(e.Node.ID()) 638 } 639 640 func (self *Network) executeConnEvent(e *Event) error { 641 if e.Conn.Up { 642 return self.Connect(e.Conn.One, e.Conn.Other) 643 } else { 644 return self.Disconnect(e.Conn.One, e.Conn.Other) 645 } 646 }