Add SSZ support for light client updates by range API (#15082)

* create ssz payload

* remove unused function

* remove access to state

* gazelle fix

* fix ssz size for electra finality update

* fix fork digest version problem

* fix chunk size

* fix fork version

* fix fork version

* add tests

* add changelog entry

* add PR link in changelog entry

* fix lint error

* Update beacon-chain/rpc/eth/light-client/handlers.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* check for context error

* send response in chunks

* remove content disposition header

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
This commit is contained in:
Bastin
2025-03-26 16:06:03 +01:00
committed by GitHub
parent 1295c987e8
commit 38a6a7a4ea
8 changed files with 524 additions and 104 deletions

View File

@@ -5279,7 +5279,7 @@ func (l *LightClientFinalityUpdateElectra) MarshalSSZ() ([]byte, error) {
// MarshalSSZTo ssz marshals the LightClientFinalityUpdateElectra object to a target array
func (l *LightClientFinalityUpdateElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(180)
offset := int(400)
// Offset (0) 'AttestedHeader'
dst = ssz.WriteOffset(dst, offset)
@@ -5295,11 +5295,17 @@ func (l *LightClientFinalityUpdateElectra) MarshalSSZTo(buf []byte) (dst []byte,
}
offset += l.FinalizedHeader.SizeSSZ()
// Offset (2) 'FinalityBranch'
dst = ssz.WriteOffset(dst, offset)
for ii := 0; ii < len(l.FinalityBranch); ii++ {
offset += 4
offset += len(l.FinalityBranch[ii])
// Field (2) 'FinalityBranch'
if size := len(l.FinalityBranch); size != 7 {
err = ssz.ErrVectorLengthFn("--.FinalityBranch", size, 7)
return
}
for ii := 0; ii < 7; ii++ {
if size := len(l.FinalityBranch[ii]); size != 32 {
err = ssz.ErrBytesLengthFn("--.FinalityBranch[ii]", size, 32)
return
}
dst = append(dst, l.FinalityBranch[ii]...)
}
// Field (3) 'SyncAggregate'
@@ -5323,26 +5329,6 @@ func (l *LightClientFinalityUpdateElectra) MarshalSSZTo(buf []byte) (dst []byte,
return
}
// Field (2) 'FinalityBranch'
if size := len(l.FinalityBranch); size > 7 {
err = ssz.ErrListTooBigFn("--.FinalityBranch", size, 7)
return
}
{
offset = 4 * len(l.FinalityBranch)
for ii := 0; ii < len(l.FinalityBranch); ii++ {
dst = ssz.WriteOffset(dst, offset)
offset += len(l.FinalityBranch[ii])
}
}
for ii := 0; ii < len(l.FinalityBranch); ii++ {
if size := len(l.FinalityBranch[ii]); size > 32 {
err = ssz.ErrBytesLengthFn("--.FinalityBranch[ii]", size, 32)
return
}
dst = append(dst, l.FinalityBranch[ii]...)
}
return
}
@@ -5350,19 +5336,19 @@ func (l *LightClientFinalityUpdateElectra) MarshalSSZTo(buf []byte) (dst []byte,
func (l *LightClientFinalityUpdateElectra) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 180 {
if size < 400 {
return ssz.ErrSize
}
tail := buf
var o0, o1, o2 uint64
var o0, o1 uint64
// Offset (0) 'AttestedHeader'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 != 180 {
if o0 != 400 {
return ssz.ErrInvalidVariableOffset
}
@@ -5371,21 +5357,25 @@ func (l *LightClientFinalityUpdateElectra) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
// Offset (2) 'FinalityBranch'
if o2 = ssz.ReadOffset(buf[8:12]); o2 > size || o1 > o2 {
return ssz.ErrOffset
// Field (2) 'FinalityBranch'
l.FinalityBranch = make([][]byte, 7)
for ii := 0; ii < 7; ii++ {
if cap(l.FinalityBranch[ii]) == 0 {
l.FinalityBranch[ii] = make([]byte, 0, len(buf[8:232][ii*32:(ii+1)*32]))
}
l.FinalityBranch[ii] = append(l.FinalityBranch[ii], buf[8:232][ii*32:(ii+1)*32]...)
}
// Field (3) 'SyncAggregate'
if l.SyncAggregate == nil {
l.SyncAggregate = new(SyncAggregate)
}
if err = l.SyncAggregate.UnmarshalSSZ(buf[12:172]); err != nil {
if err = l.SyncAggregate.UnmarshalSSZ(buf[232:392]); err != nil {
return err
}
// Field (4) 'SignatureSlot'
l.SignatureSlot = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot(ssz.UnmarshallUint64(buf[172:180]))
l.SignatureSlot = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot(ssz.UnmarshallUint64(buf[392:400]))
// Field (0) 'AttestedHeader'
{
@@ -5400,7 +5390,7 @@ func (l *LightClientFinalityUpdateElectra) UnmarshalSSZ(buf []byte) error {
// Field (1) 'FinalizedHeader'
{
buf = tail[o1:o2]
buf = tail[o1:]
if l.FinalizedHeader == nil {
l.FinalizedHeader = new(LightClientHeaderDeneb)
}
@@ -5408,35 +5398,12 @@ func (l *LightClientFinalityUpdateElectra) UnmarshalSSZ(buf []byte) error {
return err
}
}
// Field (2) 'FinalityBranch'
{
buf = tail[o2:]
num, err := ssz.DecodeDynamicLength(buf, 7)
if err != nil {
return err
}
l.FinalityBranch = make([][]byte, num)
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
if len(buf) > 32 {
return ssz.ErrBytesLength
}
if cap(l.FinalityBranch[indx]) == 0 {
l.FinalityBranch[indx] = make([]byte, 0, len(buf))
}
l.FinalityBranch[indx] = append(l.FinalityBranch[indx], buf...)
return nil
})
if err != nil {
return err
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the LightClientFinalityUpdateElectra object
func (l *LightClientFinalityUpdateElectra) SizeSSZ() (size int) {
size = 180
size = 400
// Field (0) 'AttestedHeader'
if l.AttestedHeader == nil {
@@ -5450,12 +5417,6 @@ func (l *LightClientFinalityUpdateElectra) SizeSSZ() (size int) {
}
size += l.FinalizedHeader.SizeSSZ()
// Field (2) 'FinalityBranch'
for ii := 0; ii < len(l.FinalityBranch); ii++ {
size += 4
size += len(l.FinalityBranch[ii])
}
return
}
@@ -5480,25 +5441,19 @@ func (l *LightClientFinalityUpdateElectra) HashTreeRootWith(hh *ssz.Hasher) (err
// Field (2) 'FinalityBranch'
{
subIndx := hh.Index()
num := uint64(len(l.FinalityBranch))
if num > 7 {
err = ssz.ErrIncorrectListSize
if size := len(l.FinalityBranch); size != 7 {
err = ssz.ErrVectorLengthFn("--.FinalityBranch", size, 7)
return
}
for _, elem := range l.FinalityBranch {
{
elemIndx := hh.Index()
byteLen := uint64(len(elem))
if byteLen > 32 {
err = ssz.ErrIncorrectListSize
return
}
hh.AppendBytes32(elem)
hh.MerkleizeWithMixin(elemIndx, byteLen, (32+31)/32)
subIndx := hh.Index()
for _, i := range l.FinalityBranch {
if len(i) != 32 {
err = ssz.ErrBytesLength
return
}
hh.Append(i)
}
hh.MerkleizeWithMixin(subIndx, num, 7)
hh.Merkleize(subIndx)
}
// Field (3) 'SyncAggregate'

View File

@@ -1262,7 +1262,7 @@ type LightClientFinalityUpdateElectra struct {
AttestedHeader *LightClientHeaderDeneb `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
FinalizedHeader *LightClientHeaderDeneb `protobuf:"bytes,2,opt,name=finalized_header,json=finalizedHeader,proto3" json:"finalized_header,omitempty"`
FinalityBranch [][]byte `protobuf:"bytes,3,rep,name=finality_branch,json=finalityBranch,proto3" json:"finality_branch,omitempty" ssz-max:"7,32"`
FinalityBranch [][]byte `protobuf:"bytes,3,rep,name=finality_branch,json=finalityBranch,proto3" json:"finality_branch,omitempty" ssz-size:"7,32"`
SyncAggregate *SyncAggregate `protobuf:"bytes,4,opt,name=sync_aggregate,json=syncAggregate,proto3" json:"sync_aggregate,omitempty"`
SignatureSlot github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot `protobuf:"varint,5,opt,name=signature_slot,json=signatureSlot,proto3" json:"signature_slot,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"`
}
@@ -1762,7 +1762,7 @@ var file_proto_prysm_v1alpha1_light_client_proto_rawDesc = []byte{
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, 0x0f, 0x66, 0x69, 0x6e,
0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x0f,
0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18,
0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x92, 0xb5, 0x18, 0x04, 0x37, 0x2c, 0x33, 0x32, 0x52,
0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x37, 0x2c, 0x33, 0x32, 0x52,
0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12,
0x4b, 0x0a, 0x0e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,

View File

@@ -204,7 +204,7 @@ message LightClientUpdateElectra {
message LightClientFinalityUpdateElectra {
LightClientHeaderDeneb attested_header = 1;
LightClientHeaderDeneb finalized_header = 2;
repeated bytes finality_branch = 3 [ (ethereum.eth.ext.ssz_max) = "7,32" ];
repeated bytes finality_branch = 3 [ (ethereum.eth.ext.ssz_size) = "7,32" ];
SyncAggregate sync_aggregate = 4;
uint64 signature_slot = 5 [
(ethereum.eth.ext.cast_type) =

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.33.0
// protoc v3.21.7
// protoc-gen-go v1.31.0
// protoc v4.25.1
// source: proto/testing/test.proto
package testing