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