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