github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/p2p/enr/entries.go (about) 1 package enr 2 3 import ( 4 "crypto/ecdsa" 5 "fmt" 6 "io" 7 "net" 8 9 "github.com/quickchainproject/quickchain/crypto" 10 "github.com/quickchainproject/quickchain/rlp" 11 ) 12 13 // Entry is implemented by known node record entry types. 14 // 15 // To define a new entry that is to be included in a node record, 16 // create a Go type that satisfies this interface. The type should 17 // also implement rlp.Decoder if additional checks are needed on the value. 18 type Entry interface { 19 ENRKey() string 20 } 21 22 type generic struct { 23 key string 24 value interface{} 25 } 26 27 func (g generic) ENRKey() string { return g.key } 28 29 func (g generic) EncodeRLP(w io.Writer) error { 30 return rlp.Encode(w, g.value) 31 } 32 33 func (g *generic) DecodeRLP(s *rlp.Stream) error { 34 return s.Decode(g.value) 35 } 36 37 // WithEntry wraps any value with a key name. It can be used to set and load arbitrary values 38 // in a record. The value v must be supported by rlp. To use WithEntry with Load, the value 39 // must be a pointer. 40 func WithEntry(k string, v interface{}) Entry { 41 return &generic{key: k, value: v} 42 } 43 44 // DiscPort is the "discv5" key, which holds the UDP port for discovery v5. 45 type DiscPort uint16 46 47 func (v DiscPort) ENRKey() string { return "discv5" } 48 49 // ID is the "id" key, which holds the name of the identity scheme. 50 type ID string 51 52 func (v ID) ENRKey() string { return "id" } 53 54 // IP4 is the "ip4" key, which holds a 4-byte IPv4 address. 55 type IP4 net.IP 56 57 func (v IP4) ENRKey() string { return "ip4" } 58 59 // EncodeRLP implements rlp.Encoder. 60 func (v IP4) EncodeRLP(w io.Writer) error { 61 ip4 := net.IP(v).To4() 62 if ip4 == nil { 63 return fmt.Errorf("invalid IPv4 address: %v", v) 64 } 65 return rlp.Encode(w, ip4) 66 } 67 68 // DecodeRLP implements rlp.Decoder. 69 func (v *IP4) DecodeRLP(s *rlp.Stream) error { 70 if err := s.Decode((*net.IP)(v)); err != nil { 71 return err 72 } 73 if len(*v) != 4 { 74 return fmt.Errorf("invalid IPv4 address, want 4 bytes: %v", *v) 75 } 76 return nil 77 } 78 79 // IP6 is the "ip6" key, which holds a 16-byte IPv6 address. 80 type IP6 net.IP 81 82 func (v IP6) ENRKey() string { return "ip6" } 83 84 // EncodeRLP implements rlp.Encoder. 85 func (v IP6) EncodeRLP(w io.Writer) error { 86 ip6 := net.IP(v) 87 return rlp.Encode(w, ip6) 88 } 89 90 // DecodeRLP implements rlp.Decoder. 91 func (v *IP6) DecodeRLP(s *rlp.Stream) error { 92 if err := s.Decode((*net.IP)(v)); err != nil { 93 return err 94 } 95 if len(*v) != 16 { 96 return fmt.Errorf("invalid IPv6 address, want 16 bytes: %v", *v) 97 } 98 return nil 99 } 100 101 // Secp256k1 is the "secp256k1" key, which holds a public key. 102 type Secp256k1 ecdsa.PublicKey 103 104 func (v Secp256k1) ENRKey() string { return "secp256k1" } 105 106 // EncodeRLP implements rlp.Encoder. 107 func (v Secp256k1) EncodeRLP(w io.Writer) error { 108 return rlp.Encode(w, crypto.CompressPubkey((*ecdsa.PublicKey)(&v))) 109 } 110 111 // DecodeRLP implements rlp.Decoder. 112 func (v *Secp256k1) DecodeRLP(s *rlp.Stream) error { 113 buf, err := s.Bytes() 114 if err != nil { 115 return err 116 } 117 pk, err := crypto.DecompressPubkey(buf) 118 if err != nil { 119 return err 120 } 121 *v = (Secp256k1)(*pk) 122 return nil 123 } 124 125 // KeyError is an error related to a key. 126 type KeyError struct { 127 Key string 128 Err error 129 } 130 131 // Error implements error. 132 func (err *KeyError) Error() string { 133 if err.Err == errNotFound { 134 return fmt.Sprintf("missing ENR key %q", err.Key) 135 } 136 return fmt.Sprintf("ENR key %q: %v", err.Key, err.Err) 137 } 138 139 // IsNotFound reports whether the given error means that a key/value pair is 140 // missing from a record. 141 func IsNotFound(err error) bool { 142 kerr, ok := err.(*KeyError) 143 return ok && kerr.Err == errNotFound 144 }