github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/pss/pss_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 pss 18 19 import ( 20 "bytes" 21 "context" 22 "crypto/ecdsa" 23 "encoding/binary" 24 "encoding/hex" 25 "encoding/json" 26 "flag" 27 "fmt" 28 "io/ioutil" 29 "math/rand" 30 "os" 31 "strconv" 32 "strings" 33 "sync" 34 "testing" 35 "time" 36 37 "github.com/ShyftNetwork/go-empyrean/common" 38 "github.com/ShyftNetwork/go-empyrean/common/hexutil" 39 "github.com/ShyftNetwork/go-empyrean/crypto" 40 "github.com/ShyftNetwork/go-empyrean/log" 41 "github.com/ShyftNetwork/go-empyrean/metrics" 42 "github.com/ShyftNetwork/go-empyrean/metrics/influxdb" 43 "github.com/ShyftNetwork/go-empyrean/node" 44 "github.com/ShyftNetwork/go-empyrean/p2p" 45 "github.com/ShyftNetwork/go-empyrean/p2p/enode" 46 "github.com/ShyftNetwork/go-empyrean/p2p/protocols" 47 "github.com/ShyftNetwork/go-empyrean/p2p/simulations" 48 "github.com/ShyftNetwork/go-empyrean/p2p/simulations/adapters" 49 "github.com/ShyftNetwork/go-empyrean/rpc" 50 "github.com/ShyftNetwork/go-empyrean/swarm/network" 51 "github.com/ShyftNetwork/go-empyrean/swarm/pot" 52 "github.com/ShyftNetwork/go-empyrean/swarm/state" 53 whisper "github.com/ShyftNetwork/go-empyrean/whisper/whisperv5" 54 ) 55 56 var ( 57 initOnce = sync.Once{} 58 loglevel = flag.Int("loglevel", 2, "logging verbosity") 59 longrunning = flag.Bool("longrunning", false, "do run long-running tests") 60 w *whisper.Whisper 61 wapi *whisper.PublicWhisperAPI 62 psslogmain log.Logger 63 pssprotocols map[string]*protoCtrl 64 useHandshake bool 65 noopHandlerFunc = func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 66 return nil 67 } 68 ) 69 70 func init() { 71 flag.Parse() 72 rand.Seed(time.Now().Unix()) 73 74 adapters.RegisterServices(newServices(false)) 75 initTest() 76 } 77 78 func initTest() { 79 initOnce.Do( 80 func() { 81 psslogmain = log.New("psslog", "*") 82 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 83 hf := log.LvlFilterHandler(log.Lvl(*loglevel), hs) 84 h := log.CallerFileHandler(hf) 85 log.Root().SetHandler(h) 86 87 w = whisper.New(&whisper.DefaultConfig) 88 wapi = whisper.NewPublicWhisperAPI(w) 89 90 pssprotocols = make(map[string]*protoCtrl) 91 }, 92 ) 93 } 94 95 // test that topic conversion functions give predictable results 96 func TestTopic(t *testing.T) { 97 98 api := &API{} 99 100 topicstr := strings.Join([]string{PingProtocol.Name, strconv.Itoa(int(PingProtocol.Version))}, ":") 101 102 // bytestotopic is the authoritative topic conversion source 103 topicobj := BytesToTopic([]byte(topicstr)) 104 105 // string to topic and bytes to topic must match 106 topicapiobj, _ := api.StringToTopic(topicstr) 107 if topicobj != topicapiobj { 108 t.Fatalf("bytes and string topic conversion mismatch; %s != %s", topicobj, topicapiobj) 109 } 110 111 // string representation of topichex 112 topichex := topicobj.String() 113 114 // protocoltopic wrapper on pingtopic should be same as topicstring 115 // check that it matches 116 pingtopichex := PingTopic.String() 117 if topichex != pingtopichex { 118 t.Fatalf("protocol topic conversion mismatch; %s != %s", topichex, pingtopichex) 119 } 120 121 // json marshal of topic 122 topicjsonout, err := topicobj.MarshalJSON() 123 if err != nil { 124 t.Fatal(err) 125 } 126 if string(topicjsonout)[1:len(topicjsonout)-1] != topichex { 127 t.Fatalf("topic json marshal mismatch; %s != \"%s\"", topicjsonout, topichex) 128 } 129 130 // json unmarshal of topic 131 var topicjsonin Topic 132 topicjsonin.UnmarshalJSON(topicjsonout) 133 if topicjsonin != topicobj { 134 t.Fatalf("topic json unmarshal mismatch: %x != %x", topicjsonin, topicobj) 135 } 136 } 137 138 // test bit packing of message control flags 139 func TestMsgParams(t *testing.T) { 140 var ctrl byte 141 ctrl |= pssControlRaw 142 p := newMsgParamsFromBytes([]byte{ctrl}) 143 m := newPssMsg(p) 144 if !m.isRaw() || m.isSym() { 145 t.Fatal("expected raw=true and sym=false") 146 } 147 ctrl |= pssControlSym 148 p = newMsgParamsFromBytes([]byte{ctrl}) 149 m = newPssMsg(p) 150 if !m.isRaw() || !m.isSym() { 151 t.Fatal("expected raw=true and sym=true") 152 } 153 ctrl &= 0xff &^ pssControlRaw 154 p = newMsgParamsFromBytes([]byte{ctrl}) 155 m = newPssMsg(p) 156 if m.isRaw() || !m.isSym() { 157 t.Fatal("expected raw=false and sym=true") 158 } 159 } 160 161 // test if we can insert into cache, match items with cache and cache expiry 162 func TestCache(t *testing.T) { 163 var err error 164 to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f") 165 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 166 defer cancel() 167 keys, err := wapi.NewKeyPair(ctx) 168 privkey, err := w.GetPrivateKey(keys) 169 if err != nil { 170 t.Fatal(err) 171 } 172 ps := newTestPss(privkey, nil, nil) 173 pp := NewPssParams().WithPrivateKey(privkey) 174 data := []byte("foo") 175 datatwo := []byte("bar") 176 datathree := []byte("baz") 177 wparams := &whisper.MessageParams{ 178 TTL: defaultWhisperTTL, 179 Src: privkey, 180 Dst: &privkey.PublicKey, 181 Topic: whisper.TopicType(PingTopic), 182 WorkTime: defaultWhisperWorkTime, 183 PoW: defaultWhisperPoW, 184 Payload: data, 185 } 186 woutmsg, err := whisper.NewSentMessage(wparams) 187 env, err := woutmsg.Wrap(wparams) 188 msg := &PssMsg{ 189 Payload: env, 190 To: to, 191 } 192 wparams.Payload = datatwo 193 woutmsg, err = whisper.NewSentMessage(wparams) 194 envtwo, err := woutmsg.Wrap(wparams) 195 msgtwo := &PssMsg{ 196 Payload: envtwo, 197 To: to, 198 } 199 wparams.Payload = datathree 200 woutmsg, err = whisper.NewSentMessage(wparams) 201 envthree, err := woutmsg.Wrap(wparams) 202 msgthree := &PssMsg{ 203 Payload: envthree, 204 To: to, 205 } 206 207 digest := ps.digest(msg) 208 if err != nil { 209 t.Fatalf("could not store cache msgone: %v", err) 210 } 211 digesttwo := ps.digest(msgtwo) 212 if err != nil { 213 t.Fatalf("could not store cache msgtwo: %v", err) 214 } 215 digestthree := ps.digest(msgthree) 216 if err != nil { 217 t.Fatalf("could not store cache msgthree: %v", err) 218 } 219 220 if digest == digesttwo { 221 t.Fatalf("different msgs return same hash: %d", digesttwo) 222 } 223 224 // check the cache 225 err = ps.addFwdCache(msg) 226 if err != nil { 227 t.Fatalf("write to pss expire cache failed: %v", err) 228 } 229 230 if !ps.checkFwdCache(msg) { 231 t.Fatalf("message %v should have EXPIRE record in cache but checkCache returned false", msg) 232 } 233 234 if ps.checkFwdCache(msgtwo) { 235 t.Fatalf("message %v should NOT have EXPIRE record in cache but checkCache returned true", msgtwo) 236 } 237 238 time.Sleep(pp.CacheTTL + 1*time.Second) 239 err = ps.addFwdCache(msgthree) 240 if err != nil { 241 t.Fatalf("write to pss expire cache failed: %v", err) 242 } 243 244 if ps.checkFwdCache(msg) { 245 t.Fatalf("message %v should have expired from cache but checkCache returned true", msg) 246 } 247 248 if _, ok := ps.fwdCache[digestthree]; !ok { 249 t.Fatalf("unexpired message should be in the cache: %v", digestthree) 250 } 251 252 if _, ok := ps.fwdCache[digesttwo]; ok { 253 t.Fatalf("expired message should have been cleared from the cache: %v", digesttwo) 254 } 255 } 256 257 // matching of address hints; whether a message could be or is for the node 258 func TestAddressMatch(t *testing.T) { 259 260 localaddr := network.RandomAddr().Over() 261 copy(localaddr[:8], []byte("deadbeef")) 262 remoteaddr := []byte("feedbeef") 263 kadparams := network.NewKadParams() 264 kad := network.NewKademlia(localaddr, kadparams) 265 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 266 defer cancel() 267 keys, err := wapi.NewKeyPair(ctx) 268 if err != nil { 269 t.Fatalf("Could not generate private key: %v", err) 270 } 271 privkey, err := w.GetPrivateKey(keys) 272 pssp := NewPssParams().WithPrivateKey(privkey) 273 ps, err := NewPss(kad, pssp) 274 if err != nil { 275 t.Fatal(err.Error()) 276 } 277 278 pssmsg := &PssMsg{ 279 To: remoteaddr, 280 } 281 282 // differ from first byte 283 if ps.isSelfRecipient(pssmsg) { 284 t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr) 285 } 286 if ps.isSelfPossibleRecipient(pssmsg, false) { 287 t.Fatalf("isSelfPossibleRecipient true but %x != %x", remoteaddr[:8], localaddr[:8]) 288 } 289 290 // 8 first bytes same 291 copy(remoteaddr[:4], localaddr[:4]) 292 if ps.isSelfRecipient(pssmsg) { 293 t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr) 294 } 295 if !ps.isSelfPossibleRecipient(pssmsg, false) { 296 t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8]) 297 } 298 299 // all bytes same 300 pssmsg.To = localaddr 301 if !ps.isSelfRecipient(pssmsg) { 302 t.Fatalf("isSelfRecipient false but %x == %x", remoteaddr, localaddr) 303 } 304 if !ps.isSelfPossibleRecipient(pssmsg, false) { 305 t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8]) 306 } 307 308 } 309 310 // test that message is handled by sender if a prox handler exists and sender is in prox of message 311 func TestProxShortCircuit(t *testing.T) { 312 313 // sender node address 314 localAddr := network.RandomAddr().Over() 315 localPotAddr := pot.NewAddressFromBytes(localAddr) 316 317 // set up kademlia 318 kadParams := network.NewKadParams() 319 kad := network.NewKademlia(localAddr, kadParams) 320 peerCount := kad.MinBinSize + 1 321 322 // set up pss 323 privKey, err := crypto.GenerateKey() 324 pssp := NewPssParams().WithPrivateKey(privKey) 325 ps, err := NewPss(kad, pssp) 326 if err != nil { 327 t.Fatal(err.Error()) 328 } 329 330 // create kademlia peers, so we have peers both inside and outside minproxlimit 331 var peers []*network.Peer 332 proxMessageAddress := pot.RandomAddressAt(localPotAddr, peerCount).Bytes() 333 distantMessageAddress := pot.RandomAddressAt(localPotAddr, 0).Bytes() 334 335 for i := 0; i < peerCount; i++ { 336 rw := &p2p.MsgPipeRW{} 337 ptpPeer := p2p.NewPeer(enode.ID{}, "wanna be with me? [ ] yes [ ] no", []p2p.Cap{}) 338 protoPeer := protocols.NewPeer(ptpPeer, rw, &protocols.Spec{}) 339 peerAddr := pot.RandomAddressAt(localPotAddr, i) 340 bzzPeer := &network.BzzPeer{ 341 Peer: protoPeer, 342 BzzAddr: &network.BzzAddr{ 343 OAddr: peerAddr.Bytes(), 344 UAddr: []byte(fmt.Sprintf("%x", peerAddr[:])), 345 }, 346 } 347 peer := network.NewPeer(bzzPeer, kad) 348 kad.On(peer) 349 peers = append(peers, peer) 350 } 351 352 // register it marking prox capability 353 delivered := make(chan struct{}) 354 rawHandlerFunc := func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 355 log.Trace("in allowraw handler") 356 delivered <- struct{}{} 357 return nil 358 } 359 topic := BytesToTopic([]byte{0x2a}) 360 hndlrProxDereg := ps.Register(&topic, &handler{ 361 f: rawHandlerFunc, 362 caps: &handlerCaps{ 363 raw: true, 364 prox: true, 365 }, 366 }) 367 defer hndlrProxDereg() 368 369 // send message too far away for sender to be in prox 370 // reception of this message should time out 371 errC := make(chan error) 372 go func() { 373 err := ps.SendRaw(distantMessageAddress, topic, []byte("foo")) 374 if err != nil { 375 errC <- err 376 } 377 }() 378 379 ctx, cancel := context.WithTimeout(context.TODO(), time.Second) 380 defer cancel() 381 select { 382 case <-delivered: 383 t.Fatal("raw distant message delivered") 384 case err := <-errC: 385 t.Fatal(err) 386 case <-ctx.Done(): 387 } 388 389 // send message that should be within sender prox 390 // this message should be delivered 391 go func() { 392 err := ps.SendRaw(proxMessageAddress, topic, []byte("bar")) 393 if err != nil { 394 errC <- err 395 } 396 }() 397 398 ctx, cancel = context.WithTimeout(context.TODO(), time.Second) 399 defer cancel() 400 select { 401 case <-delivered: 402 case err := <-errC: 403 t.Fatal(err) 404 case <-ctx.Done(): 405 t.Fatal("raw timeout") 406 } 407 408 // try the same prox message with sym and asym send 409 proxAddrPss := PssAddress(proxMessageAddress) 410 symKeyId, err := ps.GenerateSymmetricKey(topic, proxAddrPss, true) 411 go func() { 412 err := ps.SendSym(symKeyId, topic, []byte("baz")) 413 if err != nil { 414 errC <- err 415 } 416 }() 417 ctx, cancel = context.WithTimeout(context.TODO(), time.Second) 418 defer cancel() 419 select { 420 case <-delivered: 421 case err := <-errC: 422 t.Fatal(err) 423 case <-ctx.Done(): 424 t.Fatal("sym timeout") 425 } 426 427 err = ps.SetPeerPublicKey(&privKey.PublicKey, topic, proxAddrPss) 428 if err != nil { 429 t.Fatal(err) 430 } 431 pubKeyId := hexutil.Encode(crypto.FromECDSAPub(&privKey.PublicKey)) 432 go func() { 433 err := ps.SendAsym(pubKeyId, topic, []byte("xyzzy")) 434 if err != nil { 435 errC <- err 436 } 437 }() 438 ctx, cancel = context.WithTimeout(context.TODO(), time.Second) 439 defer cancel() 440 select { 441 case <-delivered: 442 case err := <-errC: 443 t.Fatal(err) 444 case <-ctx.Done(): 445 t.Fatal("asym timeout") 446 } 447 } 448 449 // verify that node can be set as recipient regardless of explicit message address match if minimum one handler of a topic is explicitly set to allow it 450 // note that in these tests we use the raw capability on handlers for convenience 451 func TestAddressMatchProx(t *testing.T) { 452 453 // recipient node address 454 localAddr := network.RandomAddr().Over() 455 localPotAddr := pot.NewAddressFromBytes(localAddr) 456 457 // set up kademlia 458 kadparams := network.NewKadParams() 459 kad := network.NewKademlia(localAddr, kadparams) 460 nnPeerCount := kad.MinBinSize 461 peerCount := nnPeerCount + 2 462 463 // set up pss 464 privKey, err := crypto.GenerateKey() 465 pssp := NewPssParams().WithPrivateKey(privKey) 466 ps, err := NewPss(kad, pssp) 467 if err != nil { 468 t.Fatal(err.Error()) 469 } 470 471 // create kademlia peers, so we have peers both inside and outside minproxlimit 472 var peers []*network.Peer 473 for i := 0; i < peerCount; i++ { 474 rw := &p2p.MsgPipeRW{} 475 ptpPeer := p2p.NewPeer(enode.ID{}, "362436 call me anytime", []p2p.Cap{}) 476 protoPeer := protocols.NewPeer(ptpPeer, rw, &protocols.Spec{}) 477 peerAddr := pot.RandomAddressAt(localPotAddr, i) 478 bzzPeer := &network.BzzPeer{ 479 Peer: protoPeer, 480 BzzAddr: &network.BzzAddr{ 481 OAddr: peerAddr.Bytes(), 482 UAddr: []byte(fmt.Sprintf("%x", peerAddr[:])), 483 }, 484 } 485 peer := network.NewPeer(bzzPeer, kad) 486 kad.On(peer) 487 peers = append(peers, peer) 488 } 489 490 // TODO: create a test in the network package to make a table with n peers where n-m are proxpeers 491 // meanwhile test regression for kademlia since we are compiling the test parameters from different packages 492 var proxes int 493 var conns int 494 depth := kad.NeighbourhoodDepth() 495 kad.EachConn(nil, peerCount, func(p *network.Peer, po int) bool { 496 conns++ 497 if po >= depth { 498 proxes++ 499 } 500 return true 501 }) 502 if proxes != nnPeerCount { 503 t.Fatalf("expected %d proxpeers, have %d", nnPeerCount, proxes) 504 } else if conns != peerCount { 505 t.Fatalf("expected %d peers total, have %d", peerCount, proxes) 506 } 507 508 // remote address distances from localAddr to try and the expected outcomes if we use prox handler 509 remoteDistances := []int{ 510 255, 511 nnPeerCount + 1, 512 nnPeerCount, 513 nnPeerCount - 1, 514 0, 515 } 516 expects := []bool{ 517 true, 518 true, 519 true, 520 false, 521 false, 522 } 523 524 // first the unit test on the method that calculates possible receipient using prox 525 for i, distance := range remoteDistances { 526 pssMsg := newPssMsg(&msgParams{}) 527 pssMsg.To = make([]byte, len(localAddr)) 528 copy(pssMsg.To, localAddr) 529 var byteIdx = distance / 8 530 pssMsg.To[byteIdx] ^= 1 << uint(7-(distance%8)) 531 log.Trace(fmt.Sprintf("addrmatch %v", bytes.Equal(pssMsg.To, localAddr))) 532 if ps.isSelfPossibleRecipient(pssMsg, true) != expects[i] { 533 t.Fatalf("expected distance %d to be %v", distance, expects[i]) 534 } 535 } 536 537 // we move up to higher level and test the actual message handler 538 // for each distance check if we are possible recipient when prox variant is used is set 539 540 // this handler will increment a counter for every message that gets passed to the handler 541 var receives int 542 rawHandlerFunc := func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 543 log.Trace("in allowraw handler") 544 receives++ 545 return nil 546 } 547 548 // register it marking prox capability 549 topic := BytesToTopic([]byte{0x2a}) 550 hndlrProxDereg := ps.Register(&topic, &handler{ 551 f: rawHandlerFunc, 552 caps: &handlerCaps{ 553 raw: true, 554 prox: true, 555 }, 556 }) 557 558 // test the distances 559 var prevReceive int 560 for i, distance := range remoteDistances { 561 remotePotAddr := pot.RandomAddressAt(localPotAddr, distance) 562 remoteAddr := remotePotAddr.Bytes() 563 564 var data [32]byte 565 rand.Read(data[:]) 566 pssMsg := newPssMsg(&msgParams{raw: true}) 567 pssMsg.To = remoteAddr 568 pssMsg.Expire = uint32(time.Now().Unix() + 4200) 569 pssMsg.Payload = &whisper.Envelope{ 570 Topic: whisper.TopicType(topic), 571 Data: data[:], 572 } 573 574 log.Trace("withprox addrs", "local", localAddr, "remote", remoteAddr) 575 ps.handlePssMsg(context.TODO(), pssMsg) 576 if (!expects[i] && prevReceive != receives) || (expects[i] && prevReceive == receives) { 577 t.Fatalf("expected distance %d recipient %v when prox is set for handler", distance, expects[i]) 578 } 579 prevReceive = receives 580 } 581 582 // now add a non prox-capable handler and test 583 ps.Register(&topic, &handler{ 584 f: rawHandlerFunc, 585 caps: &handlerCaps{ 586 raw: true, 587 }, 588 }) 589 receives = 0 590 prevReceive = 0 591 for i, distance := range remoteDistances { 592 remotePotAddr := pot.RandomAddressAt(localPotAddr, distance) 593 remoteAddr := remotePotAddr.Bytes() 594 595 var data [32]byte 596 rand.Read(data[:]) 597 pssMsg := newPssMsg(&msgParams{raw: true}) 598 pssMsg.To = remoteAddr 599 pssMsg.Expire = uint32(time.Now().Unix() + 4200) 600 pssMsg.Payload = &whisper.Envelope{ 601 Topic: whisper.TopicType(topic), 602 Data: data[:], 603 } 604 605 log.Trace("withprox addrs", "local", localAddr, "remote", remoteAddr) 606 ps.handlePssMsg(context.TODO(), pssMsg) 607 if (!expects[i] && prevReceive != receives) || (expects[i] && prevReceive == receives) { 608 t.Fatalf("expected distance %d recipient %v when prox is set for handler", distance, expects[i]) 609 } 610 prevReceive = receives 611 } 612 613 // now deregister the prox capable handler, now none of the messages will be handled 614 hndlrProxDereg() 615 receives = 0 616 617 for _, distance := range remoteDistances { 618 remotePotAddr := pot.RandomAddressAt(localPotAddr, distance) 619 remoteAddr := remotePotAddr.Bytes() 620 621 pssMsg := newPssMsg(&msgParams{raw: true}) 622 pssMsg.To = remoteAddr 623 pssMsg.Expire = uint32(time.Now().Unix() + 4200) 624 pssMsg.Payload = &whisper.Envelope{ 625 Topic: whisper.TopicType(topic), 626 Data: []byte(remotePotAddr.String()), 627 } 628 629 log.Trace("noprox addrs", "local", localAddr, "remote", remoteAddr) 630 ps.handlePssMsg(context.TODO(), pssMsg) 631 if receives != 0 { 632 t.Fatalf("expected distance %d to not be recipient when prox is not set for handler", distance) 633 } 634 635 } 636 } 637 638 // verify that message queueing happens when it should, and that expired and corrupt messages are dropped 639 func TestMessageProcessing(t *testing.T) { 640 641 t.Skip("Disabled due to probable faulty logic for outbox expectations") 642 // setup 643 privkey, err := crypto.GenerateKey() 644 if err != nil { 645 t.Fatal(err.Error()) 646 } 647 648 addr := make([]byte, 32) 649 addr[0] = 0x01 650 ps := newTestPss(privkey, network.NewKademlia(addr, network.NewKadParams()), NewPssParams()) 651 652 // message should pass 653 msg := newPssMsg(&msgParams{}) 654 msg.To = addr 655 msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix()) 656 msg.Payload = &whisper.Envelope{ 657 Topic: [4]byte{}, 658 Data: []byte{0x66, 0x6f, 0x6f}, 659 } 660 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 661 t.Fatal(err.Error()) 662 } 663 tmr := time.NewTimer(time.Millisecond * 100) 664 var outmsg *PssMsg 665 select { 666 case outmsg = <-ps.outbox: 667 case <-tmr.C: 668 default: 669 } 670 if outmsg != nil { 671 t.Fatalf("expected outbox empty after full address on msg, but had message %s", msg) 672 } 673 674 // message should pass and queue due to partial length 675 msg.To = addr[0:1] 676 msg.Payload.Data = []byte{0x78, 0x79, 0x80, 0x80, 0x79} 677 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 678 t.Fatal(err.Error()) 679 } 680 tmr.Reset(time.Millisecond * 100) 681 outmsg = nil 682 select { 683 case outmsg = <-ps.outbox: 684 case <-tmr.C: 685 } 686 if outmsg == nil { 687 t.Fatal("expected message in outbox on encrypt fail, but empty") 688 } 689 outmsg = nil 690 select { 691 case outmsg = <-ps.outbox: 692 default: 693 } 694 if outmsg != nil { 695 t.Fatalf("expected only one queued message but also had message %v", msg) 696 } 697 698 // full address mismatch should put message in queue 699 msg.To[0] = 0xff 700 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 701 t.Fatal(err.Error()) 702 } 703 tmr.Reset(time.Millisecond * 10) 704 outmsg = nil 705 select { 706 case outmsg = <-ps.outbox: 707 case <-tmr.C: 708 } 709 if outmsg == nil { 710 t.Fatal("expected message in outbox on address mismatch, but empty") 711 } 712 outmsg = nil 713 select { 714 case outmsg = <-ps.outbox: 715 default: 716 } 717 if outmsg != nil { 718 t.Fatalf("expected only one queued message but also had message %v", msg) 719 } 720 721 // expired message should be dropped 722 msg.Expire = uint32(time.Now().Add(-time.Second).Unix()) 723 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 724 t.Fatal(err.Error()) 725 } 726 tmr.Reset(time.Millisecond * 10) 727 outmsg = nil 728 select { 729 case outmsg = <-ps.outbox: 730 case <-tmr.C: 731 default: 732 } 733 if outmsg != nil { 734 t.Fatalf("expected empty queue but have message %v", msg) 735 } 736 737 // invalid message should return error 738 fckedupmsg := &struct { 739 pssMsg *PssMsg 740 }{ 741 pssMsg: &PssMsg{}, 742 } 743 if err := ps.handlePssMsg(context.TODO(), fckedupmsg); err == nil { 744 t.Fatalf("expected error from processMsg but error nil") 745 } 746 747 // outbox full should return error 748 msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix()) 749 for i := 0; i < defaultOutboxCapacity; i++ { 750 ps.outbox <- msg 751 } 752 msg.Payload.Data = []byte{0x62, 0x61, 0x72} 753 err = ps.handlePssMsg(context.TODO(), msg) 754 if err == nil { 755 t.Fatal("expected error when mailbox full, but was nil") 756 } 757 } 758 759 // set and generate pubkeys and symkeys 760 func TestKeys(t *testing.T) { 761 // make our key and init pss with it 762 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 763 defer cancel() 764 ourkeys, err := wapi.NewKeyPair(ctx) 765 if err != nil { 766 t.Fatalf("create 'our' key fail") 767 } 768 ctx, cancel2 := context.WithTimeout(context.Background(), time.Second) 769 defer cancel2() 770 theirkeys, err := wapi.NewKeyPair(ctx) 771 if err != nil { 772 t.Fatalf("create 'their' key fail") 773 } 774 ourprivkey, err := w.GetPrivateKey(ourkeys) 775 if err != nil { 776 t.Fatalf("failed to retrieve 'our' private key") 777 } 778 theirprivkey, err := w.GetPrivateKey(theirkeys) 779 if err != nil { 780 t.Fatalf("failed to retrieve 'their' private key") 781 } 782 ps := newTestPss(ourprivkey, nil, nil) 783 784 // set up peer with mock address, mapped to mocked publicaddress and with mocked symkey 785 addr := make(PssAddress, 32) 786 copy(addr, network.RandomAddr().Over()) 787 outkey := network.RandomAddr().Over() 788 topicobj := BytesToTopic([]byte("foo:42")) 789 ps.SetPeerPublicKey(&theirprivkey.PublicKey, topicobj, addr) 790 outkeyid, err := ps.SetSymmetricKey(outkey, topicobj, addr, false) 791 if err != nil { 792 t.Fatalf("failed to set 'our' outgoing symmetric key") 793 } 794 795 // make a symmetric key that we will send to peer for encrypting messages to us 796 inkeyid, err := ps.GenerateSymmetricKey(topicobj, addr, true) 797 if err != nil { 798 t.Fatalf("failed to set 'our' incoming symmetric key") 799 } 800 801 // get the key back from whisper, check that it's still the same 802 outkeyback, err := ps.w.GetSymKey(outkeyid) 803 if err != nil { 804 t.Fatalf(err.Error()) 805 } 806 inkey, err := ps.w.GetSymKey(inkeyid) 807 if err != nil { 808 t.Fatalf(err.Error()) 809 } 810 if !bytes.Equal(outkeyback, outkey) { 811 t.Fatalf("passed outgoing symkey doesnt equal stored: %x / %x", outkey, outkeyback) 812 } 813 814 t.Logf("symout: %v", outkeyback) 815 t.Logf("symin: %v", inkey) 816 817 // check that the key is stored in the peerpool 818 psp := ps.symKeyPool[inkeyid][topicobj] 819 if !bytes.Equal(psp.address, addr) { 820 t.Fatalf("inkey address does not match; %p != %p", psp.address, addr) 821 } 822 } 823 824 // check that we can retrieve previously added public key entires per topic and peer 825 func TestGetPublickeyEntries(t *testing.T) { 826 827 privkey, err := crypto.GenerateKey() 828 if err != nil { 829 t.Fatal(err) 830 } 831 ps := newTestPss(privkey, nil, nil) 832 833 peeraddr := network.RandomAddr().Over() 834 topicaddr := make(map[Topic]PssAddress) 835 topicaddr[Topic{0x13}] = peeraddr 836 topicaddr[Topic{0x2a}] = peeraddr[:16] 837 topicaddr[Topic{0x02, 0x9a}] = []byte{} 838 839 remoteprivkey, err := crypto.GenerateKey() 840 if err != nil { 841 t.Fatal(err) 842 } 843 remotepubkeybytes := crypto.FromECDSAPub(&remoteprivkey.PublicKey) 844 remotepubkeyhex := common.ToHex(remotepubkeybytes) 845 846 pssapi := NewAPI(ps) 847 848 for to, a := range topicaddr { 849 err = pssapi.SetPeerPublicKey(remotepubkeybytes, to, a) 850 if err != nil { 851 t.Fatal(err) 852 } 853 } 854 855 intopic, err := pssapi.GetPeerTopics(remotepubkeyhex) 856 if err != nil { 857 t.Fatal(err) 858 } 859 860 OUTER: 861 for _, tnew := range intopic { 862 for torig, addr := range topicaddr { 863 if bytes.Equal(torig[:], tnew[:]) { 864 inaddr, err := pssapi.GetPeerAddress(remotepubkeyhex, torig) 865 if err != nil { 866 t.Fatal(err) 867 } 868 if !bytes.Equal(addr, inaddr) { 869 t.Fatalf("Address mismatch for topic %x; got %x, expected %x", torig, inaddr, addr) 870 } 871 delete(topicaddr, torig) 872 continue OUTER 873 } 874 } 875 t.Fatalf("received topic %x did not match any existing topics", tnew) 876 } 877 878 if len(topicaddr) != 0 { 879 t.Fatalf("%d topics were not matched", len(topicaddr)) 880 } 881 } 882 883 // forwarding should skip peers that do not have matching pss capabilities 884 func TestPeerCapabilityMismatch(t *testing.T) { 885 886 // create privkey for forwarder node 887 privkey, err := crypto.GenerateKey() 888 if err != nil { 889 t.Fatal(err) 890 } 891 892 // initialize kad 893 baseaddr := network.RandomAddr() 894 kad := network.NewKademlia((baseaddr).Over(), network.NewKadParams()) 895 rw := &p2p.MsgPipeRW{} 896 897 // one peer has a mismatching version of pss 898 wrongpssaddr := network.RandomAddr() 899 wrongpsscap := p2p.Cap{ 900 Name: pssProtocolName, 901 Version: 0, 902 } 903 nid := enode.ID{0x01} 904 wrongpsspeer := network.NewPeer(&network.BzzPeer{ 905 Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(wrongpssaddr.Over()), []p2p.Cap{wrongpsscap}), rw, nil), 906 BzzAddr: &network.BzzAddr{OAddr: wrongpssaddr.Over(), UAddr: nil}, 907 }, kad) 908 909 // one peer doesn't even have pss (boo!) 910 nopssaddr := network.RandomAddr() 911 nopsscap := p2p.Cap{ 912 Name: "nopss", 913 Version: 1, 914 } 915 nid = enode.ID{0x02} 916 nopsspeer := network.NewPeer(&network.BzzPeer{ 917 Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(nopssaddr.Over()), []p2p.Cap{nopsscap}), rw, nil), 918 BzzAddr: &network.BzzAddr{OAddr: nopssaddr.Over(), UAddr: nil}, 919 }, kad) 920 921 // add peers to kademlia and activate them 922 // it's safe so don't check errors 923 kad.Register(wrongpsspeer.BzzAddr) 924 kad.On(wrongpsspeer) 925 kad.Register(nopsspeer.BzzAddr) 926 kad.On(nopsspeer) 927 928 // create pss 929 pssmsg := &PssMsg{ 930 To: []byte{}, 931 Expire: uint32(time.Now().Add(time.Second).Unix()), 932 Payload: &whisper.Envelope{}, 933 } 934 ps := newTestPss(privkey, kad, nil) 935 936 // run the forward 937 // it is enough that it completes; trying to send to incapable peers would create segfault 938 ps.forward(pssmsg) 939 940 } 941 942 // verifies that message handlers for raw messages only are invoked when minimum one handler for the topic exists in which raw messages are explicitly allowed 943 func TestRawAllow(t *testing.T) { 944 945 // set up pss like so many times before 946 privKey, err := crypto.GenerateKey() 947 if err != nil { 948 t.Fatal(err) 949 } 950 baseAddr := network.RandomAddr() 951 kad := network.NewKademlia((baseAddr).Over(), network.NewKadParams()) 952 ps := newTestPss(privKey, kad, nil) 953 topic := BytesToTopic([]byte{0x2a}) 954 955 // create handler innards that increments every time a message hits it 956 var receives int 957 rawHandlerFunc := func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 958 log.Trace("in allowraw handler") 959 receives++ 960 return nil 961 } 962 963 // wrap this handler function with a handler without raw capability and register it 964 hndlrNoRaw := &handler{ 965 f: rawHandlerFunc, 966 } 967 ps.Register(&topic, hndlrNoRaw) 968 969 // test it with a raw message, should be poo-poo 970 pssMsg := newPssMsg(&msgParams{ 971 raw: true, 972 }) 973 pssMsg.To = baseAddr.OAddr 974 pssMsg.Expire = uint32(time.Now().Unix() + 4200) 975 pssMsg.Payload = &whisper.Envelope{ 976 Topic: whisper.TopicType(topic), 977 } 978 ps.handlePssMsg(context.TODO(), pssMsg) 979 if receives > 0 { 980 t.Fatalf("Expected handler not to be executed with raw cap off") 981 } 982 983 // now wrap the same handler function with raw capabilities and register it 984 hndlrRaw := &handler{ 985 f: rawHandlerFunc, 986 caps: &handlerCaps{ 987 raw: true, 988 }, 989 } 990 deregRawHandler := ps.Register(&topic, hndlrRaw) 991 992 // should work now 993 pssMsg.Payload.Data = []byte("Raw Deal") 994 ps.handlePssMsg(context.TODO(), pssMsg) 995 if receives == 0 { 996 t.Fatalf("Expected handler to be executed with raw cap on") 997 } 998 999 // now deregister the raw capable handler 1000 prevReceives := receives 1001 deregRawHandler() 1002 1003 // check that raw messages fail again 1004 pssMsg.Payload.Data = []byte("Raw Trump") 1005 ps.handlePssMsg(context.TODO(), pssMsg) 1006 if receives != prevReceives { 1007 t.Fatalf("Expected handler not to be executed when raw handler is retracted") 1008 } 1009 } 1010 1011 // BELOW HERE ARE TESTS USING THE SIMULATION FRAMEWORK 1012 1013 // tests that the API layer can handle edge case values 1014 func TestApi(t *testing.T) { 1015 clients, err := setupNetwork(2, true) 1016 if err != nil { 1017 t.Fatal(err) 1018 } 1019 1020 topic := "0xdeadbeef" 1021 1022 err = clients[0].Call(nil, "pss_sendRaw", "0x", topic, "0x666f6f") 1023 if err != nil { 1024 t.Fatal(err) 1025 } 1026 1027 err = clients[0].Call(nil, "pss_sendRaw", "0xabcdef", topic, "0x") 1028 if err == nil { 1029 t.Fatal("expected error on empty msg") 1030 } 1031 1032 overflowAddr := [33]byte{} 1033 err = clients[0].Call(nil, "pss_sendRaw", hexutil.Encode(overflowAddr[:]), topic, "0x666f6f") 1034 if err == nil { 1035 t.Fatal("expected error on send too big address") 1036 } 1037 } 1038 1039 // verifies that nodes can send and receive raw (verbatim) messages 1040 func TestSendRaw(t *testing.T) { 1041 t.Run("32", testSendRaw) 1042 t.Run("8", testSendRaw) 1043 t.Run("0", testSendRaw) 1044 } 1045 1046 func testSendRaw(t *testing.T) { 1047 1048 var addrsize int64 1049 var err error 1050 1051 paramstring := strings.Split(t.Name(), "/") 1052 1053 addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) 1054 log.Info("raw send test", "addrsize", addrsize) 1055 1056 clients, err := setupNetwork(2, true) 1057 if err != nil { 1058 t.Fatal(err) 1059 } 1060 1061 topic := "0xdeadbeef" 1062 1063 var loaddrhex string 1064 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 1065 if err != nil { 1066 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 1067 } 1068 loaddrhex = loaddrhex[:2+(addrsize*2)] 1069 var roaddrhex string 1070 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 1071 if err != nil { 1072 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 1073 } 1074 roaddrhex = roaddrhex[:2+(addrsize*2)] 1075 1076 time.Sleep(time.Millisecond * 500) 1077 1078 // at this point we've verified that symkeys are saved and match on each peer 1079 // now try sending symmetrically encrypted message, both directions 1080 lmsgC := make(chan APIMsg) 1081 lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) 1082 defer lcancel() 1083 lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, true, false) 1084 log.Trace("lsub", "id", lsub) 1085 defer lsub.Unsubscribe() 1086 rmsgC := make(chan APIMsg) 1087 rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) 1088 defer rcancel() 1089 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, true, false) 1090 log.Trace("rsub", "id", rsub) 1091 defer rsub.Unsubscribe() 1092 1093 // send and verify delivery 1094 lmsg := []byte("plugh") 1095 err = clients[1].Call(nil, "pss_sendRaw", loaddrhex, topic, hexutil.Encode(lmsg)) 1096 if err != nil { 1097 t.Fatal(err) 1098 } 1099 select { 1100 case recvmsg := <-lmsgC: 1101 if !bytes.Equal(recvmsg.Msg, lmsg) { 1102 t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg) 1103 } 1104 case cerr := <-lctx.Done(): 1105 t.Fatalf("test message (left) timed out: %v", cerr) 1106 } 1107 rmsg := []byte("xyzzy") 1108 err = clients[0].Call(nil, "pss_sendRaw", roaddrhex, topic, hexutil.Encode(rmsg)) 1109 if err != nil { 1110 t.Fatal(err) 1111 } 1112 select { 1113 case recvmsg := <-rmsgC: 1114 if !bytes.Equal(recvmsg.Msg, rmsg) { 1115 t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg) 1116 } 1117 case cerr := <-rctx.Done(): 1118 t.Fatalf("test message (right) timed out: %v", cerr) 1119 } 1120 } 1121 1122 // send symmetrically encrypted message between two directly connected peers 1123 func TestSendSym(t *testing.T) { 1124 t.Run("32", testSendSym) 1125 t.Run("8", testSendSym) 1126 t.Run("0", testSendSym) 1127 } 1128 1129 func testSendSym(t *testing.T) { 1130 1131 // address hint size 1132 var addrsize int64 1133 var err error 1134 paramstring := strings.Split(t.Name(), "/") 1135 addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) 1136 log.Info("sym send test", "addrsize", addrsize) 1137 1138 clients, err := setupNetwork(2, false) 1139 if err != nil { 1140 t.Fatal(err) 1141 } 1142 1143 var topic string 1144 err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") 1145 if err != nil { 1146 t.Fatal(err) 1147 } 1148 1149 var loaddrhex string 1150 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 1151 if err != nil { 1152 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 1153 } 1154 loaddrhex = loaddrhex[:2+(addrsize*2)] 1155 var roaddrhex string 1156 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 1157 if err != nil { 1158 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 1159 } 1160 roaddrhex = roaddrhex[:2+(addrsize*2)] 1161 1162 // retrieve public key from pss instance 1163 // set this public key reciprocally 1164 var lpubkeyhex string 1165 err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey") 1166 if err != nil { 1167 t.Fatalf("rpc get node 1 pubkey fail: %v", err) 1168 } 1169 var rpubkeyhex string 1170 err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey") 1171 if err != nil { 1172 t.Fatalf("rpc get node 2 pubkey fail: %v", err) 1173 } 1174 1175 time.Sleep(time.Millisecond * 500) 1176 1177 // at this point we've verified that symkeys are saved and match on each peer 1178 // now try sending symmetrically encrypted message, both directions 1179 lmsgC := make(chan APIMsg) 1180 lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) 1181 defer lcancel() 1182 lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, false, false) 1183 log.Trace("lsub", "id", lsub) 1184 defer lsub.Unsubscribe() 1185 rmsgC := make(chan APIMsg) 1186 rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) 1187 defer rcancel() 1188 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false) 1189 log.Trace("rsub", "id", rsub) 1190 defer rsub.Unsubscribe() 1191 1192 lrecvkey := network.RandomAddr().Over() 1193 rrecvkey := network.RandomAddr().Over() 1194 1195 var lkeyids [2]string 1196 var rkeyids [2]string 1197 1198 // manually set reciprocal symkeys 1199 err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex) 1200 if err != nil { 1201 t.Fatal(err) 1202 } 1203 err = clients[1].Call(&rkeyids, "psstest_setSymKeys", lpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex) 1204 if err != nil { 1205 t.Fatal(err) 1206 } 1207 1208 // send and verify delivery 1209 lmsg := []byte("plugh") 1210 err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg)) 1211 if err != nil { 1212 t.Fatal(err) 1213 } 1214 select { 1215 case recvmsg := <-lmsgC: 1216 if !bytes.Equal(recvmsg.Msg, lmsg) { 1217 t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg) 1218 } 1219 case cerr := <-lctx.Done(): 1220 t.Fatalf("test message timed out: %v", cerr) 1221 } 1222 rmsg := []byte("xyzzy") 1223 err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg)) 1224 if err != nil { 1225 t.Fatal(err) 1226 } 1227 select { 1228 case recvmsg := <-rmsgC: 1229 if !bytes.Equal(recvmsg.Msg, rmsg) { 1230 t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg) 1231 } 1232 case cerr := <-rctx.Done(): 1233 t.Fatalf("test message timed out: %v", cerr) 1234 } 1235 } 1236 1237 // send asymmetrically encrypted message between two directly connected peers 1238 func TestSendAsym(t *testing.T) { 1239 t.Run("32", testSendAsym) 1240 t.Run("8", testSendAsym) 1241 t.Run("0", testSendAsym) 1242 } 1243 1244 func testSendAsym(t *testing.T) { 1245 1246 // address hint size 1247 var addrsize int64 1248 var err error 1249 paramstring := strings.Split(t.Name(), "/") 1250 addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) 1251 log.Info("asym send test", "addrsize", addrsize) 1252 1253 clients, err := setupNetwork(2, false) 1254 if err != nil { 1255 t.Fatal(err) 1256 } 1257 1258 var topic string 1259 err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") 1260 if err != nil { 1261 t.Fatal(err) 1262 } 1263 1264 time.Sleep(time.Millisecond * 250) 1265 1266 var loaddrhex string 1267 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 1268 if err != nil { 1269 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 1270 } 1271 loaddrhex = loaddrhex[:2+(addrsize*2)] 1272 var roaddrhex string 1273 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 1274 if err != nil { 1275 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 1276 } 1277 roaddrhex = roaddrhex[:2+(addrsize*2)] 1278 1279 // retrieve public key from pss instance 1280 // set this public key reciprocally 1281 var lpubkey string 1282 err = clients[0].Call(&lpubkey, "pss_getPublicKey") 1283 if err != nil { 1284 t.Fatalf("rpc get node 1 pubkey fail: %v", err) 1285 } 1286 var rpubkey string 1287 err = clients[1].Call(&rpubkey, "pss_getPublicKey") 1288 if err != nil { 1289 t.Fatalf("rpc get node 2 pubkey fail: %v", err) 1290 } 1291 1292 time.Sleep(time.Millisecond * 500) // replace with hive healthy code 1293 1294 lmsgC := make(chan APIMsg) 1295 lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) 1296 defer lcancel() 1297 lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, false, false) 1298 log.Trace("lsub", "id", lsub) 1299 defer lsub.Unsubscribe() 1300 rmsgC := make(chan APIMsg) 1301 rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) 1302 defer rcancel() 1303 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false) 1304 log.Trace("rsub", "id", rsub) 1305 defer rsub.Unsubscribe() 1306 1307 // store reciprocal public keys 1308 err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex) 1309 if err != nil { 1310 t.Fatal(err) 1311 } 1312 err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex) 1313 if err != nil { 1314 t.Fatal(err) 1315 } 1316 1317 // send and verify delivery 1318 rmsg := []byte("xyzzy") 1319 err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg)) 1320 if err != nil { 1321 t.Fatal(err) 1322 } 1323 select { 1324 case recvmsg := <-rmsgC: 1325 if !bytes.Equal(recvmsg.Msg, rmsg) { 1326 t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg) 1327 } 1328 case cerr := <-rctx.Done(): 1329 t.Fatalf("test message timed out: %v", cerr) 1330 } 1331 lmsg := []byte("plugh") 1332 err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg)) 1333 if err != nil { 1334 t.Fatal(err) 1335 } 1336 select { 1337 case recvmsg := <-lmsgC: 1338 if !bytes.Equal(recvmsg.Msg, lmsg) { 1339 t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg) 1340 } 1341 case cerr := <-lctx.Done(): 1342 t.Fatalf("test message timed out: %v", cerr) 1343 } 1344 } 1345 1346 type Job struct { 1347 Msg []byte 1348 SendNode enode.ID 1349 RecvNode enode.ID 1350 } 1351 1352 func worker(id int, jobs <-chan Job, rpcs map[enode.ID]*rpc.Client, pubkeys map[enode.ID]string, topic string) { 1353 for j := range jobs { 1354 rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg)) 1355 } 1356 } 1357 1358 func TestNetwork(t *testing.T) { 1359 t.Run("16/1000/4/sim", testNetwork) 1360 } 1361 1362 // params in run name: 1363 // nodes/msgs/addrbytes/adaptertype 1364 // if adaptertype is exec uses execadapter, simadapter otherwise 1365 func TestNetwork2000(t *testing.T) { 1366 //enableMetrics() 1367 1368 if !*longrunning { 1369 t.Skip("run with --longrunning flag to run extensive network tests") 1370 } 1371 t.Run("3/2000/4/sim", testNetwork) 1372 t.Run("4/2000/4/sim", testNetwork) 1373 t.Run("8/2000/4/sim", testNetwork) 1374 t.Run("16/2000/4/sim", testNetwork) 1375 } 1376 1377 func TestNetwork5000(t *testing.T) { 1378 //enableMetrics() 1379 1380 if !*longrunning { 1381 t.Skip("run with --longrunning flag to run extensive network tests") 1382 } 1383 t.Run("3/5000/4/sim", testNetwork) 1384 t.Run("4/5000/4/sim", testNetwork) 1385 t.Run("8/5000/4/sim", testNetwork) 1386 t.Run("16/5000/4/sim", testNetwork) 1387 } 1388 1389 func TestNetwork10000(t *testing.T) { 1390 //enableMetrics() 1391 1392 if !*longrunning { 1393 t.Skip("run with --longrunning flag to run extensive network tests") 1394 } 1395 t.Run("3/10000/4/sim", testNetwork) 1396 t.Run("4/10000/4/sim", testNetwork) 1397 t.Run("8/10000/4/sim", testNetwork) 1398 } 1399 1400 func testNetwork(t *testing.T) { 1401 paramstring := strings.Split(t.Name(), "/") 1402 nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0) 1403 msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0) 1404 addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0) 1405 adapter := paramstring[4] 1406 1407 log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize) 1408 1409 nodes := make([]enode.ID, nodecount) 1410 bzzaddrs := make(map[enode.ID]string, nodecount) 1411 rpcs := make(map[enode.ID]*rpc.Client, nodecount) 1412 pubkeys := make(map[enode.ID]string, nodecount) 1413 1414 sentmsgs := make([][]byte, msgcount) 1415 recvmsgs := make([]bool, msgcount) 1416 nodemsgcount := make(map[enode.ID]int, nodecount) 1417 1418 trigger := make(chan enode.ID) 1419 1420 var a adapters.NodeAdapter 1421 if adapter == "exec" { 1422 dirname, err := ioutil.TempDir(".", "") 1423 if err != nil { 1424 t.Fatal(err) 1425 } 1426 a = adapters.NewExecAdapter(dirname) 1427 } else if adapter == "tcp" { 1428 a = adapters.NewTCPAdapter(newServices(false)) 1429 } else if adapter == "sim" { 1430 a = adapters.NewSimAdapter(newServices(false)) 1431 } 1432 net := simulations.NewNetwork(a, &simulations.NetworkConfig{ 1433 ID: "0", 1434 }) 1435 defer net.Shutdown() 1436 1437 f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount)) 1438 if err != nil { 1439 t.Fatal(err) 1440 } 1441 jsonbyte, err := ioutil.ReadAll(f) 1442 if err != nil { 1443 t.Fatal(err) 1444 } 1445 var snap simulations.Snapshot 1446 err = json.Unmarshal(jsonbyte, &snap) 1447 if err != nil { 1448 t.Fatal(err) 1449 } 1450 err = net.Load(&snap) 1451 if err != nil { 1452 //TODO: Fix p2p simulation framework to not crash when loading 32-nodes 1453 //t.Fatal(err) 1454 } 1455 1456 time.Sleep(1 * time.Second) 1457 1458 triggerChecks := func(trigger chan enode.ID, id enode.ID, rpcclient *rpc.Client, topic string) error { 1459 msgC := make(chan APIMsg) 1460 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 1461 defer cancel() 1462 sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic, false, false) 1463 if err != nil { 1464 t.Fatal(err) 1465 } 1466 go func() { 1467 defer sub.Unsubscribe() 1468 for { 1469 select { 1470 case recvmsg := <-msgC: 1471 idx, _ := binary.Uvarint(recvmsg.Msg) 1472 if !recvmsgs[idx] { 1473 log.Debug("msg recv", "idx", idx, "id", id) 1474 recvmsgs[idx] = true 1475 trigger <- id 1476 } 1477 case <-sub.Err(): 1478 return 1479 } 1480 } 1481 }() 1482 return nil 1483 } 1484 1485 var topic string 1486 for i, nod := range net.GetNodes() { 1487 nodes[i] = nod.ID() 1488 rpcs[nodes[i]], err = nod.Client() 1489 if err != nil { 1490 t.Fatal(err) 1491 } 1492 if topic == "" { 1493 err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42") 1494 if err != nil { 1495 t.Fatal(err) 1496 } 1497 } 1498 var pubkey string 1499 err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey") 1500 if err != nil { 1501 t.Fatal(err) 1502 } 1503 pubkeys[nod.ID()] = pubkey 1504 var addrhex string 1505 err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr") 1506 if err != nil { 1507 t.Fatal(err) 1508 } 1509 bzzaddrs[nodes[i]] = addrhex 1510 err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic) 1511 if err != nil { 1512 t.Fatal(err) 1513 } 1514 } 1515 1516 time.Sleep(1 * time.Second) 1517 1518 // setup workers 1519 jobs := make(chan Job, 10) 1520 for w := 1; w <= 10; w++ { 1521 go worker(w, jobs, rpcs, pubkeys, topic) 1522 } 1523 1524 time.Sleep(1 * time.Second) 1525 1526 for i := 0; i < int(msgcount); i++ { 1527 sendnodeidx := rand.Intn(int(nodecount)) 1528 recvnodeidx := rand.Intn(int(nodecount - 1)) 1529 if recvnodeidx >= sendnodeidx { 1530 recvnodeidx++ 1531 } 1532 nodemsgcount[nodes[recvnodeidx]]++ 1533 sentmsgs[i] = make([]byte, 8) 1534 c := binary.PutUvarint(sentmsgs[i], uint64(i)) 1535 if c == 0 { 1536 t.Fatal("0 byte message") 1537 } 1538 if err != nil { 1539 t.Fatal(err) 1540 } 1541 err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]]) 1542 if err != nil { 1543 t.Fatal(err) 1544 } 1545 1546 jobs <- Job{ 1547 Msg: sentmsgs[i], 1548 SendNode: nodes[sendnodeidx], 1549 RecvNode: nodes[recvnodeidx], 1550 } 1551 } 1552 1553 finalmsgcount := 0 1554 ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) 1555 defer cancel() 1556 outer: 1557 for i := 0; i < int(msgcount); i++ { 1558 select { 1559 case id := <-trigger: 1560 nodemsgcount[id]-- 1561 finalmsgcount++ 1562 case <-ctx.Done(): 1563 log.Warn("timeout") 1564 break outer 1565 } 1566 } 1567 1568 for i, msg := range recvmsgs { 1569 if !msg { 1570 log.Debug("missing message", "idx", i) 1571 } 1572 } 1573 t.Logf("%d of %d messages received", finalmsgcount, msgcount) 1574 1575 if finalmsgcount != int(msgcount) { 1576 t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount) 1577 } 1578 1579 } 1580 1581 // check that in a network of a -> b -> c -> a 1582 // a doesn't receive a sent message twice 1583 func TestDeduplication(t *testing.T) { 1584 var err error 1585 1586 clients, err := setupNetwork(3, false) 1587 if err != nil { 1588 t.Fatal(err) 1589 } 1590 1591 var addrsize = 32 1592 var loaddrhex string 1593 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 1594 if err != nil { 1595 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 1596 } 1597 loaddrhex = loaddrhex[:2+(addrsize*2)] 1598 var roaddrhex string 1599 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 1600 if err != nil { 1601 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 1602 } 1603 roaddrhex = roaddrhex[:2+(addrsize*2)] 1604 var xoaddrhex string 1605 err = clients[2].Call(&xoaddrhex, "pss_baseAddr") 1606 if err != nil { 1607 t.Fatalf("rpc get node 3 baseaddr fail: %v", err) 1608 } 1609 xoaddrhex = xoaddrhex[:2+(addrsize*2)] 1610 1611 log.Info("peer", "l", loaddrhex, "r", roaddrhex, "x", xoaddrhex) 1612 1613 var topic string 1614 err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") 1615 if err != nil { 1616 t.Fatal(err) 1617 } 1618 1619 time.Sleep(time.Millisecond * 250) 1620 1621 // retrieve public key from pss instance 1622 // set this public key reciprocally 1623 var rpubkey string 1624 err = clients[1].Call(&rpubkey, "pss_getPublicKey") 1625 if err != nil { 1626 t.Fatalf("rpc get receivenode pubkey fail: %v", err) 1627 } 1628 1629 time.Sleep(time.Millisecond * 500) // replace with hive healthy code 1630 1631 rmsgC := make(chan APIMsg) 1632 rctx, cancel := context.WithTimeout(context.Background(), time.Second*1) 1633 defer cancel() 1634 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false) 1635 log.Trace("rsub", "id", rsub) 1636 defer rsub.Unsubscribe() 1637 1638 // store public key for recipient 1639 // zero-length address means forward to all 1640 // we have just two peers, they will be in proxbin, and will both receive 1641 err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, "0x") 1642 if err != nil { 1643 t.Fatal(err) 1644 } 1645 1646 // send and verify delivery 1647 rmsg := []byte("xyzzy") 1648 err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg)) 1649 if err != nil { 1650 t.Fatal(err) 1651 } 1652 1653 var receivedok bool 1654 OUTER: 1655 for { 1656 select { 1657 case <-rmsgC: 1658 if receivedok { 1659 t.Fatalf("duplicate message received") 1660 } 1661 receivedok = true 1662 case <-rctx.Done(): 1663 break OUTER 1664 } 1665 } 1666 if !receivedok { 1667 t.Fatalf("message did not arrive") 1668 } 1669 } 1670 1671 // symmetric send performance with varying message sizes 1672 func BenchmarkSymkeySend(b *testing.B) { 1673 b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend) 1674 b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend) 1675 b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend) 1676 b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend) 1677 b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend) 1678 } 1679 1680 func benchmarkSymKeySend(b *testing.B) { 1681 msgsizestring := strings.Split(b.Name(), "/") 1682 if len(msgsizestring) != 2 { 1683 b.Fatalf("benchmark called without msgsize param") 1684 } 1685 msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0) 1686 if err != nil { 1687 b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err) 1688 } 1689 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1690 defer cancel() 1691 keys, err := wapi.NewKeyPair(ctx) 1692 privkey, err := w.GetPrivateKey(keys) 1693 ps := newTestPss(privkey, nil, nil) 1694 msg := make([]byte, msgsize) 1695 rand.Read(msg) 1696 topic := BytesToTopic([]byte("foo")) 1697 to := make(PssAddress, 32) 1698 copy(to[:], network.RandomAddr().Over()) 1699 symkeyid, err := ps.GenerateSymmetricKey(topic, to, true) 1700 if err != nil { 1701 b.Fatalf("could not generate symkey: %v", err) 1702 } 1703 symkey, err := ps.w.GetSymKey(symkeyid) 1704 if err != nil { 1705 b.Fatalf("could not retrieve symkey: %v", err) 1706 } 1707 ps.SetSymmetricKey(symkey, topic, to, false) 1708 1709 b.ResetTimer() 1710 for i := 0; i < b.N; i++ { 1711 ps.SendSym(symkeyid, topic, msg) 1712 } 1713 } 1714 1715 // asymmetric send performance with varying message sizes 1716 func BenchmarkAsymkeySend(b *testing.B) { 1717 b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend) 1718 b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend) 1719 b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend) 1720 b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend) 1721 b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend) 1722 } 1723 1724 func benchmarkAsymKeySend(b *testing.B) { 1725 msgsizestring := strings.Split(b.Name(), "/") 1726 if len(msgsizestring) != 2 { 1727 b.Fatalf("benchmark called without msgsize param") 1728 } 1729 msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0) 1730 if err != nil { 1731 b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err) 1732 } 1733 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1734 defer cancel() 1735 keys, err := wapi.NewKeyPair(ctx) 1736 privkey, err := w.GetPrivateKey(keys) 1737 ps := newTestPss(privkey, nil, nil) 1738 msg := make([]byte, msgsize) 1739 rand.Read(msg) 1740 topic := BytesToTopic([]byte("foo")) 1741 to := make(PssAddress, 32) 1742 copy(to[:], network.RandomAddr().Over()) 1743 ps.SetPeerPublicKey(&privkey.PublicKey, topic, to) 1744 b.ResetTimer() 1745 for i := 0; i < b.N; i++ { 1746 ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg) 1747 } 1748 } 1749 func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) { 1750 for i := 100; i < 100000; i = i * 10 { 1751 for j := 32; j < 10000; j = j * 8 { 1752 b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr) 1753 } 1754 //b.Run(fmt.Sprintf("%d", i), benchmarkSymkeyBruteforceChangeaddr) 1755 } 1756 } 1757 1758 // decrypt performance using symkey cache, worst case 1759 // (decrypt key always last in cache) 1760 func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) { 1761 keycountstring := strings.Split(b.Name(), "/") 1762 cachesize := int64(0) 1763 var ps *Pss 1764 if len(keycountstring) < 2 { 1765 b.Fatalf("benchmark called without count param") 1766 } 1767 keycount, err := strconv.ParseInt(keycountstring[1], 10, 0) 1768 if err != nil { 1769 b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err) 1770 } 1771 if len(keycountstring) == 3 { 1772 cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0) 1773 if err != nil { 1774 b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err) 1775 } 1776 } 1777 pssmsgs := make([]*PssMsg, 0, keycount) 1778 var keyid string 1779 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1780 defer cancel() 1781 keys, err := wapi.NewKeyPair(ctx) 1782 privkey, err := w.GetPrivateKey(keys) 1783 if cachesize > 0 { 1784 ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)}) 1785 } else { 1786 ps = newTestPss(privkey, nil, nil) 1787 } 1788 topic := BytesToTopic([]byte("foo")) 1789 for i := 0; i < int(keycount); i++ { 1790 to := make(PssAddress, 32) 1791 copy(to[:], network.RandomAddr().Over()) 1792 keyid, err = ps.GenerateSymmetricKey(topic, to, true) 1793 if err != nil { 1794 b.Fatalf("cant generate symkey #%d: %v", i, err) 1795 } 1796 symkey, err := ps.w.GetSymKey(keyid) 1797 if err != nil { 1798 b.Fatalf("could not retrieve symkey %s: %v", keyid, err) 1799 } 1800 wparams := &whisper.MessageParams{ 1801 TTL: defaultWhisperTTL, 1802 KeySym: symkey, 1803 Topic: whisper.TopicType(topic), 1804 WorkTime: defaultWhisperWorkTime, 1805 PoW: defaultWhisperPoW, 1806 Payload: []byte("xyzzy"), 1807 Padding: []byte("1234567890abcdef"), 1808 } 1809 woutmsg, err := whisper.NewSentMessage(wparams) 1810 if err != nil { 1811 b.Fatalf("could not create whisper message: %v", err) 1812 } 1813 env, err := woutmsg.Wrap(wparams) 1814 if err != nil { 1815 b.Fatalf("could not generate whisper envelope: %v", err) 1816 } 1817 ps.Register(&topic, &handler{ 1818 f: noopHandlerFunc, 1819 }) 1820 pssmsgs = append(pssmsgs, &PssMsg{ 1821 To: to, 1822 Payload: env, 1823 }) 1824 } 1825 b.ResetTimer() 1826 for i := 0; i < b.N; i++ { 1827 if err := ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1], false, false); err != nil { 1828 b.Fatalf("pss processing failed: %v", err) 1829 } 1830 } 1831 } 1832 1833 func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) { 1834 for i := 100; i < 100000; i = i * 10 { 1835 for j := 32; j < 10000; j = j * 8 { 1836 b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr) 1837 } 1838 } 1839 } 1840 1841 // decrypt performance using symkey cache, best case 1842 // (decrypt key always first in cache) 1843 func benchmarkSymkeyBruteforceSameaddr(b *testing.B) { 1844 var keyid string 1845 var ps *Pss 1846 cachesize := int64(0) 1847 keycountstring := strings.Split(b.Name(), "/") 1848 if len(keycountstring) < 2 { 1849 b.Fatalf("benchmark called without count param") 1850 } 1851 keycount, err := strconv.ParseInt(keycountstring[1], 10, 0) 1852 if err != nil { 1853 b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err) 1854 } 1855 if len(keycountstring) == 3 { 1856 cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0) 1857 if err != nil { 1858 b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err) 1859 } 1860 } 1861 addr := make([]PssAddress, keycount) 1862 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1863 defer cancel() 1864 keys, err := wapi.NewKeyPair(ctx) 1865 privkey, err := w.GetPrivateKey(keys) 1866 if cachesize > 0 { 1867 ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)}) 1868 } else { 1869 ps = newTestPss(privkey, nil, nil) 1870 } 1871 topic := BytesToTopic([]byte("foo")) 1872 for i := 0; i < int(keycount); i++ { 1873 copy(addr[i], network.RandomAddr().Over()) 1874 keyid, err = ps.GenerateSymmetricKey(topic, addr[i], true) 1875 if err != nil { 1876 b.Fatalf("cant generate symkey #%d: %v", i, err) 1877 } 1878 1879 } 1880 symkey, err := ps.w.GetSymKey(keyid) 1881 if err != nil { 1882 b.Fatalf("could not retrieve symkey %s: %v", keyid, err) 1883 } 1884 wparams := &whisper.MessageParams{ 1885 TTL: defaultWhisperTTL, 1886 KeySym: symkey, 1887 Topic: whisper.TopicType(topic), 1888 WorkTime: defaultWhisperWorkTime, 1889 PoW: defaultWhisperPoW, 1890 Payload: []byte("xyzzy"), 1891 Padding: []byte("1234567890abcdef"), 1892 } 1893 woutmsg, err := whisper.NewSentMessage(wparams) 1894 if err != nil { 1895 b.Fatalf("could not create whisper message: %v", err) 1896 } 1897 env, err := woutmsg.Wrap(wparams) 1898 if err != nil { 1899 b.Fatalf("could not generate whisper envelope: %v", err) 1900 } 1901 ps.Register(&topic, &handler{ 1902 f: noopHandlerFunc, 1903 }) 1904 pssmsg := &PssMsg{ 1905 To: addr[len(addr)-1][:], 1906 Payload: env, 1907 } 1908 for i := 0; i < b.N; i++ { 1909 if err := ps.process(pssmsg, false, false); err != nil { 1910 b.Fatalf("pss processing failed: %v", err) 1911 } 1912 } 1913 } 1914 1915 // setup simulated network with bzz/discovery and pss services. 1916 // connects nodes in a circle 1917 // if allowRaw is set, omission of builtin pss encryption is enabled (see PssParams) 1918 func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) { 1919 nodes := make([]*simulations.Node, numnodes) 1920 clients = make([]*rpc.Client, numnodes) 1921 if numnodes < 2 { 1922 return nil, fmt.Errorf("Minimum two nodes in network") 1923 } 1924 adapter := adapters.NewSimAdapter(newServices(allowRaw)) 1925 net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 1926 ID: "0", 1927 DefaultService: "bzz", 1928 }) 1929 for i := 0; i < numnodes; i++ { 1930 nodeconf := adapters.RandomNodeConfig() 1931 nodeconf.Services = []string{"bzz", pssProtocolName} 1932 nodes[i], err = net.NewNodeWithConfig(nodeconf) 1933 if err != nil { 1934 return nil, fmt.Errorf("error creating node 1: %v", err) 1935 } 1936 err = net.Start(nodes[i].ID()) 1937 if err != nil { 1938 return nil, fmt.Errorf("error starting node 1: %v", err) 1939 } 1940 if i > 0 { 1941 err = net.Connect(nodes[i].ID(), nodes[i-1].ID()) 1942 if err != nil { 1943 return nil, fmt.Errorf("error connecting nodes: %v", err) 1944 } 1945 } 1946 clients[i], err = nodes[i].Client() 1947 if err != nil { 1948 return nil, fmt.Errorf("create node 1 rpc client fail: %v", err) 1949 } 1950 } 1951 if numnodes > 2 { 1952 err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID()) 1953 if err != nil { 1954 return nil, fmt.Errorf("error connecting first and last nodes") 1955 } 1956 } 1957 return clients, nil 1958 } 1959 1960 func newServices(allowRaw bool) adapters.Services { 1961 stateStore := state.NewInmemoryStore() 1962 kademlias := make(map[enode.ID]*network.Kademlia) 1963 kademlia := func(id enode.ID) *network.Kademlia { 1964 if k, ok := kademlias[id]; ok { 1965 return k 1966 } 1967 params := network.NewKadParams() 1968 params.NeighbourhoodSize = 2 1969 params.MaxBinSize = 3 1970 params.MinBinSize = 1 1971 params.MaxRetries = 1000 1972 params.RetryExponent = 2 1973 params.RetryInterval = 1000000 1974 kademlias[id] = network.NewKademlia(id[:], params) 1975 return kademlias[id] 1976 } 1977 return adapters.Services{ 1978 pssProtocolName: func(ctx *adapters.ServiceContext) (node.Service, error) { 1979 // execadapter does not exec init() 1980 initTest() 1981 1982 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 1983 defer cancel() 1984 keys, err := wapi.NewKeyPair(ctxlocal) 1985 privkey, err := w.GetPrivateKey(keys) 1986 pssp := NewPssParams().WithPrivateKey(privkey) 1987 pssp.AllowRaw = allowRaw 1988 pskad := kademlia(ctx.Config.ID) 1989 ps, err := NewPss(pskad, pssp) 1990 if err != nil { 1991 return nil, err 1992 } 1993 1994 ping := &Ping{ 1995 OutC: make(chan bool), 1996 Pong: true, 1997 } 1998 p2pp := NewPingProtocol(ping) 1999 pp, err := RegisterProtocol(ps, &PingTopic, PingProtocol, p2pp, &ProtocolParams{Asymmetric: true}) 2000 if err != nil { 2001 return nil, err 2002 } 2003 if useHandshake { 2004 SetHandshakeController(ps, NewHandshakeParams()) 2005 } 2006 ps.Register(&PingTopic, &handler{ 2007 f: pp.Handle, 2008 caps: &handlerCaps{ 2009 raw: true, 2010 }, 2011 }) 2012 ps.addAPI(rpc.API{ 2013 Namespace: "psstest", 2014 Version: "0.3", 2015 Service: NewAPITest(ps), 2016 Public: false, 2017 }) 2018 if err != nil { 2019 log.Error("Couldnt register pss protocol", "err", err) 2020 os.Exit(1) 2021 } 2022 pssprotocols[ctx.Config.ID.String()] = &protoCtrl{ 2023 C: ping.OutC, 2024 protocol: pp, 2025 run: p2pp.Run, 2026 } 2027 return ps, nil 2028 }, 2029 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 2030 addr := network.NewAddr(ctx.Config.Node()) 2031 hp := network.NewHiveParams() 2032 hp.Discovery = false 2033 config := &network.BzzConfig{ 2034 OverlayAddr: addr.Over(), 2035 UnderlayAddr: addr.Under(), 2036 HiveParams: hp, 2037 } 2038 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 2039 }, 2040 } 2041 } 2042 2043 func newTestPss(privkey *ecdsa.PrivateKey, kad *network.Kademlia, ppextra *PssParams) *Pss { 2044 nid := enode.PubkeyToIDV4(&privkey.PublicKey) 2045 // set up routing if kademlia is not passed to us 2046 if kad == nil { 2047 kp := network.NewKadParams() 2048 kp.NeighbourhoodSize = 3 2049 kad = network.NewKademlia(nid[:], kp) 2050 } 2051 2052 // create pss 2053 pp := NewPssParams().WithPrivateKey(privkey) 2054 if ppextra != nil { 2055 pp.SymKeyCacheCapacity = ppextra.SymKeyCacheCapacity 2056 } 2057 ps, err := NewPss(kad, pp) 2058 if err != nil { 2059 return nil 2060 } 2061 ps.Start(nil) 2062 2063 return ps 2064 } 2065 2066 // API calls for test/development use 2067 type APITest struct { 2068 *Pss 2069 } 2070 2071 func NewAPITest(ps *Pss) *APITest { 2072 return &APITest{Pss: ps} 2073 } 2074 2075 func (apitest *APITest) SetSymKeys(pubkeyid string, recvsymkey []byte, sendsymkey []byte, limit uint16, topic Topic, to hexutil.Bytes) ([2]string, error) { 2076 2077 recvsymkeyid, err := apitest.SetSymmetricKey(recvsymkey, topic, PssAddress(to), true) 2078 if err != nil { 2079 return [2]string{}, err 2080 } 2081 sendsymkeyid, err := apitest.SetSymmetricKey(sendsymkey, topic, PssAddress(to), false) 2082 if err != nil { 2083 return [2]string{}, err 2084 } 2085 return [2]string{recvsymkeyid, sendsymkeyid}, nil 2086 } 2087 2088 func (apitest *APITest) Clean() (int, error) { 2089 return apitest.Pss.cleanKeys(), nil 2090 } 2091 2092 // enableMetrics is starting InfluxDB reporter so that we collect stats when running tests locally 2093 func enableMetrics() { 2094 metrics.Enabled = true 2095 go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 1*time.Second, "http://localhost:8086", "metrics", "admin", "admin", "swarm.", map[string]string{ 2096 "host": "test", 2097 }) 2098 }