From c85566de0eac246944c553383f7c074bd6bccefc Mon Sep 17 00:00:00 2001 From: Tsachi Herman Date: Fri, 3 Jan 2020 13:20:58 -0500 Subject: [PATCH] Avoid waiting for block that won't be reached due to unsupported protocol upgrade. --- daemon/algod/api/server/v1/handlers/errors.go | 1 + .../algod/api/server/v1/handlers/handlers.go | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/daemon/algod/api/server/v1/handlers/errors.go b/daemon/algod/api/server/v1/handlers/errors.go index dafe63fe18..3013d42a3d 100644 --- a/daemon/algod/api/server/v1/handlers/errors.go +++ b/daemon/algod/api/server/v1/handlers/errors.go @@ -42,4 +42,5 @@ var ( errTransactionNotFound = "couldn't find the required transaction in the required range" errServiceShuttingDown = "operation aborted as server is shutting down" errUnknownTransactionType = "found a transaction with an unknown type" + errRequestedRoundInUnsupportedRound = "requested round would reach only after the protocol upgrade which isn't supported" ) diff --git a/daemon/algod/api/server/v1/handlers/handlers.go b/daemon/algod/api/server/v1/handlers/handlers.go index 5f6cf70970..cc24a89ff7 100644 --- a/daemon/algod/api/server/v1/handlers/handlers.go +++ b/daemon/algod/api/server/v1/handlers/handlers.go @@ -418,12 +418,29 @@ func WaitForBlock(ctx lib.ReqContext, w http.ResponseWriter, r *http.Request) { return } + ledger := ctx.Node.Ledger() + latestBlkHdr, err := ledger.BlockHdr(ledger.Latest()) + if err != nil { + lib.ErrorResponse(w, http.StatusInternalServerError, err, errFailedRetrievingNodeStatus, ctx.Log) + return + } + if latestBlkHdr.NextProtocol != "" { + if _, nextProtocolSupported := config.Consensus[latestBlkHdr.NextProtocol]; !nextProtocolSupported { + // see if the desired protocol switch is expect to happen before or after the above point. + if latestBlkHdr.NextProtocolSwitchOn <= basics.Round(queryRound+1) { + // we would never reach to this round, since this round would happen after the (unsupported) protocol upgrade. + lib.ErrorResponse(w, http.StatusBadRequest, err, errRequestedRoundInUnsupportedRound, ctx.Log) + return + } + } + } + select { case <-ctx.Shutdown: lib.ErrorResponse(w, http.StatusInternalServerError, err, errServiceShuttingDown, ctx.Log) return case <-time.After(1 * time.Minute): - case <-ctx.Node.Ledger().Wait(basics.Round(queryRound + 1)): + case <-ledger.Wait(basics.Round(queryRound + 1)): } nodeStatus, err := nodeStatus(ctx.Node)