mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
p2p/enr: sort pairs prior to RLP encoding; binary search on Load
This commit is contained in:
parent
d960c08a24
commit
bd9696c33d
2 changed files with 48 additions and 10 deletions
|
|
@ -69,11 +69,10 @@ func (r *Record) SetSeq(s uint32) {
|
|||
}
|
||||
|
||||
func (r *Record) Load(k Key) (bool, error) {
|
||||
for _, p := range r.pairs {
|
||||
if p.k == k.ENRKey() {
|
||||
err := rlp.DecodeBytes(p.v, k)
|
||||
return true, err
|
||||
}
|
||||
i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= k.ENRKey() })
|
||||
|
||||
if i < len(r.pairs) && r.pairs[i].k == k.ENRKey() {
|
||||
return true, rlp.DecodeBytes(r.pairs[i].v, k)
|
||||
}
|
||||
|
||||
return false, errors.New("record does not exist")
|
||||
|
|
@ -85,7 +84,29 @@ func (r *Record) Set(k Key) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.pairs = append(r.pairs, pair{k.ENRKey(), blob})
|
||||
var inserted bool
|
||||
for i, p := range r.pairs {
|
||||
if p.k == k.ENRKey() {
|
||||
// replace value of pair
|
||||
r.pairs[i].v = blob
|
||||
inserted = true
|
||||
|
||||
break
|
||||
} else if p.k > k.ENRKey() {
|
||||
// insert pair before i-th elem
|
||||
el := pair{k.ENRKey(), blob}
|
||||
|
||||
r.pairs = append(r.pairs, pair{})
|
||||
copy(r.pairs[i+1:], r.pairs[i:])
|
||||
r.pairs[i] = el
|
||||
|
||||
inserted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !inserted {
|
||||
r.pairs = append(r.pairs, pair{k.ENRKey(), blob})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -213,10 +234,6 @@ func (r *Record) Sign(privkey *ecdsa.PrivateKey) error {
|
|||
}
|
||||
|
||||
func (r *Record) serialisedContent() ([]byte, error) {
|
||||
sort.Slice(r.pairs, func(i, j int) bool {
|
||||
return r.pairs[i].k < r.pairs[j].k
|
||||
})
|
||||
|
||||
list := []interface{}{r.seq}
|
||||
|
||||
for _, p := range r.pairs {
|
||||
|
|
|
|||
|
|
@ -151,6 +151,27 @@ func TestDirty(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetSetOverwrite(t *testing.T) {
|
||||
var r Record
|
||||
|
||||
ip := IP4(net.IP{192, 168, 0, 3})
|
||||
r.Set(ip)
|
||||
|
||||
ip2 := IP4(net.IP{192, 168, 0, 4})
|
||||
r.Set(ip2)
|
||||
|
||||
var ip3 IP4
|
||||
|
||||
_, err := r.Load(&ip3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(ip2, ip3) != 0 {
|
||||
t.Fatalf("got %#v, expected %#v", ip2, ip3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignEncodeAndDecode(t *testing.T) {
|
||||
privkey, err := crypto.HexToECDSA(privkeyHex)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue