Skip to content

Commit

Permalink
refactor processElectraPayload to use a result chan
Browse files Browse the repository at this point in the history
  • Loading branch information
0xTylerHolmes committed Nov 22, 2024
1 parent 9350154 commit e09f24b
Showing 1 changed file with 16 additions and 19 deletions.
35 changes: 16 additions & 19 deletions server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,18 +684,20 @@ func (m *BoostService) processElectraPayload(w http.ResponseWriter, req *http.Re
headers := map[string]string{HeaderKeySlotUID: currentSlotUID}

// Prepare for requests
var wg sync.WaitGroup
var mu sync.Mutex
result := new(builderApi.VersionedSubmitBlindedBlockResponse)
resultCh := make(chan *builderApi.VersionedSubmitBlindedBlockResponse, len(m.relays))
var received atomic.Bool
go func() {
// Make sure we receive a response within the timeout
time.Sleep(m.httpClientGetPayload.Timeout)
resultCh <- nil
}()

// Prepare the request context, which will be cancelled after the first successful response from a relay
requestCtx, requestCtxCancel := context.WithCancel(context.Background())
defer requestCtxCancel()

for _, relay := range m.relays {
wg.Add(1)
go func(relay types.RelayEntry) {
defer wg.Done()
url := relay.GetURI(params.PathGetPayload)
log := log.WithField("url", url)
log.Debug("calling getPayload")
Expand Down Expand Up @@ -756,26 +758,21 @@ func (m *BoostService) processElectraPayload(w http.ResponseWriter, req *http.Re
}
}

// Lock before accessing the shared payload
mu.Lock()
defer mu.Unlock()

if requestCtx.Err() != nil { // request has been cancelled (or deadline exceeded)
return
}

// Received successful response. Now cancel other requests and return immediately
requestCtxCancel()
*result = *responsePayload
log.Info("received payload from relay")
if received.CompareAndSwap(false, true) {
resultCh <- responsePayload
log.Info("received payload from relay")
} else {
log.Trace("Discarding response, already received a correct response")
}
}(relay)
}

// Wait for all requests to complete...
wg.Wait()
// Wait for the first request to complete
result := <-resultCh

// If no payload has been received from relay, log loudly about withholding!
if getPayloadResponseIsEmpty(result) {
if result == nil || getPayloadResponseIsEmpty(result) {
originRelays := types.RelayEntriesToStrings(originalBid.relays)
log.WithField("relaysWithBid", strings.Join(originRelays, ", ")).Error("no payload received from relay!")
m.respondError(w, http.StatusBadGateway, errNoSuccessfulRelayResponse.Error())
Expand Down

0 comments on commit e09f24b

Please sign in to comment.