github.com/etsc3259/etsc@v0.0.0-20190109113336-a9c2c10f9c95/swarm/network/simulation/connect.go (about) 1 // Copyright 2018 The go-etsc Authors 2 // This file is part of the go-etsc library. 3 // 4 // The go-etsc library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-etsc library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-etsc library. If not, see <http://www.gnu.org/licenses/>. 16 17 package simulation 18 19 import ( 20 "strings" 21 22 "github.com/ETSC3259/etsc/p2p/enode" 23 ) 24 25 // ConnectToPivotNode connects the node with provided NodeID 26 // to the pivot node, already set by Simulation.SetPivotNode method. 27 // It is useful when constructing a star network topology 28 // when simulation adds and removes nodes dynamically. 29 func (s *Simulation) ConnectToPivotNode(id enode.ID) (err error) { 30 pid := s.PivotNodeID() 31 if pid == nil { 32 return ErrNoPivotNode 33 } 34 return s.connect(*pid, id) 35 } 36 37 // ConnectToLastNode connects the node with provided NodeID 38 // to the last node that is up, and avoiding connection to self. 39 // It is useful when constructing a chain network topology 40 // when simulation adds and removes nodes dynamically. 41 func (s *Simulation) ConnectToLastNode(id enode.ID) (err error) { 42 ids := s.UpNodeIDs() 43 l := len(ids) 44 if l < 2 { 45 return nil 46 } 47 lid := ids[l-1] 48 if lid == id { 49 lid = ids[l-2] 50 } 51 return s.connect(lid, id) 52 } 53 54 // ConnectToRandomNode connects the node with provieded NodeID 55 // to a random node that is up. 56 func (s *Simulation) ConnectToRandomNode(id enode.ID) (err error) { 57 n := s.RandomUpNode(id) 58 if n == nil { 59 return ErrNodeNotFound 60 } 61 return s.connect(n.ID, id) 62 } 63 64 // ConnectNodesFull connects all nodes one to another. 65 // It provides a complete connectivity in the network 66 // which should be rarely needed. 67 func (s *Simulation) ConnectNodesFull(ids []enode.ID) (err error) { 68 if ids == nil { 69 ids = s.UpNodeIDs() 70 } 71 l := len(ids) 72 for i := 0; i < l; i++ { 73 for j := i + 1; j < l; j++ { 74 err = s.connect(ids[i], ids[j]) 75 if err != nil { 76 return err 77 } 78 } 79 } 80 return nil 81 } 82 83 // ConnectNodesChain connects all nodes in a chain topology. 84 // If ids argument is nil, all nodes that are up will be connected. 85 func (s *Simulation) ConnectNodesChain(ids []enode.ID) (err error) { 86 if ids == nil { 87 ids = s.UpNodeIDs() 88 } 89 l := len(ids) 90 for i := 0; i < l-1; i++ { 91 err = s.connect(ids[i], ids[i+1]) 92 if err != nil { 93 return err 94 } 95 } 96 return nil 97 } 98 99 // ConnectNodesRing connects all nodes in a ring topology. 100 // If ids argument is nil, all nodes that are up will be connected. 101 func (s *Simulation) ConnectNodesRing(ids []enode.ID) (err error) { 102 if ids == nil { 103 ids = s.UpNodeIDs() 104 } 105 l := len(ids) 106 if l < 2 { 107 return nil 108 } 109 for i := 0; i < l-1; i++ { 110 err = s.connect(ids[i], ids[i+1]) 111 if err != nil { 112 return err 113 } 114 } 115 return s.connect(ids[l-1], ids[0]) 116 } 117 118 // ConnectNodesStar connects all nodes in a star topology 119 // with the center at provided NodeID. 120 // If ids argument is nil, all nodes that are up will be connected. 121 func (s *Simulation) ConnectNodesStar(id enode.ID, ids []enode.ID) (err error) { 122 if ids == nil { 123 ids = s.UpNodeIDs() 124 } 125 l := len(ids) 126 for i := 0; i < l; i++ { 127 if id == ids[i] { 128 continue 129 } 130 err = s.connect(id, ids[i]) 131 if err != nil { 132 return err 133 } 134 } 135 return nil 136 } 137 138 // ConnectNodesStarPivot connects all nodes in a star topology 139 // with the center at already set pivot node. 140 // If ids argument is nil, all nodes that are up will be connected. 141 func (s *Simulation) ConnectNodesStarPivot(ids []enode.ID) (err error) { 142 id := s.PivotNodeID() 143 if id == nil { 144 return ErrNoPivotNode 145 } 146 return s.ConnectNodesStar(*id, ids) 147 } 148 149 // connect connects two nodes but ignores already connected error. 150 func (s *Simulation) connect(oneID, otherID enode.ID) error { 151 return ignoreAlreadyConnectedErr(s.Net.Connect(oneID, otherID)) 152 } 153 154 func ignoreAlreadyConnectedErr(err error) error { 155 if err == nil || strings.Contains(err.Error(), "already connected") { 156 return nil 157 } 158 return err 159 }