diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json index f8b85e2c36..5eb179567d 100644 --- a/daemon/algod/api/algod.oas2.json +++ b/daemon/algod/api/algod.oas2.json @@ -2508,6 +2508,12 @@ "parameters": [ { "$ref": "#/parameters/catchpoint" + }, + { + "name": "initialize", + "description": "Specify a number of blocks which the ledger must be advanced by in order to start the catchup. This is useful for simplifying tools which support fast catchup, they can run the catchup unconditionally and the node will skip the catchup if it is not needed.", + "in": "query", + "type": "integer" } ], "responses": { diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml index b690d06958..fdcb3ea780 100644 --- a/daemon/algod/api/algod.oas3.yml +++ b/daemon/algod/api/algod.oas3.yml @@ -4302,6 +4302,14 @@ "x-algorand-format": "Catchpoint String" }, "x-algorand-format": "Catchpoint String" + }, + { + "description": "Specify a number of blocks which the ledger must be advanced by in order to start the catchup. This is useful for simplifying tools which support fast catchup, they can run the catchup unconditionally and the node will skip the catchup if it is not needed.", + "in": "query", + "name": "initialize", + "schema": { + "type": "integer" + } } ], "responses": { diff --git a/daemon/algod/api/server/v2/errors.go b/daemon/algod/api/server/v2/errors.go index 18a389edf6..d85ac7c0bc 100644 --- a/daemon/algod/api/server/v2/errors.go +++ b/daemon/algod/api/server/v2/errors.go @@ -44,6 +44,7 @@ var ( errFailedToParseCatchpoint = "failed to parse catchpoint" errFailedToAbortCatchup = "failed to abort catchup : %v" errFailedToStartCatchup = "failed to start catchup : %v" + errCatchpointWouldNotInitialize = "the node has already been initialized" errOperationNotAvailableDuringCatchup = "operation not available during catchup" errRESTPayloadZeroLength = "payload was of zero length" errRoundGreaterThanTheLatest = "given round is greater than the latest round" diff --git a/daemon/algod/api/server/v2/generated/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go index ea4246238c..e3bf12d981 100644 --- a/daemon/algod/api/server/v2/generated/model/types.go +++ b/daemon/algod/api/server/v2/generated/model/types.go @@ -1452,6 +1452,12 @@ type GetTransactionProofParamsHashtype string // GetTransactionProofParamsFormat defines parameters for GetTransactionProof. type GetTransactionProofParamsFormat string +// StartCatchupParams defines parameters for StartCatchup. +type StartCatchupParams struct { + // Initialize Specify a number of blocks which the ledger must be advanced by in order to start the catchup. This is useful for simplifying tools which support fast catchup, they can run the catchup unconditionally and the node will skip the catchup if it is not needed. + Initialize *uint64 `form:"initialize,omitempty" json:"initialize,omitempty"` +} + // GetLedgerStateDeltaForTransactionGroupParams defines parameters for GetLedgerStateDeltaForTransactionGroup. type GetLedgerStateDeltaForTransactionGroupParams struct { // Format Configures whether the response object is JSON or MessagePack encoded. If not provided, defaults to JSON. diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go index 34234f0aea..2eb060d94e 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go @@ -26,7 +26,7 @@ type ServerInterface interface { AbortCatchup(ctx echo.Context, catchpoint string) error // Starts a catchpoint catchup. // (POST /v2/catchup/{catchpoint}) - StartCatchup(ctx echo.Context, catchpoint string) error + StartCatchup(ctx echo.Context, catchpoint string, params StartCatchupParams) error // (POST /v2/shutdown) ShutdownNode(ctx echo.Context, params ShutdownNodeParams) error @@ -68,8 +68,17 @@ func (w *ServerInterfaceWrapper) StartCatchup(ctx echo.Context) error { ctx.Set(Api_keyScopes, []string{""}) + // Parameter object where we will unmarshal all parameters from the context + var params StartCatchupParams + // ------------- Optional query parameter "initialize" ------------- + + err = runtime.BindQueryParameter("form", true, false, "initialize", ctx.QueryParams(), ¶ms.Initialize) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter initialize: %s", err)) + } + // Invoke the callback with all the unmarshalled arguments - err = w.Handler.StartCatchup(ctx, catchpoint) + err = w.Handler.StartCatchup(ctx, catchpoint, params) return err } @@ -130,210 +139,212 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index 1a013b8477..996c66dfa0 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -1393,12 +1393,22 @@ func (v2 *Handlers) getPendingTransactions(ctx echo.Context, max *uint64, format } // startCatchup Given a catchpoint, it starts catching up to this catchpoint -func (v2 *Handlers) startCatchup(ctx echo.Context, catchpoint string) error { - _, _, err := ledgercore.ParseCatchpointLabel(catchpoint) +func (v2 *Handlers) startCatchup(ctx echo.Context, catchpoint string, initializeRounds uint64) error { + catchpointRound, _, err := ledgercore.ParseCatchpointLabel(catchpoint) if err != nil { return badRequest(ctx, err, errFailedToParseCatchpoint, v2.Log) } + if initializeRounds > 0 { + ledgerRound := v2.Node.LedgerForAPI().Latest() + if catchpointRound < (ledgerRound + basics.Round(initializeRounds)) { + v2.Log.Infof("Skipping catchup. Catchpoint round %d is not %d rounds ahead of the current round %d so it is not considered an initializing event.", catchpointRound, initializeRounds, ledgerRound) + return ctx.JSON(http.StatusOK, model.CatchpointStartResponse{ + CatchupMessage: errCatchpointWouldNotInitialize, + }) + } + } + // Select 200/201, or return an error var code int err = v2.Node.StartCatchup(catchpoint) @@ -1600,8 +1610,9 @@ func (v2 *Handlers) GetPendingTransactionsByAddress(ctx echo.Context, addr strin // StartCatchup Given a catchpoint, it starts catching up to this catchpoint // (POST /v2/catchup/{catchpoint}) -func (v2 *Handlers) StartCatchup(ctx echo.Context, catchpoint string) error { - return v2.startCatchup(ctx, catchpoint) +func (v2 *Handlers) StartCatchup(ctx echo.Context, catchpoint string, params model.StartCatchupParams) error { + init := nilToZero(params.Initialize) + return v2.startCatchup(ctx, catchpoint, init) } // AbortCatchup Given a catchpoint, it aborts catching up to this catchpoint diff --git a/daemon/algod/api/server/v2/test/handlers_test.go b/daemon/algod/api/server/v2/test/handlers_test.go index 48f89538bb..74b1fb2ae0 100644 --- a/daemon/algod/api/server/v2/test/handlers_test.go +++ b/daemon/algod/api/server/v2/test/handlers_test.go @@ -1308,6 +1308,10 @@ func TestSimulateTransactionMultipleGroups(t *testing.T) { } func startCatchupTest(t *testing.T, catchpoint string, nodeError error, expectedCode int) { + startCatchupTestFull(t, catchpoint, nodeError, expectedCode, 0, "") +} + +func startCatchupTestFull(t *testing.T, catchpoint string, nodeError error, expectedCode int, initRounds uint64, response string) { numAccounts := 1 numTransactions := 1 offlineAccounts := true @@ -1320,9 +1324,30 @@ func startCatchupTest(t *testing.T, catchpoint string, nodeError error, expected req := httptest.NewRequest(http.MethodPost, "/", nil) rec := httptest.NewRecorder() c := e.NewContext(req, rec) - err := handler.StartCatchup(c, catchpoint) + var err error + if initRounds != 0 { + err = handler.StartCatchup(c, catchpoint, model.StartCatchupParams{Initialize: &initRounds}) + } else { + err = handler.StartCatchup(c, catchpoint, model.StartCatchupParams{}) + } require.NoError(t, err) require.Equal(t, expectedCode, rec.Code) + if response != "" { + require.Contains(t, rec.Body.String(), response) + } +} + +func TestStartCatchupInit(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + minRoundsToInitialize := uint64(1_000_000) + + tooSmallCatchpoint := fmt.Sprintf("%d#DVFRZUYHEFKRLK5N6DNJRR4IABEVN2D6H76F3ZSEPIE6MKXMQWQA", minRoundsToInitialize-1) + startCatchupTestFull(t, tooSmallCatchpoint, nil, 200, minRoundsToInitialize, "the node has already been initialized") + + catchpointOK := fmt.Sprintf("%d#DVFRZUYHEFKRLK5N6DNJRR4IABEVN2D6H76F3ZSEPIE6MKXMQWQA", minRoundsToInitialize) + startCatchupTestFull(t, catchpointOK, nil, 201, minRoundsToInitialize, catchpointOK) } func TestStartCatchup(t *testing.T) {