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