github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/enr/entries.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:41</date>
    10  //</624450104786423808>
    11  
    12  
    13  package enr
    14  
    15  import (
    16  	"fmt"
    17  	"io"
    18  	"net"
    19  
    20  	"github.com/ethereum/go-ethereum/rlp"
    21  )
    22  
    23  //条目由已知的节点记录条目类型实现。
    24  //
    25  //要定义要包含在节点记录中的新条目,
    26  //创建满足此接口的Go类型。类型应该
    27  //如果需要对值进行额外检查,还可以实现rlp.decoder。
    28  type Entry interface {
    29  	ENRKey() string
    30  }
    31  
    32  type generic struct {
    33  	key   string
    34  	value interface{}
    35  }
    36  
    37  func (g generic) ENRKey() string { return g.key }
    38  
    39  func (g generic) EncodeRLP(w io.Writer) error {
    40  	return rlp.Encode(w, g.value)
    41  }
    42  
    43  func (g *generic) DecodeRLP(s *rlp.Stream) error {
    44  	return s.Decode(g.value)
    45  }
    46  
    47  //WithEntry用键名包装任何值。它可用于设置和加载任意值
    48  //在记录中。值v必须由rlp支持。要在加载时使用WithEntry,值
    49  //必须是指针。
    50  func WithEntry(k string, v interface{}) Entry {
    51  	return &generic{key: k, value: v}
    52  }
    53  
    54  //tcp是“tcp”密钥,它保存节点的tcp端口。
    55  type TCP uint16
    56  
    57  func (v TCP) ENRKey() string { return "tcp" }
    58  
    59  //udp是“udp”密钥,它保存节点的udp端口。
    60  type UDP uint16
    61  
    62  func (v UDP) ENRKey() string { return "udp" }
    63  
    64  //ID是“ID”键,它保存标识方案的名称。
    65  type ID string
    66  
    67  const IDv4 = ID("v4") //默认标识方案
    68  
    69  func (v ID) ENRKey() string { return "id" }
    70  
    71  //IP是“IP”密钥,它保存节点的IP地址。
    72  type IP net.IP
    73  
    74  func (v IP) ENRKey() string { return "ip" }
    75  
    76  //encoderlp实现rlp.encoder。
    77  func (v IP) EncodeRLP(w io.Writer) error {
    78  	if ip4 := net.IP(v).To4(); ip4 != nil {
    79  		return rlp.Encode(w, ip4)
    80  	}
    81  	return rlp.Encode(w, net.IP(v))
    82  }
    83  
    84  //decoderlp实现rlp.decoder。
    85  func (v *IP) DecodeRLP(s *rlp.Stream) error {
    86  	if err := s.Decode((*net.IP)(v)); err != nil {
    87  		return err
    88  	}
    89  	if len(*v) != 4 && len(*v) != 16 {
    90  		return fmt.Errorf("invalid IP address, want 4 or 16 bytes: %v", *v)
    91  	}
    92  	return nil
    93  }
    94  
    95  //keyError是一个与键相关的错误。
    96  type KeyError struct {
    97  	Key string
    98  	Err error
    99  }
   100  
   101  //错误实现错误。
   102  func (err *KeyError) Error() string {
   103  	if err.Err == errNotFound {
   104  		return fmt.Sprintf("missing ENR key %q", err.Key)
   105  	}
   106  	return fmt.Sprintf("ENR key %q: %v", err.Key, err.Err)
   107  }
   108  
   109  //IsNotFound报告给定的错误是否意味着键/值对
   110  //记录中缺少。
   111  func IsNotFound(err error) bool {
   112  	kerr, ok := err.(*KeyError)
   113  	return ok && kerr.Err == errNotFound
   114  }
   115