From 435fdf8467a085fa8b776fb1e6efe0be72194d7d Mon Sep 17 00:00:00 2001 From: Goran Rojovic Date: Mon, 7 Oct 2024 11:03:45 +0200 Subject: [PATCH] feat: more UTs --- aggsender/aggsender.go | 13 +++++- aggsender/aggsender_test.go | 9 ++--- aggsender/db/aggsender_db_storage.go | 20 +++++++--- aggsender/db/aggsender_db_storage_test.go | 48 ++++++++++++++++++++--- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/aggsender/aggsender.go b/aggsender/aggsender.go index 37a83535..e7a25c8b 100644 --- a/aggsender/aggsender.go +++ b/aggsender/aggsender.go @@ -12,6 +12,7 @@ import ( "github.com/0xPolygon/cdk/bridgesync" cdkcommon "github.com/0xPolygon/cdk/common" "github.com/0xPolygon/cdk/config/types" + "github.com/0xPolygon/cdk/etherman" "github.com/0xPolygon/cdk/l1infotreesync" "github.com/0xPolygon/cdk/log" treeTypes "github.com/0xPolygon/cdk/tree/types" @@ -26,11 +27,21 @@ type L1InfoTreeSyncer interface { index uint32, root common.Hash) (treeTypes.Proof, error) } +// L2BridgeSyncer is an interface defining functions that an L2BridgeSyncer should implement +type L2BridgeSyncer interface { + GetBlockByLER(ctx context.Context, ler common.Hash) (uint64, error) + GetExitRootByIndex(ctx context.Context, index uint32) (treeTypes.Root, error) + GetBridges(ctx context.Context, fromBlock, toBlock uint64) ([]bridgesync.Bridge, error) + GetClaims(ctx context.Context, fromBlock, toBlock uint64) ([]bridgesync.Claim, error) + OriginNetwork() uint32 + BlockFinality() etherman.BlockNumberFinality +} + // AggSender is a component that will send certificates to the aggLayer type AggSender struct { log *log.Logger - l2Syncer *bridgesync.BridgeSync + l2Syncer L2BridgeSyncer l2Client bridgesync.EthClienter l1infoTreeSyncer L1InfoTreeSyncer diff --git a/aggsender/aggsender_test.go b/aggsender/aggsender_test.go index 0572b590..cc031d57 100644 --- a/aggsender/aggsender_test.go +++ b/aggsender/aggsender_test.go @@ -433,7 +433,7 @@ func TestGetImportedBridgeExits(t *testing.T) { DestinationAddress: common.HexToAddress("0xabc"), Amount: big.NewInt(200), Metadata: []byte("data"), - GlobalIndex: big.NewInt(2), + GlobalIndex: bridgesync.GenerateGlobalIndex(true, 0, 2), GlobalExitRoot: common.HexToHash("0xdef"), RollupExitRoot: common.HexToHash("0xbbb"), MainnetExitRoot: common.HexToHash("0xccc"), @@ -494,11 +494,11 @@ func TestGetImportedBridgeExits(t *testing.T) { Metadata: []byte("data"), }, GlobalIndex: &agglayer.GlobalIndex{ - MainnetFlag: false, + MainnetFlag: true, RollupIndex: 0, LeafIndex: 2, }, - ClaimData: &agglayer.ClaimFromRollup{ + ClaimData: &agglayer.ClaimFromMainnnet{ L1Leaf: agglayer.L1InfoTreeLeaf{ L1InfoTreeIndex: 2, RollupExitRoot: common.HexToHash("0xbbb"), @@ -509,11 +509,10 @@ func TestGetImportedBridgeExits(t *testing.T) { BlockHash: common.HexToHash("0xabc"), }, }, - ProofLeafLER: agglayer.MerkleProof{ + ProofLeafMER: agglayer.MerkleProof{ Root: common.HexToHash("0xccc"), Proof: mockProof, }, - ProofLERToRER: agglayer.MerkleProof{}, ProofGERToL1Root: agglayer.MerkleProof{ Root: common.HexToHash("0x789"), Proof: mockProof, diff --git a/aggsender/db/aggsender_db_storage.go b/aggsender/db/aggsender_db_storage.go index b73619e2..c19d6429 100644 --- a/aggsender/db/aggsender_db_storage.go +++ b/aggsender/db/aggsender_db_storage.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" "fmt" + "math" "github.com/0xPolygon/cdk/aggsender/db/migrations" "github.com/0xPolygon/cdk/aggsender/types" @@ -72,7 +73,7 @@ func (a *AggSenderSQLStorage) GetCertificateByHeight(ctx context.Context, var certificateInfo types.CertificateInfo if err = meddler.ScanRow(rows, &certificateInfo); err != nil { - return types.CertificateInfo{}, err + return types.CertificateInfo{}, getSelectQueryError(height, err) } return certificateInfo, nil @@ -93,15 +94,12 @@ func (a *AggSenderSQLStorage) GetLastSentCertificate(ctx context.Context) (types rows, err := tx.Query(`SELECT * FROM certificate_info ORDER BY height DESC LIMIT 1;`) if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return types.CertificateInfo{}, db.ErrNotFound - } - return types.CertificateInfo{}, err + return types.CertificateInfo{}, getSelectQueryError(math.MaxUint64, err) // force checking err not found } var certificateInfo types.CertificateInfo if err = meddler.ScanRow(rows, &certificateInfo); err != nil { - return types.CertificateInfo{}, err + return types.CertificateInfo{}, getSelectQueryError(math.MaxUint64, err) // force checking err not found } return certificateInfo, nil @@ -159,6 +157,16 @@ func (a *AggSenderSQLStorage) DeleteCertificate(ctx context.Context, certificate return nil } +// clean deletes all the data from the storage +// NOTE: Used only in tests +func (a *AggSenderSQLStorage) clean() error { + if _, err := a.db.Exec(`DELETE FROM certificate_info;`); err != nil { + return err + } + + return nil +} + func getSelectQueryError(height uint64, err error) error { errToReturn := err if errors.Is(err, sql.ErrNoRows) { diff --git a/aggsender/db/aggsender_db_storage_test.go b/aggsender/db/aggsender_db_storage_test.go index b0be8ed2..7b646cb7 100644 --- a/aggsender/db/aggsender_db_storage_test.go +++ b/aggsender/db/aggsender_db_storage_test.go @@ -2,20 +2,19 @@ package db import ( "context" - "database/sql" - "errors" "path" "testing" "github.com/0xPolygon/cdk/agglayer" "github.com/0xPolygon/cdk/aggsender/db/migrations" "github.com/0xPolygon/cdk/aggsender/types" + "github.com/0xPolygon/cdk/db" "github.com/0xPolygon/cdk/log" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) -func Test_SaveLastSentCertificate(t *testing.T) { +func Test_Storage(t *testing.T) { ctx := context.Background() path := path.Join(t.TempDir(), "file::memory:?cache=shared") @@ -40,6 +39,7 @@ func Test_SaveLastSentCertificate(t *testing.T) { require.NoError(t, err) require.Equal(t, certificate, certificateFromDB) + require.NoError(t, storage.clean()) }) t.Run("DeleteCertificate", func(t *testing.T) { @@ -56,12 +56,18 @@ func Test_SaveLastSentCertificate(t *testing.T) { require.NoError(t, storage.DeleteCertificate(ctx, certificate.CertificateID)) certificateFromDB, err := storage.GetCertificateByHeight(ctx, certificate.Height) - require.Error(t, err) - require.True(t, errors.Is(err, sql.ErrNoRows)) + require.ErrorIs(t, err, db.ErrNotFound) require.Equal(t, types.CertificateInfo{}, certificateFromDB) + require.NoError(t, storage.clean()) }) t.Run("GetLastSentCertificate", func(t *testing.T) { + // try getting a certificate that doesn't exist + certificateFromDB, err := storage.GetLastSentCertificate(ctx) + require.ErrorIs(t, err, db.ErrNotFound) + require.Equal(t, types.CertificateInfo{}, certificateFromDB) + + // try getting a certificate that exists certificate := types.CertificateInfo{ Height: 3, CertificateID: common.HexToHash("0x5"), @@ -72,9 +78,39 @@ func Test_SaveLastSentCertificate(t *testing.T) { } require.NoError(t, storage.SaveLastSentCertificate(ctx, certificate)) - certificateFromDB, err := storage.GetLastSentCertificate(ctx) + certificateFromDB, err = storage.GetLastSentCertificate(ctx) + require.NoError(t, err) + + require.Equal(t, certificate, certificateFromDB) + require.NoError(t, storage.clean()) + }) + + t.Run("GetCertificateByHeight", func(t *testing.T) { + // try getting height 0 + certificateFromDB, err := storage.GetCertificateByHeight(ctx, 0) + require.NoError(t, err) + require.Equal(t, types.CertificateInfo{}, certificateFromDB) + + // try getting a certificate that doesn't exist + certificateFromDB, err = storage.GetCertificateByHeight(ctx, 4) + require.ErrorIs(t, err, db.ErrNotFound) + require.Equal(t, types.CertificateInfo{}, certificateFromDB) + + // try getting a certificate that exists + certificate := types.CertificateInfo{ + Height: 11, + CertificateID: common.HexToHash("0x17"), + NewLocalExitRoot: common.HexToHash("0x18"), + FromBlock: 17, + ToBlock: 18, + Status: agglayer.Pending, + } + require.NoError(t, storage.SaveLastSentCertificate(ctx, certificate)) + + certificateFromDB, err = storage.GetCertificateByHeight(ctx, certificate.Height) require.NoError(t, err) require.Equal(t, certificate, certificateFromDB) + require.NoError(t, storage.clean()) }) }