Skip to content
New issue

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

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

Already on GitHub? # to your account

api: StartFastCatchup initialize parameter #5752

Merged
merged 3 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions daemon/algod/api/algod.oas2.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
8 changes: 8 additions & 0 deletions daemon/algod/api/algod.oas3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
1 change: 1 addition & 0 deletions daemon/algod/api/server/v2/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 6 additions & 0 deletions daemon/algod/api/server/v2/generated/model/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

423 changes: 217 additions & 206 deletions daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go

Large diffs are not rendered by default.

19 changes: 15 additions & 4 deletions daemon/algod/api/server/v2/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
27 changes: 26 additions & 1 deletion daemon/algod/api/server/v2/test/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand Down