Skip to content

Commit

Permalink
api: StartFastCatchup initialize parameter (algorand#5752)
Browse files Browse the repository at this point in the history
  • Loading branch information
winder authored Sep 25, 2023
1 parent 63e1c02 commit 17871a3
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 211 deletions.
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

0 comments on commit 17871a3

Please sign in to comment.