forked from cerc-io/plugeth
p2p/discover: improve discv5 NODES response packing (#26033)
Instead of using a limit of three nodes per message, we can pack more nodes into each message based on ENR size. In my testing, this halves the number of sent NODES messages, because ENR size is usually < 300 bytes. This also adds RLP helper functions that compute the encoded size of []byte and string. Co-authored-by: Martin Holst Swende <martin@swende.se>
This commit is contained in:
co-authored by
Martin Holst Swende
parent
55a92fa0a4
commit
9027ee0b45
+34
-1
@@ -28,13 +28,46 @@ type RawValue []byte
|
||||
|
||||
var rawValueType = reflect.TypeOf(RawValue{})
|
||||
|
||||
// StringSize returns the encoded size of a string.
|
||||
func StringSize(s string) uint64 {
|
||||
switch {
|
||||
case len(s) == 0:
|
||||
return 1
|
||||
case len(s) == 1:
|
||||
if s[0] <= 0x7f {
|
||||
return 1
|
||||
} else {
|
||||
return 2
|
||||
}
|
||||
default:
|
||||
return uint64(headsize(uint64(len(s))) + len(s))
|
||||
}
|
||||
}
|
||||
|
||||
// BytesSize returns the encoded size of a byte slice.
|
||||
func BytesSize(b []byte) uint64 {
|
||||
switch {
|
||||
case len(b) == 0:
|
||||
return 1
|
||||
case len(b) == 1:
|
||||
if b[0] <= 0x7f {
|
||||
return 1
|
||||
} else {
|
||||
return 2
|
||||
}
|
||||
default:
|
||||
return uint64(headsize(uint64(len(b))) + len(b))
|
||||
}
|
||||
}
|
||||
|
||||
// ListSize returns the encoded size of an RLP list with the given
|
||||
// content size.
|
||||
func ListSize(contentSize uint64) uint64 {
|
||||
return uint64(headsize(contentSize)) + contentSize
|
||||
}
|
||||
|
||||
// IntSize returns the encoded size of the integer x.
|
||||
// IntSize returns the encoded size of the integer x. Note: The return type of this
|
||||
// function is 'int' for backwards-compatibility reasons. The result is always positive.
|
||||
func IntSize(x uint64) int {
|
||||
if x < 0x80 {
|
||||
return 1
|
||||
|
||||
@@ -283,3 +283,36 @@ func TestAppendUint64Random(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBytesSize(t *testing.T) {
|
||||
tests := []struct {
|
||||
v []byte
|
||||
size uint64
|
||||
}{
|
||||
{v: []byte{}, size: 1},
|
||||
{v: []byte{0x1}, size: 1},
|
||||
{v: []byte{0x7E}, size: 1},
|
||||
{v: []byte{0x7F}, size: 1},
|
||||
{v: []byte{0x80}, size: 2},
|
||||
{v: []byte{0xFF}, size: 2},
|
||||
{v: []byte{0xFF, 0xF0}, size: 3},
|
||||
{v: make([]byte, 55), size: 56},
|
||||
{v: make([]byte, 56), size: 58},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
s := BytesSize(test.v)
|
||||
if s != test.size {
|
||||
t.Errorf("BytesSize(%#x) -> %d, want %d", test.v, s, test.size)
|
||||
}
|
||||
s = StringSize(string(test.v))
|
||||
if s != test.size {
|
||||
t.Errorf("StringSize(%#x) -> %d, want %d", test.v, s, test.size)
|
||||
}
|
||||
// Sanity check:
|
||||
enc, _ := EncodeToBytes(test.v)
|
||||
if uint64(len(enc)) != test.size {
|
||||
t.Errorf("len(EncodeToBytes(%#x)) -> %d, test says %d", test.v, len(enc), test.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user