github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/pss/client/client_test.go (about) 1 // Copyright 2018 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 client 18 19 import ( 20 "bytes" 21 "context" 22 "flag" 23 "fmt" 24 "math/rand" 25 "os" 26 "sync" 27 "testing" 28 "time" 29 30 "github.com/ShyftNetwork/go-empyrean/common/hexutil" 31 "github.com/ShyftNetwork/go-empyrean/log" 32 "github.com/ShyftNetwork/go-empyrean/node" 33 "github.com/ShyftNetwork/go-empyrean/p2p" 34 "github.com/ShyftNetwork/go-empyrean/p2p/enode" 35 "github.com/ShyftNetwork/go-empyrean/p2p/simulations" 36 "github.com/ShyftNetwork/go-empyrean/p2p/simulations/adapters" 37 "github.com/ShyftNetwork/go-empyrean/rpc" 38 "github.com/ShyftNetwork/go-empyrean/swarm/network" 39 "github.com/ShyftNetwork/go-empyrean/swarm/pss" 40 "github.com/ShyftNetwork/go-empyrean/swarm/state" 41 whisper "github.com/ShyftNetwork/go-empyrean/whisper/whisperv5" 42 ) 43 44 type protoCtrl struct { 45 C chan bool 46 protocol *pss.Protocol 47 run func(*p2p.Peer, p2p.MsgReadWriter) error 48 } 49 50 var ( 51 debugdebugflag = flag.Bool("vv", false, "veryverbose") 52 debugflag = flag.Bool("v", false, "verbose") 53 w *whisper.Whisper 54 wapi *whisper.PublicWhisperAPI 55 // custom logging 56 psslogmain log.Logger 57 pssprotocols map[string]*protoCtrl 58 sendLimit = uint16(256) 59 ) 60 61 var services = newServices() 62 63 func init() { 64 flag.Parse() 65 rand.Seed(time.Now().Unix()) 66 67 adapters.RegisterServices(services) 68 69 loglevel := log.LvlInfo 70 if *debugflag { 71 loglevel = log.LvlDebug 72 } else if *debugdebugflag { 73 loglevel = log.LvlTrace 74 } 75 76 psslogmain = log.New("psslog", "*") 77 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 78 hf := log.LvlFilterHandler(loglevel, hs) 79 h := log.CallerFileHandler(hf) 80 log.Root().SetHandler(h) 81 82 w = whisper.New(&whisper.DefaultConfig) 83 wapi = whisper.NewPublicWhisperAPI(w) 84 85 pssprotocols = make(map[string]*protoCtrl) 86 } 87 88 // ping pong exchange across one expired symkey 89 func TestClientHandshake(t *testing.T) { 90 sendLimit = 3 91 92 clients, err := setupNetwork(2) 93 if err != nil { 94 t.Fatal(err) 95 } 96 97 lpsc, err := NewClientWithRPC(clients[0]) 98 if err != nil { 99 t.Fatal(err) 100 } 101 rpsc, err := NewClientWithRPC(clients[1]) 102 if err != nil { 103 t.Fatal(err) 104 } 105 lpssping := &pss.Ping{ 106 OutC: make(chan bool), 107 InC: make(chan bool), 108 Pong: false, 109 } 110 rpssping := &pss.Ping{ 111 OutC: make(chan bool), 112 InC: make(chan bool), 113 Pong: false, 114 } 115 lproto := pss.NewPingProtocol(lpssping) 116 rproto := pss.NewPingProtocol(rpssping) 117 118 ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 119 defer cancel() 120 err = lpsc.RunProtocol(ctx, lproto) 121 if err != nil { 122 t.Fatal(err) 123 } 124 err = rpsc.RunProtocol(ctx, rproto) 125 if err != nil { 126 t.Fatal(err) 127 } 128 topic := pss.PingTopic.String() 129 130 var loaddr string 131 err = clients[0].Call(&loaddr, "pss_baseAddr") 132 if err != nil { 133 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 134 } 135 var roaddr string 136 err = clients[1].Call(&roaddr, "pss_baseAddr") 137 if err != nil { 138 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 139 } 140 141 var lpubkey string 142 err = clients[0].Call(&lpubkey, "pss_getPublicKey") 143 if err != nil { 144 t.Fatalf("rpc get node 1 pubkey fail: %v", err) 145 } 146 var rpubkey string 147 err = clients[1].Call(&rpubkey, "pss_getPublicKey") 148 if err != nil { 149 t.Fatalf("rpc get node 2 pubkey fail: %v", err) 150 } 151 152 err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddr) 153 if err != nil { 154 t.Fatal(err) 155 } 156 err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddr) 157 if err != nil { 158 t.Fatal(err) 159 } 160 161 time.Sleep(time.Second) 162 163 roaddrbytes, err := hexutil.Decode(roaddr) 164 if err != nil { 165 t.Fatal(err) 166 } 167 err = lpsc.AddPssPeer(rpubkey, roaddrbytes, pss.PingProtocol) 168 if err != nil { 169 t.Fatal(err) 170 } 171 172 time.Sleep(time.Second) 173 174 for i := uint16(0); i <= sendLimit; i++ { 175 lpssping.OutC <- false 176 got := <-rpssping.InC 177 log.Warn("ok", "idx", i, "got", got) 178 time.Sleep(time.Second) 179 } 180 181 rw := lpsc.peerPool[pss.PingTopic][rpubkey] 182 lpsc.RemovePssPeer(rpubkey, pss.PingProtocol) 183 if err := rw.WriteMsg(p2p.Msg{ 184 Size: 3, 185 Payload: bytes.NewReader([]byte("foo")), 186 }); err == nil { 187 t.Fatalf("expected error on write") 188 } 189 } 190 191 func setupNetwork(numnodes int) (clients []*rpc.Client, err error) { 192 nodes := make([]*simulations.Node, numnodes) 193 clients = make([]*rpc.Client, numnodes) 194 if numnodes < 2 { 195 return nil, fmt.Errorf("Minimum two nodes in network") 196 } 197 adapter := adapters.NewSimAdapter(services) 198 net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 199 ID: "0", 200 DefaultService: "bzz", 201 }) 202 for i := 0; i < numnodes; i++ { 203 nodeconf := adapters.RandomNodeConfig() 204 nodeconf.Services = []string{"bzz", "pss"} 205 nodes[i], err = net.NewNodeWithConfig(nodeconf) 206 if err != nil { 207 return nil, fmt.Errorf("error creating node 1: %v", err) 208 } 209 err = net.Start(nodes[i].ID()) 210 if err != nil { 211 return nil, fmt.Errorf("error starting node 1: %v", err) 212 } 213 if i > 0 { 214 err = net.Connect(nodes[i].ID(), nodes[i-1].ID()) 215 if err != nil { 216 return nil, fmt.Errorf("error connecting nodes: %v", err) 217 } 218 } 219 clients[i], err = nodes[i].Client() 220 if err != nil { 221 return nil, fmt.Errorf("create node 1 rpc client fail: %v", err) 222 } 223 } 224 if numnodes > 2 { 225 err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID()) 226 if err != nil { 227 return nil, fmt.Errorf("error connecting first and last nodes") 228 } 229 } 230 return clients, nil 231 } 232 233 func newServices() adapters.Services { 234 stateStore := state.NewInmemoryStore() 235 kademlias := make(map[enode.ID]*network.Kademlia) 236 kademlia := func(id enode.ID) *network.Kademlia { 237 if k, ok := kademlias[id]; ok { 238 return k 239 } 240 params := network.NewKadParams() 241 params.NeighbourhoodSize = 2 242 params.MaxBinSize = 3 243 params.MinBinSize = 1 244 params.MaxRetries = 1000 245 params.RetryExponent = 2 246 params.RetryInterval = 1000000 247 kademlias[id] = network.NewKademlia(id[:], params) 248 return kademlias[id] 249 } 250 return adapters.Services{ 251 "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { 252 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 253 defer cancel() 254 keys, err := wapi.NewKeyPair(ctxlocal) 255 if err != nil { 256 return nil, err 257 } 258 privkey, err := w.GetPrivateKey(keys) 259 if err != nil { 260 return nil, err 261 } 262 psparams := pss.NewPssParams().WithPrivateKey(privkey) 263 pskad := kademlia(ctx.Config.ID) 264 ps, err := pss.NewPss(pskad, psparams) 265 if err != nil { 266 return nil, err 267 } 268 pshparams := pss.NewHandshakeParams() 269 pshparams.SymKeySendLimit = sendLimit 270 err = pss.SetHandshakeController(ps, pshparams) 271 if err != nil { 272 return nil, fmt.Errorf("handshake controller fail: %v", err) 273 } 274 return ps, nil 275 }, 276 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 277 addr := network.NewAddr(ctx.Config.Node()) 278 hp := network.NewHiveParams() 279 hp.Discovery = false 280 config := &network.BzzConfig{ 281 OverlayAddr: addr.Over(), 282 UnderlayAddr: addr.Under(), 283 HiveParams: hp, 284 } 285 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 286 }, 287 } 288 } 289 290 // copied from swarm/network/protocol_test_go 291 type testStore struct { 292 sync.Mutex 293 294 values map[string][]byte 295 } 296 297 func (t *testStore) Load(key string) ([]byte, error) { 298 return nil, nil 299 } 300 301 func (t *testStore) Save(key string, v []byte) error { 302 return nil 303 }