github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/pss/pss.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package pss 26 27 import ( 28 "bytes" 29 "context" 30 "crypto/ecdsa" 31 "crypto/rand" 32 "errors" 33 "fmt" 34 "sync" 35 "time" 36 37 "github.com/ethereum/go-ethereum/common" 38 "github.com/ethereum/go-ethereum/crypto" 39 "github.com/ethereum/go-ethereum/metrics" 40 "github.com/ethereum/go-ethereum/p2p" 41 "github.com/ethereum/go-ethereum/p2p/discover" 42 "github.com/ethereum/go-ethereum/p2p/protocols" 43 "github.com/ethereum/go-ethereum/rpc" 44 "github.com/ethereum/go-ethereum/swarm/log" 45 "github.com/ethereum/go-ethereum/swarm/network" 46 "github.com/ethereum/go-ethereum/swarm/pot" 47 "github.com/ethereum/go-ethereum/swarm/storage" 48 whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" 49 ) 50 51 const ( 52 defaultPaddingByteSize = 16 53 DefaultMsgTTL = time.Second * 120 54 defaultDigestCacheTTL = time.Second * 10 55 defaultSymKeyCacheCapacity = 512 56 digestLength = 32 // 57 defaultWhisperWorkTime = 3 58 defaultWhisperPoW = 0.0000000001 59 defaultMaxMsgSize = 1024 * 1024 60 defaultCleanInterval = time.Second * 60 * 10 61 defaultOutboxCapacity = 100000 62 pssProtocolName = "pss" 63 pssVersion = 2 64 hasherCount = 8 65 ) 66 67 var ( 68 addressLength = len(pot.Address{}) 69 ) 70 71 // 72 // 73 // 74 type pssCacheEntry struct { 75 expiresAt time.Time 76 } 77 78 // 79 type senderPeer interface { 80 Info() *p2p.PeerInfo 81 ID() discover.NodeID 82 Address() []byte 83 Send(context.Context, interface{}) error 84 } 85 86 // 87 // 88 type pssPeer struct { 89 lastSeen time.Time 90 address *PssAddress 91 protected bool 92 } 93 94 // 95 type PssParams struct { 96 MsgTTL time.Duration 97 CacheTTL time.Duration 98 privateKey *ecdsa.PrivateKey 99 SymKeyCacheCapacity int 100 AllowRaw bool // 101 } 102 103 // 104 func NewPssParams() *PssParams { 105 return &PssParams{ 106 MsgTTL: DefaultMsgTTL, 107 CacheTTL: defaultDigestCacheTTL, 108 SymKeyCacheCapacity: defaultSymKeyCacheCapacity, 109 } 110 } 111 112 func (params *PssParams) WithPrivateKey(privatekey *ecdsa.PrivateKey) *PssParams { 113 params.privateKey = privatekey 114 return params 115 } 116 117 // 118 // 119 // 120 type Pss struct { 121 network.Overlay // 122 privateKey *ecdsa.PrivateKey // 123 w *whisper.Whisper // 124 auxAPIs []rpc.API // 125 126 // 127 fwdPool map[string]*protocols.Peer // 128 fwdPoolMu sync.RWMutex 129 fwdCache map[pssDigest]pssCacheEntry // 130 fwdCacheMu sync.RWMutex 131 cacheTTL time.Duration // 132 msgTTL time.Duration 133 paddingByteSize int 134 capstring string 135 outbox chan *PssMsg 136 137 // 138 pubKeyPool map[string]map[Topic]*pssPeer // 139 pubKeyPoolMu sync.RWMutex 140 symKeyPool map[string]map[Topic]*pssPeer // 141 symKeyPoolMu sync.RWMutex 142 symKeyDecryptCache []*string // 143 symKeyDecryptCacheCursor int // 144 symKeyDecryptCacheCapacity int // 145 146 // 147 handlers map[Topic]map[*Handler]bool // 148 handlersMu sync.RWMutex 149 allowRaw bool 150 hashPool sync.Pool 151 152 // 153 quitC chan struct{} 154 } 155 156 func (p *Pss) String() string { 157 return fmt.Sprintf("pss: addr %x, pubkey %v", p.BaseAddr(), common.ToHex(crypto.FromECDSAPub(&p.privateKey.PublicKey))) 158 } 159 160 // 161 // 162 // 163 // 164 func NewPss(k network.Overlay, params *PssParams) (*Pss, error) { 165 if params.privateKey == nil { 166 return nil, errors.New("missing private key for pss") 167 } 168 cap := p2p.Cap{ 169 Name: pssProtocolName, 170 Version: pssVersion, 171 } 172 ps := &Pss{ 173 Overlay: k, 174 privateKey: params.privateKey, 175 w: whisper.New(&whisper.DefaultConfig), 176 quitC: make(chan struct{}), 177 178 fwdPool: make(map[string]*protocols.Peer), 179 fwdCache: make(map[pssDigest]pssCacheEntry), 180 cacheTTL: params.CacheTTL, 181 msgTTL: params.MsgTTL, 182 paddingByteSize: defaultPaddingByteSize, 183 capstring: cap.String(), 184 outbox: make(chan *PssMsg, defaultOutboxCapacity), 185 186 pubKeyPool: make(map[string]map[Topic]*pssPeer), 187 symKeyPool: make(map[string]map[Topic]*pssPeer), 188 symKeyDecryptCache: make([]*string, params.SymKeyCacheCapacity), 189 symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity, 190 191 handlers: make(map[Topic]map[*Handler]bool), 192 allowRaw: params.AllowRaw, 193 hashPool: sync.Pool{ 194 New: func() interface{} { 195 return storage.MakeHashFunc(storage.DefaultHash)() 196 }, 197 }, 198 } 199 200 for i := 0; i < hasherCount; i++ { 201 hashfunc := storage.MakeHashFunc(storage.DefaultHash)() 202 ps.hashPool.Put(hashfunc) 203 } 204 205 return ps, nil 206 } 207 208 // 209 // 210 // 211 212 func (p *Pss) Start(srv *p2p.Server) error { 213 go func() { 214 ticker := time.NewTicker(defaultCleanInterval) 215 cacheTicker := time.NewTicker(p.cacheTTL) 216 defer ticker.Stop() 217 defer cacheTicker.Stop() 218 for { 219 select { 220 case <-cacheTicker.C: 221 p.cleanFwdCache() 222 case <-ticker.C: 223 p.cleanKeys() 224 case <-p.quitC: 225 return 226 } 227 } 228 }() 229 go func() { 230 for { 231 select { 232 case msg := <-p.outbox: 233 err := p.forward(msg) 234 if err != nil { 235 log.Error(err.Error()) 236 metrics.GetOrRegisterCounter("pss.forward.err", nil).Inc(1) 237 } 238 case <-p.quitC: 239 return 240 } 241 } 242 }() 243 log.Info("Started Pss") 244 log.Info("Loaded EC keys", "pubkey", common.ToHex(crypto.FromECDSAPub(p.PublicKey())), "secp256", common.ToHex(crypto.CompressPubkey(p.PublicKey()))) 245 return nil 246 } 247 248 func (p *Pss) Stop() error { 249 log.Info("Pss shutting down") 250 close(p.quitC) 251 return nil 252 } 253 254 var pssSpec = &protocols.Spec{ 255 Name: pssProtocolName, 256 Version: pssVersion, 257 MaxMsgSize: defaultMaxMsgSize, 258 Messages: []interface{}{ 259 PssMsg{}, 260 }, 261 } 262 263 func (p *Pss) Protocols() []p2p.Protocol { 264 return []p2p.Protocol{ 265 { 266 Name: pssSpec.Name, 267 Version: pssSpec.Version, 268 Length: pssSpec.Length(), 269 Run: p.Run, 270 }, 271 } 272 } 273 274 func (p *Pss) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 275 pp := protocols.NewPeer(peer, rw, pssSpec) 276 p.fwdPoolMu.Lock() 277 p.fwdPool[peer.Info().ID] = pp 278 p.fwdPoolMu.Unlock() 279 return pp.Run(p.handlePssMsg) 280 } 281 282 func (p *Pss) APIs() []rpc.API { 283 apis := []rpc.API{ 284 { 285 Namespace: "pss", 286 Version: "1.0", 287 Service: NewAPI(p), 288 Public: true, 289 }, 290 } 291 apis = append(apis, p.auxAPIs...) 292 return apis 293 } 294 295 // 296 // 297 func (p *Pss) addAPI(api rpc.API) { 298 p.auxAPIs = append(p.auxAPIs, api) 299 } 300 301 // 302 func (p *Pss) BaseAddr() []byte { 303 return p.Overlay.BaseAddr() 304 } 305 306 // 307 func (p *Pss) PublicKey() *ecdsa.PublicKey { 308 return &p.privateKey.PublicKey 309 } 310 311 // 312 // 313 // 314 315 // 316 // 317 // 318 // 319 // 320 // 321 // 322 // 323 // 324 func (p *Pss) Register(topic *Topic, handler Handler) func() { 325 p.handlersMu.Lock() 326 defer p.handlersMu.Unlock() 327 handlers := p.handlers[*topic] 328 if handlers == nil { 329 handlers = make(map[*Handler]bool) 330 p.handlers[*topic] = handlers 331 } 332 handlers[&handler] = true 333 return func() { p.deregister(topic, &handler) } 334 } 335 func (p *Pss) deregister(topic *Topic, h *Handler) { 336 p.handlersMu.Lock() 337 defer p.handlersMu.Unlock() 338 handlers := p.handlers[*topic] 339 if len(handlers) == 1 { 340 delete(p.handlers, *topic) 341 return 342 } 343 delete(handlers, h) 344 } 345 346 // 347 func (p *Pss) getHandlers(topic Topic) map[*Handler]bool { 348 p.handlersMu.RLock() 349 defer p.handlersMu.RUnlock() 350 return p.handlers[topic] 351 } 352 353 // 354 // 355 // 356 // 357 func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error { 358 metrics.GetOrRegisterCounter("pss.handlepssmsg", nil).Inc(1) 359 360 pssmsg, ok := msg.(*PssMsg) 361 362 if !ok { 363 return fmt.Errorf("invalid message type. Expected *PssMsg, got %T ", msg) 364 } 365 if int64(pssmsg.Expire) < time.Now().Unix() { 366 metrics.GetOrRegisterCounter("pss.expire", nil).Inc(1) 367 log.Warn("pss filtered expired message", "from", common.ToHex(p.Overlay.BaseAddr()), "to", common.ToHex(pssmsg.To)) 368 return nil 369 } 370 if p.checkFwdCache(pssmsg) { 371 log.Trace("pss relay block-cache match (process)", "from", common.ToHex(p.Overlay.BaseAddr()), "to", (common.ToHex(pssmsg.To))) 372 return nil 373 } 374 p.addFwdCache(pssmsg) 375 376 if !p.isSelfPossibleRecipient(pssmsg) { 377 log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr())) 378 return p.enqueue(pssmsg) 379 } 380 381 log.Trace("pss for us, yay! ... let's process!", "pss", common.ToHex(p.BaseAddr())) 382 if err := p.process(pssmsg); err != nil { 383 qerr := p.enqueue(pssmsg) 384 if qerr != nil { 385 return fmt.Errorf("process fail: processerr %v, queueerr: %v", err, qerr) 386 } 387 } 388 return nil 389 390 } 391 392 // 393 // 394 // 395 func (p *Pss) process(pssmsg *PssMsg) error { 396 metrics.GetOrRegisterCounter("pss.process", nil).Inc(1) 397 398 var err error 399 var recvmsg *whisper.ReceivedMessage 400 var payload []byte 401 var from *PssAddress 402 var asymmetric bool 403 var keyid string 404 var keyFunc func(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) 405 406 envelope := pssmsg.Payload 407 psstopic := Topic(envelope.Topic) 408 if pssmsg.isRaw() { 409 if !p.allowRaw { 410 return errors.New("raw message support disabled") 411 } 412 payload = pssmsg.Payload.Data 413 } else { 414 if pssmsg.isSym() { 415 keyFunc = p.processSym 416 } else { 417 asymmetric = true 418 keyFunc = p.processAsym 419 } 420 421 recvmsg, keyid, from, err = keyFunc(envelope) 422 if err != nil { 423 return errors.New("Decryption failed") 424 } 425 payload = recvmsg.Payload 426 } 427 428 if len(pssmsg.To) < addressLength { 429 if err := p.enqueue(pssmsg); err != nil { 430 return err 431 } 432 } 433 p.executeHandlers(psstopic, payload, from, asymmetric, keyid) 434 435 return nil 436 437 } 438 439 func (p *Pss) executeHandlers(topic Topic, payload []byte, from *PssAddress, asymmetric bool, keyid string) { 440 handlers := p.getHandlers(topic) 441 nid, _ := discover.HexID("0x00") // 442 peer := p2p.NewPeer(nid, fmt.Sprintf("%x", from), []p2p.Cap{}) 443 for f := range handlers { 444 err := (*f)(payload, peer, asymmetric, keyid) 445 if err != nil { 446 log.Warn("Pss handler %p failed: %v", f, err) 447 } 448 } 449 } 450 451 // 452 func (p *Pss) isSelfRecipient(msg *PssMsg) bool { 453 return bytes.Equal(msg.To, p.Overlay.BaseAddr()) 454 } 455 456 // 457 func (p *Pss) isSelfPossibleRecipient(msg *PssMsg) bool { 458 local := p.Overlay.BaseAddr() 459 return bytes.Equal(msg.To[:], local[:len(msg.To)]) 460 } 461 462 // 463 // 464 // 465 466 // 467 // 468 // 469 // 470 // 471 // 472 // 473 func (p *Pss) SetPeerPublicKey(pubkey *ecdsa.PublicKey, topic Topic, address *PssAddress) error { 474 pubkeybytes := crypto.FromECDSAPub(pubkey) 475 if len(pubkeybytes) == 0 { 476 return fmt.Errorf("invalid public key: %v", pubkey) 477 } 478 pubkeyid := common.ToHex(pubkeybytes) 479 psp := &pssPeer{ 480 address: address, 481 } 482 p.pubKeyPoolMu.Lock() 483 if _, ok := p.pubKeyPool[pubkeyid]; !ok { 484 p.pubKeyPool[pubkeyid] = make(map[Topic]*pssPeer) 485 } 486 p.pubKeyPool[pubkeyid][topic] = psp 487 p.pubKeyPoolMu.Unlock() 488 log.Trace("added pubkey", "pubkeyid", pubkeyid, "topic", topic, "address", common.ToHex(*address)) 489 return nil 490 } 491 492 // 493 func (p *Pss) GenerateSymmetricKey(topic Topic, address *PssAddress, addToCache bool) (string, error) { 494 keyid, err := p.w.GenerateSymKey() 495 if err != nil { 496 return "", err 497 } 498 p.addSymmetricKeyToPool(keyid, topic, address, addToCache, false) 499 return keyid, nil 500 } 501 502 // 503 // 504 // 505 // 506 // 507 // 508 // 509 // 510 // 511 // 512 // 513 // 514 func (p *Pss) SetSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool) (string, error) { 515 return p.setSymmetricKey(key, topic, address, addtocache, true) 516 } 517 518 func (p *Pss) setSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool, protected bool) (string, error) { 519 keyid, err := p.w.AddSymKeyDirect(key) 520 if err != nil { 521 return "", err 522 } 523 p.addSymmetricKeyToPool(keyid, topic, address, addtocache, protected) 524 return keyid, nil 525 } 526 527 // 528 // 529 // 530 func (p *Pss) addSymmetricKeyToPool(keyid string, topic Topic, address *PssAddress, addtocache bool, protected bool) { 531 psp := &pssPeer{ 532 address: address, 533 protected: protected, 534 } 535 p.symKeyPoolMu.Lock() 536 if _, ok := p.symKeyPool[keyid]; !ok { 537 p.symKeyPool[keyid] = make(map[Topic]*pssPeer) 538 } 539 p.symKeyPool[keyid][topic] = psp 540 p.symKeyPoolMu.Unlock() 541 if addtocache { 542 p.symKeyDecryptCacheCursor++ 543 p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = &keyid 544 } 545 key, _ := p.GetSymmetricKey(keyid) 546 log.Trace("added symkey", "symkeyid", keyid, "symkey", common.ToHex(key), "topic", topic, "address", fmt.Sprintf("%p", address), "cache", addtocache) 547 } 548 549 // 550 // 551 // 552 // 553 func (p *Pss) GetSymmetricKey(symkeyid string) ([]byte, error) { 554 symkey, err := p.w.GetSymKey(symkeyid) 555 if err != nil { 556 return nil, err 557 } 558 return symkey, nil 559 } 560 561 // 562 func (p *Pss) GetPublickeyPeers(keyid string) (topic []Topic, address []PssAddress, err error) { 563 p.pubKeyPoolMu.RLock() 564 defer p.pubKeyPoolMu.RUnlock() 565 for t, peer := range p.pubKeyPool[keyid] { 566 topic = append(topic, t) 567 address = append(address, *peer.address) 568 } 569 570 return topic, address, nil 571 } 572 573 func (p *Pss) getPeerAddress(keyid string, topic Topic) (PssAddress, error) { 574 p.pubKeyPoolMu.RLock() 575 defer p.pubKeyPoolMu.RUnlock() 576 if peers, ok := p.pubKeyPool[keyid]; ok { 577 if t, ok := peers[topic]; ok { 578 return *t.address, nil 579 } 580 } 581 return nil, fmt.Errorf("peer with pubkey %s, topic %x not found", keyid, topic) 582 } 583 584 // 585 // 586 // 587 // 588 // 589 // 590 func (p *Pss) processSym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) { 591 metrics.GetOrRegisterCounter("pss.process.sym", nil).Inc(1) 592 593 for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- { 594 symkeyid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)] 595 symkey, err := p.w.GetSymKey(*symkeyid) 596 if err != nil { 597 continue 598 } 599 recvmsg, err := envelope.OpenSymmetric(symkey) 600 if err != nil { 601 continue 602 } 603 if !recvmsg.Validate() { 604 return nil, "", nil, fmt.Errorf("symmetrically encrypted message has invalid signature or is corrupt") 605 } 606 p.symKeyPoolMu.Lock() 607 from := p.symKeyPool[*symkeyid][Topic(envelope.Topic)].address 608 p.symKeyPoolMu.Unlock() 609 p.symKeyDecryptCacheCursor++ 610 p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = symkeyid 611 return recvmsg, *symkeyid, from, nil 612 } 613 return nil, "", nil, fmt.Errorf("could not decrypt message") 614 } 615 616 // 617 // 618 // 619 // 620 // 621 // 622 func (p *Pss) processAsym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) { 623 metrics.GetOrRegisterCounter("pss.process.asym", nil).Inc(1) 624 625 recvmsg, err := envelope.OpenAsymmetric(p.privateKey) 626 if err != nil { 627 return nil, "", nil, fmt.Errorf("could not decrypt message: %s", err) 628 } 629 // 630 if !recvmsg.Validate() { 631 return nil, "", nil, fmt.Errorf("invalid message") 632 } 633 pubkeyid := common.ToHex(crypto.FromECDSAPub(recvmsg.Src)) 634 var from *PssAddress 635 p.pubKeyPoolMu.Lock() 636 if p.pubKeyPool[pubkeyid][Topic(envelope.Topic)] != nil { 637 from = p.pubKeyPool[pubkeyid][Topic(envelope.Topic)].address 638 } 639 p.pubKeyPoolMu.Unlock() 640 return recvmsg, pubkeyid, from, nil 641 } 642 643 // 644 // 645 // 646 // 647 func (p *Pss) cleanKeys() (count int) { 648 for keyid, peertopics := range p.symKeyPool { 649 var expiredtopics []Topic 650 for topic, psp := range peertopics { 651 if psp.protected { 652 continue 653 } 654 655 var match bool 656 for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- { 657 cacheid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)] 658 if *cacheid == keyid { 659 match = true 660 } 661 } 662 if !match { 663 expiredtopics = append(expiredtopics, topic) 664 } 665 } 666 for _, topic := range expiredtopics { 667 p.symKeyPoolMu.Lock() 668 delete(p.symKeyPool[keyid], topic) 669 log.Trace("symkey cleanup deletion", "symkeyid", keyid, "topic", topic, "val", p.symKeyPool[keyid]) 670 p.symKeyPoolMu.Unlock() 671 count++ 672 } 673 } 674 return 675 } 676 677 // 678 // 679 // 680 681 func (p *Pss) enqueue(msg *PssMsg) error { 682 select { 683 case p.outbox <- msg: 684 return nil 685 default: 686 } 687 688 metrics.GetOrRegisterCounter("pss.enqueue.outbox.full", nil).Inc(1) 689 return errors.New("outbox full") 690 } 691 692 // 693 // 694 // 695 func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error { 696 if !p.allowRaw { 697 return errors.New("Raw messages not enabled") 698 } 699 pssMsgParams := &msgParams{ 700 raw: true, 701 } 702 payload := &whisper.Envelope{ 703 Data: msg, 704 Topic: whisper.TopicType(topic), 705 } 706 pssMsg := newPssMsg(pssMsgParams) 707 pssMsg.To = address 708 pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix()) 709 pssMsg.Payload = payload 710 p.addFwdCache(pssMsg) 711 return p.enqueue(pssMsg) 712 } 713 714 // 715 // 716 // 717 func (p *Pss) SendSym(symkeyid string, topic Topic, msg []byte) error { 718 symkey, err := p.GetSymmetricKey(symkeyid) 719 if err != nil { 720 return fmt.Errorf("missing valid send symkey %s: %v", symkeyid, err) 721 } 722 p.symKeyPoolMu.Lock() 723 psp, ok := p.symKeyPool[symkeyid][topic] 724 p.symKeyPoolMu.Unlock() 725 if !ok { 726 return fmt.Errorf("invalid topic '%s' for symkey '%s'", topic.String(), symkeyid) 727 } else if psp.address == nil { 728 return fmt.Errorf("no address hint for topic '%s' symkey '%s'", topic.String(), symkeyid) 729 } 730 err = p.send(*psp.address, topic, msg, false, symkey) 731 return err 732 } 733 734 // 735 // 736 // 737 func (p *Pss) SendAsym(pubkeyid string, topic Topic, msg []byte) error { 738 if _, err := crypto.UnmarshalPubkey(common.FromHex(pubkeyid)); err != nil { 739 return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkeyid) 740 } 741 p.pubKeyPoolMu.Lock() 742 psp, ok := p.pubKeyPool[pubkeyid][topic] 743 p.pubKeyPoolMu.Unlock() 744 if !ok { 745 return fmt.Errorf("invalid topic '%s' for pubkey '%s'", topic.String(), pubkeyid) 746 } else if psp.address == nil { 747 return fmt.Errorf("no address hint for topic '%s' pubkey '%s'", topic.String(), pubkeyid) 748 } 749 go func() { 750 p.send(*psp.address, topic, msg, true, common.FromHex(pubkeyid)) 751 }() 752 return nil 753 } 754 755 // 756 // 757 // 758 // 759 func (p *Pss) send(to []byte, topic Topic, msg []byte, asymmetric bool, key []byte) error { 760 metrics.GetOrRegisterCounter("pss.send", nil).Inc(1) 761 762 if key == nil || bytes.Equal(key, []byte{}) { 763 return fmt.Errorf("Zero length key passed to pss send") 764 } 765 padding := make([]byte, p.paddingByteSize) 766 c, err := rand.Read(padding) 767 if err != nil { 768 return err 769 } else if c < p.paddingByteSize { 770 return fmt.Errorf("invalid padding length: %d", c) 771 } 772 wparams := &whisper.MessageParams{ 773 TTL: defaultWhisperTTL, 774 Src: p.privateKey, 775 Topic: whisper.TopicType(topic), 776 WorkTime: defaultWhisperWorkTime, 777 PoW: defaultWhisperPoW, 778 Payload: msg, 779 Padding: padding, 780 } 781 if asymmetric { 782 pk, err := crypto.UnmarshalPubkey(key) 783 if err != nil { 784 return fmt.Errorf("Cannot unmarshal pubkey: %x", key) 785 } 786 wparams.Dst = pk 787 } else { 788 wparams.KeySym = key 789 } 790 // 791 woutmsg, err := whisper.NewSentMessage(wparams) 792 if err != nil { 793 return fmt.Errorf("failed to generate whisper message encapsulation: %v", err) 794 } 795 // 796 // 797 // 798 envelope, err := woutmsg.Wrap(wparams) 799 if err != nil { 800 return fmt.Errorf("failed to perform whisper encryption: %v", err) 801 } 802 log.Trace("pssmsg whisper done", "env", envelope, "wparams payload", common.ToHex(wparams.Payload), "to", common.ToHex(to), "asym", asymmetric, "key", common.ToHex(key)) 803 804 // 805 pssMsgParams := &msgParams{ 806 sym: !asymmetric, 807 } 808 pssMsg := newPssMsg(pssMsgParams) 809 pssMsg.To = to 810 pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix()) 811 pssMsg.Payload = envelope 812 return p.enqueue(pssMsg) 813 } 814 815 // 816 // 817 // 818 func (p *Pss) forward(msg *PssMsg) error { 819 metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1) 820 821 to := make([]byte, addressLength) 822 copy(to[:len(msg.To)], msg.To) 823 824 // 825 // 826 sent := 0 827 p.Overlay.EachConn(to, 256, func(op network.OverlayConn, po int, isproxbin bool) bool { 828 // 829 // 830 sp, ok := op.(senderPeer) 831 if !ok { 832 log.Crit("Pss cannot use kademlia peer type") 833 return false 834 } 835 info := sp.Info() 836 837 // 838 var ispss bool 839 for _, cap := range info.Caps { 840 if cap == p.capstring { 841 ispss = true 842 break 843 } 844 } 845 if !ispss { 846 log.Trace("peer doesn't have matching pss capabilities, skipping", "peer", info.Name, "caps", info.Caps) 847 return true 848 } 849 850 // 851 sendMsg := fmt.Sprintf("MSG TO %x FROM %x VIA %x", to, p.BaseAddr(), op.Address()) 852 p.fwdPoolMu.RLock() 853 pp := p.fwdPool[sp.Info().ID] 854 p.fwdPoolMu.RUnlock() 855 856 // 857 err := pp.Send(context.TODO(), msg) 858 if err != nil { 859 metrics.GetOrRegisterCounter("pss.pp.send.error", nil).Inc(1) 860 log.Error(err.Error()) 861 return true 862 } 863 sent++ 864 log.Trace(fmt.Sprintf("%v: successfully forwarded", sendMsg)) 865 866 // 867 // 868 // 869 // 870 if len(msg.To) < addressLength && bytes.Equal(msg.To, op.Address()[:len(msg.To)]) { 871 log.Trace(fmt.Sprintf("Pss keep forwarding: Partial address + full partial match")) 872 return true 873 } else if isproxbin { 874 log.Trace(fmt.Sprintf("%x is in proxbin, keep forwarding", common.ToHex(op.Address()))) 875 return true 876 } 877 // 878 // 879 // 880 // 881 return false 882 }) 883 884 if sent == 0 { 885 log.Debug("unable to forward to any peers") 886 if err := p.enqueue(msg); err != nil { 887 metrics.GetOrRegisterCounter("pss.forward.enqueue.error", nil).Inc(1) 888 log.Error(err.Error()) 889 return err 890 } 891 } 892 893 // 894 p.addFwdCache(msg) 895 return nil 896 } 897 898 // 899 // 900 // 901 902 // 903 func (p *Pss) cleanFwdCache() { 904 metrics.GetOrRegisterCounter("pss.cleanfwdcache", nil).Inc(1) 905 p.fwdCacheMu.Lock() 906 defer p.fwdCacheMu.Unlock() 907 for k, v := range p.fwdCache { 908 if v.expiresAt.Before(time.Now()) { 909 delete(p.fwdCache, k) 910 } 911 } 912 } 913 914 // 915 func (p *Pss) addFwdCache(msg *PssMsg) error { 916 metrics.GetOrRegisterCounter("pss.addfwdcache", nil).Inc(1) 917 918 var entry pssCacheEntry 919 var ok bool 920 921 p.fwdCacheMu.Lock() 922 defer p.fwdCacheMu.Unlock() 923 924 digest := p.digest(msg) 925 if entry, ok = p.fwdCache[digest]; !ok { 926 entry = pssCacheEntry{} 927 } 928 entry.expiresAt = time.Now().Add(p.cacheTTL) 929 p.fwdCache[digest] = entry 930 return nil 931 } 932 933 // 934 func (p *Pss) checkFwdCache(msg *PssMsg) bool { 935 p.fwdCacheMu.Lock() 936 defer p.fwdCacheMu.Unlock() 937 938 digest := p.digest(msg) 939 entry, ok := p.fwdCache[digest] 940 if ok { 941 if entry.expiresAt.After(time.Now()) { 942 log.Trace("unexpired cache", "digest", fmt.Sprintf("%x", digest)) 943 metrics.GetOrRegisterCounter("pss.checkfwdcache.unexpired", nil).Inc(1) 944 return true 945 } 946 metrics.GetOrRegisterCounter("pss.checkfwdcache.expired", nil).Inc(1) 947 } 948 return false 949 } 950 951 // 952 func (p *Pss) digest(msg *PssMsg) pssDigest { 953 hasher := p.hashPool.Get().(storage.SwarmHash) 954 defer p.hashPool.Put(hasher) 955 hasher.Reset() 956 hasher.Write(msg.serialize()) 957 digest := pssDigest{} 958 key := hasher.Sum(nil) 959 copy(digest[:], key[:digestLength]) 960 return digest 961 }