mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-07 22:54:17 -05:00
feat(primitives): add BuilderIndex SSZ type (#16169)
This pr adds primitives.BuilderIndex for builder registry indexing in Gloas
This commit is contained in:
3
changelog/builder-index.md
Normal file
3
changelog/builder-index.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
### Added
|
||||||
|
|
||||||
|
- `primitives.BuilderIndex`: SSZ `uint64` wrapper for builder registry indices.
|
||||||
@@ -4,6 +4,7 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"basis_points.go",
|
"basis_points.go",
|
||||||
|
"builder_index.go",
|
||||||
"committee_bits_mainnet.go",
|
"committee_bits_mainnet.go",
|
||||||
"committee_bits_minimal.go", # keep
|
"committee_bits_minimal.go", # keep
|
||||||
"committee_index.go",
|
"committee_index.go",
|
||||||
@@ -31,6 +32,7 @@ go_library(
|
|||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"builder_index_test.go",
|
||||||
"committee_index_test.go",
|
"committee_index_test.go",
|
||||||
"domain_test.go",
|
"domain_test.go",
|
||||||
"epoch_test.go",
|
"epoch_test.go",
|
||||||
|
|||||||
54
consensus-types/primitives/builder_index.go
Normal file
54
consensus-types/primitives/builder_index.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package primitives
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
fssz "github.com/prysmaticlabs/fastssz"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ fssz.HashRoot = (BuilderIndex)(0)
|
||||||
|
var _ fssz.Marshaler = (*BuilderIndex)(nil)
|
||||||
|
var _ fssz.Unmarshaler = (*BuilderIndex)(nil)
|
||||||
|
|
||||||
|
// BuilderIndex is an index into the builder registry.
|
||||||
|
type BuilderIndex uint64
|
||||||
|
|
||||||
|
// HashTreeRoot returns the SSZ hash tree root of the index.
|
||||||
|
func (b BuilderIndex) HashTreeRoot() ([32]byte, error) {
|
||||||
|
return fssz.HashWithDefaultHasher(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HashTreeRootWith appends the SSZ uint64 representation of the index to the given hasher.
|
||||||
|
func (b BuilderIndex) HashTreeRootWith(hh *fssz.Hasher) error {
|
||||||
|
hh.PutUint64(uint64(b))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalSSZ decodes the SSZ-encoded uint64 index from buf.
|
||||||
|
func (b *BuilderIndex) UnmarshalSSZ(buf []byte) error {
|
||||||
|
if len(buf) != b.SizeSSZ() {
|
||||||
|
return fmt.Errorf("expected buffer of length %d received %d", b.SizeSSZ(), len(buf))
|
||||||
|
}
|
||||||
|
*b = BuilderIndex(fssz.UnmarshallUint64(buf))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalSSZTo appends the SSZ-encoded index to dst and returns the extended buffer.
|
||||||
|
func (b *BuilderIndex) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||||
|
marshalled, err := b.MarshalSSZ()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return append(dst, marshalled...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalSSZ encodes the index as an SSZ uint64.
|
||||||
|
func (b *BuilderIndex) MarshalSSZ() ([]byte, error) {
|
||||||
|
marshalled := fssz.MarshalUint64([]byte{}, uint64(*b))
|
||||||
|
return marshalled, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeSSZ returns the size of the SSZ-encoded index in bytes.
|
||||||
|
func (b *BuilderIndex) SizeSSZ() int {
|
||||||
|
return 8
|
||||||
|
}
|
||||||
86
consensus-types/primitives/builder_index_test.go
Normal file
86
consensus-types/primitives/builder_index_test.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package primitives_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
|
||||||
|
"github.com/OffchainLabs/prysm/v7/testing/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuilderIndex_SSZRoundTripAndHashRoot(t *testing.T) {
|
||||||
|
cases := []uint64{
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
42,
|
||||||
|
(1 << 32) - 1,
|
||||||
|
1 << 32,
|
||||||
|
^uint64(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range cases {
|
||||||
|
t.Run("v="+u64name(v), func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
val := primitives.BuilderIndex(v)
|
||||||
|
require.Equal(t, 8, (&val).SizeSSZ())
|
||||||
|
|
||||||
|
enc, err := (&val).MarshalSSZ()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 8, len(enc))
|
||||||
|
|
||||||
|
wantEnc := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(wantEnc, v)
|
||||||
|
require.DeepEqual(t, wantEnc, enc)
|
||||||
|
|
||||||
|
dstPrefix := []byte("prefix:")
|
||||||
|
dst, err := (&val).MarshalSSZTo(slices.Clone(dstPrefix))
|
||||||
|
require.NoError(t, err)
|
||||||
|
wantDst := append(dstPrefix, wantEnc...)
|
||||||
|
require.DeepEqual(t, wantDst, dst)
|
||||||
|
|
||||||
|
var decoded primitives.BuilderIndex
|
||||||
|
require.NoError(t, (&decoded).UnmarshalSSZ(enc))
|
||||||
|
require.Equal(t, val, decoded)
|
||||||
|
|
||||||
|
root, err := val.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var wantRoot [32]byte
|
||||||
|
binary.LittleEndian.PutUint64(wantRoot[:8], v)
|
||||||
|
require.Equal(t, wantRoot, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuilderIndex_UnmarshalSSZRejectsWrongSize(t *testing.T) {
|
||||||
|
for _, size := range []int{7, 9} {
|
||||||
|
t.Run("size="+strconv.Itoa(size), func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
var v primitives.BuilderIndex
|
||||||
|
err := (&v).UnmarshalSSZ(make([]byte, size))
|
||||||
|
require.ErrorContains(t, "expected buffer of length 8", err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func u64name(v uint64) string {
|
||||||
|
switch v {
|
||||||
|
case 0:
|
||||||
|
return "0"
|
||||||
|
case 1:
|
||||||
|
return "1"
|
||||||
|
case 42:
|
||||||
|
return "42"
|
||||||
|
case (1 << 32) - 1:
|
||||||
|
return "2^32-1"
|
||||||
|
case 1 << 32:
|
||||||
|
return "2^32"
|
||||||
|
case ^uint64(0):
|
||||||
|
return "max"
|
||||||
|
default:
|
||||||
|
return "custom"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user