enr.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. // Package enr implements Ethereum Node Records as defined in EIP-778. A node record holds
  17. // arbitrary information about a node on the peer-to-peer network. Node information is
  18. // stored in key/value pairs. To store and retrieve key/values in a record, use the Entry
  19. // interface.
  20. //
  21. // Signature Handling
  22. //
  23. // Records must be signed before transmitting them to another node.
  24. //
  25. // Decoding a record doesn't check its signature. Code working with records from an
  26. // untrusted source must always verify two things: that the record uses an identity scheme
  27. // deemed secure, and that the signature is valid according to the declared scheme.
  28. //
  29. // When creating a record, set the entries you want and use a signing function provided by
  30. // the identity scheme to add the signature. Modifying a record invalidates the signature.
  31. //
  32. // Package enr supports the "secp256k1-keccak" identity scheme.
  33. package enr
  34. import (
  35. "bytes"
  36. "errors"
  37. "fmt"
  38. "io"
  39. "sort"
  40. "github.com/ethereum/go-ethereum/rlp"
  41. )
  42. const SizeLimit = 300 // maximum encoded size of a node record in bytes
  43. var (
  44. ErrInvalidSig = errors.New("invalid signature on node record")
  45. errNotSorted = errors.New("record key/value pairs are not sorted by key")
  46. errDuplicateKey = errors.New("record contains duplicate key")
  47. errIncompletePair = errors.New("record contains incomplete k/v pair")
  48. errTooBig = fmt.Errorf("record bigger than %d bytes", SizeLimit)
  49. errEncodeUnsigned = errors.New("can't encode unsigned record")
  50. errNotFound = errors.New("no such key in record")
  51. )
  52. // An IdentityScheme is capable of verifying record signatures and
  53. // deriving node addresses.
  54. type IdentityScheme interface {
  55. Verify(r *Record, sig []byte) error
  56. NodeAddr(r *Record) []byte
  57. }
  58. // SchemeMap is a registry of named identity schemes.
  59. type SchemeMap map[string]IdentityScheme
  60. func (m SchemeMap) Verify(r *Record, sig []byte) error {
  61. s := m[r.IdentityScheme()]
  62. if s == nil {
  63. return ErrInvalidSig
  64. }
  65. return s.Verify(r, sig)
  66. }
  67. func (m SchemeMap) NodeAddr(r *Record) []byte {
  68. s := m[r.IdentityScheme()]
  69. if s == nil {
  70. return nil
  71. }
  72. return s.NodeAddr(r)
  73. }
  74. // Record represents a node record. The zero value is an empty record.
  75. type Record struct {
  76. seq uint64 // sequence number
  77. signature []byte // the signature
  78. raw []byte // RLP encoded record
  79. pairs []pair // sorted list of all key/value pairs
  80. }
  81. // pair is a key/value pair in a record.
  82. type pair struct {
  83. k string
  84. v rlp.RawValue
  85. }
  86. // Seq returns the sequence number.
  87. func (r *Record) Seq() uint64 {
  88. return r.seq
  89. }
  90. // SetSeq updates the record sequence number. This invalidates any signature on the record.
  91. // Calling SetSeq is usually not required because setting any key in a signed record
  92. // increments the sequence number.
  93. func (r *Record) SetSeq(s uint64) {
  94. r.signature = nil
  95. r.raw = nil
  96. r.seq = s
  97. }
  98. // Load retrieves the value of a key/value pair. The given Entry must be a pointer and will
  99. // be set to the value of the entry in the record.
  100. //
  101. // Errors returned by Load are wrapped in KeyError. You can distinguish decoding errors
  102. // from missing keys using the IsNotFound function.
  103. func (r *Record) Load(e Entry) error {
  104. i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() })
  105. if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() {
  106. if err := rlp.DecodeBytes(r.pairs[i].v, e); err != nil {
  107. return &KeyError{Key: e.ENRKey(), Err: err}
  108. }
  109. return nil
  110. }
  111. return &KeyError{Key: e.ENRKey(), Err: errNotFound}
  112. }
  113. // Set adds or updates the given entry in the record. It panics if the value can't be
  114. // encoded. If the record is signed, Set increments the sequence number and invalidates
  115. // the sequence number.
  116. func (r *Record) Set(e Entry) {
  117. blob, err := rlp.EncodeToBytes(e)
  118. if err != nil {
  119. panic(fmt.Errorf("enr: can't encode %s: %v", e.ENRKey(), err))
  120. }
  121. r.invalidate()
  122. pairs := make([]pair, len(r.pairs))
  123. copy(pairs, r.pairs)
  124. i := sort.Search(len(pairs), func(i int) bool { return pairs[i].k >= e.ENRKey() })
  125. switch {
  126. case i < len(pairs) && pairs[i].k == e.ENRKey():
  127. // element is present at r.pairs[i]
  128. pairs[i].v = blob
  129. case i < len(r.pairs):
  130. // insert pair before i-th elem
  131. el := pair{e.ENRKey(), blob}
  132. pairs = append(pairs, pair{})
  133. copy(pairs[i+1:], pairs[i:])
  134. pairs[i] = el
  135. default:
  136. // element should be placed at the end of r.pairs
  137. pairs = append(pairs, pair{e.ENRKey(), blob})
  138. }
  139. r.pairs = pairs
  140. }
  141. func (r *Record) invalidate() {
  142. if r.signature != nil {
  143. r.seq++
  144. }
  145. r.signature = nil
  146. r.raw = nil
  147. }
  148. // Signature returns the signature of the record.
  149. func (r *Record) Signature() []byte {
  150. if r.signature == nil {
  151. return nil
  152. }
  153. cpy := make([]byte, len(r.signature))
  154. copy(cpy, r.signature)
  155. return cpy
  156. }
  157. // EncodeRLP implements rlp.Encoder. Encoding fails if
  158. // the record is unsigned.
  159. func (r Record) EncodeRLP(w io.Writer) error {
  160. if r.signature == nil {
  161. return errEncodeUnsigned
  162. }
  163. _, err := w.Write(r.raw)
  164. return err
  165. }
  166. // DecodeRLP implements rlp.Decoder. Decoding doesn't verify the signature.
  167. func (r *Record) DecodeRLP(s *rlp.Stream) error {
  168. dec, raw, err := decodeRecord(s)
  169. if err != nil {
  170. return err
  171. }
  172. *r = dec
  173. r.raw = raw
  174. return nil
  175. }
  176. func decodeRecord(s *rlp.Stream) (dec Record, raw []byte, err error) {
  177. raw, err = s.Raw()
  178. if err != nil {
  179. return dec, raw, err
  180. }
  181. if len(raw) > SizeLimit {
  182. return dec, raw, errTooBig
  183. }
  184. // Decode the RLP container.
  185. s = rlp.NewStream(bytes.NewReader(raw), 0)
  186. if _, err := s.List(); err != nil {
  187. return dec, raw, err
  188. }
  189. if err = s.Decode(&dec.signature); err != nil {
  190. return dec, raw, err
  191. }
  192. if err = s.Decode(&dec.seq); err != nil {
  193. return dec, raw, err
  194. }
  195. // The rest of the record contains sorted k/v pairs.
  196. var prevkey string
  197. for i := 0; ; i++ {
  198. var kv pair
  199. if err := s.Decode(&kv.k); err != nil {
  200. if err == rlp.EOL {
  201. break
  202. }
  203. return dec, raw, err
  204. }
  205. if err := s.Decode(&kv.v); err != nil {
  206. if err == rlp.EOL {
  207. return dec, raw, errIncompletePair
  208. }
  209. return dec, raw, err
  210. }
  211. if i > 0 {
  212. if kv.k == prevkey {
  213. return dec, raw, errDuplicateKey
  214. }
  215. if kv.k < prevkey {
  216. return dec, raw, errNotSorted
  217. }
  218. }
  219. dec.pairs = append(dec.pairs, kv)
  220. prevkey = kv.k
  221. }
  222. return dec, raw, s.ListEnd()
  223. }
  224. // IdentityScheme returns the name of the identity scheme in the record.
  225. func (r *Record) IdentityScheme() string {
  226. var id ID
  227. r.Load(&id)
  228. return string(id)
  229. }
  230. // VerifySignature checks whether the record is signed using the given identity scheme.
  231. func (r *Record) VerifySignature(s IdentityScheme) error {
  232. return s.Verify(r, r.signature)
  233. }
  234. // SetSig sets the record signature. It returns an error if the encoded record is larger
  235. // than the size limit or if the signature is invalid according to the passed scheme.
  236. //
  237. // You can also use SetSig to remove the signature explicitly by passing a nil scheme
  238. // and signature.
  239. //
  240. // SetSig panics when either the scheme or the signature (but not both) are nil.
  241. func (r *Record) SetSig(s IdentityScheme, sig []byte) error {
  242. switch {
  243. // Prevent storing invalid data.
  244. case s == nil && sig != nil:
  245. panic("enr: invalid call to SetSig with non-nil signature but nil scheme")
  246. case s != nil && sig == nil:
  247. panic("enr: invalid call to SetSig with nil signature but non-nil scheme")
  248. // Verify if we have a scheme.
  249. case s != nil:
  250. if err := s.Verify(r, sig); err != nil {
  251. return err
  252. }
  253. raw, err := r.encode(sig)
  254. if err != nil {
  255. return err
  256. }
  257. r.signature, r.raw = sig, raw
  258. // Reset otherwise.
  259. default:
  260. r.signature, r.raw = nil, nil
  261. }
  262. return nil
  263. }
  264. // AppendElements appends the sequence number and entries to the given slice.
  265. func (r *Record) AppendElements(list []interface{}) []interface{} {
  266. list = append(list, r.seq)
  267. for _, p := range r.pairs {
  268. list = append(list, p.k, p.v)
  269. }
  270. return list
  271. }
  272. func (r *Record) encode(sig []byte) (raw []byte, err error) {
  273. list := make([]interface{}, 1, 2*len(r.pairs)+1)
  274. list[0] = sig
  275. list = r.AppendElements(list)
  276. if raw, err = rlp.EncodeToBytes(list); err != nil {
  277. return nil, err
  278. }
  279. if len(raw) > SizeLimit {
  280. return nil, errTooBig
  281. }
  282. return raw, nil
  283. }