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