Skip to content

Commit

Permalink
Only commit to saving payload once the relay has confirmed it is avai…
Browse files Browse the repository at this point in the history
…lable
  • Loading branch information
austonst committed Sep 18, 2023
1 parent 01fd186 commit f7f00f0
Showing 1 changed file with 32 additions and 33 deletions.
65 changes: 32 additions & 33 deletions services/api/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,38 @@ func (api *RelayAPI) handleGetPayload(w http.ResponseWriter, req *http.Request)
var getPayloadResp *common.VersionedExecutionPayload
var msNeededForPublishing uint64

// Get the response - from Redis, Memcache or DB
getPayloadResp, err = api.datastore.GetGetPayloadResponse(log, payload.Slot(), proposerPubkey.String(), payload.BlockHash())
if err != nil || getPayloadResp == nil {
log.WithError(err).Warn("failed getting execution payload (1/2)")
time.Sleep(time.Duration(timeoutGetPayloadRetryMs) * time.Millisecond)

// Try again
getPayloadResp, err = api.datastore.GetGetPayloadResponse(log, payload.Slot(), proposerPubkey.String(), payload.BlockHash())
if err != nil || getPayloadResp == nil {
// Still not found! Error out now.
if errors.Is(err, datastore.ErrExecutionPayloadNotFound) {
// Couldn't find the execution payload, maybe it never was submitted to our relay! Check that now
_, err := api.db.GetBlockSubmissionEntry(payload.Slot(), proposerPubkey.String(), payload.BlockHash())
if errors.Is(err, sql.ErrNoRows) {
log.Warn("failed getting execution payload (2/2) - payload not found, block was never submitted to this relay")
api.RespondError(w, http.StatusBadRequest, "no execution payload for this request - block was never seen by this relay")
} else if err != nil {
log.WithError(err).Error("failed getting execution payload (2/2) - payload not found, and error on checking bids")
} else {
log.Error("failed getting execution payload (2/2) - payload not found, but found bid in database")
}
} else { // some other error
log.WithError(err).Error("failed getting execution payload (2/2) - error")
}
api.RespondError(w, http.StatusBadRequest, "no execution payload for this request")
return
}
}

// Now we know this relay also has the payload
log = log.WithField("timestampAfterLoadResponse", time.Now().UTC().UnixMilli())

// Save information about delivered payload
defer func() {
bidTrace, err := api.redis.GetBidTrace(payload.Slot(), proposerPubkey.String(), payload.BlockHash())
Expand Down Expand Up @@ -1354,39 +1386,6 @@ func (api *RelayAPI) handleGetPayload(w http.ResponseWriter, req *http.Request)
}
}()

// Get the response - from Redis, Memcache or DB
// note that recent mev-boost versions only send getPayload to relays that provided the bid
getPayloadResp, err = api.datastore.GetGetPayloadResponse(log, payload.Slot(), proposerPubkey.String(), payload.BlockHash())
if err != nil || getPayloadResp == nil {
log.WithError(err).Warn("failed getting execution payload (1/2)")
time.Sleep(time.Duration(timeoutGetPayloadRetryMs) * time.Millisecond)

// Try again
getPayloadResp, err = api.datastore.GetGetPayloadResponse(log, payload.Slot(), proposerPubkey.String(), payload.BlockHash())
if err != nil || getPayloadResp == nil {
// Still not found! Error out now.
if errors.Is(err, datastore.ErrExecutionPayloadNotFound) {
// Couldn't find the execution payload, maybe it never was submitted to our relay! Check that now
_, err := api.db.GetBlockSubmissionEntry(payload.Slot(), proposerPubkey.String(), payload.BlockHash())
if errors.Is(err, sql.ErrNoRows) {
log.Warn("failed getting execution payload (2/2) - payload not found, block was never submitted to this relay")
api.RespondError(w, http.StatusBadRequest, "no execution payload for this request - block was never seen by this relay")
} else if err != nil {
log.WithError(err).Error("failed getting execution payload (2/2) - payload not found, and error on checking bids")
} else {
log.Error("failed getting execution payload (2/2) - payload not found, but found bid in database")
}
} else { // some other error
log.WithError(err).Error("failed getting execution payload (2/2) - error")
}
api.RespondError(w, http.StatusBadRequest, "no execution payload for this request")
return
}
}

// Now we know this relay also has the payload
log = log.WithField("timestampAfterLoadResponse", time.Now().UTC().UnixMilli())

// Check whether getPayload has already been called -- TODO: do we need to allow multiple submissions of one blinded block?
err = api.redis.CheckAndSetLastSlotAndHashDelivered(payload.Slot(), payload.BlockHash())
log = log.WithField("timestampAfterAlreadyDeliveredCheck", time.Now().UTC().UnixMilli())
Expand Down

0 comments on commit f7f00f0

Please sign in to comment.