github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/pss/pss_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package pss 26 27 import ( 28 "bytes" 29 "context" 30 "crypto/ecdsa" 31 "encoding/binary" 32 "encoding/hex" 33 "encoding/json" 34 "flag" 35 "fmt" 36 "io/ioutil" 37 "math/rand" 38 "os" 39 "strconv" 40 "strings" 41 "sync" 42 "testing" 43 "time" 44 45 "github.com/ethereum/go-ethereum/common" 46 "github.com/ethereum/go-ethereum/common/hexutil" 47 "github.com/ethereum/go-ethereum/crypto" 48 "github.com/ethereum/go-ethereum/log" 49 "github.com/ethereum/go-ethereum/metrics" 50 "github.com/ethereum/go-ethereum/metrics/influxdb" 51 "github.com/ethereum/go-ethereum/node" 52 "github.com/ethereum/go-ethereum/p2p" 53 "github.com/ethereum/go-ethereum/p2p/discover" 54 "github.com/ethereum/go-ethereum/p2p/protocols" 55 "github.com/ethereum/go-ethereum/p2p/simulations" 56 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 57 "github.com/ethereum/go-ethereum/rpc" 58 "github.com/ethereum/go-ethereum/swarm/network" 59 "github.com/ethereum/go-ethereum/swarm/state" 60 whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" 61 ) 62 63 var ( 64 initOnce = sync.Once{} 65 debugdebugflag = flag.Bool("vv", false, "veryverbose") 66 debugflag = flag.Bool("v", false, "verbose") 67 longrunning = flag.Bool("longrunning", false, "do run long-running tests") 68 w *whisper.Whisper 69 wapi *whisper.PublicWhisperAPI 70 psslogmain log.Logger 71 pssprotocols map[string]*protoCtrl 72 useHandshake bool 73 ) 74 75 func init() { 76 flag.Parse() 77 rand.Seed(time.Now().Unix()) 78 79 adapters.RegisterServices(newServices(false)) 80 initTest() 81 } 82 83 func initTest() { 84 initOnce.Do( 85 func() { 86 loglevel := log.LvlInfo 87 if *debugflag { 88 loglevel = log.LvlDebug 89 } else if *debugdebugflag { 90 loglevel = log.LvlTrace 91 } 92 93 psslogmain = log.New("psslog", "*") 94 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 95 hf := log.LvlFilterHandler(loglevel, hs) 96 h := log.CallerFileHandler(hf) 97 log.Root().SetHandler(h) 98 99 w = whisper.New(&whisper.DefaultConfig) 100 wapi = whisper.NewPublicWhisperAPI(w) 101 102 pssprotocols = make(map[string]*protoCtrl) 103 }, 104 ) 105 } 106 107 // 108 func TestTopic(t *testing.T) { 109 110 api := &API{} 111 112 topicstr := strings.Join([]string{PingProtocol.Name, strconv.Itoa(int(PingProtocol.Version))}, ":") 113 114 // 115 topicobj := BytesToTopic([]byte(topicstr)) 116 117 // 118 topicapiobj, _ := api.StringToTopic(topicstr) 119 if topicobj != topicapiobj { 120 t.Fatalf("bytes and string topic conversion mismatch; %s != %s", topicobj, topicapiobj) 121 } 122 123 // 124 topichex := topicobj.String() 125 126 // 127 // 128 pingtopichex := PingTopic.String() 129 if topichex != pingtopichex { 130 t.Fatalf("protocol topic conversion mismatch; %s != %s", topichex, pingtopichex) 131 } 132 133 // 134 topicjsonout, err := topicobj.MarshalJSON() 135 if err != nil { 136 t.Fatal(err) 137 } 138 if string(topicjsonout)[1:len(topicjsonout)-1] != topichex { 139 t.Fatalf("topic json marshal mismatch; %s != \"%s\"", topicjsonout, topichex) 140 } 141 142 // 143 var topicjsonin Topic 144 topicjsonin.UnmarshalJSON(topicjsonout) 145 if topicjsonin != topicobj { 146 t.Fatalf("topic json unmarshal mismatch: %x != %x", topicjsonin, topicobj) 147 } 148 } 149 150 // 151 func TestMsgParams(t *testing.T) { 152 var ctrl byte 153 ctrl |= pssControlRaw 154 p := newMsgParamsFromBytes([]byte{ctrl}) 155 m := newPssMsg(p) 156 if !m.isRaw() || m.isSym() { 157 t.Fatal("expected raw=true and sym=false") 158 } 159 ctrl |= pssControlSym 160 p = newMsgParamsFromBytes([]byte{ctrl}) 161 m = newPssMsg(p) 162 if !m.isRaw() || !m.isSym() { 163 t.Fatal("expected raw=true and sym=true") 164 } 165 ctrl &= 0xff &^ pssControlRaw 166 p = newMsgParamsFromBytes([]byte{ctrl}) 167 m = newPssMsg(p) 168 if m.isRaw() || !m.isSym() { 169 t.Fatal("expected raw=false and sym=true") 170 } 171 } 172 173 // 174 func TestCache(t *testing.T) { 175 var err error 176 to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f") 177 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 178 defer cancel() 179 keys, err := wapi.NewKeyPair(ctx) 180 privkey, err := w.GetPrivateKey(keys) 181 if err != nil { 182 t.Fatal(err) 183 } 184 ps := newTestPss(privkey, nil, nil) 185 pp := NewPssParams().WithPrivateKey(privkey) 186 data := []byte("foo") 187 datatwo := []byte("bar") 188 datathree := []byte("baz") 189 wparams := &whisper.MessageParams{ 190 TTL: defaultWhisperTTL, 191 Src: privkey, 192 Dst: &privkey.PublicKey, 193 Topic: whisper.TopicType(PingTopic), 194 WorkTime: defaultWhisperWorkTime, 195 PoW: defaultWhisperPoW, 196 Payload: data, 197 } 198 woutmsg, err := whisper.NewSentMessage(wparams) 199 env, err := woutmsg.Wrap(wparams) 200 msg := &PssMsg{ 201 Payload: env, 202 To: to, 203 } 204 wparams.Payload = datatwo 205 woutmsg, err = whisper.NewSentMessage(wparams) 206 envtwo, err := woutmsg.Wrap(wparams) 207 msgtwo := &PssMsg{ 208 Payload: envtwo, 209 To: to, 210 } 211 wparams.Payload = datathree 212 woutmsg, err = whisper.NewSentMessage(wparams) 213 envthree, err := woutmsg.Wrap(wparams) 214 msgthree := &PssMsg{ 215 Payload: envthree, 216 To: to, 217 } 218 219 digest := ps.digest(msg) 220 if err != nil { 221 t.Fatalf("could not store cache msgone: %v", err) 222 } 223 digesttwo := ps.digest(msgtwo) 224 if err != nil { 225 t.Fatalf("could not store cache msgtwo: %v", err) 226 } 227 digestthree := ps.digest(msgthree) 228 if err != nil { 229 t.Fatalf("could not store cache msgthree: %v", err) 230 } 231 232 if digest == digesttwo { 233 t.Fatalf("different msgs return same hash: %d", digesttwo) 234 } 235 236 // 237 err = ps.addFwdCache(msg) 238 if err != nil { 239 t.Fatalf("write to pss expire cache failed: %v", err) 240 } 241 242 if !ps.checkFwdCache(msg) { 243 t.Fatalf("message %v should have EXPIRE record in cache but checkCache returned false", msg) 244 } 245 246 if ps.checkFwdCache(msgtwo) { 247 t.Fatalf("message %v should NOT have EXPIRE record in cache but checkCache returned true", msgtwo) 248 } 249 250 time.Sleep(pp.CacheTTL + 1*time.Second) 251 err = ps.addFwdCache(msgthree) 252 if err != nil { 253 t.Fatalf("write to pss expire cache failed: %v", err) 254 } 255 256 if ps.checkFwdCache(msg) { 257 t.Fatalf("message %v should have expired from cache but checkCache returned true", msg) 258 } 259 260 if _, ok := ps.fwdCache[digestthree]; !ok { 261 t.Fatalf("unexpired message should be in the cache: %v", digestthree) 262 } 263 264 if _, ok := ps.fwdCache[digesttwo]; ok { 265 t.Fatalf("expired message should have been cleared from the cache: %v", digesttwo) 266 } 267 } 268 269 // 270 func TestAddressMatch(t *testing.T) { 271 272 localaddr := network.RandomAddr().Over() 273 copy(localaddr[:8], []byte("deadbeef")) 274 remoteaddr := []byte("feedbeef") 275 kadparams := network.NewKadParams() 276 kad := network.NewKademlia(localaddr, kadparams) 277 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 278 defer cancel() 279 keys, err := wapi.NewKeyPair(ctx) 280 if err != nil { 281 t.Fatalf("Could not generate private key: %v", err) 282 } 283 privkey, err := w.GetPrivateKey(keys) 284 pssp := NewPssParams().WithPrivateKey(privkey) 285 ps, err := NewPss(kad, pssp) 286 if err != nil { 287 t.Fatal(err.Error()) 288 } 289 290 pssmsg := &PssMsg{ 291 To: remoteaddr, 292 Payload: &whisper.Envelope{}, 293 } 294 295 // 296 if ps.isSelfRecipient(pssmsg) { 297 t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr) 298 } 299 if ps.isSelfPossibleRecipient(pssmsg) { 300 t.Fatalf("isSelfPossibleRecipient true but %x != %x", remoteaddr[:8], localaddr[:8]) 301 } 302 303 // 304 copy(remoteaddr[:4], localaddr[:4]) 305 if ps.isSelfRecipient(pssmsg) { 306 t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr) 307 } 308 if !ps.isSelfPossibleRecipient(pssmsg) { 309 t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8]) 310 } 311 312 // 313 pssmsg.To = localaddr 314 if !ps.isSelfRecipient(pssmsg) { 315 t.Fatalf("isSelfRecipient false but %x == %x", remoteaddr, localaddr) 316 } 317 if !ps.isSelfPossibleRecipient(pssmsg) { 318 t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8]) 319 } 320 } 321 322 // 323 func TestHandlerConditions(t *testing.T) { 324 325 t.Skip("Disabled due to probable faulty logic for outbox expectations") 326 // 327 privkey, err := crypto.GenerateKey() 328 if err != nil { 329 t.Fatal(err.Error()) 330 } 331 332 addr := make([]byte, 32) 333 addr[0] = 0x01 334 ps := newTestPss(privkey, network.NewKademlia(addr, network.NewKadParams()), NewPssParams()) 335 336 // 337 msg := &PssMsg{ 338 To: addr, 339 Expire: uint32(time.Now().Add(time.Second * 60).Unix()), 340 Payload: &whisper.Envelope{ 341 Topic: [4]byte{}, 342 Data: []byte{0x66, 0x6f, 0x6f}, 343 }, 344 } 345 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 346 t.Fatal(err.Error()) 347 } 348 tmr := time.NewTimer(time.Millisecond * 100) 349 var outmsg *PssMsg 350 select { 351 case outmsg = <-ps.outbox: 352 case <-tmr.C: 353 default: 354 } 355 if outmsg != nil { 356 t.Fatalf("expected outbox empty after full address on msg, but had message %s", msg) 357 } 358 359 // 360 msg.To = addr[0:1] 361 msg.Payload.Data = []byte{0x78, 0x79, 0x80, 0x80, 0x79} 362 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 363 t.Fatal(err.Error()) 364 } 365 tmr.Reset(time.Millisecond * 100) 366 outmsg = nil 367 select { 368 case outmsg = <-ps.outbox: 369 case <-tmr.C: 370 } 371 if outmsg == nil { 372 t.Fatal("expected message in outbox on encrypt fail, but empty") 373 } 374 outmsg = nil 375 select { 376 case outmsg = <-ps.outbox: 377 default: 378 } 379 if outmsg != nil { 380 t.Fatalf("expected only one queued message but also had message %v", msg) 381 } 382 383 // 384 msg.To[0] = 0xff 385 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 386 t.Fatal(err.Error()) 387 } 388 tmr.Reset(time.Millisecond * 10) 389 outmsg = nil 390 select { 391 case outmsg = <-ps.outbox: 392 case <-tmr.C: 393 } 394 if outmsg == nil { 395 t.Fatal("expected message in outbox on address mismatch, but empty") 396 } 397 outmsg = nil 398 select { 399 case outmsg = <-ps.outbox: 400 default: 401 } 402 if outmsg != nil { 403 t.Fatalf("expected only one queued message but also had message %v", msg) 404 } 405 406 // 407 msg.Expire = uint32(time.Now().Add(-time.Second).Unix()) 408 if err := ps.handlePssMsg(context.TODO(), msg); err != nil { 409 t.Fatal(err.Error()) 410 } 411 tmr.Reset(time.Millisecond * 10) 412 outmsg = nil 413 select { 414 case outmsg = <-ps.outbox: 415 case <-tmr.C: 416 default: 417 } 418 if outmsg != nil { 419 t.Fatalf("expected empty queue but have message %v", msg) 420 } 421 422 // 423 fckedupmsg := &struct { 424 pssMsg *PssMsg 425 }{ 426 pssMsg: &PssMsg{}, 427 } 428 if err := ps.handlePssMsg(context.TODO(), fckedupmsg); err == nil { 429 t.Fatalf("expected error from processMsg but error nil") 430 } 431 432 // 433 msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix()) 434 for i := 0; i < defaultOutboxCapacity; i++ { 435 ps.outbox <- msg 436 } 437 msg.Payload.Data = []byte{0x62, 0x61, 0x72} 438 err = ps.handlePssMsg(context.TODO(), msg) 439 if err == nil { 440 t.Fatal("expected error when mailbox full, but was nil") 441 } 442 } 443 444 // 445 func TestKeys(t *testing.T) { 446 // 447 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 448 defer cancel() 449 ourkeys, err := wapi.NewKeyPair(ctx) 450 if err != nil { 451 t.Fatalf("create 'our' key fail") 452 } 453 ctx, cancel2 := context.WithTimeout(context.Background(), time.Second) 454 defer cancel2() 455 theirkeys, err := wapi.NewKeyPair(ctx) 456 if err != nil { 457 t.Fatalf("create 'their' key fail") 458 } 459 ourprivkey, err := w.GetPrivateKey(ourkeys) 460 if err != nil { 461 t.Fatalf("failed to retrieve 'our' private key") 462 } 463 theirprivkey, err := w.GetPrivateKey(theirkeys) 464 if err != nil { 465 t.Fatalf("failed to retrieve 'their' private key") 466 } 467 ps := newTestPss(ourprivkey, nil, nil) 468 469 // 470 addr := make(PssAddress, 32) 471 copy(addr, network.RandomAddr().Over()) 472 outkey := network.RandomAddr().Over() 473 topicobj := BytesToTopic([]byte("foo:42")) 474 ps.SetPeerPublicKey(&theirprivkey.PublicKey, topicobj, &addr) 475 outkeyid, err := ps.SetSymmetricKey(outkey, topicobj, &addr, false) 476 if err != nil { 477 t.Fatalf("failed to set 'our' outgoing symmetric key") 478 } 479 480 // 481 inkeyid, err := ps.GenerateSymmetricKey(topicobj, &addr, true) 482 if err != nil { 483 t.Fatalf("failed to set 'our' incoming symmetric key") 484 } 485 486 // 487 outkeyback, err := ps.w.GetSymKey(outkeyid) 488 if err != nil { 489 t.Fatalf(err.Error()) 490 } 491 inkey, err := ps.w.GetSymKey(inkeyid) 492 if err != nil { 493 t.Fatalf(err.Error()) 494 } 495 if !bytes.Equal(outkeyback, outkey) { 496 t.Fatalf("passed outgoing symkey doesnt equal stored: %x / %x", outkey, outkeyback) 497 } 498 499 t.Logf("symout: %v", outkeyback) 500 t.Logf("symin: %v", inkey) 501 502 // 503 psp := ps.symKeyPool[inkeyid][topicobj] 504 if psp.address != &addr { 505 t.Fatalf("inkey address does not match; %p != %p", psp.address, &addr) 506 } 507 } 508 509 func TestGetPublickeyEntries(t *testing.T) { 510 511 privkey, err := crypto.GenerateKey() 512 if err != nil { 513 t.Fatal(err) 514 } 515 ps := newTestPss(privkey, nil, nil) 516 517 peeraddr := network.RandomAddr().Over() 518 topicaddr := make(map[Topic]PssAddress) 519 topicaddr[Topic{0x13}] = peeraddr 520 topicaddr[Topic{0x2a}] = peeraddr[:16] 521 topicaddr[Topic{0x02, 0x9a}] = []byte{} 522 523 remoteprivkey, err := crypto.GenerateKey() 524 if err != nil { 525 t.Fatal(err) 526 } 527 remotepubkeybytes := crypto.FromECDSAPub(&remoteprivkey.PublicKey) 528 remotepubkeyhex := common.ToHex(remotepubkeybytes) 529 530 pssapi := NewAPI(ps) 531 532 for to, a := range topicaddr { 533 err = pssapi.SetPeerPublicKey(remotepubkeybytes, to, a) 534 if err != nil { 535 t.Fatal(err) 536 } 537 } 538 539 intopic, err := pssapi.GetPeerTopics(remotepubkeyhex) 540 if err != nil { 541 t.Fatal(err) 542 } 543 544 OUTER: 545 for _, tnew := range intopic { 546 for torig, addr := range topicaddr { 547 if bytes.Equal(torig[:], tnew[:]) { 548 inaddr, err := pssapi.GetPeerAddress(remotepubkeyhex, torig) 549 if err != nil { 550 t.Fatal(err) 551 } 552 if !bytes.Equal(addr, inaddr) { 553 t.Fatalf("Address mismatch for topic %x; got %x, expected %x", torig, inaddr, addr) 554 } 555 delete(topicaddr, torig) 556 continue OUTER 557 } 558 } 559 t.Fatalf("received topic %x did not match any existing topics", tnew) 560 } 561 562 if len(topicaddr) != 0 { 563 t.Fatalf("%d topics were not matched", len(topicaddr)) 564 } 565 } 566 567 type pssTestPeer struct { 568 *protocols.Peer 569 addr []byte 570 } 571 572 func (t *pssTestPeer) Address() []byte { 573 return t.addr 574 } 575 576 func (t *pssTestPeer) Update(addr network.OverlayAddr) network.OverlayAddr { 577 return addr 578 } 579 580 func (t *pssTestPeer) Off() network.OverlayAddr { 581 return &pssTestPeer{} 582 } 583 584 // 585 func TestMismatch(t *testing.T) { 586 587 // 588 privkey, err := crypto.GenerateKey() 589 if err != nil { 590 t.Fatal(err) 591 } 592 593 // 594 baseaddr := network.RandomAddr() 595 kad := network.NewKademlia((baseaddr).Over(), network.NewKadParams()) 596 rw := &p2p.MsgPipeRW{} 597 598 // 599 wrongpssaddr := network.RandomAddr() 600 wrongpsscap := p2p.Cap{ 601 Name: pssProtocolName, 602 Version: 0, 603 } 604 nid, _ := discover.HexID("0x01") 605 wrongpsspeer := &pssTestPeer{ 606 Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(wrongpssaddr.Over()), []p2p.Cap{wrongpsscap}), rw, nil), 607 addr: wrongpssaddr.Over(), 608 } 609 610 // 611 nopssaddr := network.RandomAddr() 612 nopsscap := p2p.Cap{ 613 Name: "nopss", 614 Version: 1, 615 } 616 nid, _ = discover.HexID("0x02") 617 nopsspeer := &pssTestPeer{ 618 Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(nopssaddr.Over()), []p2p.Cap{nopsscap}), rw, nil), 619 addr: nopssaddr.Over(), 620 } 621 622 // 623 // 624 kad.Register([]network.OverlayAddr{wrongpsspeer}) 625 kad.On(wrongpsspeer) 626 kad.Register([]network.OverlayAddr{nopsspeer}) 627 kad.On(nopsspeer) 628 629 // 630 pssmsg := &PssMsg{ 631 To: []byte{}, 632 Expire: uint32(time.Now().Add(time.Second).Unix()), 633 Payload: &whisper.Envelope{}, 634 } 635 ps := newTestPss(privkey, kad, nil) 636 637 // 638 // 639 ps.forward(pssmsg) 640 641 } 642 643 func TestSendRaw(t *testing.T) { 644 t.Run("32", testSendRaw) 645 t.Run("8", testSendRaw) 646 t.Run("0", testSendRaw) 647 } 648 649 func testSendRaw(t *testing.T) { 650 651 var addrsize int64 652 var err error 653 654 paramstring := strings.Split(t.Name(), "/") 655 656 addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) 657 log.Info("raw send test", "addrsize", addrsize) 658 659 clients, err := setupNetwork(2, true) 660 if err != nil { 661 t.Fatal(err) 662 } 663 664 topic := "0xdeadbeef" 665 666 var loaddrhex string 667 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 668 if err != nil { 669 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 670 } 671 loaddrhex = loaddrhex[:2+(addrsize*2)] 672 var roaddrhex string 673 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 674 if err != nil { 675 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 676 } 677 roaddrhex = roaddrhex[:2+(addrsize*2)] 678 679 time.Sleep(time.Millisecond * 500) 680 681 // 682 // 683 lmsgC := make(chan APIMsg) 684 lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) 685 defer lcancel() 686 lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) 687 log.Trace("lsub", "id", lsub) 688 defer lsub.Unsubscribe() 689 rmsgC := make(chan APIMsg) 690 rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) 691 defer rcancel() 692 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) 693 log.Trace("rsub", "id", rsub) 694 defer rsub.Unsubscribe() 695 696 // 697 lmsg := []byte("plugh") 698 err = clients[1].Call(nil, "pss_sendRaw", loaddrhex, topic, lmsg) 699 if err != nil { 700 t.Fatal(err) 701 } 702 select { 703 case recvmsg := <-lmsgC: 704 if !bytes.Equal(recvmsg.Msg, lmsg) { 705 t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg) 706 } 707 case cerr := <-lctx.Done(): 708 t.Fatalf("test message (left) timed out: %v", cerr) 709 } 710 rmsg := []byte("xyzzy") 711 err = clients[0].Call(nil, "pss_sendRaw", roaddrhex, topic, rmsg) 712 if err != nil { 713 t.Fatal(err) 714 } 715 select { 716 case recvmsg := <-rmsgC: 717 if !bytes.Equal(recvmsg.Msg, rmsg) { 718 t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg) 719 } 720 case cerr := <-rctx.Done(): 721 t.Fatalf("test message (right) timed out: %v", cerr) 722 } 723 } 724 725 // 726 func TestSendSym(t *testing.T) { 727 t.Run("32", testSendSym) 728 t.Run("8", testSendSym) 729 t.Run("0", testSendSym) 730 } 731 732 func testSendSym(t *testing.T) { 733 734 // 735 var addrsize int64 736 var err error 737 paramstring := strings.Split(t.Name(), "/") 738 addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) 739 log.Info("sym send test", "addrsize", addrsize) 740 741 clients, err := setupNetwork(2, false) 742 if err != nil { 743 t.Fatal(err) 744 } 745 746 var topic string 747 err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") 748 if err != nil { 749 t.Fatal(err) 750 } 751 752 var loaddrhex string 753 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 754 if err != nil { 755 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 756 } 757 loaddrhex = loaddrhex[:2+(addrsize*2)] 758 var roaddrhex string 759 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 760 if err != nil { 761 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 762 } 763 roaddrhex = roaddrhex[:2+(addrsize*2)] 764 765 // 766 // 767 var lpubkeyhex string 768 err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey") 769 if err != nil { 770 t.Fatalf("rpc get node 1 pubkey fail: %v", err) 771 } 772 var rpubkeyhex string 773 err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey") 774 if err != nil { 775 t.Fatalf("rpc get node 2 pubkey fail: %v", err) 776 } 777 778 time.Sleep(time.Millisecond * 500) 779 780 // 781 // 782 lmsgC := make(chan APIMsg) 783 lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) 784 defer lcancel() 785 lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) 786 log.Trace("lsub", "id", lsub) 787 defer lsub.Unsubscribe() 788 rmsgC := make(chan APIMsg) 789 rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) 790 defer rcancel() 791 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) 792 log.Trace("rsub", "id", rsub) 793 defer rsub.Unsubscribe() 794 795 lrecvkey := network.RandomAddr().Over() 796 rrecvkey := network.RandomAddr().Over() 797 798 var lkeyids [2]string 799 var rkeyids [2]string 800 801 // 802 err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex) 803 if err != nil { 804 t.Fatal(err) 805 } 806 err = clients[1].Call(&rkeyids, "psstest_setSymKeys", lpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex) 807 if err != nil { 808 t.Fatal(err) 809 } 810 811 // 812 lmsg := []byte("plugh") 813 err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg)) 814 if err != nil { 815 t.Fatal(err) 816 } 817 select { 818 case recvmsg := <-lmsgC: 819 if !bytes.Equal(recvmsg.Msg, lmsg) { 820 t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg) 821 } 822 case cerr := <-lctx.Done(): 823 t.Fatalf("test message timed out: %v", cerr) 824 } 825 rmsg := []byte("xyzzy") 826 err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg)) 827 if err != nil { 828 t.Fatal(err) 829 } 830 select { 831 case recvmsg := <-rmsgC: 832 if !bytes.Equal(recvmsg.Msg, rmsg) { 833 t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg) 834 } 835 case cerr := <-rctx.Done(): 836 t.Fatalf("test message timed out: %v", cerr) 837 } 838 } 839 840 // 841 func TestSendAsym(t *testing.T) { 842 t.Run("32", testSendAsym) 843 t.Run("8", testSendAsym) 844 t.Run("0", testSendAsym) 845 } 846 847 func testSendAsym(t *testing.T) { 848 849 // 850 var addrsize int64 851 var err error 852 paramstring := strings.Split(t.Name(), "/") 853 addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) 854 log.Info("asym send test", "addrsize", addrsize) 855 856 clients, err := setupNetwork(2, false) 857 if err != nil { 858 t.Fatal(err) 859 } 860 861 var topic string 862 err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") 863 if err != nil { 864 t.Fatal(err) 865 } 866 867 time.Sleep(time.Millisecond * 250) 868 869 var loaddrhex string 870 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 871 if err != nil { 872 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 873 } 874 loaddrhex = loaddrhex[:2+(addrsize*2)] 875 var roaddrhex string 876 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 877 if err != nil { 878 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 879 } 880 roaddrhex = roaddrhex[:2+(addrsize*2)] 881 882 // 883 // 884 var lpubkey string 885 err = clients[0].Call(&lpubkey, "pss_getPublicKey") 886 if err != nil { 887 t.Fatalf("rpc get node 1 pubkey fail: %v", err) 888 } 889 var rpubkey string 890 err = clients[1].Call(&rpubkey, "pss_getPublicKey") 891 if err != nil { 892 t.Fatalf("rpc get node 2 pubkey fail: %v", err) 893 } 894 895 time.Sleep(time.Millisecond * 500) // 896 897 lmsgC := make(chan APIMsg) 898 lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) 899 defer lcancel() 900 lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) 901 log.Trace("lsub", "id", lsub) 902 defer lsub.Unsubscribe() 903 rmsgC := make(chan APIMsg) 904 rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) 905 defer rcancel() 906 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) 907 log.Trace("rsub", "id", rsub) 908 defer rsub.Unsubscribe() 909 910 // 911 err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex) 912 if err != nil { 913 t.Fatal(err) 914 } 915 err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex) 916 if err != nil { 917 t.Fatal(err) 918 } 919 920 // 921 rmsg := []byte("xyzzy") 922 err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg)) 923 if err != nil { 924 t.Fatal(err) 925 } 926 select { 927 case recvmsg := <-rmsgC: 928 if !bytes.Equal(recvmsg.Msg, rmsg) { 929 t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg) 930 } 931 case cerr := <-rctx.Done(): 932 t.Fatalf("test message timed out: %v", cerr) 933 } 934 lmsg := []byte("plugh") 935 err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg)) 936 if err != nil { 937 t.Fatal(err) 938 } 939 select { 940 case recvmsg := <-lmsgC: 941 if !bytes.Equal(recvmsg.Msg, lmsg) { 942 t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg) 943 } 944 case cerr := <-lctx.Done(): 945 t.Fatalf("test message timed out: %v", cerr) 946 } 947 } 948 949 type Job struct { 950 Msg []byte 951 SendNode discover.NodeID 952 RecvNode discover.NodeID 953 } 954 955 func worker(id int, jobs <-chan Job, rpcs map[discover.NodeID]*rpc.Client, pubkeys map[discover.NodeID]string, topic string) { 956 for j := range jobs { 957 rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg)) 958 } 959 } 960 961 func TestNetwork(t *testing.T) { 962 t.Run("16/1000/4/sim", testNetwork) 963 } 964 965 // 966 // 967 // 968 func TestNetwork2000(t *testing.T) { 969 // 970 971 if !*longrunning { 972 t.Skip("run with --longrunning flag to run extensive network tests") 973 } 974 t.Run("3/2000/4/sim", testNetwork) 975 t.Run("4/2000/4/sim", testNetwork) 976 t.Run("8/2000/4/sim", testNetwork) 977 t.Run("16/2000/4/sim", testNetwork) 978 } 979 980 func TestNetwork5000(t *testing.T) { 981 // 982 983 if !*longrunning { 984 t.Skip("run with --longrunning flag to run extensive network tests") 985 } 986 t.Run("3/5000/4/sim", testNetwork) 987 t.Run("4/5000/4/sim", testNetwork) 988 t.Run("8/5000/4/sim", testNetwork) 989 t.Run("16/5000/4/sim", testNetwork) 990 } 991 992 func TestNetwork10000(t *testing.T) { 993 // 994 995 if !*longrunning { 996 t.Skip("run with --longrunning flag to run extensive network tests") 997 } 998 t.Run("3/10000/4/sim", testNetwork) 999 t.Run("4/10000/4/sim", testNetwork) 1000 t.Run("8/10000/4/sim", testNetwork) 1001 } 1002 1003 func testNetwork(t *testing.T) { 1004 type msgnotifyC struct { 1005 id discover.NodeID 1006 msgIdx int 1007 } 1008 1009 paramstring := strings.Split(t.Name(), "/") 1010 nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0) 1011 msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0) 1012 addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0) 1013 adapter := paramstring[4] 1014 1015 log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize) 1016 1017 nodes := make([]discover.NodeID, nodecount) 1018 bzzaddrs := make(map[discover.NodeID]string, nodecount) 1019 rpcs := make(map[discover.NodeID]*rpc.Client, nodecount) 1020 pubkeys := make(map[discover.NodeID]string, nodecount) 1021 1022 sentmsgs := make([][]byte, msgcount) 1023 recvmsgs := make([]bool, msgcount) 1024 nodemsgcount := make(map[discover.NodeID]int, nodecount) 1025 1026 trigger := make(chan discover.NodeID) 1027 1028 var a adapters.NodeAdapter 1029 if adapter == "exec" { 1030 dirname, err := ioutil.TempDir(".", "") 1031 if err != nil { 1032 t.Fatal(err) 1033 } 1034 a = adapters.NewExecAdapter(dirname) 1035 } else if adapter == "tcp" { 1036 a = adapters.NewTCPAdapter(newServices(false)) 1037 } else if adapter == "sim" { 1038 a = adapters.NewSimAdapter(newServices(false)) 1039 } 1040 net := simulations.NewNetwork(a, &simulations.NetworkConfig{ 1041 ID: "0", 1042 }) 1043 defer net.Shutdown() 1044 1045 f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount)) 1046 if err != nil { 1047 t.Fatal(err) 1048 } 1049 jsonbyte, err := ioutil.ReadAll(f) 1050 if err != nil { 1051 t.Fatal(err) 1052 } 1053 var snap simulations.Snapshot 1054 err = json.Unmarshal(jsonbyte, &snap) 1055 if err != nil { 1056 t.Fatal(err) 1057 } 1058 err = net.Load(&snap) 1059 if err != nil { 1060 // 1061 // 1062 } 1063 1064 time.Sleep(1 * time.Second) 1065 1066 triggerChecks := func(trigger chan discover.NodeID, id discover.NodeID, rpcclient *rpc.Client, topic string) error { 1067 msgC := make(chan APIMsg) 1068 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 1069 defer cancel() 1070 sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic) 1071 if err != nil { 1072 t.Fatal(err) 1073 } 1074 go func() { 1075 defer sub.Unsubscribe() 1076 for { 1077 select { 1078 case recvmsg := <-msgC: 1079 idx, _ := binary.Uvarint(recvmsg.Msg) 1080 if !recvmsgs[idx] { 1081 log.Debug("msg recv", "idx", idx, "id", id) 1082 recvmsgs[idx] = true 1083 trigger <- id 1084 } 1085 case <-sub.Err(): 1086 return 1087 } 1088 } 1089 }() 1090 return nil 1091 } 1092 1093 var topic string 1094 for i, nod := range net.GetNodes() { 1095 nodes[i] = nod.ID() 1096 rpcs[nodes[i]], err = nod.Client() 1097 if err != nil { 1098 t.Fatal(err) 1099 } 1100 if topic == "" { 1101 err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42") 1102 if err != nil { 1103 t.Fatal(err) 1104 } 1105 } 1106 var pubkey string 1107 err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey") 1108 if err != nil { 1109 t.Fatal(err) 1110 } 1111 pubkeys[nod.ID()] = pubkey 1112 var addrhex string 1113 err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr") 1114 if err != nil { 1115 t.Fatal(err) 1116 } 1117 bzzaddrs[nodes[i]] = addrhex 1118 err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic) 1119 if err != nil { 1120 t.Fatal(err) 1121 } 1122 } 1123 1124 time.Sleep(1 * time.Second) 1125 1126 // 1127 jobs := make(chan Job, 10) 1128 for w := 1; w <= 10; w++ { 1129 go worker(w, jobs, rpcs, pubkeys, topic) 1130 } 1131 1132 time.Sleep(1 * time.Second) 1133 1134 for i := 0; i < int(msgcount); i++ { 1135 sendnodeidx := rand.Intn(int(nodecount)) 1136 recvnodeidx := rand.Intn(int(nodecount - 1)) 1137 if recvnodeidx >= sendnodeidx { 1138 recvnodeidx++ 1139 } 1140 nodemsgcount[nodes[recvnodeidx]]++ 1141 sentmsgs[i] = make([]byte, 8) 1142 c := binary.PutUvarint(sentmsgs[i], uint64(i)) 1143 if c == 0 { 1144 t.Fatal("0 byte message") 1145 } 1146 if err != nil { 1147 t.Fatal(err) 1148 } 1149 err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]]) 1150 if err != nil { 1151 t.Fatal(err) 1152 } 1153 1154 jobs <- Job{ 1155 Msg: sentmsgs[i], 1156 SendNode: nodes[sendnodeidx], 1157 RecvNode: nodes[recvnodeidx], 1158 } 1159 } 1160 1161 finalmsgcount := 0 1162 ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) 1163 defer cancel() 1164 outer: 1165 for i := 0; i < int(msgcount); i++ { 1166 select { 1167 case id := <-trigger: 1168 nodemsgcount[id]-- 1169 finalmsgcount++ 1170 case <-ctx.Done(): 1171 log.Warn("timeout") 1172 break outer 1173 } 1174 } 1175 1176 for i, msg := range recvmsgs { 1177 if !msg { 1178 log.Debug("missing message", "idx", i) 1179 } 1180 } 1181 t.Logf("%d of %d messages received", finalmsgcount, msgcount) 1182 1183 if finalmsgcount != int(msgcount) { 1184 t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount) 1185 } 1186 1187 } 1188 1189 // 1190 // 1191 func TestDeduplication(t *testing.T) { 1192 var err error 1193 1194 clients, err := setupNetwork(3, false) 1195 if err != nil { 1196 t.Fatal(err) 1197 } 1198 1199 var addrsize = 32 1200 var loaddrhex string 1201 err = clients[0].Call(&loaddrhex, "pss_baseAddr") 1202 if err != nil { 1203 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 1204 } 1205 loaddrhex = loaddrhex[:2+(addrsize*2)] 1206 var roaddrhex string 1207 err = clients[1].Call(&roaddrhex, "pss_baseAddr") 1208 if err != nil { 1209 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 1210 } 1211 roaddrhex = roaddrhex[:2+(addrsize*2)] 1212 var xoaddrhex string 1213 err = clients[2].Call(&xoaddrhex, "pss_baseAddr") 1214 if err != nil { 1215 t.Fatalf("rpc get node 3 baseaddr fail: %v", err) 1216 } 1217 xoaddrhex = xoaddrhex[:2+(addrsize*2)] 1218 1219 log.Info("peer", "l", loaddrhex, "r", roaddrhex, "x", xoaddrhex) 1220 1221 var topic string 1222 err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") 1223 if err != nil { 1224 t.Fatal(err) 1225 } 1226 1227 time.Sleep(time.Millisecond * 250) 1228 1229 // 1230 // 1231 var rpubkey string 1232 err = clients[1].Call(&rpubkey, "pss_getPublicKey") 1233 if err != nil { 1234 t.Fatalf("rpc get receivenode pubkey fail: %v", err) 1235 } 1236 1237 time.Sleep(time.Millisecond * 500) // 1238 1239 rmsgC := make(chan APIMsg) 1240 rctx, cancel := context.WithTimeout(context.Background(), time.Second*1) 1241 defer cancel() 1242 rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) 1243 log.Trace("rsub", "id", rsub) 1244 defer rsub.Unsubscribe() 1245 1246 // 1247 // 1248 // 1249 err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, "0x") 1250 if err != nil { 1251 t.Fatal(err) 1252 } 1253 1254 // 1255 rmsg := []byte("xyzzy") 1256 err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg)) 1257 if err != nil { 1258 t.Fatal(err) 1259 } 1260 1261 var receivedok bool 1262 OUTER: 1263 for { 1264 select { 1265 case <-rmsgC: 1266 if receivedok { 1267 t.Fatalf("duplicate message received") 1268 } 1269 receivedok = true 1270 case <-rctx.Done(): 1271 break OUTER 1272 } 1273 } 1274 if !receivedok { 1275 t.Fatalf("message did not arrive") 1276 } 1277 } 1278 1279 // 1280 func BenchmarkSymkeySend(b *testing.B) { 1281 b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend) 1282 b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend) 1283 b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend) 1284 b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend) 1285 b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend) 1286 } 1287 1288 func benchmarkSymKeySend(b *testing.B) { 1289 msgsizestring := strings.Split(b.Name(), "/") 1290 if len(msgsizestring) != 2 { 1291 b.Fatalf("benchmark called without msgsize param") 1292 } 1293 msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0) 1294 if err != nil { 1295 b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err) 1296 } 1297 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1298 defer cancel() 1299 keys, err := wapi.NewKeyPair(ctx) 1300 privkey, err := w.GetPrivateKey(keys) 1301 ps := newTestPss(privkey, nil, nil) 1302 msg := make([]byte, msgsize) 1303 rand.Read(msg) 1304 topic := BytesToTopic([]byte("foo")) 1305 to := make(PssAddress, 32) 1306 copy(to[:], network.RandomAddr().Over()) 1307 symkeyid, err := ps.GenerateSymmetricKey(topic, &to, true) 1308 if err != nil { 1309 b.Fatalf("could not generate symkey: %v", err) 1310 } 1311 symkey, err := ps.w.GetSymKey(symkeyid) 1312 if err != nil { 1313 b.Fatalf("could not retrieve symkey: %v", err) 1314 } 1315 ps.SetSymmetricKey(symkey, topic, &to, false) 1316 1317 b.ResetTimer() 1318 for i := 0; i < b.N; i++ { 1319 ps.SendSym(symkeyid, topic, msg) 1320 } 1321 } 1322 1323 // 1324 func BenchmarkAsymkeySend(b *testing.B) { 1325 b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend) 1326 b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend) 1327 b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend) 1328 b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend) 1329 b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend) 1330 } 1331 1332 func benchmarkAsymKeySend(b *testing.B) { 1333 msgsizestring := strings.Split(b.Name(), "/") 1334 if len(msgsizestring) != 2 { 1335 b.Fatalf("benchmark called without msgsize param") 1336 } 1337 msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0) 1338 if err != nil { 1339 b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err) 1340 } 1341 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1342 defer cancel() 1343 keys, err := wapi.NewKeyPair(ctx) 1344 privkey, err := w.GetPrivateKey(keys) 1345 ps := newTestPss(privkey, nil, nil) 1346 msg := make([]byte, msgsize) 1347 rand.Read(msg) 1348 topic := BytesToTopic([]byte("foo")) 1349 to := make(PssAddress, 32) 1350 copy(to[:], network.RandomAddr().Over()) 1351 ps.SetPeerPublicKey(&privkey.PublicKey, topic, &to) 1352 b.ResetTimer() 1353 for i := 0; i < b.N; i++ { 1354 ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg) 1355 } 1356 } 1357 func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) { 1358 for i := 100; i < 100000; i = i * 10 { 1359 for j := 32; j < 10000; j = j * 8 { 1360 b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr) 1361 } 1362 // 1363 } 1364 } 1365 1366 // 1367 // 1368 func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) { 1369 keycountstring := strings.Split(b.Name(), "/") 1370 cachesize := int64(0) 1371 var ps *Pss 1372 if len(keycountstring) < 2 { 1373 b.Fatalf("benchmark called without count param") 1374 } 1375 keycount, err := strconv.ParseInt(keycountstring[1], 10, 0) 1376 if err != nil { 1377 b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err) 1378 } 1379 if len(keycountstring) == 3 { 1380 cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0) 1381 if err != nil { 1382 b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err) 1383 } 1384 } 1385 pssmsgs := make([]*PssMsg, 0, keycount) 1386 var keyid string 1387 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1388 defer cancel() 1389 keys, err := wapi.NewKeyPair(ctx) 1390 privkey, err := w.GetPrivateKey(keys) 1391 if cachesize > 0 { 1392 ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)}) 1393 } else { 1394 ps = newTestPss(privkey, nil, nil) 1395 } 1396 topic := BytesToTopic([]byte("foo")) 1397 for i := 0; i < int(keycount); i++ { 1398 to := make(PssAddress, 32) 1399 copy(to[:], network.RandomAddr().Over()) 1400 keyid, err = ps.GenerateSymmetricKey(topic, &to, true) 1401 if err != nil { 1402 b.Fatalf("cant generate symkey #%d: %v", i, err) 1403 } 1404 symkey, err := ps.w.GetSymKey(keyid) 1405 if err != nil { 1406 b.Fatalf("could not retrieve symkey %s: %v", keyid, err) 1407 } 1408 wparams := &whisper.MessageParams{ 1409 TTL: defaultWhisperTTL, 1410 KeySym: symkey, 1411 Topic: whisper.TopicType(topic), 1412 WorkTime: defaultWhisperWorkTime, 1413 PoW: defaultWhisperPoW, 1414 Payload: []byte("xyzzy"), 1415 Padding: []byte("1234567890abcdef"), 1416 } 1417 woutmsg, err := whisper.NewSentMessage(wparams) 1418 if err != nil { 1419 b.Fatalf("could not create whisper message: %v", err) 1420 } 1421 env, err := woutmsg.Wrap(wparams) 1422 if err != nil { 1423 b.Fatalf("could not generate whisper envelope: %v", err) 1424 } 1425 ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 1426 return nil 1427 }) 1428 pssmsgs = append(pssmsgs, &PssMsg{ 1429 To: to, 1430 Payload: env, 1431 }) 1432 } 1433 b.ResetTimer() 1434 for i := 0; i < b.N; i++ { 1435 if err := ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1]); err != nil { 1436 b.Fatalf("pss processing failed: %v", err) 1437 } 1438 } 1439 } 1440 1441 func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) { 1442 for i := 100; i < 100000; i = i * 10 { 1443 for j := 32; j < 10000; j = j * 8 { 1444 b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr) 1445 } 1446 } 1447 } 1448 1449 // 1450 // 1451 func benchmarkSymkeyBruteforceSameaddr(b *testing.B) { 1452 var keyid string 1453 var ps *Pss 1454 cachesize := int64(0) 1455 keycountstring := strings.Split(b.Name(), "/") 1456 if len(keycountstring) < 2 { 1457 b.Fatalf("benchmark called without count param") 1458 } 1459 keycount, err := strconv.ParseInt(keycountstring[1], 10, 0) 1460 if err != nil { 1461 b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err) 1462 } 1463 if len(keycountstring) == 3 { 1464 cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0) 1465 if err != nil { 1466 b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err) 1467 } 1468 } 1469 addr := make([]PssAddress, keycount) 1470 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 1471 defer cancel() 1472 keys, err := wapi.NewKeyPair(ctx) 1473 privkey, err := w.GetPrivateKey(keys) 1474 if cachesize > 0 { 1475 ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)}) 1476 } else { 1477 ps = newTestPss(privkey, nil, nil) 1478 } 1479 topic := BytesToTopic([]byte("foo")) 1480 for i := 0; i < int(keycount); i++ { 1481 copy(addr[i], network.RandomAddr().Over()) 1482 keyid, err = ps.GenerateSymmetricKey(topic, &addr[i], true) 1483 if err != nil { 1484 b.Fatalf("cant generate symkey #%d: %v", i, err) 1485 } 1486 1487 } 1488 symkey, err := ps.w.GetSymKey(keyid) 1489 if err != nil { 1490 b.Fatalf("could not retrieve symkey %s: %v", keyid, err) 1491 } 1492 wparams := &whisper.MessageParams{ 1493 TTL: defaultWhisperTTL, 1494 KeySym: symkey, 1495 Topic: whisper.TopicType(topic), 1496 WorkTime: defaultWhisperWorkTime, 1497 PoW: defaultWhisperPoW, 1498 Payload: []byte("xyzzy"), 1499 Padding: []byte("1234567890abcdef"), 1500 } 1501 woutmsg, err := whisper.NewSentMessage(wparams) 1502 if err != nil { 1503 b.Fatalf("could not create whisper message: %v", err) 1504 } 1505 env, err := woutmsg.Wrap(wparams) 1506 if err != nil { 1507 b.Fatalf("could not generate whisper envelope: %v", err) 1508 } 1509 ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 1510 return nil 1511 }) 1512 pssmsg := &PssMsg{ 1513 To: addr[len(addr)-1][:], 1514 Payload: env, 1515 } 1516 for i := 0; i < b.N; i++ { 1517 if err := ps.process(pssmsg); err != nil { 1518 b.Fatalf("pss processing failed: %v", err) 1519 } 1520 } 1521 } 1522 1523 // 1524 // 1525 // 1526 func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) { 1527 nodes := make([]*simulations.Node, numnodes) 1528 clients = make([]*rpc.Client, numnodes) 1529 if numnodes < 2 { 1530 return nil, fmt.Errorf("Minimum two nodes in network") 1531 } 1532 adapter := adapters.NewSimAdapter(newServices(allowRaw)) 1533 net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 1534 ID: "0", 1535 DefaultService: "bzz", 1536 }) 1537 for i := 0; i < numnodes; i++ { 1538 nodeconf := adapters.RandomNodeConfig() 1539 nodeconf.Services = []string{"bzz", pssProtocolName} 1540 nodes[i], err = net.NewNodeWithConfig(nodeconf) 1541 if err != nil { 1542 return nil, fmt.Errorf("error creating node 1: %v", err) 1543 } 1544 err = net.Start(nodes[i].ID()) 1545 if err != nil { 1546 return nil, fmt.Errorf("error starting node 1: %v", err) 1547 } 1548 if i > 0 { 1549 err = net.Connect(nodes[i].ID(), nodes[i-1].ID()) 1550 if err != nil { 1551 return nil, fmt.Errorf("error connecting nodes: %v", err) 1552 } 1553 } 1554 clients[i], err = nodes[i].Client() 1555 if err != nil { 1556 return nil, fmt.Errorf("create node 1 rpc client fail: %v", err) 1557 } 1558 } 1559 if numnodes > 2 { 1560 err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID()) 1561 if err != nil { 1562 return nil, fmt.Errorf("error connecting first and last nodes") 1563 } 1564 } 1565 return clients, nil 1566 } 1567 1568 func newServices(allowRaw bool) adapters.Services { 1569 stateStore := state.NewInmemoryStore() 1570 kademlias := make(map[discover.NodeID]*network.Kademlia) 1571 kademlia := func(id discover.NodeID) *network.Kademlia { 1572 if k, ok := kademlias[id]; ok { 1573 return k 1574 } 1575 addr := network.NewAddrFromNodeID(id) 1576 params := network.NewKadParams() 1577 params.MinProxBinSize = 2 1578 params.MaxBinSize = 3 1579 params.MinBinSize = 1 1580 params.MaxRetries = 1000 1581 params.RetryExponent = 2 1582 params.RetryInterval = 1000000 1583 kademlias[id] = network.NewKademlia(addr.Over(), params) 1584 return kademlias[id] 1585 } 1586 return adapters.Services{ 1587 pssProtocolName: func(ctx *adapters.ServiceContext) (node.Service, error) { 1588 // 1589 initTest() 1590 1591 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 1592 defer cancel() 1593 keys, err := wapi.NewKeyPair(ctxlocal) 1594 privkey, err := w.GetPrivateKey(keys) 1595 pssp := NewPssParams().WithPrivateKey(privkey) 1596 pssp.AllowRaw = allowRaw 1597 pskad := kademlia(ctx.Config.ID) 1598 ps, err := NewPss(pskad, pssp) 1599 if err != nil { 1600 return nil, err 1601 } 1602 1603 ping := &Ping{ 1604 OutC: make(chan bool), 1605 Pong: true, 1606 } 1607 p2pp := NewPingProtocol(ping) 1608 pp, err := RegisterProtocol(ps, &PingTopic, PingProtocol, p2pp, &ProtocolParams{Asymmetric: true}) 1609 if err != nil { 1610 return nil, err 1611 } 1612 if useHandshake { 1613 SetHandshakeController(ps, NewHandshakeParams()) 1614 } 1615 ps.Register(&PingTopic, pp.Handle) 1616 ps.addAPI(rpc.API{ 1617 Namespace: "psstest", 1618 Version: "0.3", 1619 Service: NewAPITest(ps), 1620 Public: false, 1621 }) 1622 if err != nil { 1623 log.Error("Couldnt register pss protocol", "err", err) 1624 os.Exit(1) 1625 } 1626 pssprotocols[ctx.Config.ID.String()] = &protoCtrl{ 1627 C: ping.OutC, 1628 protocol: pp, 1629 run: p2pp.Run, 1630 } 1631 return ps, nil 1632 }, 1633 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 1634 addr := network.NewAddrFromNodeID(ctx.Config.ID) 1635 hp := network.NewHiveParams() 1636 hp.Discovery = false 1637 config := &network.BzzConfig{ 1638 OverlayAddr: addr.Over(), 1639 UnderlayAddr: addr.Under(), 1640 HiveParams: hp, 1641 } 1642 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 1643 }, 1644 } 1645 } 1646 1647 func newTestPss(privkey *ecdsa.PrivateKey, overlay network.Overlay, ppextra *PssParams) *Pss { 1648 1649 var nid discover.NodeID 1650 copy(nid[:], crypto.FromECDSAPub(&privkey.PublicKey)) 1651 addr := network.NewAddrFromNodeID(nid) 1652 1653 // 1654 if overlay == nil { 1655 kp := network.NewKadParams() 1656 kp.MinProxBinSize = 3 1657 overlay = network.NewKademlia(addr.Over(), kp) 1658 } 1659 1660 // 1661 pp := NewPssParams().WithPrivateKey(privkey) 1662 if ppextra != nil { 1663 pp.SymKeyCacheCapacity = ppextra.SymKeyCacheCapacity 1664 } 1665 ps, err := NewPss(overlay, pp) 1666 if err != nil { 1667 return nil 1668 } 1669 ps.Start(nil) 1670 1671 return ps 1672 } 1673 1674 // 1675 type APITest struct { 1676 *Pss 1677 } 1678 1679 func NewAPITest(ps *Pss) *APITest { 1680 return &APITest{Pss: ps} 1681 } 1682 1683 func (apitest *APITest) SetSymKeys(pubkeyid string, recvsymkey []byte, sendsymkey []byte, limit uint16, topic Topic, to PssAddress) ([2]string, error) { 1684 recvsymkeyid, err := apitest.SetSymmetricKey(recvsymkey, topic, &to, true) 1685 if err != nil { 1686 return [2]string{}, err 1687 } 1688 sendsymkeyid, err := apitest.SetSymmetricKey(sendsymkey, topic, &to, false) 1689 if err != nil { 1690 return [2]string{}, err 1691 } 1692 return [2]string{recvsymkeyid, sendsymkeyid}, nil 1693 } 1694 1695 func (apitest *APITest) Clean() (int, error) { 1696 return apitest.Pss.cleanKeys(), nil 1697 } 1698 1699 // 1700 func enableMetrics() { 1701 metrics.Enabled = true 1702 go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 1*time.Second, "http:// 1703 "host": "test", 1704 }) 1705 }