enr.go 8.9 KB

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