p2p/enr: rename Key to Entry

This commit is contained in:
Anton Evangelatov 2017-12-21 17:16:45 +01:00
parent 50b3ab66b2
commit 544671fb7d
3 changed files with 39 additions and 39 deletions

View file

@ -17,11 +17,11 @@
// Package enr implements Ethereum Node Records as defined in EIP-778. A node record holds // Package enr implements Ethereum Node Records as defined in EIP-778. A node record holds
// arbitrary information about a node on the peer-to-peer network. // arbitrary information about a node on the peer-to-peer network.
// //
// Records contain named keys. To store and retrieve keys in a record, use the Key // Records contain named keys. To store and retrieve key/values in a record, use the Entry
// interface. // interface.
// //
// Records must be signed before transmitting them to another node. Decoding a record verifies // Records must be signed before transmitting them to another node. Decoding a record verifies
// its signature. When creating a record, set the keys you want, then call Sign to add the // its signature. When creating a record, set the entries you want, then call Sign to add the
// signature. Modifying a record invalidates the signature. // signature. Modifying a record invalidates the signature.
// //
// Package enr supports the "secp256k1-keccak" identity scheme. // Package enr supports the "secp256k1-keccak" identity scheme.
@ -89,41 +89,41 @@ func (r *Record) SetSeq(s uint64) {
r.seq = s r.seq = s
} }
// Load retrieves the value of a key/value pair. The given Key must be a pointer and will // Load retrieves the value of a key/value pair. The given Entry must be a pointer and will
// be set to the value of the key in the record. // be set to the value of the entry in the record.
// //
// Errors returned by Load are wrapped in KeyError. You can distinguish decoding errors // Errors returned by Load are wrapped in KeyError. You can distinguish decoding errors
// from missing keys using the IsNotFound function. // from missing keys using the IsNotFound function.
func (r *Record) Load(k Key) error { func (r *Record) Load(e Entry) error {
i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= k.ENRKey() }) i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() })
if i < len(r.pairs) && r.pairs[i].k == k.ENRKey() { if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() {
if err := rlp.DecodeBytes(r.pairs[i].v, k); err != nil { if err := rlp.DecodeBytes(r.pairs[i].v, e); err != nil {
return &KeyError{Key: k.ENRKey(), Err: err} return &KeyError{Key: e.ENRKey(), Err: err}
} }
return nil return nil
} }
return &KeyError{Key: k.ENRKey(), Err: errNotFound} return &KeyError{Key: e.ENRKey(), Err: errNotFound}
} }
// Set adds or updates the given key in the record. // Set adds or updates the given entry in the record.
// It panics if the value can't be encoded. // It panics if the value can't be encoded.
func (r *Record) Set(k Key) { func (r *Record) Set(e Entry) {
r.signature = nil r.signature = nil
r.raw = nil r.raw = nil
blob, err := rlp.EncodeToBytes(k) blob, err := rlp.EncodeToBytes(e)
if err != nil { if err != nil {
panic(fmt.Errorf("enr: can't encode %s: %v", k.ENRKey(), err)) panic(fmt.Errorf("enr: can't encode %s: %v", e.ENRKey(), err))
} }
i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= k.ENRKey() }) i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() })
if i < len(r.pairs) && r.pairs[i].k == k.ENRKey() { if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() {
// element is present at r.pairs[i] // element is present at r.pairs[i]
r.pairs[i].v = blob r.pairs[i].v = blob
return return
} else if i < len(r.pairs) { } else if i < len(r.pairs) {
// insert pair before i-th elem // insert pair before i-th elem
el := pair{k.ENRKey(), blob} el := pair{e.ENRKey(), blob}
r.pairs = append(r.pairs, pair{}) r.pairs = append(r.pairs, pair{})
copy(r.pairs[i+1:], r.pairs[i:]) copy(r.pairs[i+1:], r.pairs[i:])
r.pairs[i] = el r.pairs[i] = el
@ -131,7 +131,7 @@ func (r *Record) Set(k Key) {
} }
// element should be placed at the end of r.pairs // element should be placed at the end of r.pairs
r.pairs = append(r.pairs, pair{k.ENRKey(), blob}) r.pairs = append(r.pairs, pair{e.ENRKey(), blob})
} }
// EncodeRLP implements rlp.Encoder. Encoding fails if // EncodeRLP implements rlp.Encoder. Encoding fails if
@ -212,11 +212,11 @@ func (s256raw) ENRKey() string { return "secp256k1" }
// NodeAddr returns the node address. The return value will be nil if the record is // NodeAddr returns the node address. The return value will be nil if the record is
// unsigned. // unsigned.
func (r *Record) NodeAddr() []byte { func (r *Record) NodeAddr() []byte {
var key s256raw var entry s256raw
if r.Load(&key) != nil { if r.Load(&entry) != nil {
return nil return nil
} }
return crypto.Keccak256(key) return crypto.Keccak256(entry)
} }
// Sign signs the record with the given private key. It updates the record's identity // Sign signs the record with the given private key. It updates the record's identity
@ -266,15 +266,15 @@ func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
func (r *Record) verifySignature() error { func (r *Record) verifySignature() error {
// Get identity scheme, public key, signature. // Get identity scheme, public key, signature.
var id ID var id ID
var key s256raw var entry s256raw
if err := r.Load(&id); err != nil { if err := r.Load(&id); err != nil {
return err return err
} else if id != ID_SECP256k1_KECCAK { } else if id != ID_SECP256k1_KECCAK {
return errNoID return errNoID
} }
if err := r.Load(&key); err != nil { if err := r.Load(&entry); err != nil {
return err return err
} else if len(key) != 33 { } else if len(entry) != 33 {
return fmt.Errorf("invalid public key") return fmt.Errorf("invalid public key")
} }
@ -283,7 +283,7 @@ func (r *Record) verifySignature() error {
list = r.appendPairs(list) list = r.appendPairs(list)
h := sha3.NewKeccak256() h := sha3.NewKeccak256()
rlp.Encode(h, list) rlp.Encode(h, list)
if !crypto.VerifySignature(key, h.Sum(nil), r.signature) { if !crypto.VerifySignature(entry, h.Sum(nil), r.signature) {
return errInvalidSig return errInvalidSig
} }
return nil return nil

View file

@ -114,7 +114,7 @@ func TestLoadErrors(t *testing.T) {
// Check error for invalid keys. // Check error for invalid keys.
var list []uint var list []uint
err = r.Load(WithKey(ip4.ENRKey(), &list)) err = r.Load(WithEntry(ip4.ENRKey(), &list))
kerr, ok := err.(*KeyError) kerr, ok := err.(*KeyError)
if !ok { if !ok {
t.Fatalf("expected KeyError, got %T", err) t.Fatalf("expected KeyError, got %T", err)
@ -152,12 +152,12 @@ func TestSortedGetAndSet(t *testing.T) {
} { } {
var r Record var r Record
for _, i := range tt.input { for _, i := range tt.input {
r.Set(WithKey(i.k, &i.v)) r.Set(WithEntry(i.k, &i.v))
} }
for i, w := range tt.want { for i, w := range tt.want {
// set got's key from r.pair[i], so that we preserve order of pairs // set got's key from r.pair[i], so that we preserve order of pairs
got := pair{k: r.pairs[i].k} got := pair{k: r.pairs[i].k}
assert.NoError(t, r.Load(WithKey(w.k, &got.v))) assert.NoError(t, r.Load(WithEntry(w.k, &got.v)))
assert.Equal(t, w, got) assert.Equal(t, w, got)
} }
} }
@ -257,7 +257,7 @@ func TestPythonInterop(t *testing.T) {
if addr := r.NodeAddr(); !bytes.Equal(addr, wantAddr) { if addr := r.NodeAddr(); !bytes.Equal(addr, wantAddr) {
t.Errorf("wrong addr: got %x, want %x", addr, wantAddr) t.Errorf("wrong addr: got %x, want %x", addr, wantAddr)
} }
want := map[Key]interface{}{new(IP4): &wantIP, new(DiscPort): &wantDiscport} want := map[Entry]interface{}{new(IP4): &wantIP, new(DiscPort): &wantDiscport}
for k, v := range want { for k, v := range want {
desc := fmt.Sprintf("loading key %q", k.ENRKey()) desc := fmt.Sprintf("loading key %q", k.ENRKey())
if assert.NoError(t, r.Load(k), desc) { if assert.NoError(t, r.Load(k), desc) {
@ -272,13 +272,13 @@ func TestRecordTooBig(t *testing.T) {
key := randomString(10) key := randomString(10)
// set a big value for random key, expect error // set a big value for random key, expect error
r.Set(WithKey(key, randomString(300))) r.Set(WithEntry(key, randomString(300)))
if err := r.Sign(privkey); err != errTooBig { if err := r.Sign(privkey); err != errTooBig {
t.Fatalf("expected to get errTooBig, got %#v", err) t.Fatalf("expected to get errTooBig, got %#v", err)
} }
// set an acceptable value for random key, expect no error // set an acceptable value for random key, expect no error
r.Set(WithKey(key, randomString(100))) r.Set(WithEntry(key, randomString(100)))
require.NoError(t, r.Sign(privkey)) require.NoError(t, r.Sign(privkey))
} }
@ -292,7 +292,7 @@ func TestSignEncodeAndDecodeRandom(t *testing.T) {
key := randomString(7) key := randomString(7)
value := rnd.Uint32() value := rnd.Uint32()
pairs[key] = value pairs[key] = value
r.Set(WithKey(key, &value)) r.Set(WithEntry(key, &value))
} }
require.NoError(t, r.Sign(privkey)) require.NoError(t, r.Sign(privkey))
@ -302,7 +302,7 @@ func TestSignEncodeAndDecodeRandom(t *testing.T) {
for k, v := range pairs { for k, v := range pairs {
desc := fmt.Sprintf("key %q", k) desc := fmt.Sprintf("key %q", k)
var got uint32 var got uint32
buf := WithKey(k, &got) buf := WithEntry(k, &got)
require.NoError(t, r.Load(buf), desc) require.NoError(t, r.Load(buf), desc)
require.Equal(t, v, got, desc) require.Equal(t, v, got, desc)
} }

View file

@ -26,12 +26,12 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
// Key is implemented by known node record key types. // Entry is implemented by known node record entry types.
// //
// To define a new key that is to be included in a node record, // To define a new entry that is to be included in a node record,
// create a Go type that satisfies this interface. The type should // create a Go type that satisfies this interface. The type should
// also implement rlp.Decoder if additional checks are needed on the value. // also implement rlp.Decoder if additional checks are needed on the value.
type Key interface { type Entry interface {
ENRKey() string ENRKey() string
} }
@ -50,10 +50,10 @@ func (g *generic) DecodeRLP(s *rlp.Stream) error {
return s.Decode(g.value) return s.Decode(g.value)
} }
// WithKey wraps any value with a key name. It can be used to set and load arbitrary values // WithEntry wraps any value with a key name. It can be used to set and load arbitrary values
// in a record. The value v must be supported by rlp. To use WithKey with Load, the value // in a record. The value v must be supported by rlp. To use WithEntry with Load, the value
// must be a pointer. // must be a pointer.
func WithKey(k string, v interface{}) Key { func WithEntry(k string, v interface{}) Entry {
return &generic{key: k, value: v} return &generic{key: k, value: v}
} }