github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/whisper/whisperv5/whisper.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:46</date> 10 //</624450124931665920> 11 12 13 package whisperv5 14 15 import ( 16 "bytes" 17 "crypto/ecdsa" 18 crand "crypto/rand" 19 "crypto/sha256" 20 "fmt" 21 "runtime" 22 "sync" 23 "time" 24 25 mapset "github.com/deckarep/golang-set" 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/log" 29 "github.com/ethereum/go-ethereum/p2p" 30 "github.com/ethereum/go-ethereum/rpc" 31 "github.com/syndtr/goleveldb/leveldb/errors" 32 "golang.org/x/crypto/pbkdf2" 33 "golang.org/x/sync/syncmap" 34 ) 35 36 type Statistics struct { 37 messagesCleared int 38 memoryCleared int 39 memoryUsed int 40 cycles int 41 totalMessagesCleared int 42 } 43 44 const ( 45 minPowIdx = iota //耳语节点所需的最小功率 46 maxMsgSizeIdx = iota //Whisper节点允许的最大消息长度 47 overflowIdx = iota //消息队列溢出指示器 48 ) 49 50 //低语代表通过以太坊的黑暗通信接口 51 //网络,使用自己的P2P通信层。 52 type Whisper struct { 53 protocol p2p.Protocol //协议描述和参数 54 filters *Filters //使用订阅功能安装的消息筛选器 55 56 privateKeys map[string]*ecdsa.PrivateKey //私钥存储 57 symKeys map[string][]byte //对称密钥存储 58 keyMu sync.RWMutex //与密钥存储关联的互斥体 59 60 poolMu sync.RWMutex //用于同步消息和过期池的互斥体 61 envelopes map[common.Hash]*Envelope //此节点当前跟踪的信封池 62 expirations map[uint32]mapset.Set //邮件过期池 63 64 peerMu sync.RWMutex //用于同步活动对等集的互斥体 65 peers map[*Peer]struct{} //当前活动对等点集 66 67 messageQueue chan *Envelope //正常低语消息的消息队列 68 p2pMsgQueue chan *Envelope //对等消息的消息队列(不再转发) 69 quit chan struct{} //用于优美出口的通道 70 71 settings syncmap.Map //保留可动态更改的配置设置 72 73 statsMu sync.Mutex //警卫统计 74 stats Statistics //耳语节点统计 75 76 mailServer MailServer //邮件服务器接口 77 } 78 79 //New创建了一个准备好通过以太坊P2P网络通信的耳语客户端。 80 func New(cfg *Config) *Whisper { 81 if cfg == nil { 82 cfg = &DefaultConfig 83 } 84 85 whisper := &Whisper{ 86 privateKeys: make(map[string]*ecdsa.PrivateKey), 87 symKeys: make(map[string][]byte), 88 envelopes: make(map[common.Hash]*Envelope), 89 expirations: make(map[uint32]mapset.Set), 90 peers: make(map[*Peer]struct{}), 91 messageQueue: make(chan *Envelope, messageQueueLimit), 92 p2pMsgQueue: make(chan *Envelope, messageQueueLimit), 93 quit: make(chan struct{}), 94 } 95 96 whisper.filters = NewFilters(whisper) 97 98 whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW) 99 whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize) 100 whisper.settings.Store(overflowIdx, false) 101 102 //P2P低语子协议处理程序 103 whisper.protocol = p2p.Protocol{ 104 Name: ProtocolName, 105 Version: uint(ProtocolVersion), 106 Length: NumberOfMessageCodes, 107 Run: whisper.HandlePeer, 108 NodeInfo: func() interface{} { 109 return map[string]interface{}{ 110 "version": ProtocolVersionStr, 111 "maxMessageSize": whisper.MaxMessageSize(), 112 "minimumPoW": whisper.MinPow(), 113 } 114 }, 115 } 116 117 return whisper 118 } 119 120 func (w *Whisper) MinPow() float64 { 121 val, _ := w.settings.Load(minPowIdx) 122 return val.(float64) 123 } 124 125 //maxmessagesize返回可接受的最大消息大小。 126 func (w *Whisper) MaxMessageSize() uint32 { 127 val, _ := w.settings.Load(maxMsgSizeIdx) 128 return val.(uint32) 129 } 130 131 //溢出返回消息队列是否已满的指示。 132 func (w *Whisper) Overflow() bool { 133 val, _ := w.settings.Load(overflowIdx) 134 return val.(bool) 135 } 136 137 //API返回Whisper实现提供的RPC描述符 138 func (w *Whisper) APIs() []rpc.API { 139 return []rpc.API{ 140 { 141 Namespace: ProtocolName, 142 Version: ProtocolVersionStr, 143 Service: NewPublicWhisperAPI(w), 144 Public: true, 145 }, 146 } 147 } 148 149 //registerserver注册mailserver接口。 150 //邮件服务器将使用p2prequestcode处理所有传入的邮件。 151 func (w *Whisper) RegisterServer(server MailServer) { 152 w.mailServer = server 153 } 154 155 //协议返回此特定客户端运行的耳语子协议。 156 func (w *Whisper) Protocols() []p2p.Protocol { 157 return []p2p.Protocol{w.protocol} 158 } 159 160 //version返回耳语子协议版本号。 161 func (w *Whisper) Version() uint { 162 return w.protocol.Version 163 } 164 165 //setmaxmessagesize设置此节点允许的最大消息大小 166 func (w *Whisper) SetMaxMessageSize(size uint32) error { 167 if size > MaxMessageSize { 168 return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) 169 } 170 w.settings.Store(maxMsgSizeIdx, size) 171 return nil 172 } 173 174 //setminimumPow设置此节点所需的最小Pow 175 func (w *Whisper) SetMinimumPoW(val float64) error { 176 if val <= 0.0 { 177 return fmt.Errorf("invalid PoW: %f", val) 178 } 179 w.settings.Store(minPowIdx, val) 180 return nil 181 } 182 183 //getpeer按ID检索peer 184 func (w *Whisper) getPeer(peerID []byte) (*Peer, error) { 185 w.peerMu.Lock() 186 defer w.peerMu.Unlock() 187 for p := range w.peers { 188 id := p.peer.ID() 189 if bytes.Equal(peerID, id[:]) { 190 return p, nil 191 } 192 } 193 return nil, fmt.Errorf("Could not find peer with ID: %x", peerID) 194 } 195 196 //allowp2pmessagesfrompeer标记特定的受信任对等机, 197 //这将允许它发送历史(过期)消息。 198 func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error { 199 p, err := w.getPeer(peerID) 200 if err != nil { 201 return err 202 } 203 p.trusted = true 204 return nil 205 } 206 207 //RequestHistoricMessages向特定对等端发送带有p2prequestcode的消息, 208 //它可以实现mailserver接口,并且应该处理这个 209 //请求和响应一些对等消息(可能已过期), 210 //不能再转发了。 211 //耳语协议对信封的格式和内容不可知。 212 func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { 213 p, err := w.getPeer(peerID) 214 if err != nil { 215 return err 216 } 217 p.trusted = true 218 return p2p.Send(p.ws, p2pRequestCode, envelope) 219 } 220 221 //sendp2pmessage向特定对等发送对等消息。 222 func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error { 223 p, err := w.getPeer(peerID) 224 if err != nil { 225 return err 226 } 227 return w.SendP2PDirect(p, envelope) 228 } 229 230 //sendp2pdirect向特定对等发送对等消息。 231 func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { 232 return p2p.Send(peer.ws, p2pCode, envelope) 233 } 234 235 //NewKeyPair为客户端生成新的加密标识,并注入 236 //它进入已知的身份信息进行解密。返回新密钥对的ID。 237 func (w *Whisper) NewKeyPair() (string, error) { 238 key, err := crypto.GenerateKey() 239 if err != nil || !validatePrivateKey(key) { 240 key, err = crypto.GenerateKey() //重试一次 241 } 242 if err != nil { 243 return "", err 244 } 245 if !validatePrivateKey(key) { 246 return "", fmt.Errorf("failed to generate valid key") 247 } 248 249 id, err := GenerateRandomID() 250 if err != nil { 251 return "", fmt.Errorf("failed to generate ID: %s", err) 252 } 253 254 w.keyMu.Lock() 255 defer w.keyMu.Unlock() 256 257 if w.privateKeys[id] != nil { 258 return "", fmt.Errorf("failed to generate unique ID") 259 } 260 w.privateKeys[id] = key 261 return id, nil 262 } 263 264 //DeleteKeyPair删除指定的密钥(如果存在)。 265 func (w *Whisper) DeleteKeyPair(key string) bool { 266 w.keyMu.Lock() 267 defer w.keyMu.Unlock() 268 269 if w.privateKeys[key] != nil { 270 delete(w.privateKeys, key) 271 return true 272 } 273 return false 274 } 275 276 //AddKeyPair导入非对称私钥并返回其标识符。 277 func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { 278 id, err := GenerateRandomID() 279 if err != nil { 280 return "", fmt.Errorf("failed to generate ID: %s", err) 281 } 282 283 w.keyMu.Lock() 284 w.privateKeys[id] = key 285 w.keyMu.Unlock() 286 287 return id, nil 288 } 289 290 //hasKeyPair检查耳语节点是否配置了私钥 291 //指定的公用对。 292 func (w *Whisper) HasKeyPair(id string) bool { 293 w.keyMu.RLock() 294 defer w.keyMu.RUnlock() 295 return w.privateKeys[id] != nil 296 } 297 298 //getprivatekey检索指定标识的私钥。 299 func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { 300 w.keyMu.RLock() 301 defer w.keyMu.RUnlock() 302 key := w.privateKeys[id] 303 if key == nil { 304 return nil, fmt.Errorf("invalid id") 305 } 306 return key, nil 307 } 308 309 //generatesymkey生成一个随机对称密钥并将其存储在id下, 310 //然后返回。将在将来用于会话密钥交换。 311 func (w *Whisper) GenerateSymKey() (string, error) { 312 key := make([]byte, aesKeyLength) 313 _, err := crand.Read(key) 314 if err != nil { 315 return "", err 316 } else if !validateSymmetricKey(key) { 317 return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") 318 } 319 320 id, err := GenerateRandomID() 321 if err != nil { 322 return "", fmt.Errorf("failed to generate ID: %s", err) 323 } 324 325 w.keyMu.Lock() 326 defer w.keyMu.Unlock() 327 328 if w.symKeys[id] != nil { 329 return "", fmt.Errorf("failed to generate unique ID") 330 } 331 w.symKeys[id] = key 332 return id, nil 333 } 334 335 //addsymkeydirect存储密钥并返回其ID。 336 func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) { 337 if len(key) != aesKeyLength { 338 return "", fmt.Errorf("wrong key size: %d", len(key)) 339 } 340 341 id, err := GenerateRandomID() 342 if err != nil { 343 return "", fmt.Errorf("failed to generate ID: %s", err) 344 } 345 346 w.keyMu.Lock() 347 defer w.keyMu.Unlock() 348 349 if w.symKeys[id] != nil { 350 return "", fmt.Errorf("failed to generate unique ID") 351 } 352 w.symKeys[id] = key 353 return id, nil 354 } 355 356 //addsymkeyfrompassword根据密码生成密钥,存储并返回其ID。 357 func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) { 358 id, err := GenerateRandomID() 359 if err != nil { 360 return "", fmt.Errorf("failed to generate ID: %s", err) 361 } 362 if w.HasSymKey(id) { 363 return "", fmt.Errorf("failed to generate unique ID") 364 } 365 366 derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion) 367 if err != nil { 368 return "", err 369 } 370 371 w.keyMu.Lock() 372 defer w.keyMu.Unlock() 373 374 //需要进行双重检查,因为DeriveKeyMaterial()非常慢 375 if w.symKeys[id] != nil { 376 return "", fmt.Errorf("critical error: failed to generate unique ID") 377 } 378 w.symKeys[id] = derived 379 return id, nil 380 } 381 382 //如果有一个键与给定的ID相关联,HassymKey将返回true。 383 //否则返回false。 384 func (w *Whisper) HasSymKey(id string) bool { 385 w.keyMu.RLock() 386 defer w.keyMu.RUnlock() 387 return w.symKeys[id] != nil 388 } 389 390 //DeleteSymkey删除与名称字符串关联的键(如果存在)。 391 func (w *Whisper) DeleteSymKey(id string) bool { 392 w.keyMu.Lock() 393 defer w.keyMu.Unlock() 394 if w.symKeys[id] != nil { 395 delete(w.symKeys, id) 396 return true 397 } 398 return false 399 } 400 401 //GetSymkey返回与给定ID关联的对称密钥。 402 func (w *Whisper) GetSymKey(id string) ([]byte, error) { 403 w.keyMu.RLock() 404 defer w.keyMu.RUnlock() 405 if w.symKeys[id] != nil { 406 return w.symKeys[id], nil 407 } 408 return nil, fmt.Errorf("non-existent key ID") 409 } 410 411 //订阅安装用于筛选、解密的新消息处理程序 412 //以及随后存储的传入消息。 413 func (w *Whisper) Subscribe(f *Filter) (string, error) { 414 return w.filters.Install(f) 415 } 416 417 //GetFilter按ID返回筛选器。 418 func (w *Whisper) GetFilter(id string) *Filter { 419 return w.filters.Get(id) 420 } 421 422 //取消订阅将删除已安装的消息处理程序。 423 func (w *Whisper) Unsubscribe(id string) error { 424 ok := w.filters.Uninstall(id) 425 if !ok { 426 return fmt.Errorf("Unsubscribe: Invalid ID") 427 } 428 return nil 429 } 430 431 //send将一条消息插入到whisper发送队列中,并在 432 //网络在未来的周期中。 433 func (w *Whisper) Send(envelope *Envelope) error { 434 ok, err := w.add(envelope) 435 if err != nil { 436 return err 437 } 438 if !ok { 439 return fmt.Errorf("failed to add envelope") 440 } 441 return err 442 } 443 444 //start实现node.service,启动后台数据传播线程 445 //关于耳语协议。 446 func (w *Whisper) Start(*p2p.Server) error { 447 log.Info("started whisper v." + ProtocolVersionStr) 448 go w.update() 449 450 numCPU := runtime.NumCPU() 451 for i := 0; i < numCPU; i++ { 452 go w.processQueue() 453 } 454 455 return nil 456 } 457 458 //stop实现node.service,停止后台数据传播线程 459 //关于耳语协议。 460 func (w *Whisper) Stop() error { 461 close(w.quit) 462 log.Info("whisper stopped") 463 return nil 464 } 465 466 //当低语子协议时,底层p2p层调用handlepeer。 467 //已协商连接。 468 func (w *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 469 //创建新的对等点并开始跟踪它 470 whisperPeer := newPeer(w, peer, rw) 471 472 w.peerMu.Lock() 473 w.peers[whisperPeer] = struct{}{} 474 w.peerMu.Unlock() 475 476 defer func() { 477 w.peerMu.Lock() 478 delete(w.peers, whisperPeer) 479 w.peerMu.Unlock() 480 }() 481 482 //运行对等握手和状态更新 483 if err := whisperPeer.handshake(); err != nil { 484 return err 485 } 486 whisperPeer.start() 487 defer whisperPeer.stop() 488 489 return w.runMessageLoop(whisperPeer, rw) 490 } 491 492 //runmessageloop直接读取和处理入站消息以合并到客户端全局状态。 493 func (w *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { 494 for { 495 //获取下一个数据包 496 packet, err := rw.ReadMsg() 497 if err != nil { 498 log.Info("message loop", "peer", p.peer.ID(), "err", err) 499 return err 500 } 501 if packet.Size > w.MaxMessageSize() { 502 log.Warn("oversized message received", "peer", p.peer.ID()) 503 return errors.New("oversized message received") 504 } 505 506 switch packet.Code { 507 case statusCode: 508 //这不应该发生,但不需要惊慌;忽略这条消息。 509 log.Warn("unxepected status message received", "peer", p.peer.ID()) 510 case messagesCode: 511 //解码包含的信封 512 var envelope Envelope 513 if err := packet.Decode(&envelope); err != nil { 514 log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err) 515 return errors.New("invalid envelope") 516 } 517 cached, err := w.add(&envelope) 518 if err != nil { 519 log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err) 520 return errors.New("invalid envelope") 521 } 522 if cached { 523 p.mark(&envelope) 524 } 525 case p2pCode: 526 //点对点消息,直接发送给点绕过POW检查等。 527 //此消息不应转发给其他对等方,并且 528 //因此可能不满足POW、到期等要求。 529 //这些消息只能从受信任的对等方接收。 530 if p.trusted { 531 var envelope Envelope 532 if err := packet.Decode(&envelope); err != nil { 533 log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 534 return errors.New("invalid direct message") 535 } 536 w.postEvent(&envelope, true) 537 } 538 case p2pRequestCode: 539 //如果实现了邮件服务器,则必须进行处理。否则忽略。 540 if w.mailServer != nil { 541 var request Envelope 542 if err := packet.Decode(&request); err != nil { 543 log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 544 return errors.New("invalid p2p request") 545 } 546 w.mailServer.DeliverMail(p, &request) 547 } 548 default: 549 //新的消息类型可能在未来版本的Whisper中实现。 550 //对于前向兼容性,只需忽略即可。 551 } 552 553 packet.Discard() 554 } 555 } 556 557 //添加将新信封插入要在其中分发的消息池 558 //低语网络。它还将信封插入 559 //适当的时间戳。如果出现错误,应断开连接。 560 func (w *Whisper) add(envelope *Envelope) (bool, error) { 561 now := uint32(time.Now().Unix()) 562 sent := envelope.Expiry - envelope.TTL 563 564 if sent > now { 565 if sent-SynchAllowance > now { 566 return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) 567 } 568 //重新计算POW,针对时差进行调整,再加上一秒钟的延迟时间 569 envelope.calculatePoW(sent - now + 1) 570 } 571 572 if envelope.Expiry < now { 573 if envelope.Expiry+SynchAllowance*2 < now { 574 return false, fmt.Errorf("very old message") 575 } 576 log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) 577 return false, nil //不出错地丢弃信封 578 } 579 580 if uint32(envelope.size()) > w.MaxMessageSize() { 581 return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) 582 } 583 584 if len(envelope.Version) > 4 { 585 return false, fmt.Errorf("oversized version [%x]", envelope.Hash()) 586 } 587 588 aesNonceSize := len(envelope.AESNonce) 589 if aesNonceSize != 0 && aesNonceSize != AESNonceLength { 590 //标准aes gcm nonce大小为12字节, 591 //但无法访问常量gcmstandardnoncosize(未导出) 592 return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash()) 593 } 594 595 if envelope.PoW() < w.MinPow() { 596 log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex()) 597 return false, nil //不出错地丢弃信封 598 } 599 600 hash := envelope.Hash() 601 602 w.poolMu.Lock() 603 _, alreadyCached := w.envelopes[hash] 604 if !alreadyCached { 605 w.envelopes[hash] = envelope 606 if w.expirations[envelope.Expiry] == nil { 607 w.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() 608 } 609 if !w.expirations[envelope.Expiry].Contains(hash) { 610 w.expirations[envelope.Expiry].Add(hash) 611 } 612 } 613 w.poolMu.Unlock() 614 615 if alreadyCached { 616 log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) 617 } else { 618 log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) 619 w.statsMu.Lock() 620 w.stats.memoryUsed += envelope.size() 621 w.statsMu.Unlock() 622 w.postEvent(envelope, false) //将新消息通知本地节点 623 if w.mailServer != nil { 624 w.mailServer.Archive(envelope) 625 } 626 } 627 return true, nil 628 } 629 630 //PostEvent将消息排队以进行进一步处理。 631 func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) { 632 //如果传入消息的版本高于 633 //当前支持的版本,无法解密, 634 //因此忽略这个信息 635 if envelope.Ver() <= EnvelopeVersion { 636 if isP2P { 637 w.p2pMsgQueue <- envelope 638 } else { 639 w.checkOverflow() 640 w.messageQueue <- envelope 641 } 642 } 643 } 644 645 //检查溢出检查消息队列是否发生溢出,必要时报告。 646 func (w *Whisper) checkOverflow() { 647 queueSize := len(w.messageQueue) 648 649 if queueSize == messageQueueLimit { 650 if !w.Overflow() { 651 w.settings.Store(overflowIdx, true) 652 log.Warn("message queue overflow") 653 } 654 } else if queueSize <= messageQueueLimit/2 { 655 if w.Overflow() { 656 w.settings.Store(overflowIdx, false) 657 log.Warn("message queue overflow fixed (back to normal)") 658 } 659 } 660 } 661 662 //processqueue在whisper节点的生命周期中将消息传递给观察者。 663 func (w *Whisper) processQueue() { 664 var e *Envelope 665 for { 666 select { 667 case <-w.quit: 668 return 669 670 case e = <-w.messageQueue: 671 w.filters.NotifyWatchers(e, false) 672 673 case e = <-w.p2pMsgQueue: 674 w.filters.NotifyWatchers(e, true) 675 } 676 } 677 } 678 679 //更新循环,直到Whisper节点的生存期,更新其内部 680 //通过过期池中的过时消息来进行状态。 681 func (w *Whisper) update() { 682 //启动一个断续器以检查到期情况 683 expire := time.NewTicker(expirationCycle) 684 685 //重复更新直到请求终止 686 for { 687 select { 688 case <-expire.C: 689 w.expire() 690 691 case <-w.quit: 692 return 693 } 694 } 695 } 696 697 //expire在所有过期时间戳上迭代,删除所有过时的 698 //来自池的消息。 699 func (w *Whisper) expire() { 700 w.poolMu.Lock() 701 defer w.poolMu.Unlock() 702 703 w.statsMu.Lock() 704 defer w.statsMu.Unlock() 705 w.stats.reset() 706 now := uint32(time.Now().Unix()) 707 for expiry, hashSet := range w.expirations { 708 if expiry < now { 709 //转储所有过期消息并删除时间戳 710 hashSet.Each(func(v interface{}) bool { 711 sz := w.envelopes[v.(common.Hash)].size() 712 delete(w.envelopes, v.(common.Hash)) 713 w.stats.messagesCleared++ 714 w.stats.memoryCleared += sz 715 w.stats.memoryUsed -= sz 716 return false 717 }) 718 w.expirations[expiry].Clear() 719 delete(w.expirations, expiry) 720 } 721 } 722 } 723 724 //stats返回低语节点统计信息。 725 func (w *Whisper) Stats() Statistics { 726 w.statsMu.Lock() 727 defer w.statsMu.Unlock() 728 729 return w.stats 730 } 731 732 //信封检索节点当前汇集的所有消息。 733 func (w *Whisper) Envelopes() []*Envelope { 734 w.poolMu.RLock() 735 defer w.poolMu.RUnlock() 736 737 all := make([]*Envelope, 0, len(w.envelopes)) 738 for _, envelope := range w.envelopes { 739 all = append(all, envelope) 740 } 741 return all 742 } 743 744 //消息迭代当前所有浮动信封 745 //并检索此筛选器可以解密的所有消息。 746 func (w *Whisper) Messages(id string) []*ReceivedMessage { 747 result := make([]*ReceivedMessage, 0) 748 w.poolMu.RLock() 749 defer w.poolMu.RUnlock() 750 751 if filter := w.filters.Get(id); filter != nil { 752 for _, env := range w.envelopes { 753 msg := filter.processEnvelope(env) 754 if msg != nil { 755 result = append(result, msg) 756 } 757 } 758 } 759 return result 760 } 761 762 //ISenvelopecached检查是否已接收和缓存具有特定哈希的信封。 763 func (w *Whisper) isEnvelopeCached(hash common.Hash) bool { 764 w.poolMu.Lock() 765 defer w.poolMu.Unlock() 766 767 _, exist := w.envelopes[hash] 768 return exist 769 } 770 771 //重置在每个到期周期后重置节点的统计信息。 772 func (s *Statistics) reset() { 773 s.cycles++ 774 s.totalMessagesCleared += s.messagesCleared 775 776 s.memoryCleared = 0 777 s.messagesCleared = 0 778 } 779 780 //validatePublickey检查给定公钥的格式。 781 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 782 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 783 } 784 785 //validateprivatekey检查给定私钥的格式。 786 func validatePrivateKey(k *ecdsa.PrivateKey) bool { 787 if k == nil || k.D == nil || k.D.Sign() == 0 { 788 return false 789 } 790 return ValidatePublicKey(&k.PublicKey) 791 } 792 793 //如果键包含所有零,则validateSymmetrickey返回false 794 func validateSymmetricKey(k []byte) bool { 795 return len(k) > 0 && !containsOnlyZeros(k) 796 } 797 798 //containsonlyzer检查数据是否只包含零。 799 func containsOnlyZeros(data []byte) bool { 800 for _, b := range data { 801 if b != 0 { 802 return false 803 } 804 } 805 return true 806 } 807 808 //BytesTouintLittleEndian将切片转换为64位无符号整数。 809 func bytesToUintLittleEndian(b []byte) (res uint64) { 810 mul := uint64(1) 811 for i := 0; i < len(b); i++ { 812 res += uint64(b[i]) * mul 813 mul *= 256 814 } 815 return res 816 } 817 818 //bytestouintbigendian将切片转换为64位无符号整数。 819 func BytesToUintBigEndian(b []byte) (res uint64) { 820 for i := 0; i < len(b); i++ { 821 res *= 256 822 res += uint64(b[i]) 823 } 824 return res 825 } 826 827 //DeriveKeyMaterial从密钥或密码派生对称密钥材质。 828 //pbkdf2用于安全性,以防人们使用密码而不是随机生成的密钥。 829 func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) { 830 if version == 0 { 831 //kdf的平均计算时间不应少于0.1秒, 832 //因为这是一次会议经验 833 derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New) 834 return derivedKey, nil 835 } 836 return nil, unknownVersionError(version) 837 } 838 839 //GenerateRandomID生成一个随机字符串,然后返回该字符串用作键ID 840 func GenerateRandomID() (id string, err error) { 841 buf := make([]byte, keyIdSize) 842 _, err = crand.Read(buf) 843 if err != nil { 844 return "", err 845 } 846 if !validateSymmetricKey(buf) { 847 return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") 848 } 849 id = common.Bytes2Hex(buf) 850 return id, err 851 } 852