mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
SSZ-QL: Support nested List type (#15725)
* Add nested 2d list cases * Add elementSize member for listInfo to track each element's byte size * Fix misleading variable in RunStructTest * Changelog * Regen pb file * Update encoding/ssz/query/list.go Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com> * Rename elementSize into plural * Update changelog/syjn99_ssz-ql-nested-list.md --------- Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>
This commit is contained in:
3
changelog/syjn99_ssz-ql-nested-list.md
Normal file
3
changelog/syjn99_ssz-ql-nested-list.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
### Fixed
|
||||||
|
|
||||||
|
- SSZ-QL: Support nested `List` type (e.g., `ExecutionPayload.Transactions`)
|
||||||
@@ -60,9 +60,21 @@ func PopulateVariableLengthInfo(sszInfo *sszInfo, value any) error {
|
|||||||
if val.Kind() != reflect.Slice {
|
if val.Kind() != reflect.Slice {
|
||||||
return fmt.Errorf("expected slice for List type, got %v", val.Kind())
|
return fmt.Errorf("expected slice for List type, got %v", val.Kind())
|
||||||
}
|
}
|
||||||
|
length := val.Len()
|
||||||
|
|
||||||
length := uint64(val.Len())
|
if listInfo.element.isVariable {
|
||||||
if err := listInfo.SetLength(length); err != nil {
|
listInfo.elementSizes = make([]uint64, 0, length)
|
||||||
|
|
||||||
|
// Populate nested variable-sized type element lengths recursively.
|
||||||
|
for i := range length {
|
||||||
|
if err := PopulateVariableLengthInfo(listInfo.element, val.Index(i).Interface()); err != nil {
|
||||||
|
return fmt.Errorf("could not populate nested list element at index %d: %w", i, err)
|
||||||
|
}
|
||||||
|
listInfo.elementSizes = append(listInfo.elementSizes, listInfo.element.Size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := listInfo.SetLength(uint64(length)); err != nil {
|
||||||
return fmt.Errorf("could not set list length: %w", err)
|
return fmt.Errorf("could not set list length: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,15 +123,20 @@ func PopulateVariableLengthInfo(sszInfo *sszInfo, value any) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the actual offset for variable-sized fields.
|
|
||||||
fieldInfo.offset = currentOffset
|
|
||||||
|
|
||||||
// Recursively populate variable-sized fields.
|
// Recursively populate variable-sized fields.
|
||||||
fieldValue := derefValue.FieldByName(fieldInfo.goFieldName)
|
fieldValue := derefValue.FieldByName(fieldInfo.goFieldName)
|
||||||
if err := PopulateVariableLengthInfo(childSszInfo, fieldValue.Interface()); err != nil {
|
if err := PopulateVariableLengthInfo(childSszInfo, fieldValue.Interface()); err != nil {
|
||||||
return fmt.Errorf("could not populate from value for field %s: %w", fieldName, err)
|
return fmt.Errorf("could not populate from value for field %s: %w", fieldName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Each variable-sized element needs an offset entry.
|
||||||
|
if childSszInfo.sszType == List {
|
||||||
|
currentOffset += childSszInfo.listInfo.OffsetBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the actual offset for variable-sized fields.
|
||||||
|
fieldInfo.offset = currentOffset
|
||||||
|
|
||||||
currentOffset += childSszInfo.Size()
|
currentOffset += childSszInfo.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ type listInfo struct {
|
|||||||
element *sszInfo
|
element *sszInfo
|
||||||
// length is the actual number of elements at runtime (0 if not set).
|
// length is the actual number of elements at runtime (0 if not set).
|
||||||
length uint64
|
length uint64
|
||||||
|
// elementSizes caches each element's byte size for variable-sized type elements
|
||||||
|
elementSizes []uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *listInfo) Limit() uint64 {
|
func (l *listInfo) Limit() uint64 {
|
||||||
@@ -51,3 +53,35 @@ func (l *listInfo) SetLength(length uint64) error {
|
|||||||
l.length = length
|
l.length = length
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *listInfo) Size() uint64 {
|
||||||
|
if l == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// For fixed-sized type elements, size is multiplying length by element size.
|
||||||
|
if !l.element.isVariable {
|
||||||
|
return l.length * l.element.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
// For variable-sized type elements, sum up the sizes of each element.
|
||||||
|
totalSize := uint64(0)
|
||||||
|
for _, sz := range l.elementSizes {
|
||||||
|
totalSize += sz
|
||||||
|
}
|
||||||
|
return totalSize
|
||||||
|
}
|
||||||
|
|
||||||
|
// OffsetBytes returns the total number of offset bytes used for the list elements.
|
||||||
|
// Each variable-sized element uses 4 bytes to store its offset.
|
||||||
|
func (l *listInfo) OffsetBytes() uint64 {
|
||||||
|
if l == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if !l.element.isVariable {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return offsetBytes * l.length
|
||||||
|
}
|
||||||
|
|||||||
@@ -133,56 +133,73 @@ func TestCalculateOffsetAndLength(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "field_list_uint64",
|
name: "field_list_uint64",
|
||||||
path: ".field_list_uint64",
|
path: ".field_list_uint64",
|
||||||
expectedOffset: 108, // First part of variable-sized type.
|
expectedOffset: 112, // First part of variable-sized type.
|
||||||
expectedLength: 40, // 5 elements * uint64 (8 bytes each)
|
expectedLength: 40, // 5 elements * uint64 (8 bytes each)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "field_list_container",
|
name: "field_list_container",
|
||||||
path: ".field_list_container",
|
path: ".field_list_container",
|
||||||
expectedOffset: 148, // Second part of variable-sized type.
|
expectedOffset: 152, // Second part of variable-sized type.
|
||||||
expectedLength: 120, // 3 elements * FixedNestedContainer (40 bytes each)
|
expectedLength: 120, // 3 elements * FixedNestedContainer (40 bytes each)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "field_list_bytes32",
|
name: "field_list_bytes32",
|
||||||
path: ".field_list_bytes32",
|
path: ".field_list_bytes32",
|
||||||
expectedOffset: 268,
|
expectedOffset: 272,
|
||||||
expectedLength: 96, // 3 elements * 32 bytes each
|
expectedLength: 96, // 3 elements * 32 bytes each
|
||||||
},
|
},
|
||||||
// Nested paths
|
// Nested paths
|
||||||
{
|
{
|
||||||
name: "nested",
|
name: "nested",
|
||||||
path: ".nested",
|
path: ".nested",
|
||||||
expectedOffset: 364,
|
expectedOffset: 368,
|
||||||
// Calculated with:
|
// Calculated with:
|
||||||
// - Value1: 8 bytes
|
// - Value1: 8 bytes
|
||||||
// - field_list_uint64 offset: 4 bytes
|
// - field_list_uint64 offset: 4 bytes
|
||||||
// - field_list_uint64 length: 40 bytes
|
// - field_list_uint64 length: 40 bytes
|
||||||
expectedLength: 52,
|
// - nested_list_field offset: 4 bytes
|
||||||
|
// - nested_list_field length: 99 bytes
|
||||||
|
// - 3 offset pointers for each element in nested_list_field: 12 bytes
|
||||||
|
// Total: 8 + 4 + 40 + 4 + 99 + 12 = 167 bytes
|
||||||
|
expectedLength: 167,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nested.value1",
|
name: "nested.value1",
|
||||||
path: ".nested.value1",
|
path: ".nested.value1",
|
||||||
expectedOffset: 364,
|
expectedOffset: 368,
|
||||||
expectedLength: 8,
|
expectedLength: 8,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nested.field_list_uint64",
|
name: "nested.field_list_uint64",
|
||||||
path: ".nested.field_list_uint64",
|
path: ".nested.field_list_uint64",
|
||||||
expectedOffset: 376,
|
expectedOffset: 384,
|
||||||
expectedLength: 40,
|
expectedLength: 40,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "nested.nested_list_field",
|
||||||
|
path: ".nested.nested_list_field",
|
||||||
|
expectedOffset: 436,
|
||||||
|
expectedLength: 99,
|
||||||
|
},
|
||||||
// Bitlist field
|
// Bitlist field
|
||||||
{
|
{
|
||||||
name: "bitlist_field",
|
name: "bitlist_field",
|
||||||
path: ".bitlist_field",
|
path: ".bitlist_field",
|
||||||
expectedOffset: 416,
|
expectedOffset: 535,
|
||||||
expectedLength: 33, // 32 bytes + 1 byte for length delimiter
|
expectedLength: 33, // 32 bytes + 1 byte for length delimiter
|
||||||
},
|
},
|
||||||
|
// 2D bytes field
|
||||||
|
{
|
||||||
|
name: "nested_list_field",
|
||||||
|
path: ".nested_list_field",
|
||||||
|
expectedOffset: 580,
|
||||||
|
expectedLength: 99,
|
||||||
|
},
|
||||||
// Fixed trailing field
|
// Fixed trailing field
|
||||||
{
|
{
|
||||||
name: "trailing_field",
|
name: "trailing_field",
|
||||||
path: ".trailing_field",
|
path: ".trailing_field",
|
||||||
expectedOffset: 52, // After leading_field + 5 offset pointers
|
expectedOffset: 56, // After leading_field + 6 offset pointers
|
||||||
expectedLength: 56,
|
expectedLength: 56,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -377,6 +394,15 @@ func createVariableTestContainer() *sszquerypb.VariableTestContainer {
|
|||||||
bitlistField.SetBitAt(100, true)
|
bitlistField.SetBitAt(100, true)
|
||||||
bitlistField.SetBitAt(255, true)
|
bitlistField.SetBitAt(255, true)
|
||||||
|
|
||||||
|
// Total size: 3 lists with lengths 32, 33, and 34 = 99 bytes
|
||||||
|
nestedListField := make([][]byte, 3)
|
||||||
|
for i := range nestedListField {
|
||||||
|
nestedListField[i] = make([]byte, (32 + i)) // Different lengths for each sub-list
|
||||||
|
for j := range nestedListField[i] {
|
||||||
|
nestedListField[i][j] = byte(j + i*16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &sszquerypb.VariableTestContainer{
|
return &sszquerypb.VariableTestContainer{
|
||||||
// Fixed leading field
|
// Fixed leading field
|
||||||
LeadingField: leadingField,
|
LeadingField: leadingField,
|
||||||
@@ -394,11 +420,15 @@ func createVariableTestContainer() *sszquerypb.VariableTestContainer {
|
|||||||
Nested: &sszquerypb.VariableNestedContainer{
|
Nested: &sszquerypb.VariableNestedContainer{
|
||||||
Value1: 42,
|
Value1: 42,
|
||||||
FieldListUint64: []uint64{1, 2, 3, 4, 5},
|
FieldListUint64: []uint64{1, 2, 3, 4, 5},
|
||||||
|
NestedListField: nestedListField,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Bitlist field
|
// Bitlist field
|
||||||
BitlistField: bitlistField,
|
BitlistField: bitlistField,
|
||||||
|
|
||||||
|
// 2D bytes field
|
||||||
|
NestedListField: nestedListField,
|
||||||
|
|
||||||
// Fixed trailing field
|
// Fixed trailing field
|
||||||
TrailingField: trailingField,
|
TrailingField: trailingField,
|
||||||
}
|
}
|
||||||
@@ -445,11 +475,20 @@ func getVariableTestContainerSpec() testutil.TestSpec {
|
|||||||
Path: ".nested.field_list_uint64",
|
Path: ".nested.field_list_uint64",
|
||||||
Expected: testContainer.Nested.FieldListUint64,
|
Expected: testContainer.Nested.FieldListUint64,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Path: ".nested.nested_list_field",
|
||||||
|
Expected: testContainer.Nested.NestedListField,
|
||||||
|
},
|
||||||
// Bitlist field
|
// Bitlist field
|
||||||
{
|
{
|
||||||
Path: ".bitlist_field",
|
Path: ".bitlist_field",
|
||||||
Expected: testContainer.BitlistField,
|
Expected: testContainer.BitlistField,
|
||||||
},
|
},
|
||||||
|
// 2D bytes field
|
||||||
|
{
|
||||||
|
Path: ".nested_list_field",
|
||||||
|
Expected: testContainer.NestedListField,
|
||||||
|
},
|
||||||
// Fixed trailing field
|
// Fixed trailing field
|
||||||
{
|
{
|
||||||
Path: ".trailing_field",
|
Path: ".trailing_field",
|
||||||
|
|||||||
@@ -54,10 +54,7 @@ func (info *sszInfo) Size() uint64 {
|
|||||||
|
|
||||||
switch info.sszType {
|
switch info.sszType {
|
||||||
case List:
|
case List:
|
||||||
length := info.listInfo.length
|
return info.listInfo.Size()
|
||||||
elementSize := info.listInfo.element.Size()
|
|
||||||
|
|
||||||
return length * elementSize
|
|
||||||
|
|
||||||
case Bitlist:
|
case Bitlist:
|
||||||
return info.bitlistInfo.Size()
|
return info.bitlistInfo.Size()
|
||||||
@@ -69,6 +66,11 @@ func (info *sszInfo) Size() uint64 {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include offset bytes inside nested lists.
|
||||||
|
if fieldInfo.sszInfo.sszType == List {
|
||||||
|
size += fieldInfo.sszInfo.listInfo.OffsetBytes()
|
||||||
|
}
|
||||||
|
|
||||||
size += fieldInfo.sszInfo.Size()
|
size += fieldInfo.sszInfo.Size()
|
||||||
}
|
}
|
||||||
return size
|
return size
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ func RunStructTest(t *testing.T, spec TestSpec) {
|
|||||||
_, offset, length, err := query.CalculateOffsetAndLength(info, path)
|
_, offset, length, err := query.CalculateOffsetAndLength(info, path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedRawBytes := marshalledData[offset : offset+length]
|
actualRawBytes := marshalledData[offset : offset+length]
|
||||||
rawBytes, err := marshalAny(pathTest.Expected)
|
expectedRawBytes, err := marshalAny(pathTest.Expected)
|
||||||
require.NoError(t, err, "Marshalling expected value should not return an error")
|
require.NoError(t, err, "Marshalling expected value should not return an error")
|
||||||
require.DeepEqual(t, expectedRawBytes, rawBytes, "Extracted value should match expected")
|
require.DeepEqual(t, actualRawBytes, expectedRawBytes, "Extracted value should match expected")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
58
proto/ssz_query/ssz_query.pb.go
generated
58
proto/ssz_query/ssz_query.pb.go
generated
@@ -195,6 +195,7 @@ type VariableNestedContainer struct {
|
|||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Value1 uint64 `protobuf:"varint,1,opt,name=value1,proto3" json:"value1,omitempty"`
|
Value1 uint64 `protobuf:"varint,1,opt,name=value1,proto3" json:"value1,omitempty"`
|
||||||
FieldListUint64 []uint64 `protobuf:"varint,2,rep,packed,name=field_list_uint64,json=fieldListUint64,proto3" json:"field_list_uint64,omitempty" ssz-max:"100"`
|
FieldListUint64 []uint64 `protobuf:"varint,2,rep,packed,name=field_list_uint64,json=fieldListUint64,proto3" json:"field_list_uint64,omitempty" ssz-max:"100"`
|
||||||
|
NestedListField [][]byte `protobuf:"bytes,3,rep,name=nested_list_field,json=nestedListField,proto3" json:"nested_list_field,omitempty" ssz-max:"100,50" ssz-size:"?,?"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -243,6 +244,13 @@ func (x *VariableNestedContainer) GetFieldListUint64() []uint64 {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *VariableNestedContainer) GetNestedListField() [][]byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.NestedListField
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type VariableTestContainer struct {
|
type VariableTestContainer struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
LeadingField []byte `protobuf:"bytes,1,opt,name=leading_field,json=leadingField,proto3" json:"leading_field,omitempty" ssz-size:"32"`
|
LeadingField []byte `protobuf:"bytes,1,opt,name=leading_field,json=leadingField,proto3" json:"leading_field,omitempty" ssz-size:"32"`
|
||||||
@@ -251,7 +259,8 @@ type VariableTestContainer struct {
|
|||||||
FieldListBytes32 [][]byte `protobuf:"bytes,4,rep,name=field_list_bytes32,json=fieldListBytes32,proto3" json:"field_list_bytes32,omitempty" ssz-max:"100" ssz-size:"?,32"`
|
FieldListBytes32 [][]byte `protobuf:"bytes,4,rep,name=field_list_bytes32,json=fieldListBytes32,proto3" json:"field_list_bytes32,omitempty" ssz-max:"100" ssz-size:"?,32"`
|
||||||
Nested *VariableNestedContainer `protobuf:"bytes,5,opt,name=nested,proto3" json:"nested,omitempty"`
|
Nested *VariableNestedContainer `protobuf:"bytes,5,opt,name=nested,proto3" json:"nested,omitempty"`
|
||||||
BitlistField github_com_prysmaticlabs_go_bitfield.Bitlist `protobuf:"bytes,6,opt,name=bitlist_field,json=bitlistField,proto3" json:"bitlist_field,omitempty" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitlist" ssz-max:"2048"`
|
BitlistField github_com_prysmaticlabs_go_bitfield.Bitlist `protobuf:"bytes,6,opt,name=bitlist_field,json=bitlistField,proto3" json:"bitlist_field,omitempty" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitlist" ssz-max:"2048"`
|
||||||
TrailingField []byte `protobuf:"bytes,7,opt,name=trailing_field,json=trailingField,proto3" json:"trailing_field,omitempty" ssz-size:"56"`
|
NestedListField [][]byte `protobuf:"bytes,7,rep,name=nested_list_field,json=nestedListField,proto3" json:"nested_list_field,omitempty" ssz-max:"100,50" ssz-size:"?,?"`
|
||||||
|
TrailingField []byte `protobuf:"bytes,8,opt,name=trailing_field,json=trailingField,proto3" json:"trailing_field,omitempty" ssz-size:"56"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -328,6 +337,13 @@ func (x *VariableTestContainer) GetBitlistField() github_com_prysmaticlabs_go_bi
|
|||||||
return github_com_prysmaticlabs_go_bitfield.Bitlist(nil)
|
return github_com_prysmaticlabs_go_bitfield.Bitlist(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *VariableTestContainer) GetNestedListField() [][]byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.NestedListField
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (x *VariableTestContainer) GetTrailingField() []byte {
|
func (x *VariableTestContainer) GetTrailingField() []byte {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.TrailingField
|
return x.TrailingField
|
||||||
@@ -384,14 +400,18 @@ var file_proto_ssz_query_ssz_query_proto_rawDesc = []byte{
|
|||||||
0x74, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x35, 0x31, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12,
|
0x74, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x35, 0x31, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12,
|
||||||
0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c,
|
0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c,
|
||||||
0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52,
|
0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52,
|
||||||
0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x66,
|
0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0xa5,
|
||||||
0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64,
|
0x01, 0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65,
|
||||||
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c,
|
0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61,
|
||||||
0x75, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
0x6c, 0x75, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75,
|
||||||
0x31, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f,
|
0x65, 0x31, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74,
|
||||||
0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x42, 0x07, 0x92, 0xb5,
|
0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x42, 0x07, 0x92,
|
||||||
0x18, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4c, 0x69, 0x73, 0x74,
|
0xb5, 0x18, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4c, 0x69, 0x73,
|
||||||
0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x22, 0xdf, 0x03, 0x0a, 0x15, 0x56, 0x61, 0x72, 0x69, 0x61,
|
0x74, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x3d, 0x0a, 0x11, 0x6e, 0x65, 0x73, 0x74, 0x65,
|
||||||
|
0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x03,
|
||||||
|
0x28, 0x0c, 0x42, 0x11, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f, 0x92, 0xb5, 0x18, 0x06, 0x31,
|
||||||
|
0x30, 0x30, 0x2c, 0x35, 0x30, 0x52, 0x0f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x73,
|
||||||
|
0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x9e, 0x04, 0x0a, 0x15, 0x56, 0x61, 0x72, 0x69, 0x61,
|
||||||
0x62, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
|
0x62, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
|
||||||
0x12, 0x2b, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c,
|
0x12, 0x2b, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c,
|
||||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
|
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
|
||||||
@@ -418,14 +438,18 @@ var file_proto_ssz_query_ssz_query_proto_rawDesc = []byte{
|
|||||||
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
|
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
|
||||||
0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x6c,
|
0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x6c,
|
||||||
0x69, 0x73, 0x74, 0x92, 0xb5, 0x18, 0x04, 0x32, 0x30, 0x34, 0x38, 0x52, 0x0c, 0x62, 0x69, 0x74,
|
0x69, 0x73, 0x74, 0x92, 0xb5, 0x18, 0x04, 0x32, 0x30, 0x34, 0x38, 0x52, 0x0c, 0x62, 0x69, 0x74,
|
||||||
0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61,
|
0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x3d, 0x0a, 0x11, 0x6e, 0x65, 0x73,
|
||||||
0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
|
0x74, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x07,
|
||||||
0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c,
|
0x20, 0x03, 0x28, 0x0c, 0x42, 0x11, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f, 0x92, 0xb5, 0x18,
|
||||||
0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68,
|
0x06, 0x31, 0x30, 0x30, 0x2c, 0x35, 0x30, 0x52, 0x0f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4c,
|
||||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c,
|
0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x69,
|
||||||
0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f,
|
0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c,
|
||||||
0x74, 0x6f, 0x2f, 0x73, 0x73, 0x7a, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72,
|
0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69,
|
||||||
0x6f, 0x74, 0x6f, 0x33,
|
0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||||
|
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61,
|
||||||
|
0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x2f, 0x73, 0x73, 0x7a, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||||
|
0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ message FixedTestContainer {
|
|||||||
message VariableNestedContainer {
|
message VariableNestedContainer {
|
||||||
uint64 value1 = 1;
|
uint64 value1 = 1;
|
||||||
repeated uint64 field_list_uint64 = 2 [ (ethereum.eth.ext.ssz_max) = "100" ];
|
repeated uint64 field_list_uint64 = 2 [ (ethereum.eth.ext.ssz_max) = "100" ];
|
||||||
|
repeated bytes nested_list_field = 3 [
|
||||||
|
(ethereum.eth.ext.ssz_size) = "?,?",
|
||||||
|
(ethereum.eth.ext.ssz_max) = "100,50"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// VariableTestContainer - comprehensive variable-size container for SSZ query testing
|
// VariableTestContainer - comprehensive variable-size container for SSZ query testing
|
||||||
@@ -96,7 +100,14 @@ message VariableTestContainer {
|
|||||||
"github.com/prysmaticlabs/go-bitfield.Bitlist"
|
"github.com/prysmaticlabs/go-bitfield.Bitlist"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 2D bytes list - test list of bytelists.
|
||||||
|
// e.g., ExecutionPayload.transactions
|
||||||
|
repeated bytes nested_list_field = 7 [
|
||||||
|
(ethereum.eth.ext.ssz_size) = "?,?",
|
||||||
|
(ethereum.eth.ext.ssz_max) = "100,50"
|
||||||
|
];
|
||||||
|
|
||||||
// Fixed-size trailing field - test fixed field after variable fields
|
// Fixed-size trailing field - test fixed field after variable fields
|
||||||
// Verifies correct offset calculation after variable-size fields
|
// Verifies correct offset calculation after variable-size fields
|
||||||
bytes trailing_field = 7 [ (ethereum.eth.ext.ssz_size) = "56" ]; // Test: fixed 56-byte field at end, offset: 32 + 4 + 4 + 4 + 4 + 4 = 52
|
bytes trailing_field = 8 [ (ethereum.eth.ext.ssz_size) = "56" ]; // Test: fixed 56-byte field at end, offset: 32 + 4 + 4 + 4 + 4 + 4 + 4 = 56
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ func (v *VariableNestedContainer) MarshalSSZ() ([]byte, error) {
|
|||||||
// MarshalSSZTo ssz marshals the VariableNestedContainer object to a target array
|
// MarshalSSZTo ssz marshals the VariableNestedContainer object to a target array
|
||||||
func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
||||||
dst = buf
|
dst = buf
|
||||||
offset := int(12)
|
offset := int(16)
|
||||||
|
|
||||||
// Field (0) 'Value1'
|
// Field (0) 'Value1'
|
||||||
dst = ssz.MarshalUint64(dst, v.Value1)
|
dst = ssz.MarshalUint64(dst, v.Value1)
|
||||||
@@ -333,6 +333,13 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
|
|||||||
dst = ssz.WriteOffset(dst, offset)
|
dst = ssz.WriteOffset(dst, offset)
|
||||||
offset += len(v.FieldListUint64) * 8
|
offset += len(v.FieldListUint64) * 8
|
||||||
|
|
||||||
|
// Offset (2) 'NestedListField'
|
||||||
|
dst = ssz.WriteOffset(dst, offset)
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
offset += 4
|
||||||
|
offset += len(v.NestedListField[ii])
|
||||||
|
}
|
||||||
|
|
||||||
// Field (1) 'FieldListUint64'
|
// Field (1) 'FieldListUint64'
|
||||||
if size := len(v.FieldListUint64); size > 100 {
|
if size := len(v.FieldListUint64); size > 100 {
|
||||||
err = ssz.ErrListTooBigFn("--.FieldListUint64", size, 100)
|
err = ssz.ErrListTooBigFn("--.FieldListUint64", size, 100)
|
||||||
@@ -342,6 +349,26 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
|
|||||||
dst = ssz.MarshalUint64(dst, v.FieldListUint64[ii])
|
dst = ssz.MarshalUint64(dst, v.FieldListUint64[ii])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Field (2) 'NestedListField'
|
||||||
|
if size := len(v.NestedListField); size > 100 {
|
||||||
|
err = ssz.ErrListTooBigFn("--.NestedListField", size, 100)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{
|
||||||
|
offset = 4 * len(v.NestedListField)
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
dst = ssz.WriteOffset(dst, offset)
|
||||||
|
offset += len(v.NestedListField[ii])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
if size := len(v.NestedListField[ii]); size > 50 {
|
||||||
|
err = ssz.ErrBytesLengthFn("--.NestedListField[ii]", size, 50)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dst = append(dst, v.NestedListField[ii]...)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,12 +376,12 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
|
|||||||
func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
|
func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
|
||||||
var err error
|
var err error
|
||||||
size := uint64(len(buf))
|
size := uint64(len(buf))
|
||||||
if size < 12 {
|
if size < 16 {
|
||||||
return ssz.ErrSize
|
return ssz.ErrSize
|
||||||
}
|
}
|
||||||
|
|
||||||
tail := buf
|
tail := buf
|
||||||
var o1 uint64
|
var o1, o2 uint64
|
||||||
|
|
||||||
// Field (0) 'Value1'
|
// Field (0) 'Value1'
|
||||||
v.Value1 = ssz.UnmarshallUint64(buf[0:8])
|
v.Value1 = ssz.UnmarshallUint64(buf[0:8])
|
||||||
@@ -364,13 +391,18 @@ func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
|
|||||||
return ssz.ErrOffset
|
return ssz.ErrOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
if o1 != 12 {
|
if o1 != 16 {
|
||||||
return ssz.ErrInvalidVariableOffset
|
return ssz.ErrInvalidVariableOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Offset (2) 'NestedListField'
|
||||||
|
if o2 = ssz.ReadOffset(buf[12:16]); o2 > size || o1 > o2 {
|
||||||
|
return ssz.ErrOffset
|
||||||
|
}
|
||||||
|
|
||||||
// Field (1) 'FieldListUint64'
|
// Field (1) 'FieldListUint64'
|
||||||
{
|
{
|
||||||
buf = tail[o1:]
|
buf = tail[o1:o2]
|
||||||
num, err := ssz.DivideInt2(len(buf), 8, 100)
|
num, err := ssz.DivideInt2(len(buf), 8, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -380,16 +412,45 @@ func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
|
|||||||
v.FieldListUint64[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8])
|
v.FieldListUint64[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Field (2) 'NestedListField'
|
||||||
|
{
|
||||||
|
buf = tail[o2:]
|
||||||
|
num, err := ssz.DecodeDynamicLength(buf, 100)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.NestedListField = make([][]byte, num)
|
||||||
|
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
|
||||||
|
if len(buf) > 50 {
|
||||||
|
return ssz.ErrBytesLength
|
||||||
|
}
|
||||||
|
if cap(v.NestedListField[indx]) == 0 {
|
||||||
|
v.NestedListField[indx] = make([]byte, 0, len(buf))
|
||||||
|
}
|
||||||
|
v.NestedListField[indx] = append(v.NestedListField[indx], buf...)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SizeSSZ returns the ssz encoded size in bytes for the VariableNestedContainer object
|
// SizeSSZ returns the ssz encoded size in bytes for the VariableNestedContainer object
|
||||||
func (v *VariableNestedContainer) SizeSSZ() (size int) {
|
func (v *VariableNestedContainer) SizeSSZ() (size int) {
|
||||||
size = 12
|
size = 16
|
||||||
|
|
||||||
// Field (1) 'FieldListUint64'
|
// Field (1) 'FieldListUint64'
|
||||||
size += len(v.FieldListUint64) * 8
|
size += len(v.FieldListUint64) * 8
|
||||||
|
|
||||||
|
// Field (2) 'NestedListField'
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
size += 4
|
||||||
|
size += len(v.NestedListField[ii])
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,6 +482,29 @@ func (v *VariableNestedContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
|||||||
hh.MerkleizeWithMixin(subIndx, numItems, ssz.CalculateLimit(100, numItems, 8))
|
hh.MerkleizeWithMixin(subIndx, numItems, ssz.CalculateLimit(100, numItems, 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Field (2) 'NestedListField'
|
||||||
|
{
|
||||||
|
subIndx := hh.Index()
|
||||||
|
num := uint64(len(v.NestedListField))
|
||||||
|
if num > 100 {
|
||||||
|
err = ssz.ErrIncorrectListSize
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, elem := range v.NestedListField {
|
||||||
|
{
|
||||||
|
elemIndx := hh.Index()
|
||||||
|
byteLen := uint64(len(elem))
|
||||||
|
if byteLen > 50 {
|
||||||
|
err = ssz.ErrIncorrectListSize
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hh.AppendBytes32(elem)
|
||||||
|
hh.MerkleizeWithMixin(elemIndx, byteLen, (50+31)/32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hh.MerkleizeWithMixin(subIndx, num, 100)
|
||||||
|
}
|
||||||
|
|
||||||
hh.Merkleize(indx)
|
hh.Merkleize(indx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -433,7 +517,7 @@ func (v *VariableTestContainer) MarshalSSZ() ([]byte, error) {
|
|||||||
// MarshalSSZTo ssz marshals the VariableTestContainer object to a target array
|
// MarshalSSZTo ssz marshals the VariableTestContainer object to a target array
|
||||||
func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
||||||
dst = buf
|
dst = buf
|
||||||
offset := int(108)
|
offset := int(112)
|
||||||
|
|
||||||
// Field (0) 'LeadingField'
|
// Field (0) 'LeadingField'
|
||||||
if size := len(v.LeadingField); size != 32 {
|
if size := len(v.LeadingField); size != 32 {
|
||||||
@@ -465,7 +549,14 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
|
|||||||
dst = ssz.WriteOffset(dst, offset)
|
dst = ssz.WriteOffset(dst, offset)
|
||||||
offset += len(v.BitlistField)
|
offset += len(v.BitlistField)
|
||||||
|
|
||||||
// Field (6) 'TrailingField'
|
// Offset (6) 'NestedListField'
|
||||||
|
dst = ssz.WriteOffset(dst, offset)
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
offset += 4
|
||||||
|
offset += len(v.NestedListField[ii])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field (7) 'TrailingField'
|
||||||
if size := len(v.TrailingField); size != 56 {
|
if size := len(v.TrailingField); size != 56 {
|
||||||
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
|
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
|
||||||
return
|
return
|
||||||
@@ -517,6 +608,26 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
|
|||||||
}
|
}
|
||||||
dst = append(dst, v.BitlistField...)
|
dst = append(dst, v.BitlistField...)
|
||||||
|
|
||||||
|
// Field (6) 'NestedListField'
|
||||||
|
if size := len(v.NestedListField); size > 100 {
|
||||||
|
err = ssz.ErrListTooBigFn("--.NestedListField", size, 100)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{
|
||||||
|
offset = 4 * len(v.NestedListField)
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
dst = ssz.WriteOffset(dst, offset)
|
||||||
|
offset += len(v.NestedListField[ii])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
if size := len(v.NestedListField[ii]); size > 50 {
|
||||||
|
err = ssz.ErrBytesLengthFn("--.NestedListField[ii]", size, 50)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dst = append(dst, v.NestedListField[ii]...)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,12 +635,12 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
|
|||||||
func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
|
func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
|
||||||
var err error
|
var err error
|
||||||
size := uint64(len(buf))
|
size := uint64(len(buf))
|
||||||
if size < 108 {
|
if size < 112 {
|
||||||
return ssz.ErrSize
|
return ssz.ErrSize
|
||||||
}
|
}
|
||||||
|
|
||||||
tail := buf
|
tail := buf
|
||||||
var o1, o2, o3, o4, o5 uint64
|
var o1, o2, o3, o4, o5, o6 uint64
|
||||||
|
|
||||||
// Field (0) 'LeadingField'
|
// Field (0) 'LeadingField'
|
||||||
if cap(v.LeadingField) == 0 {
|
if cap(v.LeadingField) == 0 {
|
||||||
@@ -542,7 +653,7 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
|
|||||||
return ssz.ErrOffset
|
return ssz.ErrOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
if o1 != 108 {
|
if o1 != 112 {
|
||||||
return ssz.ErrInvalidVariableOffset
|
return ssz.ErrInvalidVariableOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,11 +677,16 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
|
|||||||
return ssz.ErrOffset
|
return ssz.ErrOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
// Field (6) 'TrailingField'
|
// Offset (6) 'NestedListField'
|
||||||
if cap(v.TrailingField) == 0 {
|
if o6 = ssz.ReadOffset(buf[52:56]); o6 > size || o5 > o6 {
|
||||||
v.TrailingField = make([]byte, 0, len(buf[52:108]))
|
return ssz.ErrOffset
|
||||||
}
|
}
|
||||||
v.TrailingField = append(v.TrailingField, buf[52:108]...)
|
|
||||||
|
// Field (7) 'TrailingField'
|
||||||
|
if cap(v.TrailingField) == 0 {
|
||||||
|
v.TrailingField = make([]byte, 0, len(buf[56:112]))
|
||||||
|
}
|
||||||
|
v.TrailingField = append(v.TrailingField, buf[56:112]...)
|
||||||
|
|
||||||
// Field (1) 'FieldListUint64'
|
// Field (1) 'FieldListUint64'
|
||||||
{
|
{
|
||||||
@@ -632,7 +748,7 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
|
|||||||
|
|
||||||
// Field (5) 'BitlistField'
|
// Field (5) 'BitlistField'
|
||||||
{
|
{
|
||||||
buf = tail[o5:]
|
buf = tail[o5:o6]
|
||||||
if err = ssz.ValidateBitlist(buf, 2048); err != nil {
|
if err = ssz.ValidateBitlist(buf, 2048); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -641,12 +757,35 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
|
|||||||
}
|
}
|
||||||
v.BitlistField = append(v.BitlistField, buf...)
|
v.BitlistField = append(v.BitlistField, buf...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Field (6) 'NestedListField'
|
||||||
|
{
|
||||||
|
buf = tail[o6:]
|
||||||
|
num, err := ssz.DecodeDynamicLength(buf, 100)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.NestedListField = make([][]byte, num)
|
||||||
|
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
|
||||||
|
if len(buf) > 50 {
|
||||||
|
return ssz.ErrBytesLength
|
||||||
|
}
|
||||||
|
if cap(v.NestedListField[indx]) == 0 {
|
||||||
|
v.NestedListField[indx] = make([]byte, 0, len(buf))
|
||||||
|
}
|
||||||
|
v.NestedListField[indx] = append(v.NestedListField[indx], buf...)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SizeSSZ returns the ssz encoded size in bytes for the VariableTestContainer object
|
// SizeSSZ returns the ssz encoded size in bytes for the VariableTestContainer object
|
||||||
func (v *VariableTestContainer) SizeSSZ() (size int) {
|
func (v *VariableTestContainer) SizeSSZ() (size int) {
|
||||||
size = 108
|
size = 112
|
||||||
|
|
||||||
// Field (1) 'FieldListUint64'
|
// Field (1) 'FieldListUint64'
|
||||||
size += len(v.FieldListUint64) * 8
|
size += len(v.FieldListUint64) * 8
|
||||||
@@ -666,6 +805,12 @@ func (v *VariableTestContainer) SizeSSZ() (size int) {
|
|||||||
// Field (5) 'BitlistField'
|
// Field (5) 'BitlistField'
|
||||||
size += len(v.BitlistField)
|
size += len(v.BitlistField)
|
||||||
|
|
||||||
|
// Field (6) 'NestedListField'
|
||||||
|
for ii := 0; ii < len(v.NestedListField); ii++ {
|
||||||
|
size += 4
|
||||||
|
size += len(v.NestedListField[ii])
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,7 +893,30 @@ func (v *VariableTestContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
|||||||
}
|
}
|
||||||
hh.PutBitlist(v.BitlistField, 2048)
|
hh.PutBitlist(v.BitlistField, 2048)
|
||||||
|
|
||||||
// Field (6) 'TrailingField'
|
// Field (6) 'NestedListField'
|
||||||
|
{
|
||||||
|
subIndx := hh.Index()
|
||||||
|
num := uint64(len(v.NestedListField))
|
||||||
|
if num > 100 {
|
||||||
|
err = ssz.ErrIncorrectListSize
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, elem := range v.NestedListField {
|
||||||
|
{
|
||||||
|
elemIndx := hh.Index()
|
||||||
|
byteLen := uint64(len(elem))
|
||||||
|
if byteLen > 50 {
|
||||||
|
err = ssz.ErrIncorrectListSize
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hh.AppendBytes32(elem)
|
||||||
|
hh.MerkleizeWithMixin(elemIndx, byteLen, (50+31)/32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hh.MerkleizeWithMixin(subIndx, num, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field (7) 'TrailingField'
|
||||||
if size := len(v.TrailingField); size != 56 {
|
if size := len(v.TrailingField); size != 56 {
|
||||||
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
|
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user