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