github.com/alexanderbez/go-ethereum@v1.8.17-0.20181024144731-0a57b29f0c8e/swarm/network/protocol_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package network 18 19 import ( 20 "flag" 21 "fmt" 22 "os" 23 "sync" 24 "testing" 25 26 "github.com/ethereum/go-ethereum/log" 27 "github.com/ethereum/go-ethereum/p2p" 28 "github.com/ethereum/go-ethereum/p2p/discover" 29 "github.com/ethereum/go-ethereum/p2p/protocols" 30 p2ptest "github.com/ethereum/go-ethereum/p2p/testing" 31 ) 32 33 const ( 34 TestProtocolVersion = 7 35 TestProtocolNetworkID = 3 36 ) 37 38 var ( 39 loglevel = flag.Int("loglevel", 2, "verbosity of logs") 40 ) 41 42 func init() { 43 flag.Parse() 44 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) 45 } 46 47 type testStore struct { 48 sync.Mutex 49 50 values map[string][]byte 51 } 52 53 func newTestStore() *testStore { 54 return &testStore{values: make(map[string][]byte)} 55 } 56 57 func (t *testStore) Load(key string) ([]byte, error) { 58 t.Lock() 59 defer t.Unlock() 60 v, ok := t.values[key] 61 if !ok { 62 return nil, fmt.Errorf("key not found: %s", key) 63 } 64 return v, nil 65 } 66 67 func (t *testStore) Save(key string, v []byte) error { 68 t.Lock() 69 defer t.Unlock() 70 t.values[key] = v 71 return nil 72 } 73 74 func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id discover.NodeID) []p2ptest.Exchange { 75 76 return []p2ptest.Exchange{ 77 { 78 Expects: []p2ptest.Expect{ 79 { 80 Code: 0, 81 Msg: lhs, 82 Peer: id, 83 }, 84 }, 85 }, 86 { 87 Triggers: []p2ptest.Trigger{ 88 { 89 Code: 0, 90 Msg: rhs, 91 Peer: id, 92 }, 93 }, 94 }, 95 } 96 } 97 98 func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester { 99 cs := make(map[string]chan bool) 100 101 srv := func(p *BzzPeer) error { 102 defer func() { 103 if cs[p.ID().String()] != nil { 104 close(cs[p.ID().String()]) 105 } 106 }() 107 return run(p) 108 } 109 110 protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error { 111 return srv(&BzzPeer{ 112 Peer: protocols.NewPeer(p, rw, spec), 113 localAddr: addr, 114 BzzAddr: NewAddrFromNodeID(p.ID()), 115 }) 116 } 117 118 s := p2ptest.NewProtocolTester(t, NewNodeIDFromAddr(addr), n, protocol) 119 120 for _, id := range s.IDs { 121 cs[id.String()] = make(chan bool) 122 } 123 124 return &bzzTester{ 125 addr: addr, 126 ProtocolTester: s, 127 cs: cs, 128 } 129 } 130 131 type bzzTester struct { 132 *p2ptest.ProtocolTester 133 addr *BzzAddr 134 cs map[string]chan bool 135 bzz *Bzz 136 } 137 138 func newBzz(addr *BzzAddr, lightNode bool) *Bzz { 139 config := &BzzConfig{ 140 OverlayAddr: addr.Over(), 141 UnderlayAddr: addr.Under(), 142 HiveParams: NewHiveParams(), 143 NetworkID: DefaultNetworkID, 144 LightNode: lightNode, 145 } 146 kad := NewKademlia(addr.OAddr, NewKadParams()) 147 bzz := NewBzz(config, kad, nil, nil, nil) 148 return bzz 149 } 150 151 func newBzzHandshakeTester(t *testing.T, n int, addr *BzzAddr, lightNode bool) *bzzTester { 152 bzz := newBzz(addr, lightNode) 153 pt := p2ptest.NewProtocolTester(t, NewNodeIDFromAddr(addr), n, bzz.runBzz) 154 155 return &bzzTester{ 156 addr: addr, 157 ProtocolTester: pt, 158 bzz: bzz, 159 } 160 } 161 162 // should test handshakes in one exchange? parallelisation 163 func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error { 164 var peers []discover.NodeID 165 id := NewNodeIDFromAddr(rhs.Addr) 166 if len(disconnects) > 0 { 167 for _, d := range disconnects { 168 peers = append(peers, d.Peer) 169 } 170 } else { 171 peers = []discover.NodeID{id} 172 } 173 174 if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, id)...); err != nil { 175 return err 176 } 177 178 if len(disconnects) > 0 { 179 return s.TestDisconnected(disconnects...) 180 } 181 182 // If we don't expect disconnect, ensure peers remain connected 183 err := s.TestDisconnected(&p2ptest.Disconnect{ 184 Peer: s.IDs[0], 185 Error: nil, 186 }) 187 188 if err == nil { 189 return fmt.Errorf("Unexpected peer disconnect") 190 } 191 192 if err.Error() != "timed out waiting for peers to disconnect" { 193 return err 194 } 195 196 return nil 197 } 198 199 func correctBzzHandshake(addr *BzzAddr, lightNode bool) *HandshakeMsg { 200 return &HandshakeMsg{ 201 Version: TestProtocolVersion, 202 NetworkID: TestProtocolNetworkID, 203 Addr: addr, 204 LightNode: lightNode, 205 } 206 } 207 208 func TestBzzHandshakeNetworkIDMismatch(t *testing.T) { 209 lightNode := false 210 addr := RandomAddr() 211 s := newBzzHandshakeTester(t, 1, addr, lightNode) 212 id := s.IDs[0] 213 214 err := s.testHandshake( 215 correctBzzHandshake(addr, lightNode), 216 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: 321, Addr: NewAddrFromNodeID(id)}, 217 &p2ptest.Disconnect{Peer: id, Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")}, 218 ) 219 220 if err != nil { 221 t.Fatal(err) 222 } 223 } 224 225 func TestBzzHandshakeVersionMismatch(t *testing.T) { 226 lightNode := false 227 addr := RandomAddr() 228 s := newBzzHandshakeTester(t, 1, addr, lightNode) 229 id := s.IDs[0] 230 231 err := s.testHandshake( 232 correctBzzHandshake(addr, lightNode), 233 &HandshakeMsg{Version: 0, NetworkID: TestProtocolNetworkID, Addr: NewAddrFromNodeID(id)}, 234 &p2ptest.Disconnect{Peer: id, Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= %d)", TestProtocolVersion)}, 235 ) 236 237 if err != nil { 238 t.Fatal(err) 239 } 240 } 241 242 func TestBzzHandshakeSuccess(t *testing.T) { 243 lightNode := false 244 addr := RandomAddr() 245 s := newBzzHandshakeTester(t, 1, addr, lightNode) 246 id := s.IDs[0] 247 248 err := s.testHandshake( 249 correctBzzHandshake(addr, lightNode), 250 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: NewAddrFromNodeID(id)}, 251 ) 252 253 if err != nil { 254 t.Fatal(err) 255 } 256 } 257 258 func TestBzzHandshakeLightNode(t *testing.T) { 259 var lightNodeTests = []struct { 260 name string 261 lightNode bool 262 }{ 263 {"on", true}, 264 {"off", false}, 265 } 266 267 for _, test := range lightNodeTests { 268 t.Run(test.name, func(t *testing.T) { 269 randomAddr := RandomAddr() 270 pt := newBzzHandshakeTester(t, 1, randomAddr, false) 271 id := pt.IDs[0] 272 addr := NewAddrFromNodeID(id) 273 274 err := pt.testHandshake( 275 correctBzzHandshake(randomAddr, false), 276 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: addr, LightNode: test.lightNode}, 277 ) 278 279 if err != nil { 280 t.Fatal(err) 281 } 282 283 if pt.bzz.handshakes[id].LightNode != test.lightNode { 284 t.Fatalf("peer LightNode flag is %v, should be %v", pt.bzz.handshakes[id].LightNode, test.lightNode) 285 } 286 }) 287 } 288 }