Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eth, consensus/bor: handle 503 status code in heimdall client #1023

Merged
merged 4 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions consensus/bor/heimdall/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var (
ErrNotSuccessfulResponse = errors.New("error while fetching data from Heimdall")
ErrNotInRejectedList = errors.New("milestoneID doesn't exist in rejected list")
ErrNotInMilestoneList = errors.New("milestoneID doesn't exist in Heimdall")
ErrServiceUnavailable = errors.New("service unavailable")
)

const (
Expand Down Expand Up @@ -277,10 +278,18 @@ func FetchWithRetry[T any](ctx context.Context, client http.Client, url *url.URL
return result, nil
}

// 503 (Service Unavailable) is thrown when an endpoint isn't activated
// yet in heimdall. E.g. when the hardfork hasn't hit yet but heimdall
// is upgraded.
if errors.Is(err, ErrServiceUnavailable) {
log.Debug("Heimdall service unavailable at the moment", "path", url.Path, "error", err)
return nil, err
}

// attempt counter
attempt := 1

log.Warn("an error while trying fetching from Heimdall", "attempt", attempt, "error", err)
log.Warn("an error while trying fetching from Heimdall", "path", url.Path, "attempt", attempt, "error", err)

// create a new ticker for retrying the request
ticker := time.NewTicker(retryCall)
Expand All @@ -307,9 +316,14 @@ retryLoop:
request = &Request{client: client, url: url, start: time.Now()}
result, err = Fetch[T](ctx, request)

if errors.Is(err, ErrServiceUnavailable) {
log.Debug("Heimdall service unavailable at the moment", "path", url.Path, "error", err)
return nil, err
}

if err != nil {
if attempt%logEach == 0 {
log.Warn("an error while trying fetching from Heimdall", "attempt", attempt, "error", err)
log.Warn("an error while trying fetching from Heimdall", "path", url.Path, "attempt", attempt, "error", err)
}

continue retryLoop
Expand Down Expand Up @@ -426,6 +440,10 @@ func internalFetch(ctx context.Context, client http.Client, u *url.URL) ([]byte,

defer res.Body.Close()

if res.StatusCode == http.StatusServiceUnavailable {
return nil, fmt.Errorf("%w: response code %d", ErrServiceUnavailable, res.StatusCode)
}

// check status code
if res.StatusCode != 200 && res.StatusCode != 204 {
return nil, fmt.Errorf("%w: response code %d", ErrNotSuccessfulResponse, res.StatusCode)
Expand Down
16 changes: 15 additions & 1 deletion eth/handler_bor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/bor"
"github.com/ethereum/go-ethereum/consensus/bor/heimdall"
"github.com/ethereum/go-ethereum/log"
)

Expand Down Expand Up @@ -63,6 +64,11 @@ func (h *ethHandler) fetchWhitelistMilestone(ctx context.Context, bor *bor.Bor,

// fetch latest milestone
milestone, err := bor.HeimdallClient.FetchMilestone(ctx)
if errors.Is(err, heimdall.ErrServiceUnavailable) {
log.Debug("Failed to fetch latest milestone for whitelisting", "err", err)
return num, hash, errMilestone
}

if err != nil {
log.Error("Failed to fetch latest milestone for whitelisting", "err", err)
return num, hash, errMilestone
Expand Down Expand Up @@ -92,9 +98,13 @@ func (h *ethHandler) fetchNoAckMilestone(ctx context.Context, bor *bor.Bor) (str

// fetch latest milestone
milestoneID, err := bor.HeimdallClient.FetchLastNoAckMilestone(ctx)
if errors.Is(err, heimdall.ErrServiceUnavailable) {
log.Debug("Failed to fetch latest no-ack milestone", "err", err)
return milestoneID, errMilestone
}

if err != nil {
log.Error("Failed to fetch latest no-ack milestone", "err", err)

return milestoneID, errMilestone
}

Expand All @@ -104,6 +114,10 @@ func (h *ethHandler) fetchNoAckMilestone(ctx context.Context, bor *bor.Bor) (str
func (h *ethHandler) fetchNoAckMilestoneByID(ctx context.Context, bor *bor.Bor, milestoneID string) error {
// fetch latest milestone
err := bor.HeimdallClient.FetchNoAckMilestone(ctx, milestoneID)
if errors.Is(err, heimdall.ErrServiceUnavailable) {
log.Debug("Failed to fetch no-ack milestone by ID", "err", err)
return err
}

// fixme: handle different types of errors
if errors.Is(err, ErrNotInRejectedList) {
Expand Down
Loading