Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(guardian-prover-health-check): add Startups, new routes for getting recent signed block #15561

Merged
merged 4 commits into from
Jan 25, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func SubcommandAction(app SubcommandApplication) cli.ActionFunc {
return err
}

slog.Info("Starting Taiko relayer application", "name", app.Name())
slog.Info("Starting Taiko guardian prover health check application", "name", app.Name())

if err := app.Start(); err != nil {
slog.Error("Starting application error", "name", app.Name(), "error", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func InitFromConfig(ctx context.Context, h *HealthChecker, cfg *Config) (err err
return err
}

startupRepo, err := repo.NewStartupRepository(db)
if err != nil {
return err
}

l1EthClient, err := ethclient.Dial(cfg.L1RPCUrl)
if err != nil {
return err
Expand Down Expand Up @@ -126,6 +131,7 @@ func InitFromConfig(ctx context.Context, h *HealthChecker, cfg *Config) (err err
EthClient: l2EthClient,
HealthCheckRepo: healthCheckRepo,
SignedBlockRepo: signedBlockRepo,
StartupRepo: startupRepo,
GuardianProvers: guardianProvers,
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package http

import (
"net/http"
"strconv"

echo "github.com/labstack/echo/v4"
"github.com/labstack/gommon/log"
)

// GetMostRecentSignedBlockByGuardianProverID
//
// returns signed block data by each guardian prover.
//
// @Summary Get most recent signed block by guardian prover ID
// @ID get-most-recent-signed-block-by-guardian-prover-ID
// @Accept json
// @Produce json
// @Success 200 {object} block
// @Router /signedBlocks/:id[get]

func (srv *Server) GetMostRecentSignedBlockByGuardianProverID(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Error("Failed to convert id to integer", "error", err)
return echo.NewHTTPError(http.StatusInternalServerError, err)
}

signedBlock, err := srv.signedBlockRepo.GetMostRecentByGuardianProverID(
id,
)

if err != nil {
log.Error("Failed to most recent block by guardian prover ID", "error", err)
return echo.NewHTTPError(http.StatusInternalServerError, err)
}

return c.JSON(http.StatusOK, signedBlock)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package http

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

"github.com/cyberhorsey/webutils/testutils"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
guardianproverhealthcheck "github.com/taikoxyz/taiko-mono/packages/guardian-prover-health-check"
)

func Test_GetMostRecentSignedBlockByGuardianProverID(t *testing.T) {
srv := newTestServer("")

for i := 0; i < 10; i++ {
err := srv.signedBlockRepo.Save(guardianproverhealthcheck.SaveSignedBlockOpts{
GuardianProverID: 1,
RecoveredAddress: "0x123",
BlockID: uint64(i),
BlockHash: "0x123",
Signature: "0x123",
})

assert.Nil(t, err)
}

tests := []struct {
name string
id string
wantStatus int
wantBodyRegexpMatches []string
}{
{
"success",
"1",
http.StatusOK,
// nolint: lll
[]string{`{"guardianProverID":1,"blockID":9,"blockHash":"0x123","signature":"0x123","recoveredAddress":"0x123","createdAt":"0001-01-01T00:00:00Z"}`},
},
{
"success",
"9839483294",
http.StatusInternalServerError,
[]string{``},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := testutils.NewUnauthenticatedRequest(
echo.GET,
fmt.Sprintf("/signedBlock/%v", tt.id),
nil,
)

rec := httptest.NewRecorder()

srv.ServeHTTP(rec, req)

testutils.AssertStatusAndBody(t, rec, tt.wantStatus, tt.wantBodyRegexpMatches)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package http

import (
"errors"
"net/http"
"strconv"

echo "github.com/labstack/echo/v4"
)

// GetMostRecentStartupByGuardianProverID
//
// returns the startup
//
// @Summary GetMostRecentStartupByGuardianProverID
// @ID get-most-recent-startup-by-guardian-prover-id
// @Accept json
// @Produce json
// @Success 200 {object} guardianproverhealthcheck.Startup
// @Router /mostRecentStartup/:id [get]

func (srv *Server) GetMostRecentStartupByGuardianProverID(
c echo.Context,
) error {
idParam := c.Param("id")
if idParam == "" {
return c.JSON(http.StatusBadRequest, errors.New("no id provided"))
}

id, err := strconv.Atoi(idParam)
if err != nil {
return c.JSON(http.StatusBadRequest, err)
}

startup, err := srv.startupRepo.GetMostRecentByGuardianProverID(c.Request().Context(), id)
if err != nil {
return c.JSON(http.StatusBadRequest, err)
}

return c.JSON(http.StatusOK, startup)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package http

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

"github.com/cyberhorsey/webutils/testutils"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
guardianproverhealthcheck "github.com/taikoxyz/taiko-mono/packages/guardian-prover-health-check"
)

func Test_GetMostRecentStartupByGuardianProverID(t *testing.T) {
srv := newTestServer("")

for i := 0; i < 5; i++ {
err := srv.startupRepo.Save(guardianproverhealthcheck.SaveStartupOpts{
GuardianProverID: 1,
GuardianProverAddress: "0x123",
Revision: "asdf",
Version: "v1.0.0",
})

assert.Nil(t, err)
}

tests := []struct {
name string
id string
wantStatus int
wantBodyRegexpMatches []string
}{
{
"success",
"1",
http.StatusOK,
// nolint: lll
[]string{`{"guardianProverID":1,"guardianProverAddress":"0x123","revision":"asdf","version":"v1.0.0","createdAt":"0001-01-01T00:00:00Z"}`},
},
{
"doesntExist",
"9839483294",
http.StatusBadRequest,
[]string{``},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := testutils.NewUnauthenticatedRequest(
echo.GET,
fmt.Sprintf("/mostRecentStartup/%v", tt.id),
nil,
)

rec := httptest.NewRecorder()

srv.ServeHTTP(rec, req)

testutils.AssertStatusAndBody(t, rec, tt.wantStatus, tt.wantBodyRegexpMatches)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package http

import (
"errors"
"net/http"
"strconv"

echo "github.com/labstack/echo/v4"
)

// GetStartupsByGuardianProverID
//
// returns a paginated list of startups by guardian prover iD
//
// @Summary Get startups by guardian prover ID
// @ID get-startups-by-guardian-prover-id
// @Accept json
// @Produce json
// @Success 200 {object} paginate.Page
// @Router /startups [get]
// @Param id string true "guardian prover ID with which to query"

func (srv *Server) GetStartupsByGuardianProverID(c echo.Context) error {
idParam := c.Param("id")
if idParam == "" {
return c.JSON(http.StatusBadRequest, errors.New("no id provided"))
}

id, err := strconv.Atoi(idParam)
if err != nil {
return c.JSON(http.StatusBadRequest, err)
}

page, err := srv.startupRepo.GetByGuardianProverID(c.Request().Context(), c.Request(), id)
if err != nil {
return c.JSON(http.StatusBadRequest, err)
}

return c.JSON(http.StatusOK, page)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package http

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

"github.com/cyberhorsey/webutils/testutils"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
guardianproverhealthcheck "github.com/taikoxyz/taiko-mono/packages/guardian-prover-health-check"
)

func Test_GetStartupsByGuardianProverID(t *testing.T) {
srv := newTestServer("")

err := srv.startupRepo.Save(guardianproverhealthcheck.SaveStartupOpts{
GuardianProverID: 1,
GuardianProverAddress: "0x123",
Revision: "asdf",
Version: "v1.0.0",
})

assert.Nil(t, err)

assert.Equal(t, nil, err)

tests := []struct {
name string
id string
wantStatus int
wantBodyRegexpMatches []string
}{
{
"success",
"1",
http.StatusOK,
// nolint: lll
[]string{`{"items":\[{"guardianProverID":1,"guardianProverAddress":"0x123","revision":"asdf","version":"v1.0.0","createdAt":"0001-01-01T00:00:00Z"}\],"page":0,"size":0,"max_page":0,"total_pages":0,"total":0,"last":false,"first":false,"visible":0}`},
},
{
"successDoesntExist",
"9839483294",
http.StatusOK,
[]string{``},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := testutils.NewUnauthenticatedRequest(
echo.GET,
fmt.Sprintf("/startups/%v", tt.id),
nil,
)

rec := httptest.NewRecorder()

srv.ServeHTTP(rec, req)

testutils.AssertStatusAndBody(t, rec, tt.wantStatus, tt.wantBodyRegexpMatches)
})
}
}
Loading
Loading