github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/pss/pss.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:44</date>
    10  //</624450117008625664>
    11  
    12  
    13  package pss
    14  
    15  import (
    16  	"bytes"
    17  	"context"
    18  	"crypto/ecdsa"
    19  	"crypto/rand"
    20  	"errors"
    21  	"fmt"
    22  	"hash"
    23  	"sync"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/crypto"
    28  	"github.com/ethereum/go-ethereum/metrics"
    29  	"github.com/ethereum/go-ethereum/p2p"
    30  	"github.com/ethereum/go-ethereum/p2p/enode"
    31  	"github.com/ethereum/go-ethereum/p2p/protocols"
    32  	"github.com/ethereum/go-ethereum/rpc"
    33  	"github.com/ethereum/go-ethereum/swarm/log"
    34  	"github.com/ethereum/go-ethereum/swarm/network"
    35  	"github.com/ethereum/go-ethereum/swarm/pot"
    36  	"github.com/ethereum/go-ethereum/swarm/storage"
    37  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
    38  	"golang.org/x/crypto/sha3"
    39  )
    40  
    41  const (
    42  	defaultPaddingByteSize     = 16
    43  	DefaultMsgTTL              = time.Second * 120
    44  	defaultDigestCacheTTL      = time.Second * 10
    45  	defaultSymKeyCacheCapacity = 512
    46  digestLength               = 32 //用于PSS缓存的摘要的字节长度(当前与Swarm Chunk哈希相同)
    47  	defaultWhisperWorkTime     = 3
    48  	defaultWhisperPoW          = 0.0000000001
    49  	defaultMaxMsgSize          = 1024 * 1024
    50  	defaultCleanInterval       = time.Second * 60 * 10
    51  	defaultOutboxCapacity      = 100000
    52  	pssProtocolName            = "pss"
    53  	pssVersion                 = 2
    54  	hasherCount                = 8
    55  )
    56  
    57  var (
    58  	addressLength = len(pot.Address{})
    59  )
    60  
    61  //缓存用于防止反向路由
    62  //也将有助于防洪机制
    63  //和邮箱实现
    64  type pssCacheEntry struct {
    65  	expiresAt time.Time
    66  }
    67  
    68  //允许访问p2p.protocols.peer.send的抽象
    69  type senderPeer interface {
    70  	Info() *p2p.PeerInfo
    71  	ID() enode.ID
    72  	Address() []byte
    73  	Send(context.Context, interface{}) error
    74  }
    75  
    76  //每键对等相关信息
    77  //成员“protected”防止对实例进行垃圾收集
    78  type pssPeer struct {
    79  	lastSeen  time.Time
    80  	address   PssAddress
    81  	protected bool
    82  }
    83  
    84  //PSS配置参数
    85  type PssParams struct {
    86  	MsgTTL              time.Duration
    87  	CacheTTL            time.Duration
    88  	privateKey          *ecdsa.PrivateKey
    89  	SymKeyCacheCapacity int
    90  AllowRaw            bool //如果为真,则允许在不使用内置PSS加密的情况下发送和接收消息
    91  }
    92  
    93  //PSS的正常默认值
    94  func NewPssParams() *PssParams {
    95  	return &PssParams{
    96  		MsgTTL:              DefaultMsgTTL,
    97  		CacheTTL:            defaultDigestCacheTTL,
    98  		SymKeyCacheCapacity: defaultSymKeyCacheCapacity,
    99  	}
   100  }
   101  
   102  func (params *PssParams) WithPrivateKey(privatekey *ecdsa.PrivateKey) *PssParams {
   103  	params.privateKey = privatekey
   104  	return params
   105  }
   106  
   107  //顶级PSS对象,负责消息发送、接收、解密和加密、消息处理程序调度器和消息转发。
   108  //
   109  //实现节点服务
   110  type Pss struct {
   111  *network.Kademlia                   //我们可以从这里得到卡德米利亚的地址
   112  privateKey        *ecdsa.PrivateKey //PSS可以拥有自己的独立密钥
   113  w                 *whisper.Whisper  //密钥和加密后端
   114  auxAPIs           []rpc.API         //内置(握手、测试)可以添加API
   115  
   116  //发送和转发
   117  fwdPool         map[string]*protocols.Peer //跟踪PSSMSG路由层上的所有对等端
   118  	fwdPoolMu       sync.RWMutex
   119  fwdCache        map[pssDigest]pssCacheEntry //pssmsg中映射到expiry、cache以确定是否删除msg的唯一字段的校验和
   120  	fwdCacheMu      sync.RWMutex
   121  cacheTTL        time.Duration //在fwdcache中保留消息的时间(未实现)
   122  	msgTTL          time.Duration
   123  	paddingByteSize int
   124  	capstring       string
   125  	outbox          chan *PssMsg
   126  
   127  //密钥与对等体
   128  pubKeyPool                 map[string]map[Topic]*pssPeer //按主题将十六进制公钥映射到对等地址。
   129  	pubKeyPoolMu               sync.RWMutex
   130  symKeyPool                 map[string]map[Topic]*pssPeer //按主题将symkeyid映射到对等地址。
   131  	symKeyPoolMu               sync.RWMutex
   132  symKeyDecryptCache         []*string //快速查找最近用于解密的符号键;最后使用的是堆栈顶部
   133  symKeyDecryptCacheCursor   int       //指向上次使用的、包装在symkeydecryptcache数组上的模块化光标
   134  symKeyDecryptCacheCapacity int       //要保留的符号键的最大数量。
   135  
   136  //消息处理
   137  handlers         map[Topic]map[*handler]bool //基于主题和版本的PSS有效负载处理程序。参见pss.handle()。
   138  	handlersMu       sync.RWMutex
   139  	hashPool         sync.Pool
   140  topicHandlerCaps map[Topic]*handlerCaps //缓存每个主题处理程序的功能(请参见handlercap*types.go中的consts)
   141  
   142  //过程
   143  	quitC chan struct{}
   144  }
   145  
   146  func (p *Pss) String() string {
   147  	return fmt.Sprintf("pss: addr %x, pubkey %v", p.BaseAddr(), common.ToHex(crypto.FromECDSAPub(&p.privateKey.PublicKey)))
   148  }
   149  
   150  //创建新的PSS实例。
   151  //
   152  //除了params,它还需要一个集群网络kademlia
   153  //以及用于消息缓存存储的文件存储。
   154  func NewPss(k *network.Kademlia, params *PssParams) (*Pss, error) {
   155  	if params.privateKey == nil {
   156  		return nil, errors.New("missing private key for pss")
   157  	}
   158  	cap := p2p.Cap{
   159  		Name:    pssProtocolName,
   160  		Version: pssVersion,
   161  	}
   162  	ps := &Pss{
   163  		Kademlia:   k,
   164  		privateKey: params.privateKey,
   165  		w:          whisper.New(&whisper.DefaultConfig),
   166  		quitC:      make(chan struct{}),
   167  
   168  		fwdPool:         make(map[string]*protocols.Peer),
   169  		fwdCache:        make(map[pssDigest]pssCacheEntry),
   170  		cacheTTL:        params.CacheTTL,
   171  		msgTTL:          params.MsgTTL,
   172  		paddingByteSize: defaultPaddingByteSize,
   173  		capstring:       cap.String(),
   174  		outbox:          make(chan *PssMsg, defaultOutboxCapacity),
   175  
   176  		pubKeyPool:                 make(map[string]map[Topic]*pssPeer),
   177  		symKeyPool:                 make(map[string]map[Topic]*pssPeer),
   178  		symKeyDecryptCache:         make([]*string, params.SymKeyCacheCapacity),
   179  		symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity,
   180  
   181  		handlers:         make(map[Topic]map[*handler]bool),
   182  		topicHandlerCaps: make(map[Topic]*handlerCaps),
   183  
   184  		hashPool: sync.Pool{
   185  			New: func() interface{} {
   186  				return sha3.NewLegacyKeccak256()
   187  			},
   188  		},
   189  	}
   190  
   191  	for i := 0; i < hasherCount; i++ {
   192  		hashfunc := storage.MakeHashFunc(storage.DefaultHash)()
   193  		ps.hashPool.Put(hashfunc)
   194  	}
   195  
   196  	return ps, nil
   197  }
   198  
   199  ////////////////////////////////////////////////
   200  //章节:节点、服务接口
   201  ////////////////////////////////////////////////
   202  
   203  func (p *Pss) Start(srv *p2p.Server) error {
   204  	go func() {
   205  		ticker := time.NewTicker(defaultCleanInterval)
   206  		cacheTicker := time.NewTicker(p.cacheTTL)
   207  		defer ticker.Stop()
   208  		defer cacheTicker.Stop()
   209  		for {
   210  			select {
   211  			case <-cacheTicker.C:
   212  				p.cleanFwdCache()
   213  			case <-ticker.C:
   214  				p.cleanKeys()
   215  			case <-p.quitC:
   216  				return
   217  			}
   218  		}
   219  	}()
   220  	go func() {
   221  		for {
   222  			select {
   223  			case msg := <-p.outbox:
   224  				err := p.forward(msg)
   225  				if err != nil {
   226  					log.Error(err.Error())
   227  					metrics.GetOrRegisterCounter("pss.forward.err", nil).Inc(1)
   228  				}
   229  			case <-p.quitC:
   230  				return
   231  			}
   232  		}
   233  	}()
   234  	log.Info("Started Pss")
   235  	log.Info("Loaded EC keys", "pubkey", common.ToHex(crypto.FromECDSAPub(p.PublicKey())), "secp256", common.ToHex(crypto.CompressPubkey(p.PublicKey())))
   236  	return nil
   237  }
   238  
   239  func (p *Pss) Stop() error {
   240  	log.Info("Pss shutting down")
   241  	close(p.quitC)
   242  	return nil
   243  }
   244  
   245  var pssSpec = &protocols.Spec{
   246  	Name:       pssProtocolName,
   247  	Version:    pssVersion,
   248  	MaxMsgSize: defaultMaxMsgSize,
   249  	Messages: []interface{}{
   250  		PssMsg{},
   251  	},
   252  }
   253  
   254  func (p *Pss) Protocols() []p2p.Protocol {
   255  	return []p2p.Protocol{
   256  		{
   257  			Name:    pssSpec.Name,
   258  			Version: pssSpec.Version,
   259  			Length:  pssSpec.Length(),
   260  			Run:     p.Run,
   261  		},
   262  	}
   263  }
   264  
   265  func (p *Pss) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
   266  	pp := protocols.NewPeer(peer, rw, pssSpec)
   267  	p.fwdPoolMu.Lock()
   268  	p.fwdPool[peer.Info().ID] = pp
   269  	p.fwdPoolMu.Unlock()
   270  	return pp.Run(p.handlePssMsg)
   271  }
   272  
   273  func (p *Pss) APIs() []rpc.API {
   274  	apis := []rpc.API{
   275  		{
   276  			Namespace: "pss",
   277  			Version:   "1.0",
   278  			Service:   NewAPI(p),
   279  			Public:    true,
   280  		},
   281  	}
   282  	apis = append(apis, p.auxAPIs...)
   283  	return apis
   284  }
   285  
   286  //向PSS API添加API方法
   287  //必须在节点启动之前运行
   288  func (p *Pss) addAPI(api rpc.API) {
   289  	p.auxAPIs = append(p.auxAPIs, api)
   290  }
   291  
   292  //返回PSS节点的Swarm Kademlia地址
   293  func (p *Pss) BaseAddr() []byte {
   294  	return p.Kademlia.BaseAddr()
   295  }
   296  
   297  //返回PSS节点的公钥
   298  func (p *Pss) PublicKey() *ecdsa.PublicKey {
   299  	return &p.privateKey.PublicKey
   300  }
   301  
   302  ////////////////////////////////////////////////
   303  //部分:消息处理
   304  ////////////////////////////////////////////////
   305  
   306  //将处理程序函数链接到主题
   307  //
   308  //信封主题与
   309  //指定的主题将传递给给定的处理程序函数。
   310  //
   311  //每个主题可能有任意数量的处理程序函数。
   312  //
   313  //返回需要调用的注销函数
   314  //注销处理程序,
   315  func (p *Pss) Register(topic *Topic, hndlr *handler) func() {
   316  	p.handlersMu.Lock()
   317  	defer p.handlersMu.Unlock()
   318  	handlers := p.handlers[*topic]
   319  	if handlers == nil {
   320  		handlers = make(map[*handler]bool)
   321  		p.handlers[*topic] = handlers
   322  		log.Debug("registered handler", "caps", hndlr.caps)
   323  	}
   324  	if hndlr.caps == nil {
   325  		hndlr.caps = &handlerCaps{}
   326  	}
   327  	handlers[hndlr] = true
   328  	if _, ok := p.topicHandlerCaps[*topic]; !ok {
   329  		p.topicHandlerCaps[*topic] = &handlerCaps{}
   330  	}
   331  	if hndlr.caps.raw {
   332  		p.topicHandlerCaps[*topic].raw = true
   333  	}
   334  	if hndlr.caps.prox {
   335  		p.topicHandlerCaps[*topic].prox = true
   336  	}
   337  	return func() { p.deregister(topic, hndlr) }
   338  }
   339  func (p *Pss) deregister(topic *Topic, hndlr *handler) {
   340  	p.handlersMu.Lock()
   341  	defer p.handlersMu.Unlock()
   342  	handlers := p.handlers[*topic]
   343  	if len(handlers) > 1 {
   344  		delete(p.handlers, *topic)
   345  //既然处理程序不在,主题帽可能已经更改。
   346  		caps := &handlerCaps{}
   347  		for h := range handlers {
   348  			if h.caps.raw {
   349  				caps.raw = true
   350  			}
   351  			if h.caps.prox {
   352  				caps.prox = true
   353  			}
   354  		}
   355  		p.topicHandlerCaps[*topic] = caps
   356  		return
   357  	}
   358  	delete(handlers, hndlr)
   359  }
   360  
   361  //获取各自主题的所有已注册处理程序
   362  func (p *Pss) getHandlers(topic Topic) map[*handler]bool {
   363  	p.handlersMu.RLock()
   364  	defer p.handlersMu.RUnlock()
   365  	return p.handlers[topic]
   366  }
   367  
   368  //筛选要处理或转发的传入邮件。
   369  //检查地址是否部分匹配
   370  //如果是的话,它可以是我们的,我们处理它
   371  //仅当有效负载无效时才会将错误传递给PSS协议处理程序PSSMSG
   372  func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error {
   373  	metrics.GetOrRegisterCounter("pss.handlepssmsg", nil).Inc(1)
   374  	pssmsg, ok := msg.(*PssMsg)
   375  	if !ok {
   376  		return fmt.Errorf("invalid message type. Expected *PssMsg, got %T ", msg)
   377  	}
   378  	log.Trace("handler", "self", label(p.Kademlia.BaseAddr()), "topic", label(pssmsg.Payload.Topic[:]))
   379  	if int64(pssmsg.Expire) < time.Now().Unix() {
   380  		metrics.GetOrRegisterCounter("pss.expire", nil).Inc(1)
   381  		log.Warn("pss filtered expired message", "from", common.ToHex(p.Kademlia.BaseAddr()), "to", common.ToHex(pssmsg.To))
   382  		return nil
   383  	}
   384  	if p.checkFwdCache(pssmsg) {
   385  		log.Trace("pss relay block-cache match (process)", "from", common.ToHex(p.Kademlia.BaseAddr()), "to", (common.ToHex(pssmsg.To)))
   386  		return nil
   387  	}
   388  	p.addFwdCache(pssmsg)
   389  
   390  	psstopic := Topic(pssmsg.Payload.Topic)
   391  
   392  //raw是要检查的最简单的处理程序意外事件,因此请首先检查
   393  	var isRaw bool
   394  	if pssmsg.isRaw() {
   395  		if _, ok := p.topicHandlerCaps[psstopic]; ok {
   396  			if !p.topicHandlerCaps[psstopic].raw {
   397  				log.Debug("No handler for raw message", "topic", psstopic)
   398  				return nil
   399  			}
   400  		}
   401  		isRaw = true
   402  	}
   403  
   404  //检查我们是否可以成为收件人:
   405  //-消息和部分地址上没有代理处理程序匹配
   406  //-消息上的代理处理程序,并且无论部分地址是否匹配,我们都在代理中
   407  //存储此结果,这样我们就不会对每个处理程序重新计算
   408  	var isProx bool
   409  	if _, ok := p.topicHandlerCaps[psstopic]; ok {
   410  		isProx = p.topicHandlerCaps[psstopic].prox
   411  	}
   412  	isRecipient := p.isSelfPossibleRecipient(pssmsg, isProx)
   413  	if !isRecipient {
   414  		log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr()), "prox", isProx)
   415  		return p.enqueue(pssmsg)
   416  	}
   417  
   418  	log.Trace("pss for us, yay! ... let's process!", "pss", common.ToHex(p.BaseAddr()), "prox", isProx, "raw", isRaw, "topic", label(pssmsg.Payload.Topic[:]))
   419  	if err := p.process(pssmsg, isRaw, isProx); err != nil {
   420  		qerr := p.enqueue(pssmsg)
   421  		if qerr != nil {
   422  			return fmt.Errorf("process fail: processerr %v, queueerr: %v", err, qerr)
   423  		}
   424  	}
   425  	return nil
   426  
   427  }
   428  
   429  //入口点,用于处理当前节点可以作为目标收件人的消息。
   430  //尝试使用存储的密钥进行对称和非对称解密。
   431  //将消息发送到与消息主题匹配的所有处理程序
   432  func (p *Pss) process(pssmsg *PssMsg, raw bool, prox bool) error {
   433  	metrics.GetOrRegisterCounter("pss.process", nil).Inc(1)
   434  
   435  	var err error
   436  	var recvmsg *whisper.ReceivedMessage
   437  	var payload []byte
   438  	var from PssAddress
   439  	var asymmetric bool
   440  	var keyid string
   441  	var keyFunc func(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, PssAddress, error)
   442  
   443  	envelope := pssmsg.Payload
   444  	psstopic := Topic(envelope.Topic)
   445  
   446  	if raw {
   447  		payload = pssmsg.Payload.Data
   448  	} else {
   449  		if pssmsg.isSym() {
   450  			keyFunc = p.processSym
   451  		} else {
   452  			asymmetric = true
   453  			keyFunc = p.processAsym
   454  		}
   455  
   456  		recvmsg, keyid, from, err = keyFunc(envelope)
   457  		if err != nil {
   458  			return errors.New("Decryption failed")
   459  		}
   460  		payload = recvmsg.Payload
   461  	}
   462  
   463  	if len(pssmsg.To) < addressLength {
   464  		if err := p.enqueue(pssmsg); err != nil {
   465  			return err
   466  		}
   467  	}
   468  	p.executeHandlers(psstopic, payload, from, raw, prox, asymmetric, keyid)
   469  
   470  	return nil
   471  
   472  }
   473  
   474  func (p *Pss) executeHandlers(topic Topic, payload []byte, from PssAddress, raw bool, prox bool, asymmetric bool, keyid string) {
   475  	handlers := p.getHandlers(topic)
   476  	peer := p2p.NewPeer(enode.ID{}, fmt.Sprintf("%x", from), []p2p.Cap{})
   477  	for h := range handlers {
   478  		if !h.caps.raw && raw {
   479  			log.Warn("norawhandler")
   480  			continue
   481  		}
   482  		if !h.caps.prox && prox {
   483  			log.Warn("noproxhandler")
   484  			continue
   485  		}
   486  		err := (h.f)(payload, peer, asymmetric, keyid)
   487  		if err != nil {
   488  			log.Warn("Pss handler failed", "err", err)
   489  		}
   490  	}
   491  }
   492  
   493  //如果使用部分地址,将返回false
   494  func (p *Pss) isSelfRecipient(msg *PssMsg) bool {
   495  	return bytes.Equal(msg.To, p.Kademlia.BaseAddr())
   496  }
   497  
   498  //测试给定消息中最左边的字节与节点的kademlia地址的匹配
   499  func (p *Pss) isSelfPossibleRecipient(msg *PssMsg, prox bool) bool {
   500  	local := p.Kademlia.BaseAddr()
   501  
   502  //如果部分地址匹配,无论代理服务器是什么,我们都是可能的收件人。
   503  //如果没有,并且没有设置代理,我们肯定没有
   504  	if bytes.Equal(msg.To, local[:len(msg.To)]) {
   505  
   506  		return true
   507  	} else if !prox {
   508  		return false
   509  	}
   510  
   511  	depth := p.Kademlia.NeighbourhoodDepth()
   512  	po, _ := network.Pof(p.Kademlia.BaseAddr(), msg.To, 0)
   513  	log.Trace("selfpossible", "po", po, "depth", depth)
   514  
   515  	return depth <= po
   516  }
   517  
   518  ////////////////////////////////////////////////
   519  //部分:加密
   520  ////////////////////////////////////////////////
   521  
   522  //将对等ECDSA公钥链接到主题
   523  //
   524  //这对于非对称消息交换是必需的
   525  //关于给定主题
   526  //
   527  //“address”中的值将用作
   528  //公钥/主题关联
   529  func (p *Pss) SetPeerPublicKey(pubkey *ecdsa.PublicKey, topic Topic, address PssAddress) error {
   530  	if err := validateAddress(address); err != nil {
   531  		return err
   532  	}
   533  	pubkeybytes := crypto.FromECDSAPub(pubkey)
   534  	if len(pubkeybytes) == 0 {
   535  		return fmt.Errorf("invalid public key: %v", pubkey)
   536  	}
   537  	pubkeyid := common.ToHex(pubkeybytes)
   538  	psp := &pssPeer{
   539  		address: address,
   540  	}
   541  	p.pubKeyPoolMu.Lock()
   542  	if _, ok := p.pubKeyPool[pubkeyid]; !ok {
   543  		p.pubKeyPool[pubkeyid] = make(map[Topic]*pssPeer)
   544  	}
   545  	p.pubKeyPool[pubkeyid][topic] = psp
   546  	p.pubKeyPoolMu.Unlock()
   547  	log.Trace("added pubkey", "pubkeyid", pubkeyid, "topic", topic, "address", address)
   548  	return nil
   549  }
   550  
   551  //自动为主题和地址提示生成新的symkey
   552  func (p *Pss) GenerateSymmetricKey(topic Topic, address PssAddress, addToCache bool) (string, error) {
   553  	keyid, err := p.w.GenerateSymKey()
   554  	if err != nil {
   555  		return "", err
   556  	}
   557  	p.addSymmetricKeyToPool(keyid, topic, address, addToCache, false)
   558  	return keyid, nil
   559  }
   560  
   561  //将对等对称密钥(任意字节序列)链接到主题
   562  //
   563  //这是对称加密邮件交换所必需的
   564  //关于给定主题
   565  //
   566  //密钥存储在Whisper后端。
   567  //
   568  //如果addtocache设置为true,则密钥将添加到密钥的缓存中。
   569  //用于尝试对传入消息进行对称解密。
   570  //
   571  //返回可用于检索键字节的字符串ID
   572  //从Whisper后端(请参阅pss.getSymmetricKey())
   573  func (p *Pss) SetSymmetricKey(key []byte, topic Topic, address PssAddress, addtocache bool) (string, error) {
   574  	if err := validateAddress(address); err != nil {
   575  		return "", err
   576  	}
   577  	return p.setSymmetricKey(key, topic, address, addtocache, true)
   578  }
   579  
   580  func (p *Pss) setSymmetricKey(key []byte, topic Topic, address PssAddress, addtocache bool, protected bool) (string, error) {
   581  	keyid, err := p.w.AddSymKeyDirect(key)
   582  	if err != nil {
   583  		return "", err
   584  	}
   585  	p.addSymmetricKeyToPool(keyid, topic, address, addtocache, protected)
   586  	return keyid, nil
   587  }
   588  
   589  //向PSS密钥池添加对称密钥,并可以选择添加密钥
   590  //用于尝试对称解密的密钥集合
   591  //传入消息
   592  func (p *Pss) addSymmetricKeyToPool(keyid string, topic Topic, address PssAddress, addtocache bool, protected bool) {
   593  	psp := &pssPeer{
   594  		address:   address,
   595  		protected: protected,
   596  	}
   597  	p.symKeyPoolMu.Lock()
   598  	if _, ok := p.symKeyPool[keyid]; !ok {
   599  		p.symKeyPool[keyid] = make(map[Topic]*pssPeer)
   600  	}
   601  	p.symKeyPool[keyid][topic] = psp
   602  	p.symKeyPoolMu.Unlock()
   603  	if addtocache {
   604  		p.symKeyDecryptCacheCursor++
   605  		p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = &keyid
   606  	}
   607  	key, _ := p.GetSymmetricKey(keyid)
   608  	log.Trace("added symkey", "symkeyid", keyid, "symkey", common.ToHex(key), "topic", topic, "address", address, "cache", addtocache)
   609  }
   610  
   611  //返回存储在Whisper后端中的对称密钥字节seqyence
   612  //通过其唯一ID
   613  //
   614  //从Whisper后端传递错误值
   615  func (p *Pss) GetSymmetricKey(symkeyid string) ([]byte, error) {
   616  	symkey, err := p.w.GetSymKey(symkeyid)
   617  	if err != nil {
   618  		return nil, err
   619  	}
   620  	return symkey, nil
   621  }
   622  
   623  //返回特定公钥的所有录制主题和地址组合
   624  func (p *Pss) GetPublickeyPeers(keyid string) (topic []Topic, address []PssAddress, err error) {
   625  	p.pubKeyPoolMu.RLock()
   626  	defer p.pubKeyPoolMu.RUnlock()
   627  	for t, peer := range p.pubKeyPool[keyid] {
   628  		topic = append(topic, t)
   629  		address = append(address, peer.address)
   630  	}
   631  
   632  	return topic, address, nil
   633  }
   634  
   635  func (p *Pss) getPeerAddress(keyid string, topic Topic) (PssAddress, error) {
   636  	p.pubKeyPoolMu.RLock()
   637  	defer p.pubKeyPoolMu.RUnlock()
   638  	if peers, ok := p.pubKeyPool[keyid]; ok {
   639  		if t, ok := peers[topic]; ok {
   640  			return t.address, nil
   641  		}
   642  	}
   643  	return nil, fmt.Errorf("peer with pubkey %s, topic %x not found", keyid, topic)
   644  }
   645  
   646  //尝试解密、验证和解包
   647  //对称加密消息
   648  //如果成功,则返回解包的Whisper ReceivedMessage结构
   649  //封装解密的消息和Whisper后端ID
   650  //用于解密消息的对称密钥。
   651  //如果解密消息失败或消息已损坏,则失败。
   652  func (p *Pss) processSym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, PssAddress, error) {
   653  	metrics.GetOrRegisterCounter("pss.process.sym", nil).Inc(1)
   654  
   655  	for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- {
   656  		symkeyid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)]
   657  		symkey, err := p.w.GetSymKey(*symkeyid)
   658  		if err != nil {
   659  			continue
   660  		}
   661  		recvmsg, err := envelope.OpenSymmetric(symkey)
   662  		if err != nil {
   663  			continue
   664  		}
   665  		if !recvmsg.Validate() {
   666  			return nil, "", nil, fmt.Errorf("symmetrically encrypted message has invalid signature or is corrupt")
   667  		}
   668  		p.symKeyPoolMu.Lock()
   669  		from := p.symKeyPool[*symkeyid][Topic(envelope.Topic)].address
   670  		p.symKeyPoolMu.Unlock()
   671  		p.symKeyDecryptCacheCursor++
   672  		p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = symkeyid
   673  		return recvmsg, *symkeyid, from, nil
   674  	}
   675  	return nil, "", nil, fmt.Errorf("could not decrypt message")
   676  }
   677  
   678  //尝试解密、验证和解包
   679  //非对称加密消息
   680  //如果成功,则返回解包的Whisper ReceivedMessage结构
   681  //封装解密的消息,以及
   682  //用于解密消息的公钥。
   683  //如果解密消息失败或消息已损坏,则失败。
   684  func (p *Pss) processAsym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, PssAddress, error) {
   685  	metrics.GetOrRegisterCounter("pss.process.asym", nil).Inc(1)
   686  
   687  	recvmsg, err := envelope.OpenAsymmetric(p.privateKey)
   688  	if err != nil {
   689  		return nil, "", nil, fmt.Errorf("could not decrypt message: %s", err)
   690  	}
   691  //检查签名(如果有签名),去掉填充
   692  	if !recvmsg.Validate() {
   693  		return nil, "", nil, fmt.Errorf("invalid message")
   694  	}
   695  	pubkeyid := common.ToHex(crypto.FromECDSAPub(recvmsg.Src))
   696  	var from PssAddress
   697  	p.pubKeyPoolMu.Lock()
   698  	if p.pubKeyPool[pubkeyid][Topic(envelope.Topic)] != nil {
   699  		from = p.pubKeyPool[pubkeyid][Topic(envelope.Topic)].address
   700  	}
   701  	p.pubKeyPoolMu.Unlock()
   702  	return recvmsg, pubkeyid, from, nil
   703  }
   704  
   705  //symkey垃圾收集
   706  //如果出现以下情况,钥匙将被取下:
   707  //-未标记为受保护
   708  //-不在传入解密缓存中
   709  func (p *Pss) cleanKeys() (count int) {
   710  	for keyid, peertopics := range p.symKeyPool {
   711  		var expiredtopics []Topic
   712  		for topic, psp := range peertopics {
   713  			if psp.protected {
   714  				continue
   715  			}
   716  
   717  			var match bool
   718  			for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- {
   719  				cacheid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)]
   720  				if *cacheid == keyid {
   721  					match = true
   722  				}
   723  			}
   724  			if !match {
   725  				expiredtopics = append(expiredtopics, topic)
   726  			}
   727  		}
   728  		for _, topic := range expiredtopics {
   729  			p.symKeyPoolMu.Lock()
   730  			delete(p.symKeyPool[keyid], topic)
   731  			log.Trace("symkey cleanup deletion", "symkeyid", keyid, "topic", topic, "val", p.symKeyPool[keyid])
   732  			p.symKeyPoolMu.Unlock()
   733  			count++
   734  		}
   735  	}
   736  	return
   737  }
   738  
   739  ////////////////////////////////////////////////
   740  //部分:消息发送
   741  ////////////////////////////////////////////////
   742  
   743  func (p *Pss) enqueue(msg *PssMsg) error {
   744  	select {
   745  	case p.outbox <- msg:
   746  		return nil
   747  	default:
   748  	}
   749  
   750  	metrics.GetOrRegisterCounter("pss.enqueue.outbox.full", nil).Inc(1)
   751  	return errors.New("outbox full")
   752  }
   753  
   754  //发送原始消息(任何加密都由调用客户端负责)
   755  //
   756  //如果不允许原始消息,将失败
   757  func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error {
   758  	if err := validateAddress(address); err != nil {
   759  		return err
   760  	}
   761  	pssMsgParams := &msgParams{
   762  		raw: true,
   763  	}
   764  	payload := &whisper.Envelope{
   765  		Data:  msg,
   766  		Topic: whisper.TopicType(topic),
   767  	}
   768  	pssMsg := newPssMsg(pssMsgParams)
   769  	pssMsg.To = address
   770  	pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix())
   771  	pssMsg.Payload = payload
   772  	p.addFwdCache(pssMsg)
   773  	err := p.enqueue(pssMsg)
   774  	if err != nil {
   775  		return err
   776  	}
   777  
   778  //如果我们有关于这个主题的代理处理程序
   779  //同时向我们自己传递信息
   780  	if _, ok := p.topicHandlerCaps[topic]; ok {
   781  		if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic].prox {
   782  			return p.process(pssMsg, true, true)
   783  		}
   784  	}
   785  	return nil
   786  }
   787  
   788  //使用对称加密发送消息
   789  //
   790  //如果密钥ID与任何存储的对称密钥不匹配,则失败
   791  func (p *Pss) SendSym(symkeyid string, topic Topic, msg []byte) error {
   792  	symkey, err := p.GetSymmetricKey(symkeyid)
   793  	if err != nil {
   794  		return fmt.Errorf("missing valid send symkey %s: %v", symkeyid, err)
   795  	}
   796  	p.symKeyPoolMu.Lock()
   797  	psp, ok := p.symKeyPool[symkeyid][topic]
   798  	p.symKeyPoolMu.Unlock()
   799  	if !ok {
   800  		return fmt.Errorf("invalid topic '%s' for symkey '%s'", topic.String(), symkeyid)
   801  	}
   802  	return p.send(psp.address, topic, msg, false, symkey)
   803  }
   804  
   805  //使用非对称加密发送消息
   806  //
   807  //如果密钥ID与存储的公钥中的任何一个不匹配,则失败
   808  func (p *Pss) SendAsym(pubkeyid string, topic Topic, msg []byte) error {
   809  	if _, err := crypto.UnmarshalPubkey(common.FromHex(pubkeyid)); err != nil {
   810  		return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkeyid)
   811  	}
   812  	p.pubKeyPoolMu.Lock()
   813  	psp, ok := p.pubKeyPool[pubkeyid][topic]
   814  	p.pubKeyPoolMu.Unlock()
   815  	if !ok {
   816  		return fmt.Errorf("invalid topic '%s' for pubkey '%s'", topic.String(), pubkeyid)
   817  	}
   818  	return p.send(psp.address, topic, msg, true, common.FromHex(pubkeyid))
   819  }
   820  
   821  //send不区分有效负载,并将接受任何字节片作为有效负载
   822  //它为指定的收件人和主题生成一个耳语信封,
   823  //并将消息有效负载包装在其中。
   824  //TODO:实现正确的消息填充
   825  func (p *Pss) send(to []byte, topic Topic, msg []byte, asymmetric bool, key []byte) error {
   826  	metrics.GetOrRegisterCounter("pss.send", nil).Inc(1)
   827  
   828  	if key == nil || bytes.Equal(key, []byte{}) {
   829  		return fmt.Errorf("Zero length key passed to pss send")
   830  	}
   831  	padding := make([]byte, p.paddingByteSize)
   832  	c, err := rand.Read(padding)
   833  	if err != nil {
   834  		return err
   835  	} else if c < p.paddingByteSize {
   836  		return fmt.Errorf("invalid padding length: %d", c)
   837  	}
   838  	wparams := &whisper.MessageParams{
   839  		TTL:      defaultWhisperTTL,
   840  		Src:      p.privateKey,
   841  		Topic:    whisper.TopicType(topic),
   842  		WorkTime: defaultWhisperWorkTime,
   843  		PoW:      defaultWhisperPoW,
   844  		Payload:  msg,
   845  		Padding:  padding,
   846  	}
   847  	if asymmetric {
   848  		pk, err := crypto.UnmarshalPubkey(key)
   849  		if err != nil {
   850  			return fmt.Errorf("Cannot unmarshal pubkey: %x", key)
   851  		}
   852  		wparams.Dst = pk
   853  	} else {
   854  		wparams.KeySym = key
   855  	}
   856  //设置传出消息容器,该容器执行加密和信封包装
   857  	woutmsg, err := whisper.NewSentMessage(wparams)
   858  	if err != nil {
   859  		return fmt.Errorf("failed to generate whisper message encapsulation: %v", err)
   860  	}
   861  //执行加密。
   862  //由于设置难度很低,无法执行/执行可忽略的POW
   863  //之后,消息就可以发送了
   864  	envelope, err := woutmsg.Wrap(wparams)
   865  	if err != nil {
   866  		return fmt.Errorf("failed to perform whisper encryption: %v", err)
   867  	}
   868  	log.Trace("pssmsg whisper done", "env", envelope, "wparams payload", common.ToHex(wparams.Payload), "to", common.ToHex(to), "asym", asymmetric, "key", common.ToHex(key))
   869  
   870  //准备DEVP2P传输
   871  	pssMsgParams := &msgParams{
   872  		sym: !asymmetric,
   873  	}
   874  	pssMsg := newPssMsg(pssMsgParams)
   875  	pssMsg.To = to
   876  	pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix())
   877  	pssMsg.Payload = envelope
   878  	err = p.enqueue(pssMsg)
   879  	if err != nil {
   880  		return err
   881  	}
   882  	if _, ok := p.topicHandlerCaps[topic]; ok {
   883  		if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic].prox {
   884  			return p.process(pssMsg, true, true)
   885  		}
   886  	}
   887  	return nil
   888  }
   889  
   890  //sendfunc是一个帮助函数,它尝试发送消息并在成功时返回true。
   891  //它在这里设置为在生产中使用,并在测试中可选地重写。
   892  var sendFunc func(p *Pss, sp *network.Peer, msg *PssMsg) bool = sendMsg
   893  
   894  //尝试发送消息,如果成功则返回true
   895  func sendMsg(p *Pss, sp *network.Peer, msg *PssMsg) bool {
   896  	var isPssEnabled bool
   897  	info := sp.Info()
   898  	for _, capability := range info.Caps {
   899  		if capability == p.capstring {
   900  			isPssEnabled = true
   901  			break
   902  		}
   903  	}
   904  	if !isPssEnabled {
   905  		log.Error("peer doesn't have matching pss capabilities, skipping", "peer", info.Name, "caps", info.Caps)
   906  		return false
   907  	}
   908  
   909  //从转发对等缓存获取协议对等
   910  	p.fwdPoolMu.RLock()
   911  	pp := p.fwdPool[sp.Info().ID]
   912  	p.fwdPoolMu.RUnlock()
   913  
   914  	err := pp.Send(context.TODO(), msg)
   915  	if err != nil {
   916  		metrics.GetOrRegisterCounter("pss.pp.send.error", nil).Inc(1)
   917  		log.Error(err.Error())
   918  	}
   919  
   920  	return err == nil
   921  }
   922  
   923  //根据算法,将基于收件人地址的PSS消息转发给对等方
   924  //如下所述。收件人地址可以是任意长度,字节片将匹配
   925  //等效长度的对等地址的MSB切片。
   926  //
   927  //如果收件人地址(或部分地址)在转发的邻近深度内
   928  //节点,然后它将被转发到转发节点的所有最近邻居。万一
   929  //部分地址,如果存在,则应转发给与部分地址匹配的所有对等方
   930  //是任意的;否则仅限于最接近收件人地址的一个对等机。在任何情况下,如果
   931  //转发失败,节点应尝试将其转发到下一个最佳对等端,直到消息
   932  //已成功转发到至少一个对等机。
   933  func (p *Pss) forward(msg *PssMsg) error {
   934  	metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1)
   935  sent := 0 //成功发送的次数
   936  	to := make([]byte, addressLength)
   937  	copy(to[:len(msg.To)], msg.To)
   938  	neighbourhoodDepth := p.Kademlia.NeighbourhoodDepth()
   939  
   940  //光明与黑暗是对立的。从地址中删除的字节越多,越黑,
   941  //但是亮度变小了。这里亮度等于目的地址中给定的位数。
   942  	luminosityRadius := len(msg.To) * 8
   943  
   944  //接近顺序功能匹配到邻接位(po<=neighbourhooddepth)
   945  	pof := pot.DefaultPof(neighbourhoodDepth)
   946  
   947  //消息广播软阈值
   948  	broadcastThreshold, _ := pof(to, p.BaseAddr(), 0)
   949  	if broadcastThreshold > luminosityRadius {
   950  		broadcastThreshold = luminosityRadius
   951  	}
   952  
   953  var onlySendOnce bool //指示是否只应将消息发送到一个地址最近的对等机
   954  
   955  //如果从收件人地址而不是基地址测量(参见kademlia.eachconn
   956  //呼叫下面),然后将出现与收件人地址位于同一个近箱中的对等机。
   957  //[至少]靠近一位,但只有在收件人地址中给出这些附加位时。
   958  	if broadcastThreshold < luminosityRadius && broadcastThreshold < neighbourhoodDepth {
   959  		broadcastThreshold++
   960  		onlySendOnce = true
   961  	}
   962  
   963  	p.Kademlia.EachConn(to, addressLength*8, func(sp *network.Peer, po int) bool {
   964  		if po < broadcastThreshold && sent > 0 {
   965  return false //停止迭代
   966  		}
   967  		if sendFunc(p, sp, msg) {
   968  			sent++
   969  			if onlySendOnce {
   970  				return false
   971  			}
   972  			if po == addressLength*8 {
   973  //如果成功发送到确切的收件人,则停止迭代(完全匹配完整地址)
   974  				return false
   975  			}
   976  		}
   977  		return true
   978  	})
   979  
   980  //如果发送失败,请在发送队列中重新插入消息
   981  	if sent == 0 {
   982  		log.Debug("unable to forward to any peers")
   983  		if err := p.enqueue(msg); err != nil {
   984  			metrics.GetOrRegisterCounter("pss.forward.enqueue.error", nil).Inc(1)
   985  			log.Error(err.Error())
   986  			return err
   987  		}
   988  	}
   989  
   990  //缓存消息
   991  	p.addFwdCache(msg)
   992  	return nil
   993  }
   994  
   995  ////////////////////////////////////////////////
   996  //部分:缓存
   997  ////////////////////////////////////////////////
   998  
   999  //cleanfwdcache用于定期从转发缓存中删除过期条目。
  1000  func (p *Pss) cleanFwdCache() {
  1001  	metrics.GetOrRegisterCounter("pss.cleanfwdcache", nil).Inc(1)
  1002  	p.fwdCacheMu.Lock()
  1003  	defer p.fwdCacheMu.Unlock()
  1004  	for k, v := range p.fwdCache {
  1005  		if v.expiresAt.Before(time.Now()) {
  1006  			delete(p.fwdCache, k)
  1007  		}
  1008  	}
  1009  }
  1010  
  1011  func label(b []byte) string {
  1012  	return fmt.Sprintf("%04x", b[:2])
  1013  }
  1014  
  1015  //向缓存中添加消息
  1016  func (p *Pss) addFwdCache(msg *PssMsg) error {
  1017  	metrics.GetOrRegisterCounter("pss.addfwdcache", nil).Inc(1)
  1018  
  1019  	var entry pssCacheEntry
  1020  	var ok bool
  1021  
  1022  	p.fwdCacheMu.Lock()
  1023  	defer p.fwdCacheMu.Unlock()
  1024  
  1025  	digest := p.digest(msg)
  1026  	if entry, ok = p.fwdCache[digest]; !ok {
  1027  		entry = pssCacheEntry{}
  1028  	}
  1029  	entry.expiresAt = time.Now().Add(p.cacheTTL)
  1030  	p.fwdCache[digest] = entry
  1031  	return nil
  1032  }
  1033  
  1034  //检查消息是否在缓存中
  1035  func (p *Pss) checkFwdCache(msg *PssMsg) bool {
  1036  	p.fwdCacheMu.Lock()
  1037  	defer p.fwdCacheMu.Unlock()
  1038  
  1039  	digest := p.digest(msg)
  1040  	entry, ok := p.fwdCache[digest]
  1041  	if ok {
  1042  		if entry.expiresAt.After(time.Now()) {
  1043  			log.Trace("unexpired cache", "digest", fmt.Sprintf("%x", digest))
  1044  			metrics.GetOrRegisterCounter("pss.checkfwdcache.unexpired", nil).Inc(1)
  1045  			return true
  1046  		}
  1047  		metrics.GetOrRegisterCounter("pss.checkfwdcache.expired", nil).Inc(1)
  1048  	}
  1049  	return false
  1050  }
  1051  
  1052  //消息摘要
  1053  func (p *Pss) digest(msg *PssMsg) pssDigest {
  1054  	return p.digestBytes(msg.serialize())
  1055  }
  1056  
  1057  func (p *Pss) digestBytes(msg []byte) pssDigest {
  1058  	hasher := p.hashPool.Get().(hash.Hash)
  1059  	defer p.hashPool.Put(hasher)
  1060  	hasher.Reset()
  1061  	hasher.Write(msg)
  1062  	digest := pssDigest{}
  1063  	key := hasher.Sum(nil)
  1064  	copy(digest[:], key[:digestLength])
  1065  	return digest
  1066  }
  1067  
  1068  func validateAddress(addr PssAddress) error {
  1069  	if len(addr) > addressLength {
  1070  		return errors.New("address too long")
  1071  	}
  1072  	return nil
  1073  }
  1074