Skip to content

Commit

Permalink
Set fields of wrapped proto object in light client setters (#14573)
Browse files Browse the repository at this point in the history
* Set fields of wrapped proto object in light client setters

* changelog <3
  • Loading branch information
rkapka committed Oct 28, 2024
1 parent ac93198 commit 3f4bde1
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 37 deletions.
29 changes: 4 additions & 25 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

## [Unreleased](https://github.com/prysmaticlabs/prysm/compare/v5.1.2...HEAD)
## [Unreleased](https://github.com/prysmaticlabs/prysm/compare/v5.1.1...HEAD)

### Added

Expand All @@ -30,8 +30,6 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
- Return false from HasBlock if the block is being synced.
- Cleanup forkchoice on failed insertions.
- Use read only validator for core processing to avoid unnecessary copying.
- Use ROBlock across block processing pipeline.
- Added missing Eth-Consensus-Version headers to GetBlockAttestationsV2 and GetAttesterSlashingsV2 endpoints.

### Deprecated

Expand All @@ -45,30 +43,12 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve

- Fixed mesh size by appending `gParams.Dhi = gossipSubDhi`
- Fix skipping partial withdrawals count.
- wait for the async StreamEvent writer to exit before leaving the http handler, avoiding race condition panics [pr](https://github.com/prysmaticlabs/prysm/pull/14557)
- Certain deb files were returning a 404 which made building new docker images without an existing
cache impossible. This has been fixed with updates to rules_oci and bazel-lib.
- Fixed an issue where the length check between block body KZG commitments and the existing cache from the database was incompatible.
- recover from panics when writing the event stream [pr](https://github.com/prysmaticlabs/prysm/pull/14545)
- Return the correct light client payload proof. [PR](https://github.com/prysmaticlabs/prysm/pull/14565)
- Set fields of wrapped proto object in light client setters. [PR](https://github.com/prysmaticlabs/prysm/pull/14573)

### Security

## [v5.1.2](https://github.com/prysmaticlabs/prysm/compare/v5.1.1...v5.1.2) - 2024-10-16

This is a hotfix release with one change.

Prysm v5.1.1 contains an updated implementation of the beacon api streaming events endpoint. This
new implementation contains a bug that can cause a panic in certain conditions. The issue is
difficult to reproduce reliably and we are still trying to determine the root cause, but in the
meantime we are issuing a patch that recovers from the panic to prevent the node from crashing.

This only impacts the v5.1.1 release beacon api event stream endpoints. This endpoint is used by the
prysm REST mode validator (a feature which requires the validator to be configured to use the beacon
api intead of prysm's stock grpc endpoints) or accessory software that connects to the events api,
like https://github.com/ethpandaops/ethereum-metrics-exporter

### Fixed

- Recover from panics when writing the event stream [#14545](https://github.com/prysmaticlabs/prysm/pull/14545)

## [v5.1.1](https://github.com/prysmaticlabs/prysm/compare/v5.1.0...v5.1.1) - 2024-10-15

Expand Down Expand Up @@ -102,7 +82,6 @@ Updating to this release is recommended at your convenience.
- fastssz version bump (better error messages).
- SSE implementation that sheds stuck clients. [pr](https://github.com/prysmaticlabs/prysm/pull/14413)
- Added GetPoolAttesterSlashingsV2 endpoint.
- Use engine API get-blobs for block subscriber to reduce block import latency and potentially reduce bandwidth.

### Changed

Expand Down
8 changes: 6 additions & 2 deletions beacon-chain/core/light-client/lightclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ func NewLightClientUpdateFromBeaconState(
if err != nil {
return nil, errors.Wrap(err, "could not get attested light client header")
}
result.SetAttestedHeader(attestedLightClientHeader)
if err = result.SetAttestedHeader(attestedLightClientHeader); err != nil {
return nil, errors.Wrap(err, "could not set attested header")
}

// if update_attested_period == update_signature_period
if updateAttestedPeriod == updateSignaturePeriod {
Expand Down Expand Up @@ -208,7 +210,9 @@ func NewLightClientUpdateFromBeaconState(
if err != nil {
return nil, errors.Wrap(err, "could not get finalized light client header")
}
result.SetFinalizedHeader(finalizedLightClientHeader)
if err = result.SetFinalizedHeader(finalizedLightClientHeader); err != nil {
return nil, errors.Wrap(err, "could not set finalized header")
}
} else {
// assert attested_state.finalized_checkpoint.root == Bytes32()
if !bytes.Equal(attestedState.FinalizedCheckpoint().Root, make([]byte, 32)) {
Expand Down
4 changes: 2 additions & 2 deletions consensus-types/interfaces/light_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ type LightClientUpdate interface {
Proto() proto.Message
Version() int
AttestedHeader() LightClientHeader
SetAttestedHeader(header LightClientHeader)
SetAttestedHeader(header LightClientHeader) error
NextSyncCommittee() *pb.SyncCommittee
SetNextSyncCommittee(sc *pb.SyncCommittee)
NextSyncCommitteeBranch() (LightClientSyncCommitteeBranch, error)
SetNextSyncCommitteeBranch(branch [][]byte) error
NextSyncCommitteeBranchElectra() (LightClientSyncCommitteeBranchElectra, error)
SetNextSyncCommitteeBranchElectra(branch [][]byte) error
FinalizedHeader() LightClientHeader
SetFinalizedHeader(header LightClientHeader)
SetFinalizedHeader(header LightClientHeader) error
FinalityBranch() LightClientFinalityBranch
SetFinalityBranch(branch [][]byte) error
SyncAggregate() *pb.SyncAggregate
Expand Down
140 changes: 132 additions & 8 deletions consensus-types/light-client/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ func NewWrappedUpdate(m proto.Message) (interfaces.LightClientUpdate, error) {
}
}

// In addition to the proto object being wrapped, we store some fields that have to be
// constructed from the proto, so that we don't have to reconstruct them every time
// in getters.
type updateAltair struct {
p *pb.LightClientUpdateAltair
attestedHeader interfaces.LightClientHeader
Expand Down Expand Up @@ -107,8 +110,19 @@ func (u *updateAltair) AttestedHeader() interfaces.LightClientHeader {
return u.attestedHeader
}

func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) {
func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Altair {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Altair))
}
u.attestedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderAltair)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderAltair{})
}
u.p.AttestedHeader = proto

return nil
}

func (u *updateAltair) NextSyncCommittee() *pb.SyncCommittee {
Expand All @@ -129,6 +143,9 @@ func (u *updateAltair) SetNextSyncCommitteeBranch(branch [][]byte) error {
return err
}
u.nextSyncCommitteeBranch = b

u.p.NextSyncCommitteeBranch = branch

return nil
}

Expand All @@ -144,8 +161,19 @@ func (u *updateAltair) FinalizedHeader() interfaces.LightClientHeader {
return u.finalizedHeader
}

func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) {
func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Altair {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Altair))
}
u.finalizedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderAltair)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderAltair{})
}
u.p.FinalizedHeader = proto

return nil
}

func (u *updateAltair) FinalityBranch() interfaces.LightClientFinalityBranch {
Expand All @@ -158,6 +186,9 @@ func (u *updateAltair) SetFinalityBranch(branch [][]byte) error {
return err
}
u.finalityBranch = b

u.p.FinalityBranch = branch

return nil
}

Expand All @@ -177,6 +208,9 @@ func (u *updateAltair) SetSignatureSlot(slot primitives.Slot) {
u.p.SignatureSlot = slot
}

// In addition to the proto object being wrapped, we store some fields that have to be
// constructed from the proto, so that we don't have to reconstruct them every time
// in getters.
type updateCapella struct {
p *pb.LightClientUpdateCapella
attestedHeader interfaces.LightClientHeader
Expand Down Expand Up @@ -254,8 +288,19 @@ func (u *updateCapella) AttestedHeader() interfaces.LightClientHeader {
return u.attestedHeader
}

func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) {
func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Capella {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Capella))
}
u.attestedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderCapella)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderCapella{})
}
u.p.AttestedHeader = proto

return nil
}

func (u *updateCapella) NextSyncCommittee() *pb.SyncCommittee {
Expand All @@ -276,6 +321,9 @@ func (u *updateCapella) SetNextSyncCommitteeBranch(branch [][]byte) error {
return err
}
u.nextSyncCommitteeBranch = b

u.p.NextSyncCommitteeBranch = branch

return nil
}

Expand All @@ -291,8 +339,19 @@ func (u *updateCapella) FinalizedHeader() interfaces.LightClientHeader {
return u.finalizedHeader
}

func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) {
func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Capella {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Capella))
}
u.finalizedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderCapella)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderCapella{})
}
u.p.FinalizedHeader = proto

return nil
}

func (u *updateCapella) FinalityBranch() interfaces.LightClientFinalityBranch {
Expand All @@ -305,6 +364,9 @@ func (u *updateCapella) SetFinalityBranch(branch [][]byte) error {
return err
}
u.finalityBranch = b

u.p.FinalityBranch = branch

return nil
}

Expand All @@ -324,6 +386,9 @@ func (u *updateCapella) SetSignatureSlot(slot primitives.Slot) {
u.p.SignatureSlot = slot
}

// In addition to the proto object being wrapped, we store some fields that have to be
// constructed from the proto, so that we don't have to reconstruct them every time
// in getters.
type updateDeneb struct {
p *pb.LightClientUpdateDeneb
attestedHeader interfaces.LightClientHeader
Expand Down Expand Up @@ -401,8 +466,19 @@ func (u *updateDeneb) AttestedHeader() interfaces.LightClientHeader {
return u.attestedHeader
}

func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) {
func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Deneb {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Deneb))
}
u.attestedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
}
u.p.AttestedHeader = proto

return nil
}

func (u *updateDeneb) NextSyncCommittee() *pb.SyncCommittee {
Expand All @@ -423,6 +499,9 @@ func (u *updateDeneb) SetNextSyncCommitteeBranch(branch [][]byte) error {
return err
}
u.nextSyncCommitteeBranch = b

u.p.NextSyncCommitteeBranch = branch

return nil
}

Expand All @@ -438,8 +517,19 @@ func (u *updateDeneb) FinalizedHeader() interfaces.LightClientHeader {
return u.finalizedHeader
}

func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) {
func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Deneb {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Deneb))
}
u.finalizedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
}
u.p.FinalizedHeader = proto

return nil
}

func (u *updateDeneb) FinalityBranch() interfaces.LightClientFinalityBranch {
Expand All @@ -452,6 +542,9 @@ func (u *updateDeneb) SetFinalityBranch(branch [][]byte) error {
return err
}
u.finalityBranch = b

u.p.FinalityBranch = branch

return nil
}

Expand All @@ -471,6 +564,9 @@ func (u *updateDeneb) SetSignatureSlot(slot primitives.Slot) {
u.p.SignatureSlot = slot
}

// In addition to the proto object being wrapped, we store some fields that have to be
// constructed from the proto, so that we don't have to reconstruct them every time
// in getters.
type updateElectra struct {
p *pb.LightClientUpdateElectra
attestedHeader interfaces.LightClientHeader
Expand Down Expand Up @@ -548,8 +644,19 @@ func (u *updateElectra) AttestedHeader() interfaces.LightClientHeader {
return u.attestedHeader
}

func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) {
func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Electra {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Electra))
}
u.attestedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
}
u.p.AttestedHeader = proto

return nil
}

func (u *updateElectra) NextSyncCommittee() *pb.SyncCommittee {
Expand Down Expand Up @@ -578,15 +685,29 @@ func (u *updateElectra) SetNextSyncCommitteeBranchElectra(branch [][]byte) error
return err
}
u.nextSyncCommitteeBranch = b

u.p.NextSyncCommitteeBranch = branch

return nil
}

func (u *updateElectra) FinalizedHeader() interfaces.LightClientHeader {
return u.finalizedHeader
}

func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) {
func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) error {
if header.Version() != version.Electra {
return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Electra))
}
u.finalizedHeader = header

proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
if !ok {
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
}
u.p.FinalizedHeader = proto

return nil
}

func (u *updateElectra) FinalityBranch() interfaces.LightClientFinalityBranch {
Expand All @@ -599,6 +720,9 @@ func (u *updateElectra) SetFinalityBranch(branch [][]byte) error {
return err
}
u.finalityBranch = b

u.p.FinalityBranch = branch

return nil
}

Expand Down

0 comments on commit 3f4bde1

Please sign in to comment.