Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

Commit

Permalink
test(all): improve test coverage (#335)
Browse files Browse the repository at this point in the history
Co-authored-by: David <david@taiko.xyz>
  • Loading branch information
RogerLamTd and davidtaikocha authored Aug 4, 2023
1 parent 4877e01 commit 7ccedd2
Show file tree
Hide file tree
Showing 14 changed files with 407 additions and 69 deletions.
15 changes: 15 additions & 0 deletions driver/anchor_tx_constructor/anchor_tx_constructor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ func (s *AnchorTxConstructorTestSuite) TestNewAnchorTransactor() {
s.Equal(common.Big0, opts.GasTipCap)
}

func (s *AnchorTxConstructorTestSuite) TestCancelCtxTransactOpts() {
ctx, cancel := context.WithCancel(context.Background())
cancel()
opts, err := s.c.transactOpts(ctx, common.Big1, common.Big256)
s.Nil(opts)
s.ErrorContains(err, "context canceled")
}

func (s *AnchorTxConstructorTestSuite) TestSign() {
// Payload 1
hash := hexutil.MustDecode("0x44943399d1507f3ce7525e9be2f987c3db9136dc759cb7f92f742154196868b9")
Expand Down Expand Up @@ -95,6 +103,13 @@ func (s *AnchorTxConstructorTestSuite) TestSign() {
s.Equal(signatureBytes, signed)
}

func (s *AnchorTxConstructorTestSuite) TestSignShortHash() {
rand := testutils.RandomHash().Bytes()
hash := rand[:len(rand)-2]
_, err := s.c.signTxPayload(hash)
s.ErrorContains(err, "hash is required to be exactly 32 bytes")
}

func TestAnchorTxConstructorTestSuite(t *testing.T) {
suite.Run(t, new(AnchorTxConstructorTestSuite))
}
20 changes: 20 additions & 0 deletions driver/chain_syncer/calldata/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,33 @@ func (s *CalldataSyncerTestSuite) SetupTest() {

s.p = prop
}
func (s *CalldataSyncerTestSuite) TestNewSyncer() {
ctx, cancel := context.WithCancel(context.Background())
cancel()
syncer, err := NewSyncer(
ctx,
s.RpcClient,
s.s.state,
s.s.progressTracker,
common.HexToAddress(os.Getenv("L1_SIGNAL_SERVICE_CONTRACT_ADDRESS")),
)
s.Nil(syncer)
s.NotNil(err)
}

func (s *CalldataSyncerTestSuite) TestProcessL1Blocks() {
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() {
head, err := s.s.rpc.L1.HeaderByNumber(context.Background(), nil)
testutils.ProposeAndInsertEmptyBlocks(&s.ClientTestSuite, s.p, s.s)
s.Nil(err)
s.Nil(s.s.ProcessL1Blocks(context.Background(), head))
}

func (s *CalldataSyncerTestSuite) TestOnBlockProposed() {
s.Nil(s.s.onBlockProposed(
context.Background(),
Expand Down
5 changes: 5 additions & 0 deletions driver/chain_syncer/chain_syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ func (s *ChainSyncerTestSuite) TestSync() {
s.Nil(s.s.Sync(head))
}

// func (s *ChainSyncerTestSuite) TestSyncTriggerBeaconSync() {
// s.s.p2pSyncVerifiedBlocks = true
// s.s.state.setLatestVerifiedBlockHash(common.Hash{})
// }

func TestChainSyncerTestSuite(t *testing.T) {
suite.Run(t, new(ChainSyncerTestSuite))
}
Expand Down
10 changes: 10 additions & 0 deletions driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/suite"
"github.com/taikoxyz/taiko-client/bindings/encoding"
"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/testutils"
Expand Down Expand Up @@ -295,6 +296,15 @@ func (s *DriverTestSuite) TestStartClose() {
s.d.Close()
}

func (s *DriverTestSuite) TestL1Current() {
// propose and insert a block
testutils.ProposeAndInsertEmptyBlocks(&s.ClientTestSuite, s.p, s.d.ChainSyncer().CalldataSyncer())
// reset L1 current with increased height
_, id, err := s.d.state.ResetL1Current(s.d.ctx, &state.HeightOrID{ID: common.Big1})
s.Equal(common.Big1, id)
s.Nil(err)
}

func TestDriverTestSuite(t *testing.T) {
suite.Run(t, new(DriverTestSuite))
}
19 changes: 18 additions & 1 deletion driver/state/l1_current_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ func (s *DriverStateTestSuite) TestSetL1Current() {
h := &types.Header{ParentHash: testutils.RandomHash()}
s.s.SetL1Current(h)
s.Equal(h.Hash(), s.s.GetL1Current().Hash())

// should warn, but not panic
s.NotPanics(func() {
s.s.SetL1Current(nil)
})
}

func (s *DriverStateTestSuite) TestResetL1CurrentEmptyHeight() {
Expand All @@ -29,5 +34,17 @@ func (s *DriverStateTestSuite) TestResetL1CurrentEmptyHeight() {

func (s *DriverStateTestSuite) TestResetL1CurrentEmptyID() {
_, _, err := s.s.ResetL1Current(context.Background(), &HeightOrID{Height: common.Big1})
s.NotNil(err)
s.ErrorContains(err, "not found")
}

func (s *DriverStateTestSuite) TestResetL1CurrentEmptyHeightAndID() {
_, _, err := s.s.ResetL1Current(context.Background(), &HeightOrID{})
s.ErrorContains(err, "empty input")
}

func (s *DriverStateTestSuite) TestResetL1CurrentCtxErr() {
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, _, err := s.s.ResetL1Current(ctx, &HeightOrID{Height: common.Big0})
s.ErrorContains(err, "context canceled")
}
15 changes: 15 additions & 0 deletions driver/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,21 @@ func (s *DriverStateTestSuite) TestGetSyncedHeaderID() {
s.Zero(id.Uint64())
}

func (s *DriverStateTestSuite) TestNewDriverContextErr() {
ctx, cancel := context.WithCancel(context.Background())
cancel()
state, err := New(ctx, s.RpcClient)
s.Nil(state)
s.ErrorContains(err, "context canceled")
}

func (s *DriverStateTestSuite) TestDriverInitContextErr() {
ctx, cancel := context.WithCancel(context.Background())
cancel()
err := s.s.init(ctx)
s.ErrorContains(err, "context canceled")
}

func TestDriverStateTestSuite(t *testing.T) {
suite.Run(t, new(DriverStateTestSuite))
}
21 changes: 21 additions & 0 deletions pkg/rpc/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"os"
"testing"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -27,3 +28,23 @@ func newTestClient(t *testing.T) *Client {

return client
}

func newTestClientWithTimeout(t *testing.T) *Client {
timeout := 5 * time.Second
client, err := NewClient(context.Background(), &ClientConfig{
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")),
TaikoProverPoolL1Address: common.HexToAddress(os.Getenv("TAIKO_PROVER_POOL_L1_ADDRESS")),
L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"),
JwtSecret: os.Getenv("JWT_SECRET"),
RetryInterval: backoff.DefaultMaxInterval,
Timeout: &timeout,
})

require.Nil(t, err)
require.NotNil(t, client)

return client
}
14 changes: 14 additions & 0 deletions pkg/rpc/dial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,17 @@ func TestDialClientWithBackoff(t *testing.T) {

require.Equal(t, common.Big0.Uint64(), genesis.Number.Uint64())
}

// NOTE: current constant backoff will only stop if passed -1 (backoff.Stop),
// and error does not match
// error comes back as "dial unix: ...." instead

// func TestDialClientWithBackoff_CtxError(t *testing.T) {
// ctx, _ := context.WithCancel(context.Background())
// _, err := DialClientWithBackoff(
// ctx,
// "",
// -1,
// )
// require.ErrorContains(t, err, "Dial engine client error")
// }
2 changes: 1 addition & 1 deletion pkg/rpc/methods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var (
)

func TestL2AccountNonce(t *testing.T) {
client := newTestClient(t)
client := newTestClientWithTimeout(t)

nonce, err := client.L2AccountNonce(context.Background(), testAddress, common.Big0)

Expand Down
147 changes: 126 additions & 21 deletions proposer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,24 @@ import (
"github.com/urfave/cli/v2"
)

func (s *ProposerTestSuite) TestNewConfigFromCliContext() {
l1Endpoint := os.Getenv("L1_NODE_WS_ENDPOINT")
l2Endpoint := os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT")
taikoL1 := os.Getenv("TAIKO_L1_ADDRESS")
taikoL2 := os.Getenv("TAIKO_L2_ADDRESS")
proposeInterval := "10s"
rpcTimeout := 5 * time.Second
var (
l1Endpoint = os.Getenv("L1_NODE_WS_ENDPOINT")
l2Endpoint = os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT")
taikoL1 = os.Getenv("TAIKO_L1_ADDRESS")
taikoL2 = os.Getenv("TAIKO_L2_ADDRESS")
proposeInterval = "10s"
rpcTimeout = 5 * time.Second
)

func (s *ProposerTestSuite) TestNewConfigFromCliContext() {
goldenTouchAddress, err := s.RpcClient.TaikoL2.GOLDENTOUCHADDRESS(nil)
s.Nil(err)

goldenTouchPrivKey, err := s.RpcClient.TaikoL2.GOLDENTOUCHPRIVATEKEY(nil)
s.Nil(err)

app := cli.NewApp()
app.Flags = []cli.Flag{
&cli.StringFlag{Name: flags.L1WSEndpoint.Name},
&cli.StringFlag{Name: flags.L2HTTPEndpoint.Name},
&cli.StringFlag{Name: flags.TaikoL1Address.Name},
&cli.StringFlag{Name: flags.TaikoL2Address.Name},
&cli.StringFlag{Name: flags.L1ProposerPrivKey.Name},
&cli.StringFlag{Name: flags.L2SuggestedFeeRecipient.Name},
&cli.StringFlag{Name: flags.ProposeInterval.Name},
&cli.StringFlag{Name: flags.TxPoolLocals.Name},
&cli.Uint64Flag{Name: flags.ProposeBlockTxReplacementMultiplier.Name},
&cli.Uint64Flag{Name: flags.RPCTimeout.Name},
&cli.Uint64Flag{Name: flags.WaitReceiptTimeout.Name},
}
app := s.SetupApp()

app.Action = func(ctx *cli.Context) error {
c, err := NewConfigFromCliContext(ctx)
s.Nil(err)
Expand Down Expand Up @@ -72,5 +62,120 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() {
"-" + flags.ProposeBlockTxReplacementMultiplier.Name, "5",
"-" + flags.RPCTimeout.Name, "5",
"-" + flags.WaitReceiptTimeout.Name, "10",
"-" + flags.ProposeBlockTxGasLimit.Name, "100000",
}))
}

func (s *ProposerTestSuite) TestNewConfigFromCliContextPrivKeyErr() {
app := s.SetupApp()

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContextPrivKeyErr",
"-" + flags.L1ProposerPrivKey.Name, string(common.FromHex("0x")),
}), "invalid L1 proposer private key")
}

func (s *ProposerTestSuite) TestNewConfigFromCliContextPropIntervalErr() {
goldenTouchPrivKey, err := s.RpcClient.TaikoL2.GOLDENTOUCHPRIVATEKEY(nil)
s.Nil(err)

app := s.SetupApp()

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContextProposeIntervalErr",
"-" + flags.L1ProposerPrivKey.Name, common.Bytes2Hex(goldenTouchPrivKey.Bytes()),
"-" + flags.ProposeInterval.Name, "",
}), "invalid proposing interval")
}

func (s *ProposerTestSuite) TestNewConfigFromCliContextEmptyPropoIntervalErr() {
goldenTouchPrivKey, err := s.RpcClient.TaikoL2.GOLDENTOUCHPRIVATEKEY(nil)
s.Nil(err)

app := s.SetupApp()

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContextEmptyProposalIntervalErr",
"-" + flags.L1ProposerPrivKey.Name, common.Bytes2Hex(goldenTouchPrivKey.Bytes()),
"-" + flags.ProposeInterval.Name, proposeInterval,
"-" + flags.ProposeEmptyBlocksInterval.Name, "",
}), "invalid proposing empty blocks interval")
}

func (s *ProposerTestSuite) TestNewConfigFromCliContextL2RecipErr() {
goldenTouchPrivKey, err := s.RpcClient.TaikoL2.GOLDENTOUCHPRIVATEKEY(nil)
s.Nil(err)

app := s.SetupApp()

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContextL2RecipErr",
"-" + flags.L1ProposerPrivKey.Name, common.Bytes2Hex(goldenTouchPrivKey.Bytes()),
"-" + flags.ProposeInterval.Name, proposeInterval,
"-" + flags.ProposeEmptyBlocksInterval.Name, proposeInterval,
"-" + flags.L2SuggestedFeeRecipient.Name, "notAnAddress",
}), "invalid L2 suggested fee recipient address")
}

func (s *ProposerTestSuite) TestNewConfigFromCliContextTxPoolLocalsErr() {
goldenTouchAddress, err := s.RpcClient.TaikoL2.GOLDENTOUCHADDRESS(nil)
s.Nil(err)

goldenTouchPrivKey, err := s.RpcClient.TaikoL2.GOLDENTOUCHPRIVATEKEY(nil)
s.Nil(err)

app := s.SetupApp()

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContextTxPoolLocalsErr",
"-" + flags.L1ProposerPrivKey.Name, common.Bytes2Hex(goldenTouchPrivKey.Bytes()),
"-" + flags.ProposeInterval.Name, proposeInterval,
"-" + flags.ProposeEmptyBlocksInterval.Name, proposeInterval,
"-" + flags.L2SuggestedFeeRecipient.Name, goldenTouchAddress.Hex(),
"-" + flags.TxPoolLocals.Name, "notAnAddress",
}), "invalid account in --txpool.locals")
}

func (s *ProposerTestSuite) TestNewConfigFromCliContextReplMultErr() {
goldenTouchAddress, err := s.RpcClient.TaikoL2.GOLDENTOUCHADDRESS(nil)
s.Nil(err)

goldenTouchPrivKey, err := s.RpcClient.TaikoL2.GOLDENTOUCHPRIVATEKEY(nil)
s.Nil(err)

app := s.SetupApp()

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContextReplMultErr",
"-" + flags.L1ProposerPrivKey.Name, common.Bytes2Hex(goldenTouchPrivKey.Bytes()),
"-" + flags.ProposeInterval.Name, proposeInterval,
"-" + flags.ProposeEmptyBlocksInterval.Name, proposeInterval,
"-" + flags.L2SuggestedFeeRecipient.Name, goldenTouchAddress.Hex(),
"-" + flags.TxPoolLocals.Name, goldenTouchAddress.Hex(),
"-" + flags.ProposeBlockTxReplacementMultiplier.Name, "0",
}), "invalid --proposeBlockTxReplacementMultiplier value")
}

func (s *ProposerTestSuite) SetupApp() *cli.App {
app := cli.NewApp()
app.Flags = []cli.Flag{
&cli.StringFlag{Name: flags.L1WSEndpoint.Name},
&cli.StringFlag{Name: flags.L2HTTPEndpoint.Name},
&cli.StringFlag{Name: flags.TaikoL1Address.Name},
&cli.StringFlag{Name: flags.TaikoL2Address.Name},
&cli.StringFlag{Name: flags.L1ProposerPrivKey.Name},
&cli.StringFlag{Name: flags.L2SuggestedFeeRecipient.Name},
&cli.StringFlag{Name: flags.ProposeEmptyBlocksInterval.Name},
&cli.StringFlag{Name: flags.ProposeInterval.Name},
&cli.StringFlag{Name: flags.TxPoolLocals.Name},
&cli.Uint64Flag{Name: flags.ProposeBlockTxReplacementMultiplier.Name},
&cli.Uint64Flag{Name: flags.RPCTimeout.Name},
&cli.Uint64Flag{Name: flags.WaitReceiptTimeout.Name},
&cli.Uint64Flag{Name: flags.ProposeBlockTxGasLimit.Name},
}
app.Action = func(ctx *cli.Context) error {
_, err := NewConfigFromCliContext(ctx)
return err
}
return app
}
5 changes: 3 additions & 2 deletions proposer/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,16 @@ func (p *Proposer) eventLoop() {
select {
case <-p.ctx.Done():
return
// proposing interval timer has been reached
case <-p.proposingTimer.C:
metrics.ProposerProposeEpochCounter.Inc(1)

// attempt propose operation
if err := p.ProposeOp(p.ctx); err != nil {
if !errors.Is(err, errNoNewTxs) {
log.Error("Proposing operation error", "error", err)
continue
}

// if no new transactions and empty block interval has passed, propose an empty block
if p.proposeEmptyBlocksInterval != nil {
if time.Now().Before(lastNonEmptyBlockProposedAt.Add(*p.proposeEmptyBlocksInterval)) {
continue
Expand Down
Loading

0 comments on commit 7ccedd2

Please sign in to comment.