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