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:
Jun Song
2025-09-26 23:23:22 +09:00
committed by GitHub
parent d68196822b
commit 29fe707143
9 changed files with 355 additions and 57 deletions

View File

@@ -195,6 +195,7 @@ type VariableNestedContainer struct {
state protoimpl.MessageState `protogen:"open.v1"`
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"`
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
sizeCache protoimpl.SizeCache
}
@@ -243,6 +244,13 @@ func (x *VariableNestedContainer) GetFieldListUint64() []uint64 {
return nil
}
func (x *VariableNestedContainer) GetNestedListField() [][]byte {
if x != nil {
return x.NestedListField
}
return nil
}
type VariableTestContainer struct {
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"`
@@ -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"`
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"`
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
sizeCache protoimpl.SizeCache
}
@@ -328,6 +337,13 @@ func (x *VariableTestContainer) GetBitlistField() github_com_prysmaticlabs_go_bi
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 {
if x != nil {
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,
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,
0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x66,
0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x31, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f,
0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x42, 0x07, 0x92, 0xb5,
0x18, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4c, 0x69, 0x73, 0x74,
0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x22, 0xdf, 0x03, 0x0a, 0x15, 0x56, 0x61, 0x72, 0x69, 0x61,
0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0xa5,
0x01, 0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65,
0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x31, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74,
0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x42, 0x07, 0x92,
0xb5, 0x18, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4c, 0x69, 0x73,
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,
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,
@@ -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,
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,
0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61,
0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x07, 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, 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,
0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x3d, 0x0a, 0x11, 0x6e, 0x65, 0x73,
0x74, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x07,
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, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x69,
0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x08, 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, 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 (

View File

@@ -65,6 +65,10 @@ message FixedTestContainer {
message VariableNestedContainer {
uint64 value1 = 1;
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
@@ -96,7 +100,14 @@ message VariableTestContainer {
"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
// 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
}

View File

@@ -324,7 +324,7 @@ func (v *VariableNestedContainer) MarshalSSZ() ([]byte, error) {
// MarshalSSZTo ssz marshals the VariableNestedContainer object to a target array
func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(12)
offset := int(16)
// Field (0) '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)
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'
if size := len(v.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])
}
// 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
}
@@ -349,12 +376,12 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 12 {
if size < 16 {
return ssz.ErrSize
}
tail := buf
var o1 uint64
var o1, o2 uint64
// Field (0) 'Value1'
v.Value1 = ssz.UnmarshallUint64(buf[0:8])
@@ -364,13 +391,18 @@ func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
if o1 != 12 {
if o1 != 16 {
return ssz.ErrInvalidVariableOffset
}
// Offset (2) 'NestedListField'
if o2 = ssz.ReadOffset(buf[12:16]); o2 > size || o1 > o2 {
return ssz.ErrOffset
}
// Field (1) 'FieldListUint64'
{
buf = tail[o1:]
buf = tail[o1:o2]
num, err := ssz.DivideInt2(len(buf), 8, 100)
if err != nil {
return err
@@ -380,16 +412,45 @@ func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
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
}
// SizeSSZ returns the ssz encoded size in bytes for the VariableNestedContainer object
func (v *VariableNestedContainer) SizeSSZ() (size int) {
size = 12
size = 16
// Field (1) 'FieldListUint64'
size += len(v.FieldListUint64) * 8
// Field (2) 'NestedListField'
for ii := 0; ii < len(v.NestedListField); ii++ {
size += 4
size += len(v.NestedListField[ii])
}
return
}
@@ -421,6 +482,29 @@ func (v *VariableNestedContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
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)
return
}
@@ -433,7 +517,7 @@ func (v *VariableTestContainer) MarshalSSZ() ([]byte, error) {
// MarshalSSZTo ssz marshals the VariableTestContainer object to a target array
func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(108)
offset := int(112)
// Field (0) 'LeadingField'
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)
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 {
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
return
@@ -517,6 +608,26 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
}
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
}
@@ -524,12 +635,12 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 108 {
if size < 112 {
return ssz.ErrSize
}
tail := buf
var o1, o2, o3, o4, o5 uint64
var o1, o2, o3, o4, o5, o6 uint64
// Field (0) 'LeadingField'
if cap(v.LeadingField) == 0 {
@@ -542,7 +653,7 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
if o1 != 108 {
if o1 != 112 {
return ssz.ErrInvalidVariableOffset
}
@@ -566,11 +677,16 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
// Field (6) 'TrailingField'
if cap(v.TrailingField) == 0 {
v.TrailingField = make([]byte, 0, len(buf[52:108]))
// Offset (6) 'NestedListField'
if o6 = ssz.ReadOffset(buf[52:56]); o6 > size || o5 > o6 {
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'
{
@@ -632,7 +748,7 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
// Field (5) 'BitlistField'
{
buf = tail[o5:]
buf = tail[o5:o6]
if err = ssz.ValidateBitlist(buf, 2048); err != nil {
return err
}
@@ -641,12 +757,35 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
}
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
}
// SizeSSZ returns the ssz encoded size in bytes for the VariableTestContainer object
func (v *VariableTestContainer) SizeSSZ() (size int) {
size = 108
size = 112
// Field (1) 'FieldListUint64'
size += len(v.FieldListUint64) * 8
@@ -666,6 +805,12 @@ func (v *VariableTestContainer) SizeSSZ() (size int) {
// Field (5) 'BitlistField'
size += len(v.BitlistField)
// Field (6) 'NestedListField'
for ii := 0; ii < len(v.NestedListField); ii++ {
size += 4
size += len(v.NestedListField[ii])
}
return
}
@@ -748,7 +893,30 @@ func (v *VariableTestContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
}
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 {
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
return