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