From 64a333a0707547589efa8356f7b69cd6c13dbdc9 Mon Sep 17 00:00:00 2001 From: Zsolt Felfoldi Date: Thu, 11 Apr 2024 16:27:51 +0200 Subject: [PATCH] beacon/light/api: include canonical and finalized flags in header response --- beacon/light/api/api_server.go | 4 +++- beacon/light/api/light_api.go | 17 ++++++++++------- beacon/light/sync/types.go | 6 +++++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/beacon/light/api/api_server.go b/beacon/light/api/api_server.go index da044f4b2d..76e2b71c98 100755 --- a/beacon/light/api/api_server.go +++ b/beacon/light/api/api_server.go @@ -73,8 +73,10 @@ func (s *ApiServer) SendRequest(id request.ID, req request.Request) { r.Updates, r.Committees, err = s.api.GetBestUpdatesAndCommittees(data.FirstPeriod, data.Count) resp = r case sync.ReqHeader: + var r sync.RespHeader log.Debug("Beacon API: requesting header", "reqid", id, "hash", common.Hash(data)) - resp, err = s.api.GetHeader(common.Hash(data)) + r.Header, r.Canonical, r.Finalized, err = s.api.GetHeader(common.Hash(data)) + resp = r case sync.ReqCheckpointData: log.Debug("Beacon API: requesting checkpoint data", "reqid", id, "hash", common.Hash(data)) resp, err = s.api.GetCheckpointData(common.Hash(data)) diff --git a/beacon/light/api/light_api.go b/beacon/light/api/light_api.go index ceb4261c3c..6892407caf 100755 --- a/beacon/light/api/light_api.go +++ b/beacon/light/api/light_api.go @@ -291,7 +291,9 @@ func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) { // GetHeader fetches and validates the beacon header with the given blockRoot. // If blockRoot is null hash then the latest head header is fetched. -func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, error) { +// The values of the canonical and finalized flags are also returned. Note that +// these flags are not validated. +func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, bool, bool, error) { var blockId string if blockRoot == (common.Hash{}) { blockId = "head" @@ -300,11 +302,12 @@ func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, error } resp, err := api.httpGetf("/eth/v1/beacon/headers/%s", blockId) if err != nil { - return types.Header{}, err + return types.Header{}, false, false, err } var data struct { - Data struct { + Finalized bool `json:"finalized"` + Data struct { Root common.Hash `json:"root"` Canonical bool `json:"canonical"` Header struct { @@ -314,16 +317,16 @@ func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, error } `json:"data"` } if err := json.Unmarshal(resp, &data); err != nil { - return types.Header{}, err + return types.Header{}, false, false, err } header := data.Data.Header.Message if blockRoot == (common.Hash{}) { blockRoot = data.Data.Root } if header.Hash() != blockRoot { - return types.Header{}, errors.New("retrieved beacon header root does not match") + return types.Header{}, false, false, errors.New("retrieved beacon header root does not match") } - return header, nil + return header, data.Data.Canonical, data.Finalized, nil } // GetCheckpointData fetches and validates bootstrap data belonging to the given checkpoint. @@ -446,7 +449,7 @@ func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func() defer wg.Done() // Request initial data. - if head, err := api.GetHeader(common.Hash{}); err == nil { + if head, _, _, err := api.GetHeader(common.Hash{}); err == nil { listener.OnNewHead(head.Slot, head.Hash()) } if signedHead, err := api.GetOptimisticHeadUpdate(); err == nil { diff --git a/beacon/light/sync/types.go b/beacon/light/sync/types.go index 6449ae842d..8aa4c95f46 100644 --- a/beacon/light/sync/types.go +++ b/beacon/light/sync/types.go @@ -36,7 +36,11 @@ type ( Updates []*types.LightClientUpdate Committees []*types.SerializedSyncCommittee } - ReqHeader common.Hash + ReqHeader common.Hash + RespHeader struct { + Header types.Header + Canonical, Finalized bool + } ReqCheckpointData common.Hash ReqBeaconBlock common.Hash )