From cf35c49a2e964ec35de760b905129d91ed14f63a Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 14 Sep 2023 20:46:14 +0800 Subject: [PATCH 1/6] feat: use httptest.Server to simplify the prover web server test code --- prover/server/api_test.go | 55 +++++++++++++++------------- prover/server/server_test.go | 71 ++++++++---------------------------- 2 files changed, 45 insertions(+), 81 deletions(-) diff --git a/prover/server/api_test.go b/prover/server/api_test.go index 32af6dacc..89b18c8ba 100644 --- a/prover/server/api_test.go +++ b/prover/server/api_test.go @@ -3,48 +3,51 @@ package server import ( "crypto/rand" "encoding/json" + "io" "net/http" - "net/http/httptest" + "strings" "time" - "github.com/cyberhorsey/webutils/testutils" "github.com/ethereum/go-ethereum/common" - "github.com/labstack/echo/v4" "github.com/taikoxyz/taiko-client/bindings/encoding" ) func (s *ProverServerTestSuite) TestGetStatusSuccess() { - rec := s.sendReq("/status") - s.Equal(http.StatusOK, rec.Code) + resp := s.sendReq("/status") + s.Equal(http.StatusOK, resp.StatusCode) status := new(Status) - s.Nil(json.Unmarshal(rec.Body.Bytes(), &status)) - s.Equal(s.srv.minProofFee.Uint64(), status.MinProofFee) - s.Equal(uint64(s.srv.maxExpiry.Seconds()), status.MaxExpiry) + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) + s.NoError(err) + s.NoError(json.Unmarshal(b, &status)) + + s.Equal(s.ps.minProofFee.Uint64(), status.MinProofFee) + s.Equal(uint64(s.ps.maxExpiry.Seconds()), status.MaxExpiry) s.Greater(status.CurrentCapacity, uint64(0)) } func (s *ProverServerTestSuite) TestProposeBlockSuccess() { - rec := httptest.NewRecorder() - - s.srv.ServeHTTP(rec, testutils.NewUnauthenticatedRequest( - echo.POST, - "/assignment", - &encoding.ProposeBlockData{ - Fee: common.Big256, - Expiry: uint64(time.Now().Add(time.Minute).Unix()), - Input: encoding.TaikoL1BlockMetadataInput{ - Proposer: common.BytesToAddress(randomHash().Bytes()), - TxListHash: randomHash(), - TxListByteStart: common.Big0, - TxListByteEnd: common.Big0, - CacheTxListInfo: false, - }, + data, err := json.Marshal(encoding.ProposeBlockData{ + Fee: common.Big256, + Expiry: uint64(time.Now().Add(time.Minute).Unix()), + Input: encoding.TaikoL1BlockMetadataInput{ + Proposer: common.BytesToAddress(randomHash().Bytes()), + TxListHash: randomHash(), + TxListByteStart: common.Big0, + TxListByteEnd: common.Big0, + CacheTxListInfo: false, }, - )) - - testutils.AssertStatusAndBody(s.T(), rec, http.StatusOK, []string{"signedPayload"}) + }) + s.NoError(err) + resp, err := http.Post(s.ws.URL+"/assignment", "application/json", strings.NewReader(string(data))) + s.NoError(err) + s.Equal(http.StatusOK, resp.StatusCode) + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) + s.NoError(err) + s.Contains(string(b), "signedPayload") } // randomHash generates a random blob of data and returns it as a hash. diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 263bdc6cc..58bf07f3b 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -1,36 +1,30 @@ package server import ( - "context" - "fmt" "net/http" "net/http/httptest" - "net/url" "os" "testing" "time" - "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/go-resty/resty/v2" echo "github.com/labstack/echo/v4" - "github.com/phayes/freeport" "github.com/stretchr/testify/suite" capacity "github.com/taikoxyz/taiko-client/prover/capacity_manager" ) type ProverServerTestSuite struct { suite.Suite - srv *ProverServer + ps *ProverServer + ws *httptest.Server // web server } func (s *ProverServerTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) - s.Nil(err) + s.NoError(err) - srv := &ProverServer{ + p := &ProverServer{ echo: echo.New(), proverPrivateKey: l1ProverPrivKey, minProofFee: common.Big1, @@ -38,64 +32,31 @@ func (s *ProverServerTestSuite) SetupTest() { capacityManager: capacity.New(1024), } - srv.echo.HideBanner = true - srv.configureMiddleware() - srv.configureRoutes() - - s.srv = srv + p.echo.HideBanner = true + p.configureMiddleware() + p.configureRoutes() + s.ps = p + s.ws = httptest.NewServer(p.echo) } func (s *ProverServerTestSuite) TestHealth() { - s.Equal(http.StatusOK, s.sendReq("/healthz").Code) + s.Equal(http.StatusOK, s.sendReq("/healthz").StatusCode) } func (s *ProverServerTestSuite) TestRoot() { - s.Equal(http.StatusOK, s.sendReq("/").Code) -} - -func (s *ProverServerTestSuite) TestStartShutdown() { - port, err := freeport.GetFreePort() - s.Nil(err) - - url, err := url.Parse(fmt.Sprintf("http://localhost:%v", port)) - s.Nil(err) - - go func() { - if err := s.srv.Start(fmt.Sprintf(":%v", port)); err != nil { - log.Error("Failed to start prover server", "error", err) - } - }() - - // Wait till the server fully started. - s.Nil(backoff.Retry(func() error { - res, err := resty.New().R().Get(url.String() + "/healthz") - if err != nil { - return err - } - if !res.IsSuccess() { - return fmt.Errorf("invalid response status code: %d", res.StatusCode()) - } - - return nil - }, backoff.NewExponentialBackOff())) - - s.Nil(s.srv.Shutdown(context.Background())) + s.Equal(http.StatusOK, s.sendReq("/").StatusCode) } func (s *ProverServerTestSuite) TearDownTest() { - s.Nil(s.srv.Shutdown(context.Background())) + s.ws.Close() } func TestProverServerTestSuite(t *testing.T) { suite.Run(t, new(ProverServerTestSuite)) } -func (s *ProverServerTestSuite) sendReq(path string) *httptest.ResponseRecorder { - req, err := http.NewRequest(echo.GET, path, nil) - s.Nil(err) - rec := httptest.NewRecorder() - - s.srv.ServeHTTP(rec, req) - - return rec +func (s *ProverServerTestSuite) sendReq(path string) *http.Response { + resp, err := http.Get(s.ws.URL + path) + s.NoError(err) + return resp } From 84da6c155dc1e620187567cce3ad8af8ea955155 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 14 Sep 2023 21:21:03 +0800 Subject: [PATCH 2/6] feat: delete useless code --- prover/server/server.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/prover/server/server.go b/prover/server/server.go index 78b4add34..73dab9a56 100644 --- a/prover/server/server.go +++ b/prover/server/server.go @@ -73,11 +73,6 @@ func (srv *ProverServer) Shutdown(ctx context.Context) error { return srv.echo.Shutdown(ctx) } -// ServeHTTP implements the `http.Handler` interface which serves HTTP requests. -func (srv *ProverServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { - srv.echo.ServeHTTP(w, r) -} - // Health endpoints for probes. func (srv *ProverServer) Health(c echo.Context) error { return c.NoContent(http.StatusOK) From d221e917a1e0fc15010773aa8f0b2b31ff4fa13c Mon Sep 17 00:00:00 2001 From: RogerLamTd Date: Mon, 18 Sep 2023 11:44:15 -0700 Subject: [PATCH 3/6] use .Nil to keep consistent with other tests --- prover/server/api_test.go | 10 +++++----- prover/server/server_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/prover/server/api_test.go b/prover/server/api_test.go index 89b18c8ba..866c543f7 100644 --- a/prover/server/api_test.go +++ b/prover/server/api_test.go @@ -20,8 +20,8 @@ func (s *ProverServerTestSuite) TestGetStatusSuccess() { defer resp.Body.Close() b, err := io.ReadAll(resp.Body) - s.NoError(err) - s.NoError(json.Unmarshal(b, &status)) + s.Nil(err) + s.Nil(json.Unmarshal(b, &status)) s.Equal(s.ps.minProofFee.Uint64(), status.MinProofFee) s.Equal(uint64(s.ps.maxExpiry.Seconds()), status.MaxExpiry) @@ -40,13 +40,13 @@ func (s *ProverServerTestSuite) TestProposeBlockSuccess() { CacheTxListInfo: false, }, }) - s.NoError(err) + s.Nil(err) resp, err := http.Post(s.ws.URL+"/assignment", "application/json", strings.NewReader(string(data))) - s.NoError(err) + s.Nil(err) s.Equal(http.StatusOK, resp.StatusCode) defer resp.Body.Close() b, err := io.ReadAll(resp.Body) - s.NoError(err) + s.Nil(err) s.Contains(string(b), "signedPayload") } diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 58bf07f3b..5af5008ff 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -22,7 +22,7 @@ type ProverServerTestSuite struct { func (s *ProverServerTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) - s.NoError(err) + s.Nil(err) p := &ProverServer{ echo: echo.New(), @@ -57,6 +57,6 @@ func TestProverServerTestSuite(t *testing.T) { func (s *ProverServerTestSuite) sendReq(path string) *http.Response { resp, err := http.Get(s.ws.URL + path) - s.NoError(err) + s.Nil(err) return resp } From 9fd2b58dd3ccc86ac3fc3c722e9b232dd8f6d211 Mon Sep 17 00:00:00 2001 From: RogerLamTd Date: Mon, 18 Sep 2023 12:55:44 -0700 Subject: [PATCH 4/6] restore start and shutdown test --- prover/server/server_test.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 5af5008ff..4ee90ad91 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -1,15 +1,22 @@ package server import ( + "context" + "fmt" "net/http" "net/http/httptest" + "net/url" "os" "testing" "time" + "github.com/cenkalti/backoff" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/go-resty/resty/v2" echo "github.com/labstack/echo/v4" + "github.com/phayes/freeport" "github.com/stretchr/testify/suite" capacity "github.com/taikoxyz/taiko-client/prover/capacity_manager" ) @@ -47,6 +54,35 @@ func (s *ProverServerTestSuite) TestRoot() { s.Equal(http.StatusOK, s.sendReq("/").StatusCode) } +func (s *ProverServerTestSuite) TestStartShutdown() { + port, err := freeport.GetFreePort() + s.Nil(err) + + url, err := url.Parse(fmt.Sprintf("http://localhost:%v", port)) + s.Nil(err) + + go func() { + if err := s.ps.Start(fmt.Sprintf(":%v", port)); err != nil { + log.Error("Failed to start prover server", "error", err) + } + }() + + // Wait till the server fully started. + s.Nil(backoff.Retry(func() error { + res, err := resty.New().R().Get(url.String() + "/healthz") + if err != nil { + return err + } + if !res.IsSuccess() { + return fmt.Errorf("invalid response status code: %d", res.StatusCode()) + } + + return nil + }, backoff.NewExponentialBackOff())) + + s.Nil(s.ps.Shutdown(context.Background())) +} + func (s *ProverServerTestSuite) TearDownTest() { s.ws.Close() } From ef9d7e7c06752af68285b4485672957b0dbc44f9 Mon Sep 17 00:00:00 2001 From: RogerLamTd Date: Mon, 18 Sep 2023 13:00:00 -0700 Subject: [PATCH 5/6] fix import --- prover/server/server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 4ee90ad91..5db942acc 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/cenkalti/backoff" + "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" From 8a447088524f50c3748f70dd5495c447123dc21c Mon Sep 17 00:00:00 2001 From: David Date: Wed, 20 Sep 2023 10:41:44 +0800 Subject: [PATCH 6/6] fix(proposer): fix proposing fee initialization (#396) --- proposer/prover_selector/eth_fee_eoa_selector.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposer/prover_selector/eth_fee_eoa_selector.go b/proposer/prover_selector/eth_fee_eoa_selector.go index e5454e56e..bd091d36b 100644 --- a/proposer/prover_selector/eth_fee_eoa_selector.go +++ b/proposer/prover_selector/eth_fee_eoa_selector.go @@ -96,7 +96,7 @@ func (s *ETHFeeEOASelector) AssignProver( // If we do not find a prover, we can increase the fee up to a point, or give up. for i := 0; i < int(s.proposalFeeIterations); i++ { var ( - fee = s.feeBase + fee = new(big.Int).Set(s.feeBase) expiry = uint64(time.Now().Add(s.proposalExpiry).Unix()) )