From da9eb21e12df78076a308d2b28ab5fdc725bbe16 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 31 Aug 2023 15:15:32 +0800 Subject: [PATCH 01/25] feat(proposer): introduce `ProverSelector` interface --- driver/chain_syncer/calldata/syncer_test.go | 10 +- driver/chain_syncer/chain_syncer_test.go | 10 +- driver/driver_test.go | 9 +- proposer/config.go | 22 +- proposer/proposer.go | 218 ++------------- proposer/proposer_test.go | 36 +-- proposer/prover_selector/eth_fee_selector.go | 254 ++++++++++++++++++ proposer/prover_selector/interface.go | 17 ++ .../valid_proof_submitter_test.go | 10 +- prover/prover_test.go | 3 +- testutils/helper.go | 17 +- 11 files changed, 351 insertions(+), 255 deletions(-) create mode 100644 proposer/prover_selector/eth_fee_selector.go create mode 100644 proposer/prover_selector/interface.go diff --git a/driver/chain_syncer/calldata/syncer_test.go b/driver/chain_syncer/calldata/syncer_test.go index fb6ac7ace..e1ff7de3e 100644 --- a/driver/chain_syncer/calldata/syncer_test.go +++ b/driver/chain_syncer/calldata/syncer_test.go @@ -2,9 +2,9 @@ package calldata import ( "context" - "fmt" "math/big" "math/rand" + "net/url" "os" "testing" "time" @@ -32,8 +32,6 @@ type CalldataSyncerTestSuite struct { func (s *CalldataSyncerTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() - port := testutils.RandomPort() - state, err := state.New(context.Background(), s.RpcClient) s.Nil(err) @@ -51,6 +49,8 @@ func (s *CalldataSyncerTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests + localProverEndpoint := testutils.LocalRandomProverEndpoint() + s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), @@ -62,12 +62,12 @@ func (s *CalldataSyncerTestSuite) SetupTest() { ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []string{fmt.Sprintf("http://localhost:%v", port)}, + ProverEndpoints: []*url.URL{localProverEndpoint}, BlockProposalFee: big.NewInt(1000), BlockProposalFeeIterations: 3, }))) - srv, cancel, err := testutils.HTTPServer(&s.ClientTestSuite, port) + srv, cancel, err := testutils.HTTPServer(&s.ClientTestSuite, localProverEndpoint) s.Nil(err) s.srv = srv diff --git a/driver/chain_syncer/chain_syncer_test.go b/driver/chain_syncer/chain_syncer_test.go index 39cd092cc..12299017c 100644 --- a/driver/chain_syncer/chain_syncer_test.go +++ b/driver/chain_syncer/chain_syncer_test.go @@ -2,8 +2,8 @@ package chainSyncer import ( "context" - "fmt" "math/big" + "net/url" "os" "testing" @@ -33,8 +33,6 @@ type ChainSyncerTestSuite struct { func (s *ChainSyncerTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() - port := testutils.RandomPort() - state, err := state.New(context.Background(), s.RpcClient) s.Nil(err) @@ -53,6 +51,8 @@ func (s *ChainSyncerTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests + localProverEndpoint := testutils.LocalRandomProverEndpoint() + s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), @@ -64,12 +64,12 @@ func (s *ChainSyncerTestSuite) SetupTest() { ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []string{fmt.Sprintf("http://localhost:%v", port)}, + ProverEndpoints: []*url.URL{localProverEndpoint}, BlockProposalFee: big.NewInt(1000), BlockProposalFeeIterations: 3, }))) - srv, srvCancel, err := testutils.HTTPServer(&s.ClientTestSuite, port) + srv, srvCancel, err := testutils.HTTPServer(&s.ClientTestSuite, localProverEndpoint) s.Nil(err) s.srv = srv diff --git a/driver/driver_test.go b/driver/driver_test.go index 925f32702..56d049057 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -2,8 +2,8 @@ package driver import ( "context" - "fmt" "math/big" + "net/url" "os" "testing" "time" @@ -30,8 +30,6 @@ type DriverTestSuite struct { func (s *DriverTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() - port := testutils.RandomPort() - // Init driver jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) s.Nil(err) @@ -54,6 +52,7 @@ func (s *DriverTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) + localPorverEndpoint := testutils.LocalRandomProverEndpoint() proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), p, (&proposer.Config{ @@ -67,13 +66,13 @@ func (s *DriverTestSuite) SetupTest() { ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []string{fmt.Sprintf("http://localhost:%v", port)}, + ProverEndpoints: []*url.URL{localPorverEndpoint}, BlockProposalFee: big.NewInt(1000), BlockProposalFeeIterations: 3, }))) s.p = p - srv, srvCancel, err := testutils.HTTPServer(&s.ClientTestSuite, port) + srv, srvCancel, err := testutils.HTTPServer(&s.ClientTestSuite, localPorverEndpoint) s.Nil(err) s.srv = srv diff --git a/proposer/config.go b/proposer/config.go index 7da3c0276..34428ef7c 100644 --- a/proposer/config.go +++ b/proposer/config.go @@ -4,6 +4,7 @@ import ( "crypto/ecdsa" "fmt" "math/big" + "net/url" "strings" "time" @@ -33,9 +34,9 @@ type Config struct { RPCTimeout *time.Duration WaitReceiptTimeout time.Duration ProposeBlockTxGasTipCap *big.Int - ProverEndpoints []string + ProverEndpoints []*url.URL BlockProposalFee *big.Int - BlockProposalFeeIncreasePercentage uint64 + BlockProposalFeeIncreasePercentage *big.Int BlockProposalFeeIterations uint64 } @@ -108,9 +109,14 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { proposeBlockTxGasTipCap = new(big.Int).SetUint64(c.Uint64(flags.ProposeBlockTxGasTipCap.Name)) } - var proverEndpoints []string - - proverEndpoints = append(proverEndpoints, strings.Split(c.String(flags.ProverEndpoints.Name), ",")...) + var proverEndpoints []*url.URL + for _, e := range strings.Split(c.String(flags.ProverEndpoints.Name), ",") { + endpoint, err := url.Parse(e) + if err != nil { + return nil, err + } + proverEndpoints = append(proverEndpoints, endpoint) + } blockProposalFee, ok := new(big.Int).SetString(c.String(flags.BlockProposalFee.Name), 10) if !ok { @@ -138,7 +144,9 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { ProposeBlockTxGasTipCap: proposeBlockTxGasTipCap, ProverEndpoints: proverEndpoints, BlockProposalFee: blockProposalFee, - BlockProposalFeeIncreasePercentage: c.Uint64(flags.BlockProposalFeeIncreasePercentage.Name), - BlockProposalFeeIterations: c.Uint64(flags.BlockProposalFeeIterations.Name), + BlockProposalFeeIncreasePercentage: new(big.Int).SetUint64( + c.Uint64(flags.BlockProposalFeeIncreasePercentage.Name), + ), + BlockProposalFeeIterations: c.Uint64(flags.BlockProposalFeeIterations.Name), }, nil } diff --git a/proposer/proposer.go b/proposer/proposer.go index f3b147767..6e5c311a0 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -1,16 +1,12 @@ package proposer import ( - "bytes" "context" "crypto/ecdsa" - "encoding/json" "errors" "fmt" - "io" "math/big" "math/rand" - "net/http" "strings" "sync" "time" @@ -27,23 +23,19 @@ import ( "github.com/taikoxyz/taiko-client/bindings/encoding" "github.com/taikoxyz/taiko-client/metrics" "github.com/taikoxyz/taiko-client/pkg/rpc" + selector "github.com/taikoxyz/taiko-client/proposer/prover_selector" "github.com/urfave/cli/v2" "golang.org/x/sync/errgroup" ) var ( errNoNewTxs = errors.New("no new transactions") - errUnableToFindProver = errors.New("unable to find prover") maxSendProposeBlockTxRetry = 10 retryInterval = 12 * time.Second + proverAssignmentTimeout = 90 * time.Minute requestProverServerTimeout = 12 * time.Second ) -type proposeBlockResponse struct { - SignedPayload []byte `json:"signedPayload"` - Prover common.Address `json:"prover"` -} - // Proposer keep proposing new transactions from L2 execution engine's tx pool at a fixed interval. type Proposer struct { // RPC clients @@ -64,15 +56,13 @@ type Proposer struct { proposeBlockTxGasLimit *uint64 txReplacementTipMultiplier uint64 proposeBlockTxGasTipCap *big.Int - proverEndpoints []string + + // Prover selector + proverSelector selector.ProverSelector // Protocol configurations protocolConfigs *bindings.TaikoDataConfig - // Block proposal fee configurations - blockProposalFee *big.Int - blockProposalFeeIncreasePercentage uint64 - // Only for testing purposes CustomProposeOpHook func() error AfterCommitHook func() error @@ -111,9 +101,6 @@ func InitFromConfig(ctx context.Context, p *Proposer, cfg *Config) (err error) { p.proposeBlockTxGasTipCap = cfg.ProposeBlockTxGasTipCap p.ctx = ctx p.waitReceiptTimeout = cfg.WaitReceiptTimeout - p.proverEndpoints = cfg.ProverEndpoints - p.blockProposalFee = cfg.BlockProposalFee - p.blockProposalFeeIncreasePercentage = cfg.BlockProposalFeeIncreasePercentage p.cfg = cfg // RPC clients @@ -138,6 +125,20 @@ func InitFromConfig(ctx context.Context, p *Proposer, cfg *Config) (err error) { log.Info("Protocol configs", "configs", p.protocolConfigs) + if p.proverSelector, err = selector.NewETHFeeSelector( + &protocolConfigs, + p.rpc, + cfg.TaikoL1Address, + cfg.BlockProposalFee, + cfg.BlockProposalFeeIncreasePercentage, + cfg.ProverEndpoints, + cfg.BlockProposalFeeIterations, + proverAssignmentTimeout, + requestProverServerTimeout, + ); err != nil { + return err + } + return nil } @@ -410,7 +411,7 @@ func (p *Proposer) ProposeTxList( txNum uint, nonce *uint64, ) error { - assignment, fee, err := p.assignProver(ctx, meta) + assignment, fee, err := p.proverSelector.AssignProver(ctx, meta) if err != nil { return err } @@ -494,185 +495,6 @@ func (p *Proposer) updateProposingTicker() { p.proposingTimer = time.NewTimer(duration) } -// assignProver attempts to find a prover who wants to win the block. -// if no provers want to do it for the price we set, we increase the price, and try again. -func (p *Proposer) assignProver( - ctx context.Context, - meta *encoding.TaikoL1BlockMetadataInput, -) ([]byte, *big.Int, error) { - initialFee := p.blockProposalFee - - percentBig := big.NewInt(int64(p.blockProposalFeeIncreasePercentage)) - - // iterate over each configured endpoint, and see if someone wants to accept your block. - // if it is denied, we continue on to the next endpoint. - // if we do not find a prover, we can increase the fee up to a point, or give up. - // TODO(jeff): we loop 3 times, this should be a config var - for i := 0; i < int(p.cfg.BlockProposalFeeIterations); i++ { - fee := new(big.Int).Set(initialFee) - - // increase fee on each failed loop - if i > 0 { - cumulativePercent := new(big.Int).Mul(percentBig, big.NewInt(int64(i))) - increase := new(big.Int).Mul(fee, cumulativePercent) - increase.Div(increase, big.NewInt(100)) - fee.Add(fee, increase) - } - - expiry := uint64(time.Now().Add(90 * time.Minute).Unix()) - - proposeBlockReq := &encoding.ProposeBlockData{ - Expiry: expiry, - Input: *meta, - Fee: fee, - } - - jsonBody, err := json.Marshal(proposeBlockReq) - if err != nil { - return nil, nil, err - } - - r := bytes.NewReader(jsonBody) - - for _, endpoint := range p.proverEndpoints { - log.Info( - "Attempting to assign prover", - "endpoint", endpoint, - "fee", fee.String(), - "expiry", expiry, - ) - client := &http.Client{Timeout: requestProverServerTimeout} - - req, err := http.NewRequestWithContext( - ctx, - "POST", - fmt.Sprintf("%v/%v", endpoint, "proposeBlock"), - r, - ) - if err != nil { - log.Error("Init http request error", "endpoint", endpoint, "err", err) - continue - } - req.Header.Add("Content-Type", "application/json") - - res, err := client.Do(req) - if err != nil { - log.Error("Request prover server error", "endpoint", endpoint, "err", err) - continue - } - - if res.StatusCode != http.StatusOK { - log.Info( - "Prover rejected request to assign block", - "endpoint", endpoint, - "fee", fee.String(), - "expiry", expiry, - ) - continue - } - - resBody, err := io.ReadAll(res.Body) - if err != nil { - log.Error("Read response body error", "endpoint", endpoint, "err", err) - continue - } - - resp := &proposeBlockResponse{} - if err := json.Unmarshal(resBody, resp); err != nil { - log.Error("Unmarshal response body error", "endpoint", endpoint, "err", err) - continue - } - - // ensure prover in response is the same as the one recovered - // from the signature - encodedBlockData, err := encoding.EncodeProposeBlockData(proposeBlockReq) - if err != nil { - log.Error("Encode block data error", "endpoint", endpoint, "error", err) - continue - } - - pubKey, err := crypto.SigToPub(crypto.Keccak256Hash(encodedBlockData).Bytes(), resp.SignedPayload) - if err != nil { - log.Error("Failed to get public key from signature", "endpoint", endpoint, "error", err) - continue - } - - if crypto.PubkeyToAddress(*pubKey).Hex() != resp.Prover.Hex() { - log.Info( - "Assigned prover signature did not recover to provided prover address", - "endpoint", endpoint, - "recoveredAddress", crypto.PubkeyToAddress(*pubKey).Hex(), - "providedProver", resp.Prover.Hex(), - ) - continue - } - - // make sure the prover has the necessary balance either in TaikoL1 token balances - // or, if not, check allowance, as contract will attempt to burn directly after - // if it doesnt have the available tokenbalance in-contract. - taikoTokenBalance, err := p.rpc.TaikoL1.GetTaikoTokenBalance(&bind.CallOpts{Context: ctx}, resp.Prover) - if err != nil { - log.Error( - "Get taiko token balance error", - "endpoint", endpoint, - "providedProver", resp.Prover.Hex(), - "error", err, - ) - continue - } - - if p.protocolConfigs.ProofBond.Cmp(taikoTokenBalance) > 0 { - // check allowance on taikotoken contract - allowance, err := p.rpc.TaikoToken.Allowance(&bind.CallOpts{Context: ctx}, resp.Prover, p.cfg.TaikoL1Address) - if err != nil { - log.Error( - "Get taiko token allowance error", - "endpoint", endpoint, - "providedProver", resp.Prover.Hex(), - "error", err, - ) - continue - } - - if p.protocolConfigs.ProofBond.Cmp(allowance) > 0 { - log.Info( - "Assigned prover does not have required on-chain token balance or allowance", - "endpoint", endpoint, - "providedProver", resp.Prover.Hex(), - "taikoTokenBalance", taikoTokenBalance.String(), - "allowance", allowance.String(), - "proofBond", p.protocolConfigs.ProofBond, - "requiredFee", fee.String(), - ) - continue - } - } - - // convert signature to one solidity can recover by adding 27 to 65th byte - resp.SignedPayload[64] = uint8(uint(resp.SignedPayload[64])) + 27 - - encoded, err := encoding.EncodeProverAssignment(&encoding.ProverAssignment{ - Prover: resp.Prover, - Expiry: proposeBlockReq.Expiry, - Data: resp.SignedPayload, - }) - if err != nil { - return nil, nil, err - } - - log.Info( - "Prover assigned for block", - "prover", resp.Prover.Hex(), - "signedPayload", common.Bytes2Hex(resp.SignedPayload), - ) - - return encoded, fee, nil - } - } - - return nil, nil, errUnableToFindProver -} - // Name returns the application name. func (p *Proposer) Name() string { return "proposer" diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 3b162dbbf..5550a30e1 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "net/url" "os" "testing" "time" @@ -30,8 +31,6 @@ type ProposerTestSuite struct { func (s *ProposerTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() - port := testutils.RandomPort() - l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) @@ -39,6 +38,8 @@ func (s *ProposerTestSuite) SetupTest() { ctx, cancel := context.WithCancel(context.Background()) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests + proverEndpoint := testutils.LocalRandomProverEndpoint() + s.Nil(InitFromConfig(ctx, p, (&Config{ L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT"), @@ -51,9 +52,9 @@ func (s *ProposerTestSuite) SetupTest() { MaxProposedTxListsPerEpoch: 1, ProposeBlockTxReplacementMultiplier: 2, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []string{fmt.Sprintf("http://localhost:%v", port)}, + ProverEndpoints: []*url.URL{proverEndpoint}, BlockProposalFee: big.NewInt(100000), - BlockProposalFeeIncreasePercentage: 10, + BlockProposalFeeIncreasePercentage: common.Big2, BlockProposalFeeIterations: 3, }))) @@ -84,7 +85,7 @@ func (s *ProposerTestSuite) SetupTest() { }() go func() { - if err := s.srv.Start(fmt.Sprintf(":%v", port)); err != nil { + if err := s.srv.Start(fmt.Sprintf(":%v", proverEndpoint.Port())); err != nil { log.Crit("error starting prover http server", "error", err) } }() @@ -207,7 +208,7 @@ func (s *ProposerTestSuite) TestSendProposeBlockTx() { CacheTxListInfo: false, } - assignment, fee, err := s.p.assignProver(context.Background(), meta) + assignment, fee, err := s.p.proverSelector.AssignProver(context.Background(), meta) s.Nil(err) newTx, err := s.p.sendProposeBlockTx( @@ -223,25 +224,6 @@ func (s *ProposerTestSuite) TestSendProposeBlockTx() { s.Greater(newTx.GasTipCap().Uint64(), tx.GasTipCap().Uint64()) } -func (s *ProposerTestSuite) TestAssignProver_NoProvers() { - meta := &encoding.TaikoL1BlockMetadataInput{ - Beneficiary: s.p.L2SuggestedFeeRecipient(), - TxListHash: testutils.RandomHash(), - TxListByteStart: common.Big0, - TxListByteEnd: common.Big0, - CacheTxListInfo: false, - } - - s.SetL1Automine(false) - defer s.SetL1Automine(true) - - s.p.proverEndpoints = []string{} - - _, _, err := s.p.assignProver(context.Background(), meta) - - s.Equal(err, errUnableToFindProver) -} - func (s *ProposerTestSuite) TestAssignProver_SuccessFirstRound() { meta := &encoding.TaikoL1BlockMetadataInput{ Beneficiary: s.p.L2SuggestedFeeRecipient(), @@ -254,10 +236,10 @@ func (s *ProposerTestSuite) TestAssignProver_SuccessFirstRound() { s.SetL1Automine(false) defer s.SetL1Automine(true) - _, fee, err := s.p.assignProver(context.Background(), meta) + _, fee, err := s.p.proverSelector.AssignProver(context.Background(), meta) s.Nil(err) - s.Equal(fee.Uint64(), s.p.blockProposalFee.Uint64()) + s.Equal(fee.Uint64(), s.p.cfg.BlockProposalFee.Uint64()) } func (s *ProposerTestSuite) TestUpdateProposingTicker() { diff --git a/proposer/prover_selector/eth_fee_selector.go b/proposer/prover_selector/eth_fee_selector.go new file mode 100644 index 000000000..3e011abf0 --- /dev/null +++ b/proposer/prover_selector/eth_fee_selector.go @@ -0,0 +1,254 @@ +package selector + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "math/big" + "net/http" + "net/url" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +var ( + httpScheme = "http" + errEmptyProverEndpoints = errors.New("empty prover endpoints") + errUnableToFindProver = errors.New("unable to find prover") +) + +type assignProverResponse struct { + SignedPayload []byte `json:"signedPayload"` + Prover common.Address `json:"prover"` +} + +type ETHFeeSelector struct { + protocolConfigs *bindings.TaikoDataConfig + rpc *rpc.Client + taikoL1Address common.Address + feeBase *big.Int + feeIncreasePercentage *big.Int + proverEndpoints []*url.URL + proposalFeeIterations uint64 + proposalExpiry time.Duration + requestTimeout time.Duration +} + +func NewETHFeeSelector( + protocolConfigs *bindings.TaikoDataConfig, + rpc *rpc.Client, + taikoL1Address common.Address, + feeBase *big.Int, + feeIncreasePercentage *big.Int, + proverEndpoints []*url.URL, + proposalFeeIterations uint64, + proposalExpiry time.Duration, + requestTimeout time.Duration, +) (*ETHFeeSelector, error) { + if len(proverEndpoints) == 0 { + return nil, errEmptyProverEndpoints + } + + for _, endpoint := range proverEndpoints { + if endpoint.Scheme != httpScheme { + return nil, fmt.Errorf("invalid prover endpoint %s", endpoint) + } + } + + return ÐFeeSelector{ + protocolConfigs, + rpc, + taikoL1Address, + feeBase, + feeIncreasePercentage, + proverEndpoints, + proposalFeeIterations, + proposalExpiry, + requestTimeout, + }, nil +} + +func (s *ETHFeeSelector) ProverEndpoints() []*url.URL { return s.proverEndpoints } + +func (s *ETHFeeSelector) AssignProver( + ctx context.Context, + meta *encoding.TaikoL1BlockMetadataInput, +) ([]byte, *big.Int, error) { + // Iterate over each configured endpoint, and see if someone wants to accept this block. + // If it is denied, we continue on to the next endpoint. + // 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 + expiry = uint64(time.Now().Add(s.proposalExpiry).Unix()) + ) + + // Increase fee on each failed loop + if i > 0 { + cumulativePercent := new(big.Int).Mul(s.feeIncreasePercentage, big.NewInt(int64(i))) + increase := new(big.Int).Mul(fee, cumulativePercent) + increase.Div(increase, big.NewInt(100)) + fee.Add(fee, increase) + } + + proposeBlockReq := &encoding.ProposeBlockData{ + Expiry: expiry, + Input: *meta, + Fee: fee, + } + + jsonBody, err := json.Marshal(proposeBlockReq) + if err != nil { + return nil, nil, err + } + + r := bytes.NewReader(jsonBody) + + for _, endpoint := range s.proverEndpoints { + log.Info( + "Attempting to assign prover", + "endpoint", endpoint, + "fee", fee.String(), + "expiry", expiry, + ) + client := &http.Client{Timeout: s.requestTimeout} + + req, err := http.NewRequestWithContext( + ctx, + "POST", + fmt.Sprintf("%v/%v", endpoint, "proposeBlock"), + r, + ) + if err != nil { + log.Error("Init http request error", "endpoint", endpoint, "err", err) + continue + } + req.Header.Add("Content-Type", "application/json") + + res, err := client.Do(req) + if err != nil { + log.Error("Request prover server error", "endpoint", endpoint, "err", err) + continue + } + + if res.StatusCode != http.StatusOK { + log.Info( + "Prover rejected request to assign block", + "endpoint", endpoint, + "fee", fee.String(), + "expiry", expiry, + ) + continue + } + + resBody, err := io.ReadAll(res.Body) + if err != nil { + log.Error("Read response body error", "endpoint", endpoint, "err", err) + continue + } + + resp := &assignProverResponse{} + if err := json.Unmarshal(resBody, resp); err != nil { + log.Error("Unmarshal response body error", "endpoint", endpoint, "err", err) + continue + } + + // ensure prover in response is the same as the one recovered + // from the signature + encodedBlockData, err := encoding.EncodeProposeBlockData(proposeBlockReq) + if err != nil { + log.Error("Encode block data error", "endpoint", endpoint, "error", err) + continue + } + + pubKey, err := crypto.SigToPub(crypto.Keccak256Hash(encodedBlockData).Bytes(), resp.SignedPayload) + if err != nil { + log.Error("Failed to get public key from signature", "endpoint", endpoint, "error", err) + continue + } + + if crypto.PubkeyToAddress(*pubKey).Hex() != resp.Prover.Hex() { + log.Info( + "Assigned prover signature did not recover to provided prover address", + "endpoint", endpoint, + "recoveredAddress", crypto.PubkeyToAddress(*pubKey).Hex(), + "providedProver", resp.Prover.Hex(), + ) + continue + } + + // make sure the prover has the necessary balance either in TaikoL1 token balances + // or, if not, check allowance, as contract will attempt to burn directly after + // if it doesnt have the available tokenbalance in-contract. + taikoTokenBalance, err := s.rpc.TaikoL1.GetTaikoTokenBalance(&bind.CallOpts{Context: ctx}, resp.Prover) + if err != nil { + log.Error( + "Get taiko token balance error", + "endpoint", endpoint, + "providedProver", resp.Prover.Hex(), + "error", err, + ) + continue + } + + if s.protocolConfigs.ProofBond.Cmp(taikoTokenBalance) > 0 { + // check allowance on taikotoken contract + allowance, err := s.rpc.TaikoToken.Allowance(&bind.CallOpts{Context: ctx}, resp.Prover, s.taikoL1Address) + if err != nil { + log.Error( + "Get taiko token allowance error", + "endpoint", endpoint, + "providedProver", resp.Prover.Hex(), + "error", err, + ) + continue + } + + if s.protocolConfigs.ProofBond.Cmp(allowance) > 0 { + log.Info( + "Assigned prover does not have required on-chain token balance or allowance", + "endpoint", endpoint, + "providedProver", resp.Prover.Hex(), + "taikoTokenBalance", taikoTokenBalance.String(), + "allowance", allowance.String(), + "proofBond", s.protocolConfigs.ProofBond, + "requiredFee", fee.String(), + ) + continue + } + } + + // convert signature to one solidity can recover by adding 27 to 65th byte + resp.SignedPayload[64] = uint8(uint(resp.SignedPayload[64])) + 27 + + encoded, err := encoding.EncodeProverAssignment(&encoding.ProverAssignment{ + Prover: resp.Prover, + Expiry: proposeBlockReq.Expiry, + Data: resp.SignedPayload, + }) + if err != nil { + return nil, nil, err + } + + log.Info( + "Prover assigned for block", + "prover", resp.Prover.Hex(), + "signedPayload", common.Bytes2Hex(resp.SignedPayload), + ) + + return encoded, fee, nil + } + } + + return nil, nil, errUnableToFindProver +} diff --git a/proposer/prover_selector/interface.go b/proposer/prover_selector/interface.go new file mode 100644 index 000000000..53ab9df14 --- /dev/null +++ b/proposer/prover_selector/interface.go @@ -0,0 +1,17 @@ +package selector + +import ( + "context" + "math/big" + "net/url" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +type ProverSelector interface { + AssignProver( + ctx context.Context, + meta *encoding.TaikoL1BlockMetadataInput, + ) (signedPayload []byte, fee *big.Int, err error) + ProverEndpoints() []*url.URL +} diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index 0cd36ada1..29942f178 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -3,8 +3,8 @@ package submitter import ( "bytes" "context" - "fmt" "math/big" + "net/url" "os" "sync" "testing" @@ -38,8 +38,6 @@ type ProofSubmitterTestSuite struct { func (s *ProofSubmitterTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() - port := testutils.RandomPort() - l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) @@ -82,6 +80,8 @@ func (s *ProofSubmitterTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests + localProverEndpoint := testutils.LocalRandomProverEndpoint() + s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), @@ -93,12 +93,12 @@ func (s *ProofSubmitterTestSuite) SetupTest() { ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []string{fmt.Sprintf("http://localhost:%v", port)}, + ProverEndpoints: []*url.URL{localProverEndpoint}, BlockProposalFee: big.NewInt(1000), BlockProposalFeeIterations: 3, }))) - srv, cancel, err := testutils.HTTPServer(&s.ClientTestSuite, port) + srv, cancel, err := testutils.HTTPServer(&s.ClientTestSuite, localProverEndpoint) s.Nil(err) s.srv = srv diff --git a/prover/prover_test.go b/prover/prover_test.go index 1e1c74e7c..2ab855b31 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "net/url" "os" "testing" "time" @@ -100,7 +101,7 @@ func (s *ProverTestSuite) SetupTest() { ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []string{fmt.Sprintf("http://localhost:%v", port)}, + ProverEndpoints: []*url.URL{testutils.LocalRandomProverEndpoint()}, BlockProposalFee: big.NewInt(1000), BlockProposalFeeIterations: 3, }))) diff --git a/testutils/helper.go b/testutils/helper.go index 928d651b2..8af4504c5 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "math/rand" + "net/url" "os" "time" @@ -181,7 +182,7 @@ func DepositEtherToL2(s *ClientTestSuite, depositerPrivKey *ecdsa.PrivateKey, re // HTTPServer starts a new prover server that has channel listeners to respond and react // to requests for capacity, which provers can call. -func HTTPServer(s *ClientTestSuite, port int) (*http.Server, func(), error) { +func HTTPServer(s *ClientTestSuite, url *url.URL) (*http.Server, func(), error) { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) @@ -209,7 +210,7 @@ func HTTPServer(s *ClientTestSuite, port int) (*http.Server, func(), error) { }() go func() { - _ = srv.Start(fmt.Sprintf(":%v", port)) + _ = srv.Start(fmt.Sprintf(":%v", url.Port())) }() return srv, func() { @@ -245,6 +246,18 @@ func RandomPort() int { return port } +// LocalRandomProverEndpoint returns a local free random prover endpoint. +func LocalRandomProverEndpoint() *url.URL { + port := RandomPort() + + proverEndpoint, err := url.Parse(fmt.Sprintf("http://localhost:%v", port)) + if err != nil { + log.Crit("Failed to parse local prover endpoint", "err", err) + } + + return proverEndpoint +} + // SignatureFromRSV creates the signature bytes from r,s,v. func SignatureFromRSV(r, s string, v byte) []byte { return append(append(hexutil.MustDecode(r), hexutil.MustDecode(s)...), v) From 9fa32297ee4670d9229282926f7962c85bbc8958 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 31 Aug 2023 16:01:54 +0800 Subject: [PATCH 02/25] feat(proposer): update ETHFeeSelector --- go.mod | 1 + go.sum | 3 + proposer/prover_selector/eth_fee_selector.go | 240 +++++++++---------- 3 files changed, 112 insertions(+), 132 deletions(-) diff --git a/go.mod b/go.mod index 5b32e6115..13a1ce37a 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/cyberhorsey/webutils v0.0.0-20230314183728-56890c6ddbe7 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 github.com/ethereum/go-ethereum v1.12.2 + github.com/go-resty/resty/v2 v2.7.0 github.com/labstack/echo/v4 v4.11.1 github.com/labstack/gommon v0.4.0 github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 diff --git a/go.sum b/go.sum index 5c5ff3d39..a5c45b295 100644 --- a/go.sum +++ b/go.sum @@ -130,6 +130,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/validator/v10 v10.4.0/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -491,6 +493,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= diff --git a/proposer/prover_selector/eth_fee_selector.go b/proposer/prover_selector/eth_fee_selector.go index 3e011abf0..5b0b60e6e 100644 --- a/proposer/prover_selector/eth_fee_selector.go +++ b/proposer/prover_selector/eth_fee_selector.go @@ -1,14 +1,10 @@ package selector import ( - "bytes" "context" - "encoding/json" "errors" "fmt" - "io" "math/big" - "net/http" "net/url" "time" @@ -16,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/go-resty/resty/v2" "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" "github.com/taikoxyz/taiko-client/pkg/rpc" @@ -100,155 +97,134 @@ func (s *ETHFeeSelector) AssignProver( increase.Div(increase, big.NewInt(100)) fee.Add(fee, increase) } - - proposeBlockReq := &encoding.ProposeBlockData{ - Expiry: expiry, - Input: *meta, - Fee: fee, - } - - jsonBody, err := json.Marshal(proposeBlockReq) - if err != nil { - return nil, nil, err - } - - r := bytes.NewReader(jsonBody) - for _, endpoint := range s.proverEndpoints { - log.Info( - "Attempting to assign prover", - "endpoint", endpoint, - "fee", fee.String(), - "expiry", expiry, - ) - client := &http.Client{Timeout: s.requestTimeout} - - req, err := http.NewRequestWithContext( - ctx, - "POST", - fmt.Sprintf("%v/%v", endpoint, "proposeBlock"), - r, - ) + encodedAssignment, proverAddress, err := assignProver(ctx, meta, endpoint, fee, expiry, s.requestTimeout) if err != nil { - log.Error("Init http request error", "endpoint", endpoint, "err", err) + log.Warn("Failed to assign prover", "endpoint", endpoint, "error", err) continue } - req.Header.Add("Content-Type", "application/json") - res, err := client.Do(req) + ok, err := s.checkProverBalance(ctx, proverAddress) if err != nil { - log.Error("Request prover server error", "endpoint", endpoint, "err", err) + log.Warn("Failed to check prover balance", "endpoint", endpoint, "error", err) continue } - - if res.StatusCode != http.StatusOK { - log.Info( - "Prover rejected request to assign block", - "endpoint", endpoint, - "fee", fee.String(), - "expiry", expiry, - ) + if !ok { continue } - resBody, err := io.ReadAll(res.Body) - if err != nil { - log.Error("Read response body error", "endpoint", endpoint, "err", err) - continue - } + return encodedAssignment, fee, nil + } + } - resp := &assignProverResponse{} - if err := json.Unmarshal(resBody, resp); err != nil { - log.Error("Unmarshal response body error", "endpoint", endpoint, "err", err) - continue - } + return nil, nil, errUnableToFindProver +} - // ensure prover in response is the same as the one recovered - // from the signature - encodedBlockData, err := encoding.EncodeProposeBlockData(proposeBlockReq) - if err != nil { - log.Error("Encode block data error", "endpoint", endpoint, "error", err) - continue - } +// checkProverBalance checks if the prover has the necessary balance either in TaikoL1 token balances +// or, if not, then check allowance, as contract will attempt to burn directly after +// if it doesnt have the available token balance in-contract. +func (s *ETHFeeSelector) checkProverBalance(ctx context.Context, prover common.Address) (bool, error) { + taikoTokenBalance, err := s.rpc.TaikoL1.GetTaikoTokenBalance(&bind.CallOpts{Context: ctx}, prover) + if err != nil { + return false, err + } - pubKey, err := crypto.SigToPub(crypto.Keccak256Hash(encodedBlockData).Bytes(), resp.SignedPayload) - if err != nil { - log.Error("Failed to get public key from signature", "endpoint", endpoint, "error", err) - continue - } + if s.protocolConfigs.ProofBond.Cmp(taikoTokenBalance) > 0 { + // Check allowance on taiko token contract + allowance, err := s.rpc.TaikoToken.Allowance(&bind.CallOpts{Context: ctx}, prover, s.taikoL1Address) + if err != nil { + return false, err + } - if crypto.PubkeyToAddress(*pubKey).Hex() != resp.Prover.Hex() { - log.Info( - "Assigned prover signature did not recover to provided prover address", - "endpoint", endpoint, - "recoveredAddress", crypto.PubkeyToAddress(*pubKey).Hex(), - "providedProver", resp.Prover.Hex(), - ) - continue - } + if s.protocolConfigs.ProofBond.Cmp(allowance) > 0 { + log.Info( + "Assigned prover does not have required on-chain token balance or allowance", + "providedProver", prover.Hex(), + "taikoTokenBalance", taikoTokenBalance.String(), + "allowance", allowance.String(), + "proofBond", s.protocolConfigs.ProofBond, + ) + return false, nil + } + } - // make sure the prover has the necessary balance either in TaikoL1 token balances - // or, if not, check allowance, as contract will attempt to burn directly after - // if it doesnt have the available tokenbalance in-contract. - taikoTokenBalance, err := s.rpc.TaikoL1.GetTaikoTokenBalance(&bind.CallOpts{Context: ctx}, resp.Prover) - if err != nil { - log.Error( - "Get taiko token balance error", - "endpoint", endpoint, - "providedProver", resp.Prover.Hex(), - "error", err, - ) - continue - } + return true, nil +} - if s.protocolConfigs.ProofBond.Cmp(taikoTokenBalance) > 0 { - // check allowance on taikotoken contract - allowance, err := s.rpc.TaikoToken.Allowance(&bind.CallOpts{Context: ctx}, resp.Prover, s.taikoL1Address) - if err != nil { - log.Error( - "Get taiko token allowance error", - "endpoint", endpoint, - "providedProver", resp.Prover.Hex(), - "error", err, - ) - continue - } - - if s.protocolConfigs.ProofBond.Cmp(allowance) > 0 { - log.Info( - "Assigned prover does not have required on-chain token balance or allowance", - "endpoint", endpoint, - "providedProver", resp.Prover.Hex(), - "taikoTokenBalance", taikoTokenBalance.String(), - "allowance", allowance.String(), - "proofBond", s.protocolConfigs.ProofBond, - "requiredFee", fee.String(), - ) - continue - } - } +func assignProver( + ctx context.Context, + meta *encoding.TaikoL1BlockMetadataInput, + endpoint *url.URL, + fee *big.Int, + expiry uint64, + timeout time.Duration, +) ([]byte, common.Address, error) { + log.Info( + "Attempting to assign prover", + "endpoint", endpoint, + "fee", fee.String(), + "expiry", expiry, + ) + + // Send the HTTP request + var ( + client = resty.New() + reqBody = &encoding.ProposeBlockData{Expiry: expiry, Input: *meta, Fee: fee} + result = assignProverResponse{} + ) + requestUrl, err := url.JoinPath(endpoint.String(), "/proposeBlock") + if err != nil { + return nil, common.Address{}, err + } - // convert signature to one solidity can recover by adding 27 to 65th byte - resp.SignedPayload[64] = uint8(uint(resp.SignedPayload[64])) + 27 + ctxTimeout, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + resp, err := client.R(). + SetContext(ctxTimeout). + SetHeader("Content-Type", "application/json"). + SetHeader("Accept", "application/json"). + SetBody(reqBody). + SetResult(&result). + Post(requestUrl) + if err != nil { + return nil, common.Address{}, err + } + if !resp.IsSuccess() { + return nil, common.Address{}, fmt.Errorf("unsuccessful response %d", resp.StatusCode()) + } - encoded, err := encoding.EncodeProverAssignment(&encoding.ProverAssignment{ - Prover: resp.Prover, - Expiry: proposeBlockReq.Expiry, - Data: resp.SignedPayload, - }) - if err != nil { - return nil, nil, err - } + // Ensure prover in response is the same as the one recovered + // from the signature + encodedBlockData, err := encoding.EncodeProposeBlockData(reqBody) + if err != nil { + return nil, common.Address{}, err + } - log.Info( - "Prover assigned for block", - "prover", resp.Prover.Hex(), - "signedPayload", common.Bytes2Hex(resp.SignedPayload), - ) + pubKey, err := crypto.SigToPub(crypto.Keccak256Hash(encodedBlockData).Bytes(), result.SignedPayload) + if err != nil { + return nil, common.Address{}, err + } - return encoded, fee, nil - } + if crypto.PubkeyToAddress(*pubKey).Hex() != result.Prover.Hex() { + return nil, common.Address{}, fmt.Errorf( + "assigned prover signature did not recover to provided prover address %s != %s", + crypto.PubkeyToAddress(*pubKey).Hex(), + result.Prover.Hex(), + ) } - return nil, nil, errUnableToFindProver + // Convert signature to one solidity can recover by adding 27 to 65th byte + result.SignedPayload[64] = uint8(uint(result.SignedPayload[64])) + 27 + + encoded, err := encoding.EncodeProverAssignment(&encoding.ProverAssignment{ + Prover: result.Prover, + Expiry: reqBody.Expiry, + Data: result.SignedPayload, + }) + if err != nil { + return nil, common.Address{}, err + } + + return encoded, result.Prover, nil } From 6e6737f236d9dc394ba26e9eb6a7e11806d34466 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 31 Aug 2023 17:02:50 +0800 Subject: [PATCH 03/25] test: more tests --- proposer/proposer_test.go | 4 +- .../prover_selector/eth_fee_selector_test.go | 76 +++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 proposer/prover_selector/eth_fee_selector_test.go diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 5550a30e1..472d037e4 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -53,7 +53,7 @@ func (s *ProposerTestSuite) SetupTest() { ProposeBlockTxReplacementMultiplier: 2, WaitReceiptTimeout: 10 * time.Second, ProverEndpoints: []*url.URL{proverEndpoint}, - BlockProposalFee: big.NewInt(100000), + BlockProposalFee: common.Big256, BlockProposalFeeIncreasePercentage: common.Big2, BlockProposalFeeIterations: 3, }))) @@ -64,7 +64,7 @@ func (s *ProposerTestSuite) SetupTest() { serverOpts := http.NewServerOpts{ ProverPrivateKey: l1ProverPrivKey, - MinProofFee: big.NewInt(1), + MinProofFee: common.Big1, MaxCapacity: 10, RequestCurrentCapacityCh: make(chan struct{}), ReceiveCurrentCapacityCh: make(chan uint64), diff --git a/proposer/prover_selector/eth_fee_selector_test.go b/proposer/prover_selector/eth_fee_selector_test.go new file mode 100644 index 000000000..8ebe04754 --- /dev/null +++ b/proposer/prover_selector/eth_fee_selector_test.go @@ -0,0 +1,76 @@ +package selector + +import ( + "context" + "fmt" + "net/url" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/suite" + "github.com/taikoxyz/taiko-client/prover/http" + "github.com/taikoxyz/taiko-client/testutils" +) + +type ProverSelectorTestSuite struct { + testutils.ClientTestSuite + s *ETHFeeSelector + proverAddress common.Address + srv *http.Server +} + +func (s *ProverSelectorTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + proverEndpoint := testutils.LocalRandomProverEndpoint() + + l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + srv, err := http.NewServer(http.NewServerOpts{ + ProverPrivateKey: l1ProverPrivKey, + MinProofFee: common.Big1, + MaxCapacity: 10, + RequestCurrentCapacityCh: make(chan struct{}), + ReceiveCurrentCapacityCh: make(chan uint64), + }) + s.Nil(err) + s.srv = srv + s.proverAddress = crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey) + + go func() { + if err := s.srv.Start(fmt.Sprintf(":%v", proverEndpoint.Port())); err != nil { + log.Crit("error starting prover http server", "error", err) + } + }() + + protocolConfigs, err := s.RpcClient.TaikoL1.GetConfig(nil) + s.Nil(err) + + s.s, err = NewETHFeeSelector( + &protocolConfigs, + s.RpcClient, + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.Big256, + common.Big2, + []*url.URL{proverEndpoint}, + 32, + 1*time.Minute, + 1*time.Minute, + ) + s.Nil(err) +} + +func (s *ProverSelectorTestSuite) TestCheckProverBalance() { + ok, err := s.s.checkProverBalance(context.Background(), s.proverAddress) + s.Nil(err) + s.True(ok) +} + +func TestProverSelectorTestSuite(t *testing.T) { + suite.Run(t, new(ProverSelectorTestSuite)) +} From 0d9d153ad80d7fe63d0ee56c9517f1da7d0d64e1 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 3 Sep 2023 10:08:00 +0800 Subject: [PATCH 04/25] test: update tests --- proposer/config_test.go | 6 ++++-- prover/http/server.go | 3 +-- prover/prover_test.go | 34 ++++++++++++++++------------------ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/proposer/config_test.go b/proposer/config_test.go index 9747ef0f4..0555bda14 100644 --- a/proposer/config_test.go +++ b/proposer/config_test.go @@ -50,12 +50,14 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() { s.Equal(uint64(5), c.ProposeBlockTxReplacementMultiplier) s.Equal(rpcTimeout, *c.RPCTimeout) s.Equal(10*time.Second, c.WaitReceiptTimeout) - s.Equal(strings.Split(proverEndpoints, ","), c.ProverEndpoints) + for i, e := range strings.Split(proverEndpoints, ",") { + s.Equal(c.ProverEndpoints[i].String(), e) + } fee, _ := new(big.Int).SetString(blockProposalFee, 10) s.Equal(fee, c.BlockProposalFee) - s.Equal(uint64(15), c.BlockProposalFeeIncreasePercentage) + s.Equal(uint64(15), c.BlockProposalFeeIncreasePercentage.Uint64()) s.Equal(uint64(5), c.BlockProposalFeeIterations) s.Nil(new(Proposer).InitFromCli(context.Background(), ctx)) diff --git a/prover/http/server.go b/prover/http/server.go index 0afb3acaf..3d5ca01c2 100644 --- a/prover/http/server.go +++ b/prover/http/server.go @@ -9,9 +9,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/labstack/echo/v4/middleware" - echo "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" ) type Server struct { diff --git a/prover/prover_test.go b/prover/prover_test.go index 2ab855b31..d2780785f 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -30,10 +30,6 @@ type ProverTestSuite struct { proposer *proposer.Proposer } -var ( - port = testutils.RandomPort() -) - func (s *ProverTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() @@ -62,9 +58,10 @@ func (s *ProverTestSuite) SetupTest() { }))) s.p = p s.cancel = cancel + proverEndpoint := testutils.LocalRandomProverEndpoint() go func() { - _ = s.p.srv.Start(fmt.Sprintf(":%v", port)) + _ = s.p.srv.Start(fmt.Sprintf(":%v", proverEndpoint.Port())) }() // Init driver @@ -91,19 +88,20 @@ func (s *ProverTestSuite) SetupTest() { proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests - MaxProposedTxListsPerEpoch: 1, - WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{testutils.LocalRandomProverEndpoint()}, - BlockProposalFee: big.NewInt(1000), - BlockProposalFeeIterations: 3, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, + ProverEndpoints: []*url.URL{proverEndpoint}, + BlockProposalFee: big.NewInt(1000), + BlockProposalFeeIterations: 3, + BlockProposalFeeIncreasePercentage: common.Big2, }))) s.proposer = prop From da40cdada7054031944afda71ee02235f7eefa02 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 3 Sep 2023 10:16:55 +0800 Subject: [PATCH 05/25] test: fix lint errors --- prover/prover_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prover/prover_test.go b/prover/prover_test.go index d2780785f..686d40f8a 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -95,7 +95,7 @@ func (s *ProverTestSuite) SetupTest() { TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), L1ProposerPrivKey: l1ProposerPrivKey, L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, ProverEndpoints: []*url.URL{proverEndpoint}, From 5c625aac9bd641b1ffbf4d4baf001bdb474b123c Mon Sep 17 00:00:00 2001 From: David Date: Sun, 3 Sep 2023 10:32:53 +0800 Subject: [PATCH 06/25] feat: update opts --- proposer/proposer_test.go | 2 +- proposer/prover_selector/eth_fee_selector_test.go | 2 +- prover/http/routes.go | 1 - prover/http/server.go | 2 +- prover/prover.go | 2 +- prover/prover_test.go | 2 +- testutils/helper.go | 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 472d037e4..f4ee7a002 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -62,7 +62,7 @@ func (s *ProposerTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - serverOpts := http.NewServerOpts{ + serverOpts := &http.NewServerOpts{ ProverPrivateKey: l1ProverPrivKey, MinProofFee: common.Big1, MaxCapacity: 10, diff --git a/proposer/prover_selector/eth_fee_selector_test.go b/proposer/prover_selector/eth_fee_selector_test.go index 8ebe04754..6b2eadfee 100644 --- a/proposer/prover_selector/eth_fee_selector_test.go +++ b/proposer/prover_selector/eth_fee_selector_test.go @@ -31,7 +31,7 @@ func (s *ProverSelectorTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - srv, err := http.NewServer(http.NewServerOpts{ + srv, err := http.NewServer(&http.NewServerOpts{ ProverPrivateKey: l1ProverPrivKey, MinProofFee: common.Big1, MaxCapacity: 10, diff --git a/prover/http/routes.go b/prover/http/routes.go index c7195ac42..0f7124d29 100644 --- a/prover/http/routes.go +++ b/prover/http/routes.go @@ -3,6 +3,5 @@ package http func (srv *Server) configureRoutes() { srv.echo.GET("/healthz", srv.Health) srv.echo.GET("/", srv.Health) - srv.echo.POST("/proposeBlock", srv.ProposeBlock) } diff --git a/prover/http/server.go b/prover/http/server.go index 3d5ca01c2..02fdc5c63 100644 --- a/prover/http/server.go +++ b/prover/http/server.go @@ -33,7 +33,7 @@ type NewServerOpts struct { ReceiveCurrentCapacityCh chan uint64 } -func NewServer(opts NewServerOpts) (*Server, error) { +func NewServer(opts *NewServerOpts) (*Server, error) { address := crypto.PubkeyToAddress(opts.ProverPrivateKey.PublicKey) srv := &Server{ proverPrivateKey: opts.ProverPrivateKey, diff --git a/prover/prover.go b/prover/prover.go index 9965eb597..f1ea280e6 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -121,7 +121,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.receiveCurrentCapacityCh = make(chan uint64, 1024) if !p.cfg.OracleProver { - p.srv, err = http.NewServer(http.NewServerOpts{ + p.srv, err = http.NewServer(&http.NewServerOpts{ ProverPrivateKey: p.cfg.L1ProverPrivKey, MaxCapacity: p.cfg.Capacity, MinProofFee: p.cfg.MinProofFee, diff --git a/prover/prover_test.go b/prover/prover_test.go index 686d40f8a..ed31d22e1 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -201,7 +201,7 @@ func (s *ProverTestSuite) TestStartClose() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - s.p.srv, _ = http.NewServer(http.NewServerOpts{ + s.p.srv, _ = http.NewServer(&http.NewServerOpts{ ProverPrivateKey: l1ProverPrivKey, }) s.Nil(s.p.Start()) diff --git a/testutils/helper.go b/testutils/helper.go index 8af4504c5..2721023c5 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -186,7 +186,7 @@ func HTTPServer(s *ClientTestSuite, url *url.URL) (*http.Server, func(), error) l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - serverOpts := http.NewServerOpts{ + serverOpts := &http.NewServerOpts{ ProverPrivateKey: l1ProverPrivKey, MinProofFee: big.NewInt(1), MaxCapacity: 10, From d1568537d394706ab40d4c67c3747c8a5a14b9b6 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 3 Sep 2023 11:14:47 +0800 Subject: [PATCH 07/25] test: update testutils --- .../prover_selector/eth_fee_selector_test.go | 24 +------------------ testutils/suite.go | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/proposer/prover_selector/eth_fee_selector_test.go b/proposer/prover_selector/eth_fee_selector_test.go index 6b2eadfee..30f4748b0 100644 --- a/proposer/prover_selector/eth_fee_selector_test.go +++ b/proposer/prover_selector/eth_fee_selector_test.go @@ -2,7 +2,6 @@ package selector import ( "context" - "fmt" "net/url" "os" "testing" @@ -10,9 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/suite" - "github.com/taikoxyz/taiko-client/prover/http" "github.com/taikoxyz/taiko-client/testutils" ) @@ -20,34 +17,15 @@ type ProverSelectorTestSuite struct { testutils.ClientTestSuite s *ETHFeeSelector proverAddress common.Address - srv *http.Server } func (s *ProverSelectorTestSuite) SetupTest() { s.ClientTestSuite.SetupTest() - proverEndpoint := testutils.LocalRandomProverEndpoint() - l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - - srv, err := http.NewServer(&http.NewServerOpts{ - ProverPrivateKey: l1ProverPrivKey, - MinProofFee: common.Big1, - MaxCapacity: 10, - RequestCurrentCapacityCh: make(chan struct{}), - ReceiveCurrentCapacityCh: make(chan uint64), - }) - s.Nil(err) - s.srv = srv s.proverAddress = crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey) - go func() { - if err := s.srv.Start(fmt.Sprintf(":%v", proverEndpoint.Port())); err != nil { - log.Crit("error starting prover http server", "error", err) - } - }() - protocolConfigs, err := s.RpcClient.TaikoL1.GetConfig(nil) s.Nil(err) @@ -57,7 +35,7 @@ func (s *ProverSelectorTestSuite) SetupTest() { common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), common.Big256, common.Big2, - []*url.URL{proverEndpoint}, + []*url.URL{s.ProverEndpoints[0]}, 32, 1*time.Minute, 1*time.Minute, diff --git a/testutils/suite.go b/testutils/suite.go index 83bf62fb4..761fdeaad 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -3,8 +3,11 @@ package testutils import ( "context" "crypto/ecdsa" + "fmt" "math/big" + "net/url" "os" + "sync" "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -14,6 +17,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/prover/http" ) type ClientTestSuite struct { @@ -22,6 +26,8 @@ type ClientTestSuite struct { RpcClient *rpc.Client TestAddrPrivKey *ecdsa.PrivateKey TestAddr common.Address + ProverEndpoints []*url.URL + once sync.Once } func (s *ClientTestSuite) SetupTest() { @@ -68,6 +74,24 @@ func (s *ClientTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) + s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} + s.once.Do(func() { + go func() { + proverServer, err := http.NewServer(&http.NewServerOpts{ + ProverPrivateKey: l1ProverPrivKey, + MinProofFee: common.Big1, + MaxCapacity: 10, + RequestCurrentCapacityCh: make(chan struct{}), + ReceiveCurrentCapacityCh: make(chan uint64), + }) + s.Nil(err) + + if err := proverServer.Start(fmt.Sprintf(":%v", s.ProverEndpoints[0].Port())); err != nil { + log.Crit("Failed to start prover http server", "error", err) + } + }() + }) + tokenBalance, err := rpcCli.TaikoL1.GetTaikoTokenBalance(nil, crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey)) s.Nil(err) From 074a0020674325abc84dfc57edcb06c4fc2cbd6d Mon Sep 17 00:00:00 2001 From: alexshliu <104080237+alexshliu@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:31:48 +0800 Subject: [PATCH 08/25] feat(pkg): add `isSyncing` method (#379) --- pkg/rpc/methods.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pkg/rpc/methods.go b/pkg/rpc/methods.go index 9e40dc68e..3e7d486fd 100644 --- a/pkg/rpc/methods.go +++ b/pkg/rpc/methods.go @@ -96,10 +96,7 @@ func (c *Client) WaitTillL2ExecutionEngineSynced(ctx context.Context) error { return err } - if progress.SyncProgress != nil || - progress.CurrentBlockID == nil || - progress.HighestBlockID == nil || - progress.CurrentBlockID.Cmp(progress.HighestBlockID) < 0 { + if progress.isSyncing() { log.Info("L2 execution engine is syncing", "progress", progress) return errSyncing } @@ -281,6 +278,14 @@ type L2SyncProgress struct { HighestBlockID *big.Int } +// isSyncing returns true if the L2 execution engine is syncing with L1. +func (p *L2SyncProgress) isSyncing() bool { + return p.SyncProgress != nil || + p.CurrentBlockID == nil || + p.HighestBlockID == nil || + p.CurrentBlockID.Cmp(p.HighestBlockID) < 0 +} + // L2ExecutionEngineSyncProgress fetches the sync progress of the given L2 execution engine. func (c *Client) L2ExecutionEngineSyncProgress(ctx context.Context) (*L2SyncProgress, error) { ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) From 91cd5215dbb36c22aa0b431ade7d67f0c4665af5 Mon Sep 17 00:00:00 2001 From: John Chase <68833933+joohhnnn@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:38:54 +0800 Subject: [PATCH 09/25] chore(deps): upgrade `gohashtree` for ARM64 (#380) Co-authored-by: David --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 13a1ce37a..8f19c878c 100644 --- a/go.mod +++ b/go.mod @@ -81,7 +81,7 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab // indirect - github.com/prysmaticlabs/gohashtree v0.0.2-alpha // indirect + github.com/prysmaticlabs/gohashtree v0.0.3-alpha // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index a5c45b295..87a5320a9 100644 --- a/go.sum +++ b/go.sum @@ -349,8 +349,8 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab h1:Y3PcvUrnneMWLuypZpwPz8P70/DQsz6KgV9JveKpyZs= github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= -github.com/prysmaticlabs/gohashtree v0.0.2-alpha h1:hk5ZsDQuSkyUMhTd55qB396P1+dtyIKiSwMmYE/hyEU= -github.com/prysmaticlabs/gohashtree v0.0.2-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/gohashtree v0.0.3-alpha h1:1EVinCWdb3Lorq7xn8DYQHf48nCcdAM3Vb18KsFlRWY= +github.com/prysmaticlabs/gohashtree v0.0.3-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/prysmaticlabs/prysm/v4 v4.0.1 h1:5A3YJb+FdTFT9qn+P0ZkxLAK0+yVgctJLmkq5R6um6A= github.com/prysmaticlabs/prysm/v4 v4.0.1/go.mod h1:EQ8hYKry3NYHGirqLiQh8gXJ/O12dWZXpKC67CO2GQU= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= From 3a6d0ad7ff26e2f5446899044adde6ab98b4e29f Mon Sep 17 00:00:00 2001 From: David Date: Mon, 4 Sep 2023 16:15:37 +0800 Subject: [PATCH 10/25] chore: update go version --- Dockerfile | 2 +- driver/chain_syncer/calldata/syncer_test.go | 49 ++++++------------- driver/chain_syncer/chain_syncer_test.go | 36 ++++++-------- driver/driver_test.go | 41 ++++++---------- go.mod | 2 +- go.sum | 18 +++++++ proposer/proposer_test.go | 28 +---------- .../valid_proof_submitter_test.go | 41 ++++++---------- prover/prover.go | 1 - prover/prover_test.go | 9 +--- testutils/suite.go | 14 +----- version/version.go | 2 +- 12 files changed, 83 insertions(+), 160 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3aa050c51..f30426dea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19-alpine as builder +FROM golang:1.21-alpine as builder RUN apk add --no-cache gcc musl-dev linux-headers git make diff --git a/driver/chain_syncer/calldata/syncer_test.go b/driver/chain_syncer/calldata/syncer_test.go index e1ff7de3e..57ad5d6fb 100644 --- a/driver/chain_syncer/calldata/syncer_test.go +++ b/driver/chain_syncer/calldata/syncer_test.go @@ -4,7 +4,6 @@ import ( "context" "math/big" "math/rand" - "net/url" "os" "testing" "time" @@ -17,16 +16,13 @@ import ( "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" "github.com/taikoxyz/taiko-client/driver/state" "github.com/taikoxyz/taiko-client/proposer" - "github.com/taikoxyz/taiko-client/prover/http" "github.com/taikoxyz/taiko-client/testutils" ) type CalldataSyncerTestSuite struct { testutils.ClientTestSuite - s *Syncer - p testutils.Proposer - srv *http.Server - cancel context.CancelFunc + s *Syncer + p testutils.Proposer } func (s *CalldataSyncerTestSuite) SetupTest() { @@ -49,34 +45,27 @@ func (s *CalldataSyncerTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests - localProverEndpoint := testutils.LocalRandomProverEndpoint() s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, - MaxProposedTxListsPerEpoch: 1, - WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{localProverEndpoint}, - BlockProposalFee: big.NewInt(1000), - BlockProposalFeeIterations: 3, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, + MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, + ProverEndpoints: s.ProverEndpoints, + BlockProposalFee: big.NewInt(1000), + BlockProposalFeeIterations: 3, + BlockProposalFeeIncreasePercentage: common.Big2, }))) - srv, cancel, err := testutils.HTTPServer(&s.ClientTestSuite, localProverEndpoint) - s.Nil(err) - - s.srv = srv - s.cancel = cancel - s.p = prop } func (s *CalldataSyncerTestSuite) TestCancelNewSyncer() { - defer s.cancel() ctx, cancel := context.WithCancel(context.Background()) cancel() syncer, err := NewSyncer( @@ -91,14 +80,12 @@ func (s *CalldataSyncerTestSuite) TestCancelNewSyncer() { } func (s *CalldataSyncerTestSuite) TestProcessL1Blocks() { - defer s.cancel() head, err := s.s.rpc.L1.HeaderByNumber(context.Background(), nil) s.Nil(err) s.Nil(s.s.ProcessL1Blocks(context.Background(), head)) } func (s *CalldataSyncerTestSuite) TestProcessL1BlocksReorg() { - defer s.cancel() head, err := s.s.rpc.L1.HeaderByNumber(context.Background(), nil) testutils.ProposeAndInsertEmptyBlocks(&s.ClientTestSuite, s.p, s.s) s.Nil(err) @@ -106,7 +93,6 @@ func (s *CalldataSyncerTestSuite) TestProcessL1BlocksReorg() { } func (s *CalldataSyncerTestSuite) TestOnBlockProposed() { - defer s.cancel() s.Nil(s.s.onBlockProposed( context.Background(), &bindings.TaikoL1ClientBlockProposed{BlockId: common.Big0}, @@ -120,7 +106,6 @@ func (s *CalldataSyncerTestSuite) TestOnBlockProposed() { } func (s *CalldataSyncerTestSuite) TestInsertNewHead() { - defer s.cancel() parent, err := s.s.rpc.L2.HeaderByNumber(context.Background(), nil) s.Nil(err) l1Head, err := s.s.rpc.L1.BlockByNumber(context.Background(), nil) @@ -153,7 +138,6 @@ func (s *CalldataSyncerTestSuite) TestInsertNewHead() { } func (s *CalldataSyncerTestSuite) TestTreasuryIncomeAllAnchors() { - defer s.cancel() treasury := common.HexToAddress(os.Getenv("TREASURY")) s.NotZero(treasury.Big().Uint64()) @@ -176,7 +160,6 @@ func (s *CalldataSyncerTestSuite) TestTreasuryIncomeAllAnchors() { } func (s *CalldataSyncerTestSuite) TestTreasuryIncome() { - defer s.cancel() treasury := common.HexToAddress(os.Getenv("TREASURY")) s.NotZero(treasury.Big().Uint64()) diff --git a/driver/chain_syncer/chain_syncer_test.go b/driver/chain_syncer/chain_syncer_test.go index 12299017c..08f64bcaa 100644 --- a/driver/chain_syncer/chain_syncer_test.go +++ b/driver/chain_syncer/chain_syncer_test.go @@ -3,7 +3,6 @@ package chainSyncer import ( "context" "math/big" - "net/url" "os" "testing" @@ -27,7 +26,6 @@ type ChainSyncerTestSuite struct { snapshotID string p testutils.Proposer srv *http.Server - cancel func() } func (s *ChainSyncerTestSuite) SetupTest() { @@ -51,30 +49,24 @@ func (s *ChainSyncerTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests - localProverEndpoint := testutils.LocalRandomProverEndpoint() s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, - MaxProposedTxListsPerEpoch: 1, - WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{localProverEndpoint}, - BlockProposalFee: big.NewInt(1000), - BlockProposalFeeIterations: 3, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, + MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, + ProverEndpoints: s.ProverEndpoints, + BlockProposalFee: big.NewInt(1000), + BlockProposalFeeIterations: 3, + BlockProposalFeeIncreasePercentage: common.Big2, }))) - srv, srvCancel, err := testutils.HTTPServer(&s.ClientTestSuite, localProverEndpoint) - s.Nil(err) - - s.srv = srv - s.cancel = srvCancel - s.p = prop } diff --git a/driver/driver_test.go b/driver/driver_test.go index 56d049057..1d4e271d8 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -3,7 +3,6 @@ package driver import ( "context" "math/big" - "net/url" "os" "testing" "time" @@ -15,7 +14,6 @@ import ( "github.com/taikoxyz/taiko-client/driver/state" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/proposer" - "github.com/taikoxyz/taiko-client/prover/http" "github.com/taikoxyz/taiko-client/testutils" ) @@ -24,7 +22,6 @@ type DriverTestSuite struct { cancel context.CancelFunc p *proposer.Proposer d *Driver - srv *http.Server } func (s *DriverTestSuite) SetupTest() { @@ -46,40 +43,32 @@ func (s *DriverTestSuite) SetupTest() { JwtSecret: string(jwtSecret), })) s.d = d + s.cancel = cancel // Init proposer p := new(proposer.Proposer) l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) - localPorverEndpoint := testutils.LocalRandomProverEndpoint() proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), p, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests - MaxProposedTxListsPerEpoch: 1, - WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{localPorverEndpoint}, - BlockProposalFee: big.NewInt(1000), - BlockProposalFeeIterations: 3, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, + ProverEndpoints: s.ProverEndpoints, + BlockProposalFee: big.NewInt(1000), + BlockProposalFeeIterations: 3, + BlockProposalFeeIncreasePercentage: common.Big2, }))) s.p = p - - srv, srvCancel, err := testutils.HTTPServer(&s.ClientTestSuite, localPorverEndpoint) - s.Nil(err) - - s.srv = srv - s.cancel = func() { - cancel() - srvCancel() - } } func (s *DriverTestSuite) TestName() { diff --git a/go.mod b/go.mod index 8f19c878c..97b47ff04 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/taikoxyz/taiko-client -go 1.18 +go 1.21 require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 diff --git a/go.sum b/go.sum index 87a5320a9..4c612b29a 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,7 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= +github.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= @@ -32,6 +33,7 @@ github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8 github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -74,12 +76,14 @@ github.com/cyberhorsey/errors v0.0.0-20220929234051-087d6d8bb841/go.mod h1:qSH/I github.com/cyberhorsey/webutils v0.0.0-20230314183728-56890c6ddbe7 h1:KYOh2RfWAltxYsfD/Ar5D3zB4+AuNQejXW5BvMlGor4= github.com/cyberhorsey/webutils v0.0.0-20230314183728-56890c6ddbe7/go.mod h1:bNNUHadsCy1HleNUToQ/t11vmKI9/+9Taw8K6GyxERo= github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= +github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -100,6 +104,7 @@ github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= @@ -107,6 +112,7 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -116,6 +122,7 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/ github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -179,6 +186,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -194,9 +202,11 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= @@ -246,6 +256,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.0.0/go.mod h1:tZv7nai5buKSg5h/8E6zz4LsD/Dqh9/91Mvs7Z5Zyno= github.com/labstack/echo/v4 v4.1.15/go.mod h1:GWO5IBVzI371K8XJe50CSvHjQCafK6cw8R/moLhEU6o= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= @@ -256,6 +267,7 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -294,6 +306,7 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= @@ -327,6 +340,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= @@ -363,6 +377,7 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -386,6 +401,7 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -414,6 +430,7 @@ github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7Am github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -633,6 +650,7 @@ gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/R gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index f4ee7a002..0d3d8e259 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -2,9 +2,7 @@ package proposer import ( "context" - "fmt" "math/big" - "net/url" "os" "testing" "time" @@ -12,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/bindings" @@ -38,7 +35,6 @@ func (s *ProposerTestSuite) SetupTest() { ctx, cancel := context.WithCancel(context.Background()) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests - proverEndpoint := testutils.LocalRandomProverEndpoint() s.Nil(InitFromConfig(ctx, p, (&Config{ L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), @@ -52,7 +48,7 @@ func (s *ProposerTestSuite) SetupTest() { MaxProposedTxListsPerEpoch: 1, ProposeBlockTxReplacementMultiplier: 2, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{proverEndpoint}, + ProverEndpoints: s.ProverEndpoints, BlockProposalFee: common.Big256, BlockProposalFeeIncreasePercentage: common.Big2, BlockProposalFeeIterations: 3, @@ -84,12 +80,6 @@ func (s *ProposerTestSuite) SetupTest() { } }() - go func() { - if err := s.srv.Start(fmt.Sprintf(":%v", proverEndpoint.Port())); err != nil { - log.Crit("error starting prover http server", "error", err) - } - }() - s.p = p s.cancel = cancel } @@ -257,22 +247,6 @@ func (s *ProposerTestSuite) TestStartClose() { s.NotPanics(func() { s.p.Close(context.Background()) }) } -// TODO: not working -// func (s *ProposerTestSuite) TestEventLoopEmptyBlock() { -// fiveSecs := 5 * time.Second -// s.p.proposingInterval = &fiveSecs -// s.p.proposeEmptyBlocksInterval = &fiveSecs -// s.p.Start() -// time.Sleep(30 * time.Second) -// s.cancel() -// s.p.Close() -// // check if empty blocks have been proposed? query TaikoL1 contract? -// block, err := s.p.rpc.L2.BlockByNumber(context.Background(), nil) -// s.Nil(err) -// s.Equal(uint64(block.GasLimit()), uint64(21000)) -// s.Equal(block.TxHash(), common.Hash(crypto.Keccak256Hash([]byte{}))) -// } - func TestProposerTestSuite(t *testing.T) { suite.Run(t, new(ProposerTestSuite)) } diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index 29942f178..ffb743dea 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "math/big" - "net/url" "os" "sync" "testing" @@ -19,7 +18,6 @@ import ( "github.com/taikoxyz/taiko-client/driver/chain_syncer/calldata" "github.com/taikoxyz/taiko-client/driver/state" "github.com/taikoxyz/taiko-client/proposer" - "github.com/taikoxyz/taiko-client/prover/http" proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" "github.com/taikoxyz/taiko-client/testutils" ) @@ -31,8 +29,6 @@ type ProofSubmitterTestSuite struct { proposer *proposer.Proposer validProofCh chan *proofProducer.ProofWithHeader invalidProofCh chan *proofProducer.ProofWithHeader - srv *http.Server - cancel context.CancelFunc } func (s *ProofSubmitterTestSuite) SetupTest() { @@ -80,34 +76,28 @@ func (s *ProofSubmitterTestSuite) SetupTest() { l1ProposerPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests - localProverEndpoint := testutils.LocalRandomProverEndpoint() s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests - MaxProposedTxListsPerEpoch: 1, - WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{localProverEndpoint}, - BlockProposalFee: big.NewInt(1000), - BlockProposalFeeIterations: 3, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, + ProverEndpoints: s.ProverEndpoints, + BlockProposalFee: big.NewInt(1000), + BlockProposalFeeIterations: 3, + BlockProposalFeeIncreasePercentage: common.Big2, }))) - srv, cancel, err := testutils.HTTPServer(&s.ClientTestSuite, localProverEndpoint) - s.Nil(err) - - s.srv = srv - s.cancel = cancel s.proposer = prop } func (s *ProofSubmitterTestSuite) TestValidProofSubmitterRequestProofDeadlineExceeded() { - defer s.cancel() ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() @@ -118,7 +108,6 @@ func (s *ProofSubmitterTestSuite) TestValidProofSubmitterRequestProofDeadlineExc } func (s *ProofSubmitterTestSuite) TestValidProofSubmitterSubmitProofMetadataNotFound() { - defer s.cancel() s.Error( s.validProofSubmitter.SubmitProof( context.Background(), &proofProducer.ProofWithHeader{ @@ -132,7 +121,6 @@ func (s *ProofSubmitterTestSuite) TestValidProofSubmitterSubmitProofMetadataNotF } func (s *ProofSubmitterTestSuite) TestValidSubmitProofs() { - defer s.cancel() events := testutils.ProposeAndInsertEmptyBlocks(&s.ClientTestSuite, s.proposer, s.calldataSyncer) for _, e := range events { @@ -143,7 +131,6 @@ func (s *ProofSubmitterTestSuite) TestValidSubmitProofs() { } func (s *ProofSubmitterTestSuite) TestValidProofSubmitterRequestProofCancelled() { - defer s.cancel() ctx, cancel := context.WithCancel(context.Background()) go func() { time.AfterFunc(2*time.Second, func() { diff --git a/prover/prover.go b/prover/prover.go index f1ea280e6..df1ddbfb0 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -187,7 +187,6 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.oracleProverAddress = oracleProverAddress var producer proofProducer.ProofProducer - if cfg.Dummy { producer = &proofProducer.DummyProofProducer{ RandomDummyProofDelayLowerBound: p.cfg.RandomDummyProofDelayLowerBound, diff --git a/prover/prover_test.go b/prover/prover_test.go index ed31d22e1..ce77e4088 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -2,9 +2,7 @@ package prover import ( "context" - "fmt" "math/big" - "net/url" "os" "testing" "time" @@ -58,11 +56,6 @@ func (s *ProverTestSuite) SetupTest() { }))) s.p = p s.cancel = cancel - proverEndpoint := testutils.LocalRandomProverEndpoint() - - go func() { - _ = s.p.srv.Start(fmt.Sprintf(":%v", proverEndpoint.Port())) - }() // Init driver jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) @@ -98,7 +91,7 @@ func (s *ProverTestSuite) SetupTest() { ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: []*url.URL{proverEndpoint}, + ProverEndpoints: s.ProverEndpoints, BlockProposalFee: big.NewInt(1000), BlockProposalFeeIterations: 3, BlockProposalFeeIncreasePercentage: common.Big2, diff --git a/testutils/suite.go b/testutils/suite.go index 761fdeaad..3555972c2 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -3,7 +3,6 @@ package testutils import ( "context" "crypto/ecdsa" - "fmt" "math/big" "net/url" "os" @@ -17,7 +16,6 @@ import ( "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/pkg/rpc" - "github.com/taikoxyz/taiko-client/prover/http" ) type ClientTestSuite struct { @@ -77,18 +75,8 @@ func (s *ClientTestSuite) SetupTest() { s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} s.once.Do(func() { go func() { - proverServer, err := http.NewServer(&http.NewServerOpts{ - ProverPrivateKey: l1ProverPrivKey, - MinProofFee: common.Big1, - MaxCapacity: 10, - RequestCurrentCapacityCh: make(chan struct{}), - ReceiveCurrentCapacityCh: make(chan uint64), - }) + _, _, err := HTTPServer(s, s.ProverEndpoints[0]) s.Nil(err) - - if err := proverServer.Start(fmt.Sprintf(":%v", s.ProverEndpoints[0].Port())); err != nil { - log.Crit("Failed to start prover http server", "error", err) - } }() }) diff --git a/version/version.go b/version/version.go index e2bf17534..4eed8b039 100644 --- a/version/version.go +++ b/version/version.go @@ -2,7 +2,7 @@ package version // Version info. var ( - Version = "0.14.0" + Version = "0.15.0" Meta = "dev" ) From 0d15ff54109cbf1b28b943d37269776afdfaba70 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 4 Sep 2023 16:26:14 +0800 Subject: [PATCH 11/25] chore: fix lint errors --- bindings/encoding/struct_test.go | 5 +++-- cmd/main.go | 6 ------ driver/chain_syncer/chain_syncer_test.go | 2 -- driver/driver_test.go | 2 +- pkg/tx_list_validator/tx_list_validator_test.go | 7 +++++-- prover/proof_submitter/valid_proof_submitter_test.go | 2 +- testutils/helper.go | 2 +- 7 files changed, 11 insertions(+), 15 deletions(-) diff --git a/bindings/encoding/struct_test.go b/bindings/encoding/struct_test.go index a817ad751..31a6f0a43 100644 --- a/bindings/encoding/struct_test.go +++ b/bindings/encoding/struct_test.go @@ -1,6 +1,7 @@ package encoding import ( + cryptoRand "crypto/rand" "math/big" "math/rand" "testing" @@ -122,7 +123,7 @@ func TestToExecutableData(t *testing.T) { // randomHash generates a random blob of data and returns it as a hash. func randomHash() common.Hash { var hash common.Hash - if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil { + if n, err := cryptoRand.Read(hash[:]); n != common.HashLength || err != nil { panic(err) } return hash @@ -131,7 +132,7 @@ func randomHash() common.Hash { // randomBytes generates a random bytes. func randomBytes(size int) (b []byte) { b = make([]byte, size) - if _, err := rand.Read(b); err != nil { + if _, err := cryptoRand.Read(b); err != nil { log.Crit("Generate random bytes error", "error", err) } return diff --git a/cmd/main.go b/cmd/main.go index ea37d4119..db99f174a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,9 +2,7 @@ package main import ( "fmt" - "math/rand" "os" - "time" "github.com/taikoxyz/taiko-client/cmd/flags" "github.com/taikoxyz/taiko-client/cmd/utils" @@ -15,10 +13,6 @@ import ( "github.com/urfave/cli/v2" ) -func init() { - rand.Seed(time.Now().UnixNano()) -} - func main() { app := cli.NewApp() diff --git a/driver/chain_syncer/chain_syncer_test.go b/driver/chain_syncer/chain_syncer_test.go index 08f64bcaa..251eff58f 100644 --- a/driver/chain_syncer/chain_syncer_test.go +++ b/driver/chain_syncer/chain_syncer_test.go @@ -16,7 +16,6 @@ import ( "github.com/taikoxyz/taiko-client/driver/state" "github.com/taikoxyz/taiko-client/pkg/rpc" "github.com/taikoxyz/taiko-client/proposer" - "github.com/taikoxyz/taiko-client/prover/http" "github.com/taikoxyz/taiko-client/testutils" ) @@ -25,7 +24,6 @@ type ChainSyncerTestSuite struct { s *L2ChainSyncer snapshotID string p testutils.Proposer - srv *http.Server } func (s *ChainSyncerTestSuite) SetupTest() { diff --git a/driver/driver_test.go b/driver/driver_test.go index 1d4e271d8..a543b36fa 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -60,7 +60,7 @@ func (s *DriverTestSuite) SetupTest() { TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), L1ProposerPrivKey: l1ProposerPrivKey, L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, ProverEndpoints: s.ProverEndpoints, diff --git a/pkg/tx_list_validator/tx_list_validator_test.go b/pkg/tx_list_validator/tx_list_validator_test.go index f85b06529..cf7d9a3e9 100644 --- a/pkg/tx_list_validator/tx_list_validator_test.go +++ b/pkg/tx_list_validator/tx_list_validator_test.go @@ -1,14 +1,15 @@ package tx_list_validator import ( + "crypto/rand" "math/big" - "math/rand" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/require" @@ -132,6 +133,8 @@ func rlpEncodedTransactionBytes(l int, signed bool) []byte { func randBytes(l uint64) []byte { b := make([]byte, l) - rand.Read(b) + if _, err := rand.Read(b); err != nil { + log.Crit("Failed to generate random bytes", "error", err) + } return b } diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index ffb743dea..9d749c67f 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -85,7 +85,7 @@ func (s *ProofSubmitterTestSuite) SetupTest() { TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), L1ProposerPrivKey: l1ProposerPrivKey, L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, ProverEndpoints: s.ProverEndpoints, diff --git a/testutils/helper.go b/testutils/helper.go index 2721023c5..c9ad3ddc5 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -3,9 +3,9 @@ package testutils import ( "context" "crypto/ecdsa" + "crypto/rand" "fmt" "math/big" - "math/rand" "net/url" "os" "time" From 6556118672808c4115ba520e65ecca49c1b8e2e4 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 4 Sep 2023 22:44:43 +0800 Subject: [PATCH 12/25] feat: update tests --- testutils/suite.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/testutils/suite.go b/testutils/suite.go index 3555972c2..d4ea2aa49 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -6,7 +6,6 @@ import ( "math/big" "net/url" "os" - "sync" "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -16,6 +15,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/prover/http" ) type ClientTestSuite struct { @@ -25,7 +25,7 @@ type ClientTestSuite struct { TestAddrPrivKey *ecdsa.PrivateKey TestAddr common.Address ProverEndpoints []*url.URL - once sync.Once + proverServer *http.Server } func (s *ClientTestSuite) SetupTest() { @@ -73,12 +73,9 @@ func (s *ClientTestSuite) SetupTest() { s.Nil(err) s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} - s.once.Do(func() { - go func() { - _, _, err := HTTPServer(s, s.ProverEndpoints[0]) - s.Nil(err) - }() - }) + server, _, err := HTTPServer(s, s.ProverEndpoints[0]) + s.Nil(err) + s.proverServer = server tokenBalance, err := rpcCli.TaikoL1.GetTaikoTokenBalance(nil, crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey)) s.Nil(err) @@ -110,6 +107,7 @@ func (s *ClientTestSuite) TearDownTest() { s.True(revertRes) s.Nil(rpc.SetHead(context.Background(), s.RpcClient.L2RawRPC, common.Big0)) + s.Nil(s.proverServer.Shutdown(context.Background())) } func (s *ClientTestSuite) SetL1Automine(automine bool) { From ff86db9f4cd34f74fbf64512841fdd69f200c62e Mon Sep 17 00:00:00 2001 From: David Date: Mon, 4 Sep 2023 22:56:22 +0800 Subject: [PATCH 13/25] test: update tests --- prover/http/server.go | 11 +++++++++-- testutils/helper.go | 21 ++++++++++----------- testutils/suite.go | 2 +- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/prover/http/server.go b/prover/http/server.go index 02fdc5c63..a2508557b 100644 --- a/prover/http/server.go +++ b/prover/http/server.go @@ -31,6 +31,7 @@ type NewServerOpts struct { MinProofFee *big.Int RequestCurrentCapacityCh chan struct{} ReceiveCurrentCapacityCh chan uint64 + HideBanner bool // only for testing purposes } func NewServer(opts *NewServerOpts) (*Server, error) { @@ -45,6 +46,10 @@ func NewServer(opts *NewServerOpts) (*Server, error) { receiveCurrentCapacityCh: opts.ReceiveCurrentCapacityCh, } + if opts.HideBanner { + srv.echo.HideBanner = true + } + srv.configureMiddleware() srv.configureRoutes() @@ -71,6 +76,7 @@ func (srv *Server) Health(c echo.Context) error { return c.NoContent(http.StatusOK) } +// LogSkipper implements the `middleware.Skipper` interface. func LogSkipper(c echo.Context) bool { switch c.Request().URL.Path { case "/healthz": @@ -82,13 +88,14 @@ func LogSkipper(c echo.Context) bool { } } +// configureMiddleware configures the server middlewares. func (srv *Server) configureMiddleware() { srv.echo.Use(middleware.RequestID()) srv.echo.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ Skipper: LogSkipper, - Format: `{"time":"${time_rfc3339_nano}","level":"INFO","message":{"id":"${id}","remote_ip":"${remote_ip}",` + //nolint:lll - `"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` + //nolint:lll + Format: `{"time":"${time_rfc3339_nano}","level":"INFO","message":{"id":"${id}","remote_ip":"${remote_ip}",` + + `"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` + `"response_status":${status},"error":"${error}","latency":${latency},"latency_human":"${latency_human}",` + `"bytes_in":${bytes_in},"bytes_out":${bytes_out}}}` + "\n", Output: os.Stdout, diff --git a/testutils/helper.go b/testutils/helper.go index c9ad3ddc5..ae026f0e5 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -7,7 +7,6 @@ import ( "fmt" "math/big" "net/url" - "os" "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -180,18 +179,20 @@ func DepositEtherToL2(s *ClientTestSuite, depositerPrivKey *ecdsa.PrivateKey, re } } -// HTTPServer starts a new prover server that has channel listeners to respond and react +// NewTestProverServer starts a new prover server that has channel listeners to respond and react // to requests for capacity, which provers can call. -func HTTPServer(s *ClientTestSuite, url *url.URL) (*http.Server, func(), error) { - l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) - s.Nil(err) - +func NewTestProverServer( + s *ClientTestSuite, + proverPrivKey *ecdsa.PrivateKey, + url *url.URL, +) (*http.Server, func(), error) { serverOpts := &http.NewServerOpts{ - ProverPrivateKey: l1ProverPrivKey, - MinProofFee: big.NewInt(1), + ProverPrivateKey: proverPrivKey, + MinProofFee: common.Big1, MaxCapacity: 10, RequestCurrentCapacityCh: make(chan struct{}), ReceiveCurrentCapacityCh: make(chan uint64), + HideBanner: true, } srv, err := http.NewServer(serverOpts) @@ -209,9 +210,7 @@ func HTTPServer(s *ClientTestSuite, url *url.URL) (*http.Server, func(), error) } }() - go func() { - _ = srv.Start(fmt.Sprintf(":%v", url.Port())) - }() + go func() { _ = srv.Start(fmt.Sprintf(":%v", url.Port())) }() return srv, func() { cancel() diff --git a/testutils/suite.go b/testutils/suite.go index d4ea2aa49..b1c35130a 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -73,7 +73,7 @@ func (s *ClientTestSuite) SetupTest() { s.Nil(err) s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} - server, _, err := HTTPServer(s, s.ProverEndpoints[0]) + server, _, err := NewTestProverServer(s, l1ProverPrivKey, s.ProverEndpoints[0]) s.Nil(err) s.proverServer = server From ab862e0dc3af9003aed6326d1345525ed12f0bbd Mon Sep 17 00:00:00 2001 From: David Date: Tue, 5 Sep 2023 12:26:31 +0800 Subject: [PATCH 14/25] test: update tests --- driver/chain_syncer/chain_syncer_test.go | 15 +++---- proposer/prover_selector/eth_fee_selector.go | 8 +--- prover/config_test.go | 3 -- prover/http/propose_block.go | 6 ++- prover/http/routes.go | 7 --- prover/http/server.go | 26 ++++++----- prover/http/server_test.go | 6 +-- prover/prover_test.go | 21 ++++++--- testutils/helper.go | 46 ++++++++++++-------- testutils/suite.go | 4 +- 10 files changed, 77 insertions(+), 65 deletions(-) delete mode 100644 prover/http/routes.go diff --git a/driver/chain_syncer/chain_syncer_test.go b/driver/chain_syncer/chain_syncer_test.go index 251eff58f..1ef204ec4 100644 --- a/driver/chain_syncer/chain_syncer_test.go +++ b/driver/chain_syncer/chain_syncer_test.go @@ -85,7 +85,6 @@ func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead2() { testutils.ProposeAndInsertEmptyBlocks(&s.ClientTestSuite, s.p, s.s.calldataSyncer) // NOTE: need to prove the proposed blocks to be verified, writing helper function - // generate transactopts to interact with TaikoL1 contract with. privKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) @@ -98,10 +97,10 @@ func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead2() { l2Head, err := s.RpcClient.L2.HeaderByNumber(context.Background(), nil) s.Nil(err) - log.Info("L1HeaderByNumber head:", "number", head.Number) + log.Info("L1HeaderByNumber head", "number", head.Number) // (equiv to s.state.GetL2Head().Number) - log.Info("L2HeaderByNumber head:", "number", l2Head.Number) - log.Info("LatestVerifiedBlock number:", "number", s.s.state.GetLatestVerifiedBlock().ID.Uint64()) + log.Info("L2HeaderByNumber head", "number", l2Head.Number) + log.Info("LatestVerifiedBlock number", "number", s.s.state.GetLatestVerifiedBlock().ID.Uint64()) config, err := s.s.rpc.TaikoL1.GetConfig(&bind.CallOpts{}) s.Nil(err) @@ -114,7 +113,7 @@ func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead2() { "evm_increaseTime", config.ProofRegularCooldown.Uint64())) s.NotNil(result) - log.Info("evm time increase:", "number", result) + log.Info("EVM time increase", "number", result) // interact with TaikoL1 contract to allow for verification of L2 blocks tx, err := s.s.rpc.TaikoL1.VerifyBlocks(opts, uint64(3)) @@ -127,9 +126,9 @@ func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead2() { l2Head2, err := s.RpcClient.L2.HeaderByNumber(context.Background(), nil) s.Nil(err) - log.Info("L1HeaderByNumber head2:", "number", head2.Number) - log.Info("L2HeaderByNumber head:", "number", l2Head2.Number) - log.Info("LatestVerifiedBlock number:", "number", s.s.state.GetLatestVerifiedBlock().ID.Uint64()) + log.Info("L1HeaderByNumber head2", "number", head2.Number) + log.Info("L2HeaderByNumber head", "number", l2Head2.Number) + log.Info("LatestVerifiedBlock number", "number", s.s.state.GetLatestVerifiedBlock().ID.Uint64()) s.RevertSnapshot() } diff --git a/proposer/prover_selector/eth_fee_selector.go b/proposer/prover_selector/eth_fee_selector.go index 5b0b60e6e..a031d326d 100644 --- a/proposer/prover_selector/eth_fee_selector.go +++ b/proposer/prover_selector/eth_fee_selector.go @@ -16,6 +16,7 @@ import ( "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/prover/http" ) var ( @@ -24,11 +25,6 @@ var ( errUnableToFindProver = errors.New("unable to find prover") ) -type assignProverResponse struct { - SignedPayload []byte `json:"signedPayload"` - Prover common.Address `json:"prover"` -} - type ETHFeeSelector struct { protocolConfigs *bindings.TaikoDataConfig rpc *rpc.Client @@ -170,7 +166,7 @@ func assignProver( var ( client = resty.New() reqBody = &encoding.ProposeBlockData{Expiry: expiry, Input: *meta, Fee: fee} - result = assignProverResponse{} + result = http.ProposeBlockResponse{} ) requestUrl, err := url.JoinPath(endpoint.String(), "/proposeBlock") if err != nil { diff --git a/prover/config_test.go b/prover/config_test.go index 31bad348e..a857e942a 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" "github.com/taikoxyz/taiko-client/cmd/flags" "github.com/urfave/cli/v2" ) @@ -22,11 +21,9 @@ var ( minProofFee = "1024" ) -// TODO: fix this test func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { app := s.SetupApp() app.Action = func(ctx *cli.Context) error { - log.Info("ctx", "ctx", ctx.FlagNames(), "v", ctx.Args()) c, err := NewConfigFromCliContext(ctx) s.Nil(err) s.Equal(l1WsEndpoint, c.L1WsEndpoint) diff --git a/prover/http/propose_block.go b/prover/http/propose_block.go index f1adad314..7ced5f494 100644 --- a/prover/http/propose_block.go +++ b/prover/http/propose_block.go @@ -12,7 +12,9 @@ import ( "github.com/taikoxyz/taiko-client/bindings/encoding" ) -type proposeBlockResp struct { +// ProposeBlockResponse represents the JSON response which will be returned by +// the ProposeBlock request handler. +type ProposeBlockResponse struct { SignedPayload []byte `json:"signedPayload"` Prover common.Address `json:"prover"` } @@ -54,7 +56,7 @@ func (srv *Server) ProposeBlock(c echo.Context) error { return echo.NewHTTPError(http.StatusInternalServerError, err) } - resp := &proposeBlockResp{ + resp := &ProposeBlockResponse{ SignedPayload: signed, Prover: srv.proverAddress, } diff --git a/prover/http/routes.go b/prover/http/routes.go deleted file mode 100644 index 0f7124d29..000000000 --- a/prover/http/routes.go +++ /dev/null @@ -1,7 +0,0 @@ -package http - -func (srv *Server) configureRoutes() { - srv.echo.GET("/healthz", srv.Health) - srv.echo.GET("/", srv.Health) - srv.echo.POST("/proposeBlock", srv.ProposeBlock) -} diff --git a/prover/http/server.go b/prover/http/server.go index a2508557b..103da5d98 100644 --- a/prover/http/server.go +++ b/prover/http/server.go @@ -13,27 +13,29 @@ import ( "github.com/labstack/echo/v4/middleware" ) +// Server represents a prover server instance. type Server struct { echo *echo.Echo proverPrivateKey *ecdsa.PrivateKey proverAddress common.Address - // capacity related configs + // Capacity related configs maxCapacity uint64 requestCurrentCapacityCh chan struct{} receiveCurrentCapacityCh chan uint64 minProofFee *big.Int } +// NewServerOpts contains all configurations for creating a prover server instance. type NewServerOpts struct { ProverPrivateKey *ecdsa.PrivateKey MaxCapacity uint64 MinProofFee *big.Int RequestCurrentCapacityCh chan struct{} ReceiveCurrentCapacityCh chan uint64 - HideBanner bool // only for testing purposes } +// NewServer creates a new prover server instance. func NewServer(opts *NewServerOpts) (*Server, error) { address := crypto.PubkeyToAddress(opts.ProverPrivateKey.PublicKey) srv := &Server{ @@ -46,32 +48,29 @@ func NewServer(opts *NewServerOpts) (*Server, error) { receiveCurrentCapacityCh: opts.ReceiveCurrentCapacityCh, } - if opts.HideBanner { - srv.echo.HideBanner = true - } - + srv.echo.HideBanner = true srv.configureMiddleware() srv.configureRoutes() return srv, nil } -// Start starts the HTTP server +// Start starts the HTTP server. func (srv *Server) Start(address string) error { return srv.echo.Start(address) } -// Shutdown shuts down the HTTP server +// Shutdown shuts down the HTTP server. func (srv *Server) Shutdown(ctx context.Context) error { return srv.echo.Shutdown(ctx) } -// ServeHTTP implements the `http.Handler` interface which serves HTTP requests +// ServeHTTP implements the `http.Handler` interface which serves HTTP requests. func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { srv.echo.ServeHTTP(w, r) } -// Health endpoints for probes +// Health endpoints for probes. func (srv *Server) Health(c echo.Context) error { return c.NoContent(http.StatusOK) } @@ -101,3 +100,10 @@ func (srv *Server) configureMiddleware() { Output: os.Stdout, })) } + +// configureRoutes contains all routes which will be used by prover server. +func (srv *Server) configureRoutes() { + srv.echo.GET("/", srv.Health) + srv.echo.GET("/healthz", srv.Health) + srv.echo.POST("/proposeBlock", srv.ProposeBlock) +} diff --git a/prover/http/server_test.go b/prover/http/server_test.go index f89c266b5..660e4de83 100644 --- a/prover/http/server_test.go +++ b/prover/http/server_test.go @@ -32,7 +32,7 @@ func newTestServer(url string) *Server { return srv } -func Test_Health(t *testing.T) { +func TestHealth(t *testing.T) { srv := newTestServer("") req, _ := http.NewRequest(echo.GET, "/healthz", nil) @@ -45,7 +45,7 @@ func Test_Health(t *testing.T) { } } -func Test_Root(t *testing.T) { +func TestRoot(t *testing.T) { srv := newTestServer("") req, _ := http.NewRequest(echo.GET, "/", nil) @@ -58,7 +58,7 @@ func Test_Root(t *testing.T) { } } -func Test_StartShutdown(t *testing.T) { +func TestStartShutdown(t *testing.T) { srv := newTestServer("") go func() { diff --git a/prover/prover_test.go b/prover/prover_test.go index ce77e4088..d5b28863a 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -2,8 +2,9 @@ package prover import ( "context" - "math/big" + "net/url" "os" + "strconv" "testing" "time" @@ -35,6 +36,10 @@ func (s *ProverTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) + proverServerUrl := testutils.LocalRandomProverEndpoint() + port, err := strconv.Atoi(proverServerUrl.Port()) + s.Nil(err) + ctx, cancel := context.WithCancel(context.Background()) p := new(Prover) s.Nil(InitFromConfig(ctx, p, (&Config{ @@ -51,9 +56,11 @@ func (s *ProverTestSuite) SetupTest() { MaxConcurrentProvingJobs: 1, CheckProofWindowExpiredInterval: 5 * time.Second, ProveUnassignedBlocks: true, - Capacity: 100, - MinProofFee: big.NewInt(1), + Capacity: 1024, + MinProofFee: common.Big1, + HTTPServerPort: uint64(port), }))) + p.srv = testutils.NewTestProverServer(&s.ClientTestSuite, l1ProverPrivKey, proverServerUrl) s.p = p s.cancel = cancel @@ -91,8 +98,8 @@ func (s *ProverTestSuite) SetupTest() { ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, WaitReceiptTimeout: 10 * time.Second, - ProverEndpoints: s.ProverEndpoints, - BlockProposalFee: big.NewInt(1000), + ProverEndpoints: []*url.URL{proverServerUrl}, + BlockProposalFee: common.Big256, BlockProposalFeeIterations: 3, BlockProposalFeeIncreasePercentage: common.Big2, }))) @@ -202,6 +209,10 @@ func (s *ProverTestSuite) TestStartClose() { s.NotPanics(func() { s.p.Close(context.Background()) }) } +func (s *ProverTestSuite) TearDownTest() { + s.Nil(s.p.srv.Shutdown(context.Background())) +} + func TestProverTestSuite(t *testing.T) { suite.Run(t, new(ProverTestSuite)) } diff --git a/testutils/helper.go b/testutils/helper.go index ae026f0e5..5fcaf7674 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -6,9 +6,11 @@ import ( "crypto/rand" "fmt" "math/big" + netHttp "net/http" "net/url" "time" + "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -16,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" + "github.com/go-resty/resty/v2" "github.com/phayes/freeport" "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" @@ -185,37 +188,44 @@ func NewTestProverServer( s *ClientTestSuite, proverPrivKey *ecdsa.PrivateKey, url *url.URL, -) (*http.Server, func(), error) { +) *http.Server { serverOpts := &http.NewServerOpts{ ProverPrivateKey: proverPrivKey, MinProofFee: common.Big1, - MaxCapacity: 10, - RequestCurrentCapacityCh: make(chan struct{}), - ReceiveCurrentCapacityCh: make(chan uint64), - HideBanner: true, + MaxCapacity: 1024, + RequestCurrentCapacityCh: make(chan struct{}, 1), + ReceiveCurrentCapacityCh: make(chan uint64, 1), } srv, err := http.NewServer(serverOpts) s.Nil(err) - ctx, cancel := context.WithCancel(context.Background()) go func() { - for { - select { - case <-serverOpts.RequestCurrentCapacityCh: - serverOpts.ReceiveCurrentCapacityCh <- 100 - case <-ctx.Done(): - return - } + for range serverOpts.RequestCurrentCapacityCh { + serverOpts.ReceiveCurrentCapacityCh <- 1024 } }() - go func() { _ = srv.Start(fmt.Sprintf(":%v", url.Port())) }() + go func() { + if err := srv.Start(fmt.Sprintf(":%v", url.Port())); err != netHttp.ErrServerClosed { + 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())) - return srv, func() { - cancel() - _ = srv.Shutdown(ctx) - }, err + return srv } // RandomHash generates a random blob of data and returns it as a hash. diff --git a/testutils/suite.go b/testutils/suite.go index b1c35130a..5c62d5d3f 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -73,9 +73,7 @@ func (s *ClientTestSuite) SetupTest() { s.Nil(err) s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} - server, _, err := NewTestProverServer(s, l1ProverPrivKey, s.ProverEndpoints[0]) - s.Nil(err) - s.proverServer = server + s.proverServer = NewTestProverServer(s, l1ProverPrivKey, s.ProverEndpoints[0]) tokenBalance, err := rpcCli.TaikoL1.GetTaikoTokenBalance(nil, crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey)) s.Nil(err) From bf1f7bc23a2857a7ffa64fd8383823ee1c72f0d3 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 5 Sep 2023 12:31:35 +0800 Subject: [PATCH 15/25] feat: unused config --- proposer/proposer_test.go | 1 - prover/http/server.go | 3 --- prover/http/server_test.go | 1 - prover/prover.go | 1 - testutils/helper.go | 1 - 5 files changed, 7 deletions(-) diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 0d3d8e259..e95b0e914 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -61,7 +61,6 @@ func (s *ProposerTestSuite) SetupTest() { serverOpts := &http.NewServerOpts{ ProverPrivateKey: l1ProverPrivKey, MinProofFee: common.Big1, - MaxCapacity: 10, RequestCurrentCapacityCh: make(chan struct{}), ReceiveCurrentCapacityCh: make(chan uint64), } diff --git a/prover/http/server.go b/prover/http/server.go index 103da5d98..33700f3cb 100644 --- a/prover/http/server.go +++ b/prover/http/server.go @@ -20,7 +20,6 @@ type Server struct { proverAddress common.Address // Capacity related configs - maxCapacity uint64 requestCurrentCapacityCh chan struct{} receiveCurrentCapacityCh chan uint64 minProofFee *big.Int @@ -29,7 +28,6 @@ type Server struct { // NewServerOpts contains all configurations for creating a prover server instance. type NewServerOpts struct { ProverPrivateKey *ecdsa.PrivateKey - MaxCapacity uint64 MinProofFee *big.Int RequestCurrentCapacityCh chan struct{} ReceiveCurrentCapacityCh chan uint64 @@ -42,7 +40,6 @@ func NewServer(opts *NewServerOpts) (*Server, error) { proverPrivateKey: opts.ProverPrivateKey, proverAddress: address, echo: echo.New(), - maxCapacity: opts.MaxCapacity, minProofFee: opts.MinProofFee, requestCurrentCapacityCh: opts.RequestCurrentCapacityCh, receiveCurrentCapacityCh: opts.ReceiveCurrentCapacityCh, diff --git a/prover/http/server_test.go b/prover/http/server_test.go index 660e4de83..72b271632 100644 --- a/prover/http/server_test.go +++ b/prover/http/server_test.go @@ -20,7 +20,6 @@ func newTestServer(url string) *Server { srv := &Server{ echo: echo.New(), proverPrivateKey: l1ProverPrivKey, - maxCapacity: 8, minProofFee: big.NewInt(1), requestCurrentCapacityCh: make(chan struct{}, 1024), receiveCurrentCapacityCh: make(chan uint64, 1024), diff --git a/prover/prover.go b/prover/prover.go index df1ddbfb0..76c4a209b 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -123,7 +123,6 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { if !p.cfg.OracleProver { p.srv, err = http.NewServer(&http.NewServerOpts{ ProverPrivateKey: p.cfg.L1ProverPrivKey, - MaxCapacity: p.cfg.Capacity, MinProofFee: p.cfg.MinProofFee, RequestCurrentCapacityCh: p.requestCurrentCapacityCh, ReceiveCurrentCapacityCh: p.receiveCurrentCapacityCh, diff --git a/testutils/helper.go b/testutils/helper.go index 5fcaf7674..1cc49fe4e 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -192,7 +192,6 @@ func NewTestProverServer( serverOpts := &http.NewServerOpts{ ProverPrivateKey: proverPrivKey, MinProofFee: common.Big1, - MaxCapacity: 1024, RequestCurrentCapacityCh: make(chan struct{}, 1), ReceiveCurrentCapacityCh: make(chan uint64, 1), } From d970a699825b7ddaca11cf39dd27346a13d99e33 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 5 Sep 2023 12:33:30 +0800 Subject: [PATCH 16/25] feat: reuse zeroAddress --- pkg/rpc/client.go | 2 +- pkg/rpc/utils.go | 4 ++-- prover/prover.go | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/rpc/client.go b/pkg/rpc/client.go index f7e6f8844..2f04b6e0d 100644 --- a/pkg/rpc/client.go +++ b/pkg/rpc/client.go @@ -100,7 +100,7 @@ func NewClient(ctx context.Context, cfg *ClientConfig) (*Client, error) { } var taikoToken *bindings.TaikoToken - if cfg.TaikoTokenAddress.Hex() != zeroAddress.Hex() { + if cfg.TaikoTokenAddress.Hex() != ZeroAddress.Hex() { taikoToken, err = bindings.NewTaikoToken(cfg.TaikoTokenAddress, l1RPC) if err != nil { return nil, err diff --git a/pkg/rpc/utils.go b/pkg/rpc/utils.go index e34c0afb6..e416210f7 100644 --- a/pkg/rpc/utils.go +++ b/pkg/rpc/utils.go @@ -19,9 +19,9 @@ import ( ) var ( + ZeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") waitReceiptPollingInterval = 3 * time.Second defaultWaitReceiptTimeout = 1 * time.Minute - zeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") ) // GetProtocolStateVariables gets the protocol states from TaikoL1 contract. @@ -195,7 +195,7 @@ func IsArchiveNode(ctx context.Context, client *EthClient, l2GenesisHeight uint6 ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) defer cancel() - if _, err := client.BalanceAt(ctxWithTimeout, zeroAddress, new(big.Int).SetUint64(l2GenesisHeight)); err != nil { + if _, err := client.BalanceAt(ctxWithTimeout, ZeroAddress, new(big.Int).SetUint64(l2GenesisHeight)); err != nil { if strings.Contains(err.Error(), "missing trie node") { return false, nil } diff --git a/prover/prover.go b/prover/prover.go index 76c4a209b..c3a41f471 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -31,7 +31,6 @@ import ( var ( errNoCapacity = errors.New("no prover capacity available") - zeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") ) type cancelFunc func() @@ -940,7 +939,7 @@ func (p *Prover) checkProofWindowExpired(ctx context.Context, l1Height, blockId return encoding.TryParsingCustomError(err) } - if transition.Prover == zeroAddress { + if transition.Prover == rpc.ZeroAddress { log.Info( "Proof window for proof not assigned to us expired, requesting proof", "blockID", From a4d50f29da8898f1a293a57d33cf13dfd4b3f126 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 5 Sep 2023 12:36:39 +0800 Subject: [PATCH 17/25] feat: rename --- proposer/proposer_test.go | 8 +++--- proposer/prover_selector/eth_fee_selector.go | 4 +-- prover/prover.go | 12 ++++---- prover/prover_test.go | 4 +-- prover/{http => server}/propose_block.go | 4 +-- prover/{http => server}/propose_block_test.go | 2 +- prover/{http => server}/server.go | 28 +++++++++---------- prover/{http => server}/server_test.go | 6 ++-- testutils/helper.go | 12 ++++---- testutils/suite.go | 4 +-- 10 files changed, 42 insertions(+), 42 deletions(-) rename prover/{http => server}/propose_block.go (96%) rename prover/{http => server}/propose_block_test.go (99%) rename prover/{http => server}/server.go (77%) rename prover/{http => server}/server_test.go (94%) diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index e95b0e914..8e1e74810 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -14,7 +14,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" - "github.com/taikoxyz/taiko-client/prover/http" + "github.com/taikoxyz/taiko-client/prover/server" "github.com/taikoxyz/taiko-client/testutils" ) @@ -22,7 +22,7 @@ type ProposerTestSuite struct { testutils.ClientTestSuite p *Proposer cancel context.CancelFunc - srv *http.Server + srv *server.ProverServer } func (s *ProposerTestSuite) SetupTest() { @@ -58,14 +58,14 @@ func (s *ProposerTestSuite) SetupTest() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - serverOpts := &http.NewServerOpts{ + serverOpts := &server.NewProverServerOpts{ ProverPrivateKey: l1ProverPrivKey, MinProofFee: common.Big1, RequestCurrentCapacityCh: make(chan struct{}), ReceiveCurrentCapacityCh: make(chan uint64), } - s.srv, err = http.NewServer(serverOpts) + s.srv, err = server.New(serverOpts) s.Nil(err) go func() { diff --git a/proposer/prover_selector/eth_fee_selector.go b/proposer/prover_selector/eth_fee_selector.go index a031d326d..c4aa5b836 100644 --- a/proposer/prover_selector/eth_fee_selector.go +++ b/proposer/prover_selector/eth_fee_selector.go @@ -16,7 +16,7 @@ import ( "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" "github.com/taikoxyz/taiko-client/pkg/rpc" - "github.com/taikoxyz/taiko-client/prover/http" + "github.com/taikoxyz/taiko-client/prover/server" ) var ( @@ -166,7 +166,7 @@ func assignProver( var ( client = resty.New() reqBody = &encoding.ProposeBlockData{Expiry: expiry, Input: *meta, Fee: fee} - result = http.ProposeBlockResponse{} + result = server.ProposeBlockResponse{} ) requestUrl, err := url.JoinPath(endpoint.String(), "/proposeBlock") if err != nil { diff --git a/prover/prover.go b/prover/prover.go index c3a41f471..076f435de 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" "math/big" - netHttp "net/http" + "net/http" "strings" "sync" "time" @@ -23,9 +23,9 @@ import ( "github.com/taikoxyz/taiko-client/metrics" eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" "github.com/taikoxyz/taiko-client/pkg/rpc" - "github.com/taikoxyz/taiko-client/prover/http" proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" proofSubmitter "github.com/taikoxyz/taiko-client/prover/proof_submitter" + "github.com/taikoxyz/taiko-client/prover/server" "github.com/urfave/cli/v2" ) @@ -45,8 +45,8 @@ type Prover struct { // Clients rpc *rpc.Client - // HTTP Server - srv *http.Server + // Prover Server + srv *server.ProverServer // Contract configurations protocolConfigs *bindings.TaikoDataConfig @@ -120,7 +120,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.receiveCurrentCapacityCh = make(chan uint64, 1024) if !p.cfg.OracleProver { - p.srv, err = http.NewServer(&http.NewServerOpts{ + p.srv, err = server.New(&server.NewProverServerOpts{ ProverPrivateKey: p.cfg.L1ProverPrivKey, MinProofFee: p.cfg.MinProofFee, RequestCurrentCapacityCh: p.requestCurrentCapacityCh, @@ -230,7 +230,7 @@ func (p *Prover) Start() error { p.initSubscription() if !p.cfg.OracleProver { go func() { - if err := p.srv.Start(fmt.Sprintf(":%v", p.cfg.HTTPServerPort)); !errors.Is(err, netHttp.ErrServerClosed) { + if err := p.srv.Start(fmt.Sprintf(":%v", p.cfg.HTTPServerPort)); !errors.Is(err, http.ErrServerClosed) { log.Crit("Failed to start http server", "error", err) } }() diff --git a/prover/prover_test.go b/prover/prover_test.go index d5b28863a..2ada1add3 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -16,8 +16,8 @@ import ( "github.com/taikoxyz/taiko-client/driver" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/proposer" - "github.com/taikoxyz/taiko-client/prover/http" producer "github.com/taikoxyz/taiko-client/prover/proof_producer" + "github.com/taikoxyz/taiko-client/prover/server" "github.com/taikoxyz/taiko-client/testutils" ) @@ -201,7 +201,7 @@ func (s *ProverTestSuite) TestStartClose() { l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) s.Nil(err) - s.p.srv, _ = http.NewServer(&http.NewServerOpts{ + s.p.srv, _ = server.New(&server.NewProverServerOpts{ ProverPrivateKey: l1ProverPrivKey, }) s.Nil(s.p.Start()) diff --git a/prover/http/propose_block.go b/prover/server/propose_block.go similarity index 96% rename from prover/http/propose_block.go rename to prover/server/propose_block.go index 7ced5f494..98a665552 100644 --- a/prover/http/propose_block.go +++ b/prover/server/propose_block.go @@ -1,4 +1,4 @@ -package http +package server import ( "context" @@ -22,7 +22,7 @@ type ProposeBlockResponse struct { // ProposeBlock handles a propose block request, decides if this prover wants to // handle this block, and if so, returns a signed payload the proposer // can submit onchain. -func (srv *Server) ProposeBlock(c echo.Context) error { +func (srv *ProverServer) ProposeBlock(c echo.Context) error { r := &encoding.ProposeBlockData{} if err := c.Bind(r); err != nil { return c.JSON(http.StatusUnprocessableEntity, err) diff --git a/prover/http/propose_block_test.go b/prover/server/propose_block_test.go similarity index 99% rename from prover/http/propose_block_test.go rename to prover/server/propose_block_test.go index 5acd7a4a2..9eb7c8dba 100644 --- a/prover/http/propose_block_test.go +++ b/prover/server/propose_block_test.go @@ -1,4 +1,4 @@ -package http +package server import ( "crypto/rand" diff --git a/prover/http/server.go b/prover/server/server.go similarity index 77% rename from prover/http/server.go rename to prover/server/server.go index 33700f3cb..5c3e49b1f 100644 --- a/prover/http/server.go +++ b/prover/server/server.go @@ -1,4 +1,4 @@ -package http +package server import ( "context" @@ -13,8 +13,8 @@ import ( "github.com/labstack/echo/v4/middleware" ) -// Server represents a prover server instance. -type Server struct { +// ProverServer represents a prover server instance. +type ProverServer struct { echo *echo.Echo proverPrivateKey *ecdsa.PrivateKey proverAddress common.Address @@ -25,18 +25,18 @@ type Server struct { minProofFee *big.Int } -// NewServerOpts contains all configurations for creating a prover server instance. -type NewServerOpts struct { +// NewProverServerOpts contains all configurations for creating a prover server instance. +type NewProverServerOpts struct { ProverPrivateKey *ecdsa.PrivateKey MinProofFee *big.Int RequestCurrentCapacityCh chan struct{} ReceiveCurrentCapacityCh chan uint64 } -// NewServer creates a new prover server instance. -func NewServer(opts *NewServerOpts) (*Server, error) { +// New creates a new prover server instance. +func New(opts *NewProverServerOpts) (*ProverServer, error) { address := crypto.PubkeyToAddress(opts.ProverPrivateKey.PublicKey) - srv := &Server{ + srv := &ProverServer{ proverPrivateKey: opts.ProverPrivateKey, proverAddress: address, echo: echo.New(), @@ -53,22 +53,22 @@ func NewServer(opts *NewServerOpts) (*Server, error) { } // Start starts the HTTP server. -func (srv *Server) Start(address string) error { +func (srv *ProverServer) Start(address string) error { return srv.echo.Start(address) } // Shutdown shuts down the HTTP server. -func (srv *Server) Shutdown(ctx context.Context) error { +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 *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (srv *ProverServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { srv.echo.ServeHTTP(w, r) } // Health endpoints for probes. -func (srv *Server) Health(c echo.Context) error { +func (srv *ProverServer) Health(c echo.Context) error { return c.NoContent(http.StatusOK) } @@ -85,7 +85,7 @@ func LogSkipper(c echo.Context) bool { } // configureMiddleware configures the server middlewares. -func (srv *Server) configureMiddleware() { +func (srv *ProverServer) configureMiddleware() { srv.echo.Use(middleware.RequestID()) srv.echo.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ @@ -99,7 +99,7 @@ func (srv *Server) configureMiddleware() { } // configureRoutes contains all routes which will be used by prover server. -func (srv *Server) configureRoutes() { +func (srv *ProverServer) configureRoutes() { srv.echo.GET("/", srv.Health) srv.echo.GET("/healthz", srv.Health) srv.echo.POST("/proposeBlock", srv.ProposeBlock) diff --git a/prover/http/server_test.go b/prover/server/server_test.go similarity index 94% rename from prover/http/server_test.go rename to prover/server/server_test.go index 72b271632..07c48aadc 100644 --- a/prover/http/server_test.go +++ b/prover/server/server_test.go @@ -1,4 +1,4 @@ -package http +package server import ( "context" @@ -14,10 +14,10 @@ import ( "github.com/stretchr/testify/assert" ) -func newTestServer(url string) *Server { +func newTestServer(url string) *ProverServer { l1ProverPrivKey, _ := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) - srv := &Server{ + srv := &ProverServer{ echo: echo.New(), proverPrivateKey: l1ProverPrivKey, minProofFee: big.NewInt(1), diff --git a/testutils/helper.go b/testutils/helper.go index 1cc49fe4e..c750fb357 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -6,7 +6,7 @@ import ( "crypto/rand" "fmt" "math/big" - netHttp "net/http" + "net/http" "net/url" "time" @@ -22,7 +22,7 @@ import ( "github.com/phayes/freeport" "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" - "github.com/taikoxyz/taiko-client/prover/http" + "github.com/taikoxyz/taiko-client/prover/server" ) func ProposeInvalidTxListBytes(s *ClientTestSuite, proposer Proposer) { @@ -188,15 +188,15 @@ func NewTestProverServer( s *ClientTestSuite, proverPrivKey *ecdsa.PrivateKey, url *url.URL, -) *http.Server { - serverOpts := &http.NewServerOpts{ +) *server.ProverServer { + serverOpts := &server.NewProverServerOpts{ ProverPrivateKey: proverPrivKey, MinProofFee: common.Big1, RequestCurrentCapacityCh: make(chan struct{}, 1), ReceiveCurrentCapacityCh: make(chan uint64, 1), } - srv, err := http.NewServer(serverOpts) + srv, err := server.New(serverOpts) s.Nil(err) go func() { @@ -206,7 +206,7 @@ func NewTestProverServer( }() go func() { - if err := srv.Start(fmt.Sprintf(":%v", url.Port())); err != netHttp.ErrServerClosed { + if err := srv.Start(fmt.Sprintf(":%v", url.Port())); err != http.ErrServerClosed { log.Error("Failed to start prover server", "error", err) } }() diff --git a/testutils/suite.go b/testutils/suite.go index 5c62d5d3f..c922593ed 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -15,7 +15,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/pkg/rpc" - "github.com/taikoxyz/taiko-client/prover/http" + "github.com/taikoxyz/taiko-client/prover/server" ) type ClientTestSuite struct { @@ -25,7 +25,7 @@ type ClientTestSuite struct { TestAddrPrivKey *ecdsa.PrivateKey TestAddr common.Address ProverEndpoints []*url.URL - proverServer *http.Server + proverServer *server.ProverServer } func (s *ClientTestSuite) SetupTest() { From 6f644d4c1fdbc42847ba9ca91609173591eaf3f4 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 6 Sep 2023 14:55:28 +0800 Subject: [PATCH 18/25] test: update tests --- proposer/proposer_test.go | 2 +- prover/prover_test.go | 12 +----------- prover/server/propose_block_test.go | 2 +- prover/server/server_test.go | 4 ++-- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 8e1e74810..663d4888f 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -213,7 +213,7 @@ func (s *ProposerTestSuite) TestSendProposeBlockTx() { s.Greater(newTx.GasTipCap().Uint64(), tx.GasTipCap().Uint64()) } -func (s *ProposerTestSuite) TestAssignProver_SuccessFirstRound() { +func (s *ProposerTestSuite) TestAssignProverSuccessFirstRound() { meta := &encoding.TaikoL1BlockMetadataInput{ Beneficiary: s.p.L2SuggestedFeeRecipient(), TxListHash: testutils.RandomHash(), diff --git a/prover/prover_test.go b/prover/prover_test.go index 2ada1add3..35bb42a6e 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -17,7 +17,6 @@ import ( "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/proposer" producer "github.com/taikoxyz/taiko-client/prover/proof_producer" - "github.com/taikoxyz/taiko-client/prover/server" "github.com/taikoxyz/taiko-client/testutils" ) @@ -198,21 +197,12 @@ func (s *ProverTestSuite) TestCheckChainVerification() { } func (s *ProverTestSuite) TestStartClose() { - l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) - s.Nil(err) - - s.p.srv, _ = server.New(&server.NewProverServerOpts{ - ProverPrivateKey: l1ProverPrivKey, - }) + s.p.cfg.OracleProver = true s.Nil(s.p.Start()) s.cancel() s.NotPanics(func() { s.p.Close(context.Background()) }) } -func (s *ProverTestSuite) TearDownTest() { - s.Nil(s.p.srv.Shutdown(context.Background())) -} - func TestProverTestSuite(t *testing.T) { suite.Run(t, new(ProverTestSuite)) } diff --git a/prover/server/propose_block_test.go b/prover/server/propose_block_test.go index 9eb7c8dba..a6e1f4ccb 100644 --- a/prover/server/propose_block_test.go +++ b/prover/server/propose_block_test.go @@ -22,7 +22,7 @@ func randomHash() common.Hash { } return hash } -func Test_ProposeBlock(t *testing.T) { +func TestProposeBlock(t *testing.T) { srv := newTestServer("") tests := []struct { diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 07c48aadc..99c4175ed 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -40,7 +40,7 @@ func TestHealth(t *testing.T) { srv.ServeHTTP(rec, req) if rec.Code != http.StatusOK { - t.Fatalf("Test_Health expected code %v, got %v", http.StatusOK, rec.Code) + t.Fatalf("TestHealth expected code %v, got %v", http.StatusOK, rec.Code) } } @@ -53,7 +53,7 @@ func TestRoot(t *testing.T) { srv.ServeHTTP(rec, req) if rec.Code != http.StatusOK { - t.Fatalf("Test_Root expected code %v, got %v", http.StatusOK, rec.Code) + t.Fatalf("TestRoot expected code %v, got %v", http.StatusOK, rec.Code) } } From 4619533b82e5c8ca5b72c32940f9736945f41b67 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 6 Sep 2023 15:21:46 +0800 Subject: [PATCH 19/25] test: update tests --- bindings/.githead | 2 +- bindings/encoding/input.go | 4 ++-- bindings/encoding/input_test.go | 4 ++-- bindings/encoding/struct.go | 2 +- bindings/encoding/struct_test.go | 4 ++-- bindings/gen_taiko_l1.go | 11 +++++------ driver/chain_syncer/calldata/syncer.go | 4 ++-- driver/chain_syncer/calldata/syncer_test.go | 16 ++++++++-------- proposer/proposer.go | 4 ++-- proposer/proposer_test.go | 6 +++--- prover/proof_producer/dummy_producer.go | 2 +- prover/proof_producer/zkevm_cmd_producer.go | 2 +- prover/proof_producer/zkevm_rpcd_producer.go | 2 +- prover/proof_submitter/valid_proof_submitter.go | 2 +- prover/server/propose_block.go | 2 ++ prover/server/propose_block_test.go | 4 ++-- testutils/helper.go | 4 ++-- 17 files changed, 38 insertions(+), 37 deletions(-) diff --git a/bindings/.githead b/bindings/.githead index 0d8a74c9d..ff5b83cf8 100644 --- a/bindings/.githead +++ b/bindings/.githead @@ -1 +1 @@ -c8969b64bbaacf9ec6d239608509424fdc02ee97 +8028a49ea2dfc123b1c818afb722a029d3743e5c diff --git a/bindings/encoding/input.go b/bindings/encoding/input.go index bce39d85b..12ec44ebb 100644 --- a/bindings/encoding/input.go +++ b/bindings/encoding/input.go @@ -22,7 +22,7 @@ var ( Type: "bytes32", }, { - Name: "beneficiary", + Name: "proposer", Type: "address", }, { @@ -76,7 +76,7 @@ var ( Type: "uint32", }, { - Name: "beneficiary", + Name: "proposer", Type: "address", }, { diff --git a/bindings/encoding/input_test.go b/bindings/encoding/input_test.go index fc92098db..7b17cf93e 100644 --- a/bindings/encoding/input_test.go +++ b/bindings/encoding/input_test.go @@ -99,7 +99,7 @@ func TestEncodeBlockMetadata(t *testing.T) { Id: uint64(1), L1Height: uint64(1), L1Hash: abcdBytes, - Beneficiary: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), + Proposer: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), TxListHash: abcdBytes, TxListByteStart: big.NewInt(0), TxListByteEnd: big.NewInt(1000), @@ -131,7 +131,7 @@ func TestEncodeBlockMetadata(t *testing.T) { Id: uint64(1), L1Height: uint64(1), L1Hash: abcdBytes, - Beneficiary: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), + Proposer: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), TxListHash: abcdBytes, TxListByteStart: big.NewInt(0), TxListByteEnd: big.NewInt(1000), diff --git a/bindings/encoding/struct.go b/bindings/encoding/struct.go index bd2f6bc85..d0f61fd59 100644 --- a/bindings/encoding/struct.go +++ b/bindings/encoding/struct.go @@ -43,7 +43,7 @@ type TaikoL1Evidence struct { type TaikoL1BlockMetadataInput struct { TxListHash [32]byte - Beneficiary common.Address + Proposer common.Address TxListByteStart *big.Int TxListByteEnd *big.Int CacheTxListInfo bool diff --git a/bindings/encoding/struct_test.go b/bindings/encoding/struct_test.go index 31a6f0a43..00f05a105 100644 --- a/bindings/encoding/struct_test.go +++ b/bindings/encoding/struct_test.go @@ -34,7 +34,7 @@ var ( BaseFee: new(big.Int).SetUint64(rand.Uint64()), } testMetaInput = TaikoL1BlockMetadataInput{ - Beneficiary: common.BytesToAddress(randomHash().Bytes()), + Proposer: common.BytesToAddress(randomHash().Bytes()), TxListHash: randomHash(), TxListByteStart: common.Big0, TxListByteEnd: common.Big0, @@ -50,7 +50,7 @@ var ( TxListByteStart: common.Big0, TxListByteEnd: common.Big256, GasLimit: rand.Uint32(), - Beneficiary: common.BytesToAddress(randomHash().Bytes()), + Proposer: common.BytesToAddress(randomHash().Bytes()), DepositsProcessed: []bindings.TaikoDataEthDeposit{}, } ) diff --git a/bindings/gen_taiko_l1.go b/bindings/gen_taiko_l1.go index d85337358..5d5da1bcc 100644 --- a/bindings/gen_taiko_l1.go +++ b/bindings/gen_taiko_l1.go @@ -38,7 +38,6 @@ type TaikoDataBlock struct { ProposedAt uint64 NextTransitionId uint32 VerifiedTransitionId uint32 - ProofWindow uint16 } // TaikoDataBlockMetadata is an auto generated low-level Go binding around an user-defined struct. @@ -52,7 +51,7 @@ type TaikoDataBlockMetadata struct { TxListByteStart *big.Int TxListByteEnd *big.Int GasLimit uint32 - Beneficiary common.Address + Proposer common.Address DepositsProcessed []TaikoDataEthDeposit } @@ -127,7 +126,7 @@ type TaikoDataTransition struct { // TaikoL1ClientMetaData contains all meta data concerning the TaikoL1Client contract. var TaikoL1ClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ASSIGNMENT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ASSIGNMENT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER_SIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER_SIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_PROVEABLE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_PROVEABLE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TRANSITION_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TRANSITION_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"}],\"name\":\"RESOLVER_ZERO_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addressManager\",\"type\":\"address\"}],\"name\":\"AddressManagerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"srcHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"}],\"name\":\"CrossChainSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"srcHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"}],\"name\":\"CrossChainSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"name\":\"deposit\",\"type\":\"tuple\"}],\"name\":\"EthDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"name\":\"deposit\",\"type\":\"tuple\"}],\"name\":\"EthDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"canDepositEthToL2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"depositEtherToL2\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"depositTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"}],\"name\":\"getBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"proofBond\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextTransitionId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"verifiedTransitionId\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"proofWindow\",\"type\":\"uint16\"}],\"internalType\":\"structTaikoData.Block\",\"name\":\"blk\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"relaySignalRoot\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"blockMaxProposals\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockRingBufferSize\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockMaxVerificationsPerTx\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockFeeBaseGas\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"blockMaxTxListBytes\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"blockTxListExpiry\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerRewardPerSecond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerRewardMax\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofRegularCooldown\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofOracleCooldown\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"proofWindow\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"proofBond\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"skipProverAssignmentVerificaiton\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositRingBufferSize\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"ethDepositMinCountPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"ethDepositMaxCountPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"ethDepositMinAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"ethDepositMaxAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositMaxFee\",\"type\":\"uint256\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"}],\"name\":\"getCrossChainBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"}],\"name\":\"getCrossChainSignalRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numEthDeposits\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getTaikoTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"}],\"name\":\"getTransition\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.Transition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"id\",\"type\":\"uint16\"}],\"name\":\"getVerifierName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"assignment\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"}],\"name\":\"proposeBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAddressManager\",\"type\":\"address\"}],\"name\":\"setAddressManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numEthDeposits\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.SlotA\",\"name\":\"slotA\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.SlotB\",\"name\":\"slotB\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"maxBlocks\",\"type\":\"uint64\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ASSIGNMENT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ASSIGNMENT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER_SIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROVER_SIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_PROVEABLE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_PROVEABLE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TRANSITION_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TRANSITION_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"}],\"name\":\"RESOLVER_ZERO_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addressManager\",\"type\":\"address\"}],\"name\":\"AddressManagerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"srcHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"}],\"name\":\"CrossChainSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"srcHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"}],\"name\":\"CrossChainSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"name\":\"deposit\",\"type\":\"tuple\"}],\"name\":\"EthDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"name\":\"deposit\",\"type\":\"tuple\"}],\"name\":\"EthDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"canDepositEthToL2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"depositEtherToL2\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"depositTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"}],\"name\":\"getBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"proofBond\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextTransitionId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"verifiedTransitionId\",\"type\":\"uint32\"}],\"internalType\":\"structTaikoData.Block\",\"name\":\"blk\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"relaySignalRoot\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"blockMaxProposals\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockRingBufferSize\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockMaxVerificationsPerTx\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockFeeBaseGas\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"blockMaxTxListBytes\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"blockTxListExpiry\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerRewardPerSecond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerRewardMax\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofRegularCooldown\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofOracleCooldown\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"proofWindow\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"proofBond\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"skipProverAssignmentVerificaiton\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositRingBufferSize\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"ethDepositMinCountPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"ethDepositMaxCountPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"ethDepositMinAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"ethDepositMaxAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositMaxFee\",\"type\":\"uint256\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"}],\"name\":\"getCrossChainBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"}],\"name\":\"getCrossChainSignalRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numEthDeposits\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getTaikoTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"}],\"name\":\"getTransition\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.Transition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"id\",\"type\":\"uint16\"}],\"name\":\"getVerifierName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"assignment\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"}],\"name\":\"proposeBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAddressManager\",\"type\":\"address\"}],\"name\":\"setAddressManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numEthDeposits\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.SlotA\",\"name\":\"slotA\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.SlotB\",\"name\":\"slotB\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"maxBlocks\",\"type\":\"uint64\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", } // TaikoL1ClientABI is the input ABI used to generate the binding from. @@ -340,7 +339,7 @@ func (_TaikoL1Client *TaikoL1ClientCallerSession) CanDepositEthToL2(amount *big. // GetBlock is a free data retrieval call binding the contract method 0x5fa15e79. // -// Solidity: function getBlock(uint64 blockId) view returns((bytes32,address,uint96,uint64,uint64,uint32,uint32,uint16) blk) +// Solidity: function getBlock(uint64 blockId) view returns((bytes32,address,uint96,uint64,uint64,uint32,uint32) blk) func (_TaikoL1Client *TaikoL1ClientCaller) GetBlock(opts *bind.CallOpts, blockId uint64) (TaikoDataBlock, error) { var out []interface{} err := _TaikoL1Client.contract.Call(opts, &out, "getBlock", blockId) @@ -357,14 +356,14 @@ func (_TaikoL1Client *TaikoL1ClientCaller) GetBlock(opts *bind.CallOpts, blockId // GetBlock is a free data retrieval call binding the contract method 0x5fa15e79. // -// Solidity: function getBlock(uint64 blockId) view returns((bytes32,address,uint96,uint64,uint64,uint32,uint32,uint16) blk) +// Solidity: function getBlock(uint64 blockId) view returns((bytes32,address,uint96,uint64,uint64,uint32,uint32) blk) func (_TaikoL1Client *TaikoL1ClientSession) GetBlock(blockId uint64) (TaikoDataBlock, error) { return _TaikoL1Client.Contract.GetBlock(&_TaikoL1Client.CallOpts, blockId) } // GetBlock is a free data retrieval call binding the contract method 0x5fa15e79. // -// Solidity: function getBlock(uint64 blockId) view returns((bytes32,address,uint96,uint64,uint64,uint32,uint32,uint16) blk) +// Solidity: function getBlock(uint64 blockId) view returns((bytes32,address,uint96,uint64,uint64,uint32,uint32) blk) func (_TaikoL1Client *TaikoL1ClientCallerSession) GetBlock(blockId uint64) (TaikoDataBlock, error) { return _TaikoL1Client.Contract.GetBlock(&_TaikoL1Client.CallOpts, blockId) } diff --git a/driver/chain_syncer/calldata/syncer.go b/driver/chain_syncer/calldata/syncer.go index 5f618c6b8..cb9db3562 100644 --- a/driver/chain_syncer/calldata/syncer.go +++ b/driver/chain_syncer/calldata/syncer.go @@ -422,11 +422,11 @@ func (s *Syncer) createExecutionPayloads( attributes := &engine.PayloadAttributes{ Timestamp: event.Meta.Timestamp, Random: event.Meta.MixHash, - SuggestedFeeRecipient: event.Meta.Beneficiary, + SuggestedFeeRecipient: event.Meta.Proposer, Withdrawals: withdrawals, BlockMetadata: &engine.BlockMetadata{ HighestBlockID: headBlockID, - Beneficiary: event.Meta.Beneficiary, + Beneficiary: event.Meta.Proposer, GasLimit: uint64(event.Meta.GasLimit) + s.anchorConstructor.GasLimit(), Timestamp: event.Meta.Timestamp, TxList: txListBytes, diff --git a/driver/chain_syncer/calldata/syncer_test.go b/driver/chain_syncer/calldata/syncer_test.go index 57ad5d6fb..8186b6353 100644 --- a/driver/chain_syncer/calldata/syncer_test.go +++ b/driver/chain_syncer/calldata/syncer_test.go @@ -115,14 +115,14 @@ func (s *CalldataSyncerTestSuite) TestInsertNewHead() { &bindings.TaikoL1ClientBlockProposed{ BlockId: common.Big1, Meta: bindings.TaikoDataBlockMetadata{ - Id: 1, - L1Height: l1Head.NumberU64(), - L1Hash: l1Head.Hash(), - Beneficiary: common.BytesToAddress(testutils.RandomBytes(1024)), - TxListHash: testutils.RandomHash(), - MixHash: testutils.RandomHash(), - GasLimit: rand.Uint32(), - Timestamp: uint64(time.Now().Unix()), + Id: 1, + L1Height: l1Head.NumberU64(), + L1Hash: l1Head.Hash(), + Proposer: common.BytesToAddress(testutils.RandomBytes(1024)), + TxListHash: testutils.RandomHash(), + MixHash: testutils.RandomHash(), + GasLimit: rand.Uint32(), + Timestamp: uint64(time.Now().Unix()), }, }, parent, diff --git a/proposer/proposer.go b/proposer/proposer.go index 6e5c311a0..382e106ce 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -305,7 +305,7 @@ func (p *Proposer) ProposeOp(ctx context.Context) error { txNonce := nonce + uint64(i) if err := p.ProposeTxList(ctx, &encoding.TaikoL1BlockMetadataInput{ - Beneficiary: p.l2SuggestedFeeRecipient, + Proposer: p.l2SuggestedFeeRecipient, TxListHash: crypto.Keccak256Hash(txListBytes), TxListByteStart: common.Big0, TxListByteEnd: new(big.Int).SetUint64(uint64(len(txListBytes))), @@ -470,7 +470,7 @@ func (p *Proposer) ProposeTxList( func (p *Proposer) ProposeEmptyBlockOp(ctx context.Context) error { return p.ProposeTxList(ctx, &encoding.TaikoL1BlockMetadataInput{ TxListHash: crypto.Keccak256Hash([]byte{}), - Beneficiary: p.L2SuggestedFeeRecipient(), + Proposer: p.L2SuggestedFeeRecipient(), TxListByteStart: common.Big0, TxListByteEnd: common.Big0, CacheTxListInfo: false, diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 663d4888f..62a533059 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -131,7 +131,7 @@ func (s *ProposerTestSuite) TestProposeOp() { _, isPending, err := s.p.rpc.L1.TransactionByHash(context.Background(), event.Raw.TxHash) s.Nil(err) s.False(isPending) - s.Equal(s.p.l2SuggestedFeeRecipient, event.Meta.Beneficiary) + s.Equal(s.p.l2SuggestedFeeRecipient, event.Meta.Proposer) receipt, err := s.p.rpc.L1.TransactionReceipt(context.Background(), event.Raw.TxHash) s.Nil(err) @@ -190,7 +190,7 @@ func (s *ProposerTestSuite) TestSendProposeBlockTx() { s.Nil(err) meta := &encoding.TaikoL1BlockMetadataInput{ - Beneficiary: s.p.L2SuggestedFeeRecipient(), + Proposer: s.p.L2SuggestedFeeRecipient(), TxListHash: crypto.Keccak256Hash(encoded), TxListByteStart: common.Big0, TxListByteEnd: new(big.Int).SetUint64(uint64(len(encoded))), @@ -215,7 +215,7 @@ func (s *ProposerTestSuite) TestSendProposeBlockTx() { func (s *ProposerTestSuite) TestAssignProverSuccessFirstRound() { meta := &encoding.TaikoL1BlockMetadataInput{ - Beneficiary: s.p.L2SuggestedFeeRecipient(), + Proposer: s.p.L2SuggestedFeeRecipient(), TxListHash: testutils.RandomHash(), TxListByteStart: common.Big0, TxListByteEnd: common.Big0, diff --git a/prover/proof_producer/dummy_producer.go b/prover/proof_producer/dummy_producer.go index 50235e98c..507c6ce3d 100644 --- a/prover/proof_producer/dummy_producer.go +++ b/prover/proof_producer/dummy_producer.go @@ -30,7 +30,7 @@ func (d *DummyProofProducer) RequestProof( log.Info( "Request dummy proof", "blockID", blockID, - "beneficiary", meta.Beneficiary, + "proposer", meta.Proposer, "height", header.Number, "hash", header.Hash(), ) diff --git a/prover/proof_producer/zkevm_cmd_producer.go b/prover/proof_producer/zkevm_cmd_producer.go index a49b08603..12478e7c0 100644 --- a/prover/proof_producer/zkevm_cmd_producer.go +++ b/prover/proof_producer/zkevm_cmd_producer.go @@ -45,7 +45,7 @@ func (p *ZkevmCmdProducer) RequestProof( log.Info( "Request proof from ZKEVM CMD", "blockID", blockID, - "beneficiary", meta.Beneficiary, + "proposer", meta.Proposer, "height", header.Number, "hash", header.Hash(), "cmd", p.CmdPath, diff --git a/prover/proof_producer/zkevm_rpcd_producer.go b/prover/proof_producer/zkevm_rpcd_producer.go index 4a9b7aaac..2663e0edd 100644 --- a/prover/proof_producer/zkevm_rpcd_producer.go +++ b/prover/proof_producer/zkevm_rpcd_producer.go @@ -131,7 +131,7 @@ func (p *ZkevmRpcdProducer) RequestProof( log.Info( "Request proof from zkevm-chain proverd service", "blockID", blockID, - "beneficiary", meta.Beneficiary, + "proposer", meta.Proposer, "height", header.Number, "hash", header.Hash(), ) diff --git a/prover/proof_submitter/valid_proof_submitter.go b/prover/proof_submitter/valid_proof_submitter.go index 5fe072224..9416dd7bc 100644 --- a/prover/proof_submitter/valid_proof_submitter.go +++ b/prover/proof_submitter/valid_proof_submitter.go @@ -171,7 +171,7 @@ func (s *ValidProofSubmitter) SubmitProof( log.Info( "New valid block proof", "blockID", proofWithHeader.BlockID, - "beneficiary", proofWithHeader.Meta.Beneficiary, + "proposer", proofWithHeader.Meta.Proposer, "hash", proofWithHeader.Header.Hash(), "proof", common.Bytes2Hex(proofWithHeader.ZkProof), "graffiti", common.Bytes2Hex(s.graffiti[:]), diff --git a/prover/server/propose_block.go b/prover/server/propose_block.go index 98a665552..999134f7a 100644 --- a/prover/server/propose_block.go +++ b/prover/server/propose_block.go @@ -41,11 +41,13 @@ func (srv *ProverServer) ProposeBlock(c echo.Context) error { select { case capacity := <-srv.receiveCurrentCapacityCh: if capacity == 0 { + log.Warn("Prover does not have capacity") return echo.NewHTTPError(http.StatusUnprocessableEntity, "prover does not have capacity") } encoded, err := encoding.EncodeProposeBlockData(r) if err != nil { + log.Error("Failed to encode proposeBlock data", "error", err) return echo.NewHTTPError(http.StatusUnprocessableEntity, err) } diff --git a/prover/server/propose_block_test.go b/prover/server/propose_block_test.go index a6e1f4ccb..88140cfe6 100644 --- a/prover/server/propose_block_test.go +++ b/prover/server/propose_block_test.go @@ -38,7 +38,7 @@ func TestProposeBlock(t *testing.T) { Fee: big.NewInt(1000), Expiry: uint64(time.Now().Unix()), Input: encoding.TaikoL1BlockMetadataInput{ - Beneficiary: common.BytesToAddress(randomHash().Bytes()), + Proposer: common.BytesToAddress(randomHash().Bytes()), TxListHash: randomHash(), TxListByteStart: common.Big0, TxListByteEnd: common.Big0, @@ -57,7 +57,7 @@ func TestProposeBlock(t *testing.T) { Fee: big.NewInt(1000), Expiry: uint64(time.Now().Unix()), Input: encoding.TaikoL1BlockMetadataInput{ - Beneficiary: common.BytesToAddress(randomHash().Bytes()), + Proposer: common.BytesToAddress(randomHash().Bytes()), TxListHash: randomHash(), TxListByteStart: common.Big0, TxListByteEnd: common.Big0, diff --git a/testutils/helper.go b/testutils/helper.go index c750fb357..df1beba64 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -29,7 +29,7 @@ func ProposeInvalidTxListBytes(s *ClientTestSuite, proposer Proposer) { invalidTxListBytes := RandomBytes(256) s.Nil(proposer.ProposeTxList(context.Background(), &encoding.TaikoL1BlockMetadataInput{ - Beneficiary: proposer.L2SuggestedFeeRecipient(), + Proposer: proposer.L2SuggestedFeeRecipient(), TxListHash: crypto.Keccak256Hash(invalidTxListBytes), TxListByteStart: common.Big0, TxListByteEnd: new(big.Int).SetUint64(uint64(len(invalidTxListBytes))), @@ -62,7 +62,7 @@ func ProposeAndInsertEmptyBlocks( s.Nil(err) s.Nil(proposer.ProposeTxList(context.Background(), &encoding.TaikoL1BlockMetadataInput{ - Beneficiary: proposer.L2SuggestedFeeRecipient(), + Proposer: proposer.L2SuggestedFeeRecipient(), TxListHash: crypto.Keccak256Hash(encoded), TxListByteStart: common.Big0, TxListByteEnd: new(big.Int).SetUint64(uint64(len(encoded))), From f3d95b76ce8efe1e09b4262477234be609334618 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 6 Sep 2023 15:58:51 +0800 Subject: [PATCH 20/25] test: update tests --- prover/server/propose_block_test.go | 114 +++++++++++----------------- prover/server/server_test.go | 77 +++++++++++-------- testutils/helper.go | 3 +- 3 files changed, 95 insertions(+), 99 deletions(-) diff --git a/prover/server/propose_block_test.go b/prover/server/propose_block_test.go index 88140cfe6..7e83c584e 100644 --- a/prover/server/propose_block_test.go +++ b/prover/server/propose_block_test.go @@ -2,10 +2,8 @@ package server import ( "crypto/rand" - "math/big" "net/http" "net/http/httptest" - "testing" "time" "github.com/cyberhorsey/webutils/testutils" @@ -14,79 +12,59 @@ import ( "github.com/taikoxyz/taiko-client/bindings/encoding" ) -// randomHash generates a random blob of data and returns it as a hash. -func randomHash() common.Hash { - var hash common.Hash - if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil { - panic(err) - } - return hash -} -func TestProposeBlock(t *testing.T) { - srv := newTestServer("") +func (s *ProverServerTestSuite) TestProposeBlockSuccess() { + s.srv.receiveCurrentCapacityCh <- 1024 - tests := []struct { - name string - req *encoding.ProposeBlockData - chResponseFunc func() - wantStatus int - wantBodyRegexpMatches []string - }{ - { - "success", - &encoding.ProposeBlockData{ - Fee: big.NewInt(1000), - Expiry: uint64(time.Now().Unix()), - Input: encoding.TaikoL1BlockMetadataInput{ - Proposer: common.BytesToAddress(randomHash().Bytes()), - TxListHash: randomHash(), - TxListByteStart: common.Big0, - TxListByteEnd: common.Big0, - CacheTxListInfo: false, - }, - }, - func() { - srv.receiveCurrentCapacityCh <- 100 - }, - http.StatusOK, - []string{`"signedPayload"`}, - }, - { - "contextTimeout", - &encoding.ProposeBlockData{ - Fee: big.NewInt(1000), - Expiry: uint64(time.Now().Unix()), - Input: encoding.TaikoL1BlockMetadataInput{ - Proposer: common.BytesToAddress(randomHash().Bytes()), - TxListHash: randomHash(), - TxListByteStart: common.Big0, - TxListByteEnd: common.Big0, - CacheTxListInfo: false, - }, + rec := httptest.NewRecorder() + + s.srv.ServeHTTP(rec, testutils.NewUnauthenticatedRequest( + echo.POST, + "/proposeBlock", + &encoding.ProposeBlockData{ + Fee: common.Big256, + Expiry: uint64(time.Now().Unix()), + Input: encoding.TaikoL1BlockMetadataInput{ + Proposer: common.BytesToAddress(randomHash().Bytes()), + TxListHash: randomHash(), + TxListByteStart: common.Big0, + TxListByteEnd: common.Big0, + CacheTxListInfo: false, }, - nil, - http.StatusUnprocessableEntity, - []string{`{"message":"timed out trying to get capacity"}`}, }, - } + )) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.chResponseFunc != nil { - go tt.chResponseFunc() - } + testutils.AssertStatusAndBody(s.T(), rec, http.StatusOK, []string{"signedPayload"}) +} - req := testutils.NewUnauthenticatedRequest( - echo.POST, - "/proposeBlock", - tt.req, - ) +func (s *ProverServerTestSuite) TestProposeBlockTimeout() { + rec := httptest.NewRecorder() - rec := httptest.NewRecorder() + s.srv.ServeHTTP(rec, testutils.NewUnauthenticatedRequest( + echo.POST, + "/proposeBlock", + &encoding.ProposeBlockData{ + Fee: common.Big256, + Expiry: uint64(time.Now().Unix()), + Input: encoding.TaikoL1BlockMetadataInput{ + Proposer: common.BytesToAddress(randomHash().Bytes()), + TxListHash: randomHash(), + TxListByteStart: common.Big0, + TxListByteEnd: common.Big0, + CacheTxListInfo: false, + }, + }, + )) - srv.ServeHTTP(rec, req) + testutils.AssertStatusAndBody( + s.T(), rec, http.StatusUnprocessableEntity, []string{`{"message":"timed out trying to get capacity"}`}, + ) +} - testutils.AssertStatusAndBody(t, rec, tt.wantStatus, tt.wantBodyRegexpMatches) - }) +// randomHash generates a random blob of data and returns it as a hash. +func randomHash() common.Hash { + var hash common.Hash + if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil { + panic(err) } + return hash } diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 99c4175ed..396c06a46 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -2,25 +2,34 @@ package server import ( "context" - "math/big" + "fmt" "net/http" "net/http/httptest" + "net/url" "os" - "testing" + "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/go-resty/resty/v2" echo "github.com/labstack/echo/v4" - "github.com/stretchr/testify/assert" + "github.com/phayes/freeport" + "github.com/stretchr/testify/suite" ) -func newTestServer(url string) *ProverServer { - l1ProverPrivKey, _ := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) +type ProverServerTestSuite struct { + suite.Suite + srv *ProverServer +} + +func (s *ProverServerTestSuite) SetupTest() { + l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) srv := &ProverServer{ echo: echo.New(), proverPrivateKey: l1ProverPrivKey, - minProofFee: big.NewInt(1), + minProofFee: common.Big1, requestCurrentCapacityCh: make(chan struct{}, 1024), receiveCurrentCapacityCh: make(chan uint64, 1024), } @@ -28,40 +37,48 @@ func newTestServer(url string) *ProverServer { srv.configureMiddleware() srv.configureRoutes() - return srv + s.srv = srv } -func TestHealth(t *testing.T) { - srv := newTestServer("") +func (s *ProverServerTestSuite) TestHealth() { + s.Equal(http.StatusOK, s.sendReq("/healthz").Code) +} - req, _ := http.NewRequest(echo.GET, "/healthz", nil) - rec := httptest.NewRecorder() +func (s *ProverServerTestSuite) TestRoot() { + s.Equal(http.StatusOK, s.sendReq("/").Code) +} - srv.ServeHTTP(rec, req) +func (s *ProverServerTestSuite) TestStartShutdown() { + port, err := freeport.GetFreePort() + s.Nil(err) - if rec.Code != http.StatusOK { - t.Fatalf("TestHealth expected code %v, got %v", http.StatusOK, rec.Code) - } -} + url, err := url.Parse(fmt.Sprintf("http://localhost:%v", port)) + s.Nil(err) -func TestRoot(t *testing.T) { - srv := newTestServer("") + go func() { s.Nil(s.srv.Start(fmt.Sprintf(":%v", port))) }() - req, _ := http.NewRequest(echo.GET, "/", nil) - rec := httptest.NewRecorder() + // 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()) + } - srv.ServeHTTP(rec, req) + return nil + }, backoff.NewExponentialBackOff())) - if rec.Code != http.StatusOK { - t.Fatalf("TestRoot expected code %v, got %v", http.StatusOK, rec.Code) - } + s.Nil(s.srv.Shutdown(context.Background())) } -func TestStartShutdown(t *testing.T) { - srv := newTestServer("") +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) - go func() { - _ = srv.Start(":3928") - }() - assert.Nil(t, srv.Shutdown(context.Background())) + return rec } diff --git a/testutils/helper.go b/testutils/helper.go index df1beba64..8cdf42bd0 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -4,6 +4,7 @@ import ( "context" "crypto/ecdsa" "crypto/rand" + "errors" "fmt" "math/big" "net/http" @@ -206,7 +207,7 @@ func NewTestProverServer( }() go func() { - if err := srv.Start(fmt.Sprintf(":%v", url.Port())); err != http.ErrServerClosed { + if err := srv.Start(fmt.Sprintf(":%v", url.Port())); !errors.Is(err, http.ErrServerClosed) { log.Error("Failed to start prover server", "error", err) } }() From 3b1717e5293bfd375f108c3d8a78130ef090960e Mon Sep 17 00:00:00 2001 From: David Date: Wed, 6 Sep 2023 16:31:38 +0800 Subject: [PATCH 21/25] feat: more comments --- proposer/proposer.go | 2 +- ...ee_selector.go => eth_fee_eoa_selector.go} | 20 ++++++++++++------- ...r_test.go => eth_fee_eoa_selector_test.go} | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) rename proposer/prover_selector/{eth_fee_selector.go => eth_fee_eoa_selector.go} (88%) rename proposer/prover_selector/{eth_fee_selector_test.go => eth_fee_eoa_selector_test.go} (94%) diff --git a/proposer/proposer.go b/proposer/proposer.go index 382e106ce..5953f4f5a 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -125,7 +125,7 @@ func InitFromConfig(ctx context.Context, p *Proposer, cfg *Config) (err error) { log.Info("Protocol configs", "configs", p.protocolConfigs) - if p.proverSelector, err = selector.NewETHFeeSelector( + if p.proverSelector, err = selector.NewETHFeeEOASelector( &protocolConfigs, p.rpc, cfg.TaikoL1Address, diff --git a/proposer/prover_selector/eth_fee_selector.go b/proposer/prover_selector/eth_fee_eoa_selector.go similarity index 88% rename from proposer/prover_selector/eth_fee_selector.go rename to proposer/prover_selector/eth_fee_eoa_selector.go index c4aa5b836..c2e9dea7d 100644 --- a/proposer/prover_selector/eth_fee_selector.go +++ b/proposer/prover_selector/eth_fee_eoa_selector.go @@ -25,7 +25,9 @@ var ( errUnableToFindProver = errors.New("unable to find prover") ) -type ETHFeeSelector struct { +// ETHFeeEOASelector is a prover selector implementation which use ETHs as prover fee and +// all provers selected must be EOA accounts. +type ETHFeeEOASelector struct { protocolConfigs *bindings.TaikoDataConfig rpc *rpc.Client taikoL1Address common.Address @@ -37,7 +39,8 @@ type ETHFeeSelector struct { requestTimeout time.Duration } -func NewETHFeeSelector( +// NewETHFeeEOASelector creates a new ETHFeeEOASelector instance. +func NewETHFeeEOASelector( protocolConfigs *bindings.TaikoDataConfig, rpc *rpc.Client, taikoL1Address common.Address, @@ -47,7 +50,7 @@ func NewETHFeeSelector( proposalFeeIterations uint64, proposalExpiry time.Duration, requestTimeout time.Duration, -) (*ETHFeeSelector, error) { +) (*ETHFeeEOASelector, error) { if len(proverEndpoints) == 0 { return nil, errEmptyProverEndpoints } @@ -58,7 +61,7 @@ func NewETHFeeSelector( } } - return ÐFeeSelector{ + return ÐFeeEOASelector{ protocolConfigs, rpc, taikoL1Address, @@ -71,9 +74,11 @@ func NewETHFeeSelector( }, nil } -func (s *ETHFeeSelector) ProverEndpoints() []*url.URL { return s.proverEndpoints } +// ProverEndpoints returns all registered prover endpoints. +func (s *ETHFeeEOASelector) ProverEndpoints() []*url.URL { return s.proverEndpoints } -func (s *ETHFeeSelector) AssignProver( +// AssignProver tries to pick a prover through the registered prover endpoints. +func (s *ETHFeeEOASelector) AssignProver( ctx context.Context, meta *encoding.TaikoL1BlockMetadataInput, ) ([]byte, *big.Int, error) { @@ -119,7 +124,7 @@ func (s *ETHFeeSelector) AssignProver( // checkProverBalance checks if the prover has the necessary balance either in TaikoL1 token balances // or, if not, then check allowance, as contract will attempt to burn directly after // if it doesnt have the available token balance in-contract. -func (s *ETHFeeSelector) checkProverBalance(ctx context.Context, prover common.Address) (bool, error) { +func (s *ETHFeeEOASelector) checkProverBalance(ctx context.Context, prover common.Address) (bool, error) { taikoTokenBalance, err := s.rpc.TaikoL1.GetTaikoTokenBalance(&bind.CallOpts{Context: ctx}, prover) if err != nil { return false, err @@ -147,6 +152,7 @@ func (s *ETHFeeSelector) checkProverBalance(ctx context.Context, prover common.A return true, nil } +// assignProver tries to assign a proof generation task to the given prover by HTTP API. func assignProver( ctx context.Context, meta *encoding.TaikoL1BlockMetadataInput, diff --git a/proposer/prover_selector/eth_fee_selector_test.go b/proposer/prover_selector/eth_fee_eoa_selector_test.go similarity index 94% rename from proposer/prover_selector/eth_fee_selector_test.go rename to proposer/prover_selector/eth_fee_eoa_selector_test.go index 30f4748b0..634aebb96 100644 --- a/proposer/prover_selector/eth_fee_selector_test.go +++ b/proposer/prover_selector/eth_fee_eoa_selector_test.go @@ -15,7 +15,7 @@ import ( type ProverSelectorTestSuite struct { testutils.ClientTestSuite - s *ETHFeeSelector + s *ETHFeeEOASelector proverAddress common.Address } @@ -29,7 +29,7 @@ func (s *ProverSelectorTestSuite) SetupTest() { protocolConfigs, err := s.RpcClient.TaikoL1.GetConfig(nil) s.Nil(err) - s.s, err = NewETHFeeSelector( + s.s, err = NewETHFeeEOASelector( &protocolConfigs, s.RpcClient, common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), From 89528b2b73a28c1b0a7b8bc37c141f899d7f1c97 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 6 Sep 2023 16:40:43 +0800 Subject: [PATCH 22/25] feat: remove an unused field --- prover/prover.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/prover/prover.go b/prover/prover.go index 076f435de..2474b579f 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -87,7 +87,6 @@ type Prover struct { checkProofWindowExpiredInterval time.Duration // capacity-related configs - maxCapacity uint64 currentCapacity uint64 requestCurrentCapacityCh chan struct{} receiveCurrentCapacityCh chan uint64 @@ -114,7 +113,6 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.currentBlocksBeingProvenMutex = &sync.Mutex{} p.currentBlocksWaitingForProofWindow = make(map[uint64]uint64, 0) p.currentBlocksWaitingForProofWindowMutex = &sync.Mutex{} - p.maxCapacity = cfg.Capacity p.currentCapacity = cfg.Capacity p.requestCurrentCapacityCh = make(chan struct{}, 1024) p.receiveCurrentCapacityCh = make(chan uint64, 1024) From e671958ad844ca134571458da5599e9080d2280c Mon Sep 17 00:00:00 2001 From: David Date: Wed, 6 Sep 2023 23:36:41 +0800 Subject: [PATCH 23/25] chore: update ci --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a8710e59d..6619e76a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.21 cache: true - name: Lint @@ -52,7 +52,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.21 cache: true cache-dependency-path: ${{ env.CLIENT_DIR }}/go.sum From 2051d8515a4492350a654a7917df7f7de910e890 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 7 Sep 2023 14:50:34 +0800 Subject: [PATCH 24/25] feat(prover): introduce `CapacityManager` to manage prover capacity (#384) --- proposer/proposer_test.go | 17 +--- prover/capacity_manager/capacity_manager.go | 46 +++++++++ .../capacity_manager/capacity_manager_test.go | 34 +++++++ prover/prover.go | 97 ++++++++----------- prover/prover_test.go | 9 +- prover/server/propose_block.go | 59 ++++------- prover/server/propose_block_test.go | 2 - prover/server/server.go | 26 +++-- prover/server/server_test.go | 8 +- testutils/helper.go | 21 ++-- testutils/suite.go | 3 +- 11 files changed, 171 insertions(+), 151 deletions(-) create mode 100644 prover/capacity_manager/capacity_manager.go create mode 100644 prover/capacity_manager/capacity_manager_test.go diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 62a533059..e867020e7 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -59,26 +59,13 @@ func (s *ProposerTestSuite) SetupTest() { s.Nil(err) serverOpts := &server.NewProverServerOpts{ - ProverPrivateKey: l1ProverPrivKey, - MinProofFee: common.Big1, - RequestCurrentCapacityCh: make(chan struct{}), - ReceiveCurrentCapacityCh: make(chan uint64), + ProverPrivateKey: l1ProverPrivKey, + MinProofFee: common.Big1, } s.srv, err = server.New(serverOpts) s.Nil(err) - go func() { - for { - select { - case <-serverOpts.RequestCurrentCapacityCh: - serverOpts.ReceiveCurrentCapacityCh <- 100 - case <-ctx.Done(): - return - } - } - }() - s.p = p s.cancel = cancel } diff --git a/prover/capacity_manager/capacity_manager.go b/prover/capacity_manager/capacity_manager.go new file mode 100644 index 000000000..27355c4fd --- /dev/null +++ b/prover/capacity_manager/capacity_manager.go @@ -0,0 +1,46 @@ +package capacity_manager + +import ( + "sync" +) + +// CapacityManager manages the prover capacity concurrent-safely. +type CapacityManager struct { + capacity uint64 + mutex sync.RWMutex +} + +// New creates a new CapacityManager instance. +func New(capacity uint64) *CapacityManager { + return &CapacityManager{capacity: capacity} +} + +// ReadCapacity reads the current capacity. +func (m *CapacityManager) ReadCapacity() uint64 { + m.mutex.RLock() + defer m.mutex.RUnlock() + + return m.capacity +} + +// ReleaseCapacity releases one capacity. +func (m *CapacityManager) ReleaseOneCapacity() uint64 { + m.mutex.Lock() + defer m.mutex.Unlock() + + m.capacity += 1 + return m.capacity +} + +// TakeOneCapacity takes one capacitĀ·y. +func (m *CapacityManager) TakeOneCapacity() (uint64, bool) { + m.mutex.Lock() + defer m.mutex.Unlock() + + if m.capacity == 0 { + return 0, false + } + + m.capacity -= 1 + return m.capacity, true +} diff --git a/prover/capacity_manager/capacity_manager_test.go b/prover/capacity_manager/capacity_manager_test.go new file mode 100644 index 000000000..1c1213e50 --- /dev/null +++ b/prover/capacity_manager/capacity_manager_test.go @@ -0,0 +1,34 @@ +package capacity_manager + +import ( + "github.com/stretchr/testify/suite" +) + +var ( + testCapacity uint64 = 1024 +) + +type CapacityManagerTestSuite struct { + suite.Suite + m *CapacityManager +} + +func (s *CapacityManagerTestSuite) SetupTest() { + s.m = New(testCapacity) +} + +func (s *CapacityManagerTestSuite) TestReadCapacity() { + s.Equal(testCapacity, s.m.ReadCapacity()) +} + +func (s *CapacityManagerTestSuite) TestReleaseOneCapacity() { + s.Equal(testCapacity+1, s.m.ReleaseOneCapacity()) + s.Equal(testCapacity+1, s.m.ReadCapacity()) +} + +func (s *CapacityManagerTestSuite) TestTakeOneCapacity() { + capacity, ok := s.m.TakeOneCapacity() + s.True(ok) + s.Equal(testCapacity-1, capacity) + s.Equal(testCapacity-1, s.m.ReadCapacity()) +} diff --git a/prover/prover.go b/prover/prover.go index 2474b579f..8f2174db9 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -23,6 +23,7 @@ import ( "github.com/taikoxyz/taiko-client/metrics" eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" "github.com/taikoxyz/taiko-client/pkg/rpc" + capacity "github.com/taikoxyz/taiko-client/prover/capacity_manager" proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" proofSubmitter "github.com/taikoxyz/taiko-client/prover/proof_submitter" "github.com/taikoxyz/taiko-client/prover/server" @@ -87,9 +88,7 @@ type Prover struct { checkProofWindowExpiredInterval time.Duration // capacity-related configs - currentCapacity uint64 - requestCurrentCapacityCh chan struct{} - receiveCurrentCapacityCh chan uint64 + capacityManager *capacity.CapacityManager ctx context.Context wg sync.WaitGroup @@ -110,24 +109,10 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.cfg = cfg p.ctx = ctx p.currentBlocksBeingProven = make(map[uint64]cancelFunc) - p.currentBlocksBeingProvenMutex = &sync.Mutex{} + p.currentBlocksBeingProvenMutex = new(sync.Mutex) p.currentBlocksWaitingForProofWindow = make(map[uint64]uint64, 0) - p.currentBlocksWaitingForProofWindowMutex = &sync.Mutex{} - p.currentCapacity = cfg.Capacity - p.requestCurrentCapacityCh = make(chan struct{}, 1024) - p.receiveCurrentCapacityCh = make(chan uint64, 1024) - - if !p.cfg.OracleProver { - p.srv, err = server.New(&server.NewProverServerOpts{ - ProverPrivateKey: p.cfg.L1ProverPrivKey, - MinProofFee: p.cfg.MinProofFee, - RequestCurrentCapacityCh: p.requestCurrentCapacityCh, - ReceiveCurrentCapacityCh: p.receiveCurrentCapacityCh, - }) - if err != nil { - return err - } - } + p.currentBlocksWaitingForProofWindowMutex = new(sync.Mutex) + p.capacityManager = capacity.New(cfg.Capacity) // Clients if p.rpc, err = rpc.NewClient(p.ctx, &rpc.ClientConfig{ @@ -142,6 +127,17 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { return err } + // Prover server + if !p.cfg.OracleProver { + if p.srv, err = server.New(&server.NewProverServerOpts{ + ProverPrivateKey: p.cfg.L1ProverPrivKey, + MinProofFee: p.cfg.MinProofFee, + CapacityManager: p.capacityManager, + }); err != nil { + return err + } + } + // Configs protocolConfigs, err := p.rpc.TaikoL1.GetConfig(&bind.CallOpts{Context: ctx}) if err != nil { @@ -234,28 +230,10 @@ func (p *Prover) Start() error { }() } go p.eventLoop() - go p.watchCurrentCapacity() return nil } -func (p *Prover) watchCurrentCapacity() { - p.wg.Add(1) - defer func() { - p.wg.Done() - }() - - for { - select { - case <-p.ctx.Done(): - return - case <-p.requestCurrentCapacityCh: - log.Info("Received request for current capacity", "currentCapacity", p.currentCapacity) - p.receiveCurrentCapacityCh <- p.currentCapacity - } - } -} - // eventLoop starts the main loop of Taiko prover. func (p *Prover) eventLoop() { defer func() { @@ -626,11 +604,9 @@ func (p *Prover) onBlockProposed( p.currentBlocksBeingProvenMutex.Unlock() if !p.cfg.OracleProver { - if p.currentCapacity == 0 { + if _, ok := p.capacityManager.TakeOneCapacity(); !ok { return errNoCapacity } - - p.currentCapacity-- } return p.validProofSubmitter.RequestProof(ctx, event) @@ -674,7 +650,7 @@ func (p *Prover) submitProofOp(ctx context.Context, proofWithHeader *proofProduc if err := backoff.Retry( func() error { if !p.cfg.OracleProver { - p.currentCapacity++ + p.capacityManager.ReleaseOneCapacity() } err := p.validProofSubmitter.SubmitProof(p.ctx, proofWithHeader) @@ -914,7 +890,10 @@ func (p *Prover) checkProofWindowExpired(ctx context.Context, l1Height, blockId if isExpired { log.Debug( - "Block proof window is expired", "blockID", blockId, "l1Height", l1Height) + "Block proof window is expired", + "blockID", blockId, + "l1Height", l1Height, + ) // we should remove this block from being watched regardless of whether the block // has a valid proof @@ -940,13 +919,14 @@ func (p *Prover) checkProofWindowExpired(ctx context.Context, l1Height, blockId if transition.Prover == rpc.ZeroAddress { log.Info( "Proof window for proof not assigned to us expired, requesting proof", - "blockID", - blockId, - "l1Height", - l1Height, + "blockID", blockId, + "l1Height", l1Height, ) // we can generate the proof, no proof came in by proof window expiring - if err := p.requestProofForBlockId(new(big.Int).SetUint64(blockId), new(big.Int).SetUint64(l1Height)); err != nil { + if err := p.requestProofForBlockId( + new(big.Int).SetUint64(blockId), + new(big.Int).SetUint64(l1Height), + ); err != nil { return err } } else { @@ -962,18 +942,17 @@ func (p *Prover) checkProofWindowExpired(ctx context.Context, l1Height, blockId if block.Hash() != transition.BlockHash { log.Info( "Invalid proof detected while watching for proof window expiration, requesting proof", - "blockID", - blockId, - "l1Height", - l1Height, - "expectedBlockHash", - block.Hash(), - "transitionBlockHash", - common.Bytes2Hex(transition.BlockHash[:]), + "blockID", blockId, + "l1Height", l1Height, + "expectedBlockHash", block.Hash(), + "transitionBlockHash", common.Bytes2Hex(transition.BlockHash[:]), ) // we can generate the proof, the proof is incorrect since blockHash does not match // the correct one but parentHash/gasUsed are correct. - if err := p.requestProofForBlockId(new(big.Int).SetUint64(blockId), new(big.Int).SetUint64(l1Height)); err != nil { + if err := p.requestProofForBlockId( + new(big.Int).SetUint64(blockId), + new(big.Int).SetUint64(l1Height), + ); err != nil { return err } } @@ -1025,7 +1004,9 @@ func (p *Prover) requestProofForBlockId(blockId *big.Int, l1Height *big.Int) err } if !p.cfg.OracleProver { - p.currentCapacity-- + if _, ok := p.capacityManager.TakeOneCapacity(); !ok { + return errNoCapacity + } } return nil diff --git a/prover/prover_test.go b/prover/prover_test.go index 35bb42a6e..3deb7e619 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -59,7 +59,12 @@ func (s *ProverTestSuite) SetupTest() { MinProofFee: common.Big1, HTTPServerPort: uint64(port), }))) - p.srv = testutils.NewTestProverServer(&s.ClientTestSuite, l1ProverPrivKey, proverServerUrl) + p.srv = testutils.NewTestProverServer( + &s.ClientTestSuite, + l1ProverPrivKey, + p.capacityManager, + proverServerUrl, + ) s.p = p s.cancel = cancel @@ -104,8 +109,6 @@ func (s *ProverTestSuite) SetupTest() { }))) s.proposer = prop - - go s.p.watchCurrentCapacity() } func (s *ProverTestSuite) TestName() { diff --git a/prover/server/propose_block.go b/prover/server/propose_block.go index 999134f7a..51059617b 100644 --- a/prover/server/propose_block.go +++ b/prover/server/propose_block.go @@ -1,9 +1,7 @@ package server import ( - "context" "net/http" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -23,50 +21,33 @@ type ProposeBlockResponse struct { // handle this block, and if so, returns a signed payload the proposer // can submit onchain. func (srv *ProverServer) ProposeBlock(c echo.Context) error { - r := &encoding.ProposeBlockData{} - if err := c.Bind(r); err != nil { + res := new(encoding.ProposeBlockData) + if err := c.Bind(res); err != nil { return c.JSON(http.StatusUnprocessableEntity, err) } - if r.Fee.Cmp(srv.minProofFee) < 0 { + if res.Fee.Cmp(srv.minProofFee) < 0 { return echo.NewHTTPError(http.StatusUnprocessableEntity, "proof fee too low") } - srv.requestCurrentCapacityCh <- struct{}{} - - ctx, cancel := context.WithTimeout(c.Request().Context(), 8*time.Second) - defer cancel() - - for { - select { - case capacity := <-srv.receiveCurrentCapacityCh: - if capacity == 0 { - log.Warn("Prover does not have capacity") - return echo.NewHTTPError(http.StatusUnprocessableEntity, "prover does not have capacity") - } - - encoded, err := encoding.EncodeProposeBlockData(r) - if err != nil { - log.Error("Failed to encode proposeBlock data", "error", err) - return echo.NewHTTPError(http.StatusUnprocessableEntity, err) - } - - hashed := crypto.Keccak256Hash(encoded) - - signed, err := crypto.Sign(hashed.Bytes(), srv.proverPrivateKey) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, err) - } + if srv.capacityManager.ReadCapacity() == 0 { + log.Warn("Prover does not have capacity") + return echo.NewHTTPError(http.StatusUnprocessableEntity, "prover does not have capacity") + } - resp := &ProposeBlockResponse{ - SignedPayload: signed, - Prover: srv.proverAddress, - } + encoded, err := encoding.EncodeProposeBlockData(res) + if err != nil { + log.Error("Failed to encode proposeBlock data", "error", err) + return echo.NewHTTPError(http.StatusUnprocessableEntity, err) + } - return c.JSON(http.StatusOK, resp) - case <-ctx.Done(): - log.Info("timed out trying to get capacity") - return echo.NewHTTPError(http.StatusUnprocessableEntity, "timed out trying to get capacity") - } + signed, err := crypto.Sign(crypto.Keccak256Hash(encoded).Bytes(), srv.proverPrivateKey) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err) } + + return c.JSON(http.StatusOK, &ProposeBlockResponse{ + SignedPayload: signed, + Prover: srv.proverAddress, + }) } diff --git a/prover/server/propose_block_test.go b/prover/server/propose_block_test.go index 7e83c584e..74659b6eb 100644 --- a/prover/server/propose_block_test.go +++ b/prover/server/propose_block_test.go @@ -13,8 +13,6 @@ import ( ) func (s *ProverServerTestSuite) TestProposeBlockSuccess() { - s.srv.receiveCurrentCapacityCh <- 1024 - rec := httptest.NewRecorder() s.srv.ServeHTTP(rec, testutils.NewUnauthenticatedRequest( diff --git a/prover/server/server.go b/prover/server/server.go index 5c3e49b1f..58bdacd4c 100644 --- a/prover/server/server.go +++ b/prover/server/server.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" echo "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" + capacity "github.com/taikoxyz/taiko-client/prover/capacity_manager" ) // ProverServer represents a prover server instance. @@ -19,30 +20,27 @@ type ProverServer struct { proverPrivateKey *ecdsa.PrivateKey proverAddress common.Address - // Capacity related configs - requestCurrentCapacityCh chan struct{} - receiveCurrentCapacityCh chan uint64 - minProofFee *big.Int + // capacity-related configs + capacityManager *capacity.CapacityManager + minProofFee *big.Int } // NewProverServerOpts contains all configurations for creating a prover server instance. type NewProverServerOpts struct { - ProverPrivateKey *ecdsa.PrivateKey - MinProofFee *big.Int - RequestCurrentCapacityCh chan struct{} - ReceiveCurrentCapacityCh chan uint64 + ProverPrivateKey *ecdsa.PrivateKey + MinProofFee *big.Int + CapacityManager *capacity.CapacityManager } // New creates a new prover server instance. func New(opts *NewProverServerOpts) (*ProverServer, error) { address := crypto.PubkeyToAddress(opts.ProverPrivateKey.PublicKey) srv := &ProverServer{ - proverPrivateKey: opts.ProverPrivateKey, - proverAddress: address, - echo: echo.New(), - minProofFee: opts.MinProofFee, - requestCurrentCapacityCh: opts.RequestCurrentCapacityCh, - receiveCurrentCapacityCh: opts.ReceiveCurrentCapacityCh, + proverPrivateKey: opts.ProverPrivateKey, + proverAddress: address, + echo: echo.New(), + minProofFee: opts.MinProofFee, + capacityManager: opts.CapacityManager, } srv.echo.HideBanner = true diff --git a/prover/server/server_test.go b/prover/server/server_test.go index 396c06a46..b898517c3 100644 --- a/prover/server/server_test.go +++ b/prover/server/server_test.go @@ -27,11 +27,9 @@ func (s *ProverServerTestSuite) SetupTest() { s.Nil(err) srv := &ProverServer{ - echo: echo.New(), - proverPrivateKey: l1ProverPrivKey, - minProofFee: common.Big1, - requestCurrentCapacityCh: make(chan struct{}, 1024), - receiveCurrentCapacityCh: make(chan uint64, 1024), + echo: echo.New(), + proverPrivateKey: l1ProverPrivKey, + minProofFee: common.Big1, } srv.configureMiddleware() diff --git a/testutils/helper.go b/testutils/helper.go index 8cdf42bd0..a1b33aaa6 100644 --- a/testutils/helper.go +++ b/testutils/helper.go @@ -23,6 +23,7 @@ import ( "github.com/phayes/freeport" "github.com/taikoxyz/taiko-client/bindings" "github.com/taikoxyz/taiko-client/bindings/encoding" + capacity "github.com/taikoxyz/taiko-client/prover/capacity_manager" "github.com/taikoxyz/taiko-client/prover/server" ) @@ -188,24 +189,16 @@ func DepositEtherToL2(s *ClientTestSuite, depositerPrivKey *ecdsa.PrivateKey, re func NewTestProverServer( s *ClientTestSuite, proverPrivKey *ecdsa.PrivateKey, + capacityManager *capacity.CapacityManager, url *url.URL, ) *server.ProverServer { - serverOpts := &server.NewProverServerOpts{ - ProverPrivateKey: proverPrivKey, - MinProofFee: common.Big1, - RequestCurrentCapacityCh: make(chan struct{}, 1), - ReceiveCurrentCapacityCh: make(chan uint64, 1), - } - - srv, err := server.New(serverOpts) + srv, err := server.New(&server.NewProverServerOpts{ + ProverPrivateKey: proverPrivKey, + MinProofFee: common.Big1, + CapacityManager: capacityManager, + }) s.Nil(err) - go func() { - for range serverOpts.RequestCurrentCapacityCh { - serverOpts.ReceiveCurrentCapacityCh <- 1024 - } - }() - go func() { if err := srv.Start(fmt.Sprintf(":%v", url.Port())); !errors.Is(err, http.ErrServerClosed) { log.Error("Failed to start prover server", "error", err) diff --git a/testutils/suite.go b/testutils/suite.go index c922593ed..fc9713782 100644 --- a/testutils/suite.go +++ b/testutils/suite.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/taikoxyz/taiko-client/pkg/jwt" "github.com/taikoxyz/taiko-client/pkg/rpc" + capacity "github.com/taikoxyz/taiko-client/prover/capacity_manager" "github.com/taikoxyz/taiko-client/prover/server" ) @@ -73,7 +74,7 @@ func (s *ClientTestSuite) SetupTest() { s.Nil(err) s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} - s.proverServer = NewTestProverServer(s, l1ProverPrivKey, s.ProverEndpoints[0]) + s.proverServer = NewTestProverServer(s, l1ProverPrivKey, capacity.New(1024), s.ProverEndpoints[0]) tokenBalance, err := rpcCli.TaikoL1.GetTaikoTokenBalance(nil, crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey)) s.Nil(err) From 7582d6291af2a43af7cd5761d7644bc829284699 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 7 Sep 2023 15:17:48 +0800 Subject: [PATCH 25/25] feat: update api --- prover/server/propose_block.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prover/server/propose_block.go b/prover/server/propose_block.go index 51059617b..5cce33b87 100644 --- a/prover/server/propose_block.go +++ b/prover/server/propose_block.go @@ -21,12 +21,12 @@ type ProposeBlockResponse struct { // handle this block, and if so, returns a signed payload the proposer // can submit onchain. func (srv *ProverServer) ProposeBlock(c echo.Context) error { - res := new(encoding.ProposeBlockData) - if err := c.Bind(res); err != nil { + req := new(encoding.ProposeBlockData) + if err := c.Bind(req); err != nil { return c.JSON(http.StatusUnprocessableEntity, err) } - if res.Fee.Cmp(srv.minProofFee) < 0 { + if req.Fee.Cmp(srv.minProofFee) < 0 { return echo.NewHTTPError(http.StatusUnprocessableEntity, "proof fee too low") } @@ -35,7 +35,7 @@ func (srv *ProverServer) ProposeBlock(c echo.Context) error { return echo.NewHTTPError(http.StatusUnprocessableEntity, "prover does not have capacity") } - encoded, err := encoding.EncodeProposeBlockData(res) + encoded, err := encoding.EncodeProposeBlockData(req) if err != nil { log.Error("Failed to encode proposeBlock data", "error", err) return echo.NewHTTPError(http.StatusUnprocessableEntity, err)