From 0d4e4bb8c74baac814f7b32a87ac80a0aa7a4088 Mon Sep 17 00:00:00 2001 From: Vlad <13818348+walldiss@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:49:47 +0800 Subject: [PATCH] refactor(api/gateway) return error from gateway if header is not synced yet (#2108) ## Overview If header was not in header store, gateway would hang until client context was canceled. PR allows gateway to return an error immediately in this case. --------- Co-authored-by: rene <41963722+renaynay@users.noreply.github.com> --- api/gateway/availability.go | 15 +++++++++++++++ api/gateway/header.go | 14 ++++++++++++++ api/gateway/share.go | 18 ++++++++++++++---- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/api/gateway/availability.go b/api/gateway/availability.go index e5e53e0dba..b35593e24f 100644 --- a/api/gateway/availability.go +++ b/api/gateway/availability.go @@ -2,6 +2,7 @@ package gateway import ( "encoding/json" + "fmt" "net/http" "strconv" @@ -27,6 +28,20 @@ func (h *Handler) handleHeightAvailabilityRequest(w http.ResponseWriter, r *http return } + //TODO: change this to NetworkHead once the adjacency in the store is fixed. + head, err := h.header.LocalHead(r.Context()) + if err != nil { + writeError(w, http.StatusInternalServerError, heightAvailabilityEndpoint, err) + return + } + if headHeight := int(head.Height()); headHeight < height { + err = fmt.Errorf( + "current head local chain head: %d is lower than requested height: %d"+ + " give header sync some time and retry later", headHeight, height) + writeError(w, http.StatusServiceUnavailable, heightAvailabilityEndpoint, err) + return + } + header, err := h.header.GetByHeight(r.Context(), uint64(height)) if err != nil { writeError(w, http.StatusInternalServerError, heightAvailabilityEndpoint, err) diff --git a/api/gateway/header.go b/api/gateway/header.go index 50fb058213..88ac3b0923 100644 --- a/api/gateway/header.go +++ b/api/gateway/header.go @@ -2,6 +2,7 @@ package gateway import ( "encoding/json" + "fmt" "net/http" "strconv" @@ -69,6 +70,19 @@ func (h *Handler) performGetHeaderRequest( writeError(w, http.StatusBadRequest, endpoint, err) return nil, err } + //TODO: change this to NetworkHead once the adjacency in the store is fixed. + head, err := h.header.LocalHead(r.Context()) + if err != nil { + writeError(w, http.StatusInternalServerError, heightAvailabilityEndpoint, err) + return nil, err + } + if headHeight := int(head.Height()); headHeight < height { + err = fmt.Errorf( + "current head local chain head: %d is lower than requested height: %d"+ + " give header sync some time and retry later", headHeight, height) + writeError(w, http.StatusServiceUnavailable, endpoint, err) + return nil, err + } // perform request header, err := h.header.GetByHeight(r.Context(), uint64(height)) if err != nil { diff --git a/api/gateway/share.go b/api/gateway/share.go index caa1714eef..13903fd14b 100644 --- a/api/gateway/share.go +++ b/api/gateway/share.go @@ -4,6 +4,7 @@ import ( "context" "encoding/hex" "encoding/json" + "fmt" "net/http" "strconv" @@ -98,10 +99,19 @@ func (h *Handler) getShares(ctx context.Context, height uint64, nID namespace.ID err error header *header.ExtendedHeader ) - switch height { - case 0: - header, err = h.header.LocalHead(ctx) - default: + + //TODO: change this to NetworkHead once the adjacency in the store is fixed. + header, err = h.header.LocalHead(ctx) + if err != nil { + return nil, 0, err + } + + if height > 0 { + if storeHeight := uint64(header.Height()); storeHeight < height { + return nil, 0, fmt.Errorf( + "current head local chain head: %d is lower than requested height: %d"+ + " give header sync some time and retry later", storeHeight, height) + } header, err = h.header.GetByHeight(ctx, height) } if err != nil {