From 552583d72a8ce4fa6e5f25bdb79d78db689c9fa8 Mon Sep 17 00:00:00 2001 From: Alexander Tesfamichael Date: Thu, 14 Dec 2023 22:05:47 +0100 Subject: [PATCH] feat(payloads): log first publish time --- beaconclient/multi_beacon_client.go | 31 +++++++++++++++++++---------- services/api/service.go | 6 +++--- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/beaconclient/multi_beacon_client.go b/beaconclient/multi_beacon_client.go index 808e8231..11d5870a 100644 --- a/beaconclient/multi_beacon_client.go +++ b/beaconclient/multi_beacon_client.go @@ -7,6 +7,7 @@ import ( "os" "strings" "sync" + "time" "github.com/flashbots/mev-boost-relay/common" "github.com/sirupsen/logrus" @@ -42,7 +43,7 @@ type IMultiBeaconClient interface { // GetStateValidators returns all active and pending validators from the beacon node GetStateValidators(stateID string) (*GetStateValidatorsResponse, error) GetProposerDuties(epoch uint64) (*ProposerDutiesResponse, error) - PublishBlock(block *common.SignedBeaconBlock) (code int, err error) + PublishBlock(block *common.SignedBeaconBlock) (code int, firstPublishTime int64, err error) GetGenesis() (*GetGenesisResponse, error) GetSpec() (spec *GetSpecResponse, err error) GetForkSchedule() (spec *GetForkScheduleResponse, err error) @@ -249,13 +250,14 @@ func (c *MultiBeaconClient) beaconInstancesByLeastUsed() []IBeaconInstance { } type publishResp struct { - index int - code int - err error + index int + code int + err error + completedAt int64 } // PublishBlock publishes the signed beacon block via https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/publishBlock -func (c *MultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code int, err error) { +func (c *MultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code int, firstPublishTime int64, err error) { log := c.log.WithFields(logrus.Fields{ "slot": block.Slot(), "blockHash": block.BlockHash(), @@ -263,7 +265,7 @@ func (c *MultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code clients := c.beaconInstancesByLastResponse() - // The chan will be cleaner up automatically once the function exists even if it was still being written to + // The chan will be cleaned up automatically once the function exits even if it was still being written to resChans := make(chan publishResp, len(clients)) for i, client := range clients { @@ -272,9 +274,10 @@ func (c *MultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code go func(index int, client IBeaconInstance) { code, err := client.PublishBlock(block, c.broadcastMode) resChans <- publishResp{ - index: index, - code: code, - err: err, + index: index, + code: code, + err: err, + completedAt: time.Now().UTC().UnixMilli(), } }(i, client) } @@ -295,14 +298,20 @@ func (c *MultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code continue } + if firstPublishTime == 0 { + firstPublishTime = res.completedAt + } else if res.completedAt < firstPublishTime { + firstPublishTime = res.completedAt + } + c.bestBeaconIndex.Store(int64(res.index)) log.WithField("statusCode", res.code).Info("published block") - return res.code, nil + return res.code, firstPublishTime, nil } log.Error("failed to publish block on any CL node") - return lastErrPublishResp.code, fmt.Errorf("last error: %w", lastErrPublishResp.err) + return lastErrPublishResp.code, 0, fmt.Errorf("last error: %w", lastErrPublishResp.err) } // GetGenesis returns the genesis info - https://ethereum.github.io/beacon-APIs/#/Beacon/getGenesis diff --git a/services/api/service.go b/services/api/service.go index 9e6436c6..b1e075c0 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1569,15 +1569,15 @@ func (api *RelayAPI) handleGetPayload(w http.ResponseWriter, req *http.Request) timeBeforePublish = time.Now().UTC().UnixMilli() log = log.WithField("timestampBeforePublishing", timeBeforePublish) signedBeaconBlock := common.SignedBlindedBeaconBlockToBeaconBlock(payload, getPayloadResp) - code, err := api.beaconClient.PublishBlock(signedBeaconBlock) // errors are logged inside + code, firstPublishTime, err := api.beaconClient.PublishBlock(signedBeaconBlock) // errors are logged inside if err != nil || code != http.StatusOK { log.WithError(err).WithField("code", code).Error("failed to publish block") api.RespondError(w, http.StatusBadRequest, "failed to publish block") return } timeAfterPublish = time.Now().UTC().UnixMilli() - msNeededForPublishing = uint64(timeAfterPublish - timeBeforePublish) - log = log.WithField("timestampAfterPublishing", timeAfterPublish) + msNeededForPublishing = uint64(firstPublishTime - timeBeforePublish) + log = log.WithField("timestampAfterPublishing", firstPublishTime) log.WithField("msNeededForPublishing", msNeededForPublishing).Info("block published through beacon node") // give the beacon network some time to propagate the block