github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/p2p/enr/entries.go (about) 1 // Copyright 2017 The go-simplechain Authors 2 // This file is part of the go-simplechain library. 3 // 4 // The go-simplechain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-simplechain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-simplechain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package enr 18 19 import ( 20 "fmt" 21 "io" 22 "net" 23 24 "github.com/bigzoro/my_simplechain/rlp" 25 ) 26 27 // Entry is implemented by known node record entry types. 28 // 29 // To define a new entry that is to be included in a node record, 30 // create a Go type that satisfies this interface. The type should 31 // also implement rlp.Decoder if additional checks are needed on the value. 32 type Entry interface { 33 ENRKey() string 34 } 35 36 type generic struct { 37 key string 38 value interface{} 39 } 40 41 func (g generic) ENRKey() string { return g.key } 42 43 func (g generic) EncodeRLP(w io.Writer) error { 44 return rlp.Encode(w, g.value) 45 } 46 47 func (g *generic) DecodeRLP(s *rlp.Stream) error { 48 return s.Decode(g.value) 49 } 50 51 // WithEntry wraps any value with a key name. It can be used to set and load arbitrary values 52 // in a record. The value v must be supported by rlp. To use WithEntry with Load, the value 53 // must be a pointer. 54 func WithEntry(k string, v interface{}) Entry { 55 return &generic{key: k, value: v} 56 } 57 58 // RaftPort is the "raftport" key, which holds the raftport of the node 59 type RaftPort uint16 60 61 func (v RaftPort) ENRKey() string { return "raftport" } 62 63 type Hostname string 64 65 func (v Hostname) ENRKey() string { return "hostname" } 66 67 // TCP is the "tcp" key, which holds the TCP port of the node. 68 type TCP uint16 69 70 func (v TCP) ENRKey() string { return "tcp" } 71 72 // UDP is the "udp" key, which holds the IPv6-specific UDP port of the node. 73 type TCP6 uint16 74 75 func (v TCP6) ENRKey() string { return "tcp6" } 76 77 // UDP is the "udp" key, which holds the UDP port of the node. 78 type UDP uint16 79 80 func (v UDP) ENRKey() string { return "udp" } 81 82 // UDP is the "udp" key, which holds the IPv6-specific UDP port of the node. 83 type UDP6 uint16 84 85 func (v UDP6) ENRKey() string { return "udp6" } 86 87 // ID is the "id" key, which holds the name of the identity scheme. 88 type ID string 89 90 const IDv4 = ID("v4") // the default identity scheme 91 92 func (v ID) ENRKey() string { return "id" } 93 94 // IP is either the "ip" or "ip6" key, depending on the value. 95 // Use this value to encode IP addresses that can be either v4 or v6. 96 // To load an address from a record use the IPv4 or IPv6 types. 97 type IP net.IP 98 99 func (v IP) ENRKey() string { 100 if net.IP(v).To4() == nil { 101 return "ip6" 102 } 103 return "ip" 104 } 105 106 // EncodeRLP implements rlp.Encoder. 107 func (v IP) EncodeRLP(w io.Writer) error { 108 if ip4 := net.IP(v).To4(); ip4 != nil { 109 return rlp.Encode(w, ip4) 110 } 111 if ip6 := net.IP(v).To16(); ip6 != nil { 112 return rlp.Encode(w, ip6) 113 } 114 return fmt.Errorf("invalid IP address: %v", net.IP(v)) 115 } 116 117 // DecodeRLP implements rlp.Decoder. 118 func (v *IP) DecodeRLP(s *rlp.Stream) error { 119 if err := s.Decode((*net.IP)(v)); err != nil { 120 return err 121 } 122 if len(*v) != 4 && len(*v) != 16 { 123 return fmt.Errorf("invalid IP address, want 4 or 16 bytes: %v", *v) 124 } 125 return nil 126 } 127 128 // IPv4 is the "ip" key, which holds the IP address of the node. 129 type IPv4 net.IP 130 131 func (v IPv4) ENRKey() string { return "ip" } 132 133 // EncodeRLP implements rlp.Encoder. 134 func (v IPv4) EncodeRLP(w io.Writer) error { 135 ip4 := net.IP(v).To4() 136 if ip4 == nil { 137 return fmt.Errorf("invalid IPv4 address: %v", net.IP(v)) 138 } 139 return rlp.Encode(w, ip4) 140 } 141 142 // DecodeRLP implements rlp.Decoder. 143 func (v *IPv4) DecodeRLP(s *rlp.Stream) error { 144 if err := s.Decode((*net.IP)(v)); err != nil { 145 return err 146 } 147 if len(*v) != 4 { 148 return fmt.Errorf("invalid IPv4 address, want 4 bytes: %v", *v) 149 } 150 return nil 151 } 152 153 // IPv6 is the "ip6" key, which holds the IP address of the node. 154 type IPv6 net.IP 155 156 func (v IPv6) ENRKey() string { return "ip6" } 157 158 // EncodeRLP implements rlp.Encoder. 159 func (v IPv6) EncodeRLP(w io.Writer) error { 160 ip6 := net.IP(v).To16() 161 if ip6 == nil { 162 return fmt.Errorf("invalid IPv6 address: %v", net.IP(v)) 163 } 164 return rlp.Encode(w, ip6) 165 } 166 167 // DecodeRLP implements rlp.Decoder. 168 func (v *IPv6) DecodeRLP(s *rlp.Stream) error { 169 if err := s.Decode((*net.IP)(v)); err != nil { 170 return err 171 } 172 if len(*v) != 16 { 173 return fmt.Errorf("invalid IPv6 address, want 16 bytes: %v", *v) 174 } 175 return nil 176 } 177 178 // KeyError is an error related to a key. 179 type KeyError struct { 180 Key string 181 Err error 182 } 183 184 // Error implements error. 185 func (err *KeyError) Error() string { 186 if err.Err == errNotFound { 187 return fmt.Sprintf("missing ENR key %q", err.Key) 188 } 189 return fmt.Sprintf("ENR key %q: %v", err.Key, err.Err) 190 } 191 192 // IsNotFound reports whether the given error means that a key/value pair is 193 // missing from a record. 194 func IsNotFound(err error) bool { 195 kerr, ok := err.(*KeyError) 196 return ok && kerr.Err == errNotFound 197 }