github.com/codingfuture/orig-energi3@v0.8.4/swarm/pss/pss_test.go (about) 1 // Copyright 2018 The Energi Core Authors 2 // Copyright 2018 The go-ethereum Authors 3 // This file is part of the Energi Core library. 4 // 5 // The Energi Core library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The Energi Core library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>. 17 18 package pss 19 20 import ( 21 "bytes" 22 "context" 23 "crypto/ecdsa" 24 "encoding/binary" 25 "encoding/hex" 26 "encoding/json" 27 "flag" 28 "fmt" 29 "io/ioutil" 30 "math/rand" 31 "os" 32 "strconv" 33 "strings" 34 "sync" 35 "testing" 36 "time" 37 38 "github.com/ethereum/go-ethereum/common" 39 "github.com/ethereum/go-ethereum/common/hexutil" 40 "github.com/ethereum/go-ethereum/crypto" 41 "github.com/ethereum/go-ethereum/log" 42 "github.com/ethereum/go-ethereum/metrics" 43 "github.com/ethereum/go-ethereum/metrics/influxdb" 44 "github.com/ethereum/go-ethereum/node" 45 "github.com/ethereum/go-ethereum/p2p" 46 "github.com/ethereum/go-ethereum/p2p/enode" 47 "github.com/ethereum/go-ethereum/p2p/protocols" 48 "github.com/ethereum/go-ethereum/p2p/simulations" 49 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 50 "github.com/ethereum/go-ethereum/rpc" 51 "github.com/ethereum/go-ethereum/swarm/network" 52 "github.com/ethereum/go-ethereum/swarm/pot" 53 "github.com/ethereum/go-ethereum/swarm/state" 54 whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" 55 ) 56 57 var ( 58 initOnce = sync.Once{} 59 loglevel = flag.Int("loglevel", 2, "logging verbosity") 60 longrunning = flag.Bool("longrunning", false, "do run long-running tests") 61 w *whisper.Whisper 62 wapi *whisper.PublicWhisperAPI 63 psslogmain log.Logger 64 pssprotocols map[string]*protoCtrl 65 useHandshake bool 66 noopHandlerFunc = func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 67 return nil 68 } 69 ) 70 71 func init() { 72 testing.Init() 73 flag.Parse() 74 rand.Seed(time.Now().Unix()) 75 76 adapters.RegisterServices(newServices(false)) 77 initTest() 78 } 79 80 func initTest() { 81 initOnce.Do( 82 func() { 83 psslogmain = log.New("psslog", "*") 84 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 85 hf := log.LvlFilterHandler(log.Lvl(*loglevel), hs) 86 h := log.CallerFileHandler(hf) 87 log.Root().SetHandler(h) 88 89 w = whisper.New(&whisper.DefaultConfig) 90 wapi = whisper.NewPublicWhisperAPI(w) 91 92 pssprotocols = make(map[string]*protoCtrl) 93 }, 94 ) 95 } 96 97 // test that topic conversion functions give predictable results 98 func TestTopic(t *testing.T) { 99 100 api := &API{} 101 102 topicstr := strings.Join([]string{PingProtocol.Name, strconv.Itoa(int(PingProtocol.Version))}, ":") 103 104 // bytestotopic is the authoritative topic conversion source 105 topicobj := BytesToTopic([]byte(topicstr)) 106 107 // string to topic and bytes to topic must match 108 topicapiobj, _ := api.StringToTopic(topicstr) 109 if topicobj != topicapiobj { 110 t.Fatalf("bytes and string topic conversion mismatch; %s != %s", topicobj, topicapiobj) 111 } 112 113 // string representation of topichex 114 topichex := topicobj.String() 115 116 // protocoltopic wrapper on pingtopic should be same as topicstring 117 // check that it matches 118 pingtopichex := PingTopic.String() 119 if topichex != pingtopichex { 120 t.Fatalf("protocol topic conversion mismatch; %s != %s", topichex, pingtopichex) 121 } 122 123 // json marshal of topic 124 topicjsonout, err := topicobj.MarshalJSON() 125 if err != nil { 126 t.Fatal(err) 127 } 128 if string(topicjsonout)[1:len(topicjsonout)-1] != topichex { 129 t.Fatalf("topic json marshal mismatch; %s != \"%s\"", topicjsonout, topichex) 130 } 131 132 // json unmarshal of topic 133 var topicjsonin Topic 134 topicjsonin.UnmarshalJSON(topicjsonout) 135 if topicjsonin != topicobj { 136 t.Fatalf("topic json unmarshal mismatch: %x != %x", topicjsonin, topicobj) 137 } 138 } 139 140 // test bit packing of message control flags 141 func TestMsgParams(t *testing.T) { 142 var ctrl byte 143 ctrl |= pssControlRaw 144 p := newMsgParamsFromBytes([]byte{ctrl}) 145 m := newPssMsg(p) 146 if !m.isRaw() || m.isSym() { 147 t.Fatal("expected raw=true and sym=false") 148 } 149 ctrl |= pssControlSym 150 p = newMsgParamsFromBytes([]byte{ctrl}) 151 m = newPssMsg(p) 152 if !m.isRaw() || !m.isSym() { 153 t.Fatal("expected raw=true and sym=true") 154 } 155 ctrl &= 0xff &^ pssControlRaw 156 p = newMsgParamsFromBytes([]byte{ctrl}) 157 m = newPssMsg(p) 158 if m.isRaw() || !m.isSym() { 159 t.Fatal("expected raw=false and sym=true") 160 } 161 } 162 163 // test if we can insert into cache, match items with cache and cache expiry 164 func TestCache(t *testing.T) { 165 var err error 166 to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f") 167 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 168 defer cancel() 169 keys, err := wapi.NewKeyPair(ctx) 170 privkey, err := w.GetPrivateKey(keys) 171 if err != nil { 172 t.Fatal(err) 173 } 174 ps := newTestPss(privkey, nil, nil) 175 defer ps.Stop() 176 pp := NewPssParams().WithPrivateKey(privkey) 177 data := []byte("foo") 178 datatwo := []byte("bar") 179 datathree := []byte("baz") 180 wparams := &whisper.MessageParams{ 181 TTL: defaultWhisperTTL, 182 Src: privkey, 183 Dst: &privkey.PublicKey, 184 Topic: whisper.TopicType(PingTopic), 185 WorkTime: defaultWhisperWorkTime, 186 PoW: defaultWhisperPoW, 187 Payload: data, 188 } 189 woutmsg, err := whisper.NewSentMessage(wparams) 190 env, err := woutmsg.Wrap(wparams) 191 msg := &PssMsg{ 192 Payload: env, 193 To: to, 194 } 195 wparams.Payload = datatwo 196 woutmsg, err = whisper.NewSentMessage(wparams) 197 envtwo, err := woutmsg.Wrap(wparams) 198 msgtwo := &PssMsg{ 199 Payload: envtwo, 200 To: to, 201 } 202 wparams.Payload = datathree 203 woutmsg, err = whisper.NewSentMessage(wparams) 204 envthree, err := woutmsg.Wrap(wparams) 205 msgthree := &PssMsg{ 206 Payload: envthree, 207 To: to, 208 } 209 210 digest := ps.digest(msg) 211 if err != nil { 212 t.Fatalf("could not store cache msgone: %v", err) 213 } 214 digesttwo := ps.digest(msgtwo) 215 if err != nil { 216 t.Fatalf("could not store cache msgtwo: %v", err) 217 } 218 digestthree := ps.digest(msgthree) 219 if err != nil { 220 t.Fatalf("could not store cache msgthree: %v", err) 221 } 222 223 if digest == digesttwo { 224 t.Fatalf("different msgs return same hash: %d", digesttwo) 225 } 226 227 // check the cache 228 err = ps.addFwdCache(msg) 229 if err != nil { 230 t.Fatalf("write to pss expire cache failed: %v", err) 231 } 232 233 if !ps.checkFwdCache(msg) { 234 t.Fatalf("message %v should have EXPIRE record in cache but checkCache returned false", msg) 235 } 236 237 if ps.checkFwdCache(msgtwo) { 238 t.Fatalf("message %v should NOT have EXPIRE record in cache but checkCache returned true", msgtwo) 239 } 240 241 time.Sleep(pp.CacheTTL + 1*time.Second) 242 err = ps.addFwdCache(msgthree) 243 if err != nil { 244 t.Fatalf("write to pss expire cache failed: %v", err) 245 } 246 247 if ps.checkFwdCache(msg) { 248 t.Fatalf("message %v should have expired from cache but checkCache returned true", msg) 249 } 250 251 if _, ok := ps.fwdCache[digestthree]; !ok { 252 t.Fatalf("unexpired message should be in the cache: %v", digestthree) 253 } 254 255 if _, ok := ps.fwdCache[digesttwo]; ok { 256 t.Fatalf("expired message should have been cleared from the cache: %v", digesttwo) 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 }