Skip to content

Commit

Permalink
fix: replace existing certificate
Browse files Browse the repository at this point in the history
  • Loading branch information
goran-ethernal committed Nov 7, 2024
1 parent 5e44136 commit 5242ecf
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 3 deletions.
36 changes: 33 additions & 3 deletions aggsender/db/aggsender_db_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,15 @@ func (a *AggSenderSQLStorage) GetCertificatesByStatus(ctx context.Context,

// GetCertificateByHeight returns a certificate by its height
func (a *AggSenderSQLStorage) GetCertificateByHeight(ctx context.Context,
height uint64) (types.CertificateInfo, error) {
return getCertificateByHeight(ctx, a.db, height)
}

// getCertificateByHeight returns a certificate by its height using the provided db
func getCertificateByHeight(ctx context.Context, db meddler.DB,

Check failure on line 97 in aggsender/db/aggsender_db_storage.go

View workflow job for this annotation

GitHub Actions / lint

`getCertificateByHeight` - `ctx` is unused (unparam)
height uint64) (types.CertificateInfo, error) {
var certificateInfo types.CertificateInfo
if err := meddler.QueryRow(a.db, &certificateInfo,
if err := meddler.QueryRow(db, &certificateInfo,
"SELECT * FROM certificate_info WHERE height = $1;", height); err != nil {
return types.CertificateInfo{}, getSelectQueryError(height, err)
}
Expand Down Expand Up @@ -124,9 +130,23 @@ func (a *AggSenderSQLStorage) SaveLastSentCertificate(ctx context.Context, certi
}
}()

cert, err := getCertificateByHeight(ctx, tx, certificate.Height)
if err != nil && !errors.Is(err, db.ErrNotFound) {
return err
}

if cert.CertificateID != (common.Hash{}) {
// we already have a certificate with this height
// we need to delete it before inserting the new one
if err = deleteCertificate(ctx, tx, cert.CertificateID); err != nil {
return err
}
}

if err = meddler.Insert(tx, "certificate_info", &certificate); err != nil {
return fmt.Errorf("error inserting certificate info: %w", err)
}

if err = tx.Commit(); err != nil {
return err
}
Expand All @@ -150,9 +170,10 @@ func (a *AggSenderSQLStorage) DeleteCertificate(ctx context.Context, certificate
}
}()

if _, err = tx.Exec(`DELETE FROM certificate_info WHERE certificate_id = $1;`, certificateID); err != nil {
return fmt.Errorf("error deleting certificate info: %w", err)
if err = deleteCertificate(ctx, a.db, certificateID); err != nil {
return err
}

if err = tx.Commit(); err != nil {
return err
}
Expand All @@ -162,6 +183,15 @@ func (a *AggSenderSQLStorage) DeleteCertificate(ctx context.Context, certificate
return nil
}

// deleteCertificate deletes a certificate from the storage using the provided db
func deleteCertificate(ctx context.Context, db meddler.DB, certificateID common.Hash) error {

Check failure on line 187 in aggsender/db/aggsender_db_storage.go

View workflow job for this annotation

GitHub Actions / lint

`deleteCertificate` - `ctx` is unused (unparam)
if _, err := db.Exec(`DELETE FROM certificate_info WHERE certificate_id = $1;`, certificateID); err != nil {
return fmt.Errorf("error deleting certificate info: %w", err)
}

return nil
}

// UpdateCertificateStatus updates the status of a certificate
func (a *AggSenderSQLStorage) UpdateCertificateStatus(ctx context.Context, certificate types.CertificateInfo) error {
tx, err := db.NewTx(ctx, a.db)
Expand Down
83 changes: 83 additions & 0 deletions aggsender/db/aggsender_db_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,86 @@ func Test_Storage(t *testing.T) {
require.NoError(t, storage.clean())
})
}

func Test_SaveLastSentCertificate(t *testing.T) {
ctx := context.Background()

path := path.Join(t.TempDir(), "file::memory:?cache=shared")
log.Debugf("sqlite path: %s", path)
require.NoError(t, migrations.RunMigrations(path))

storage, err := NewAggSenderSQLStorage(log.WithFields("aggsender-db"), path)
require.NoError(t, err)

t.Run("SaveNewCertificate", func(t *testing.T) {
certificate := types.CertificateInfo{
Height: 1,
CertificateID: common.HexToHash("0x1"),
NewLocalExitRoot: common.HexToHash("0x2"),
FromBlock: 1,
ToBlock: 2,
Status: agglayer.Settled,
}
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())
})

t.Run("UpdateExistingCertificate", func(t *testing.T) {
certificate := types.CertificateInfo{
Height: 2,
CertificateID: common.HexToHash("0x3"),
NewLocalExitRoot: common.HexToHash("0x4"),
FromBlock: 3,
ToBlock: 4,
Status: agglayer.InError,
}
require.NoError(t, storage.SaveLastSentCertificate(ctx, certificate))

// Update the certificate with the same height
updatedCertificate := types.CertificateInfo{
Height: 2,
CertificateID: common.HexToHash("0x5"),
NewLocalExitRoot: common.HexToHash("0x6"),
FromBlock: 3,
ToBlock: 6,
Status: agglayer.Pending,
}
require.NoError(t, storage.SaveLastSentCertificate(ctx, updatedCertificate))

certificateFromDB, err := storage.GetCertificateByHeight(ctx, updatedCertificate.Height)
require.NoError(t, err)
require.Equal(t, updatedCertificate, certificateFromDB)
require.NoError(t, storage.clean())
})

t.Run("SaveCertificateWithRollback", func(t *testing.T) {
// Simulate an error during the transaction to trigger a rollback
certificate := types.CertificateInfo{
Height: 3,
CertificateID: common.HexToHash("0x7"),
NewLocalExitRoot: common.HexToHash("0x8"),
FromBlock: 7,
ToBlock: 8,
Status: agglayer.Settled,
}

// Close the database to force an error
require.NoError(t, storage.db.Close())

err := storage.SaveLastSentCertificate(ctx, certificate)
require.Error(t, err)

// Reopen the database and check that the certificate was not saved
storage.db, err = db.NewSQLiteDB(path)
require.NoError(t, err)

certificateFromDB, err := storage.GetCertificateByHeight(ctx, certificate.Height)
require.ErrorIs(t, err, db.ErrNotFound)
require.Equal(t, types.CertificateInfo{}, certificateFromDB)
require.NoError(t, storage.clean())
})
}

0 comments on commit 5242ecf

Please sign in to comment.