Skip to content

Commit

Permalink
Fix lost data
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaubennassar committed Feb 2, 2024
1 parent 3a6b23e commit a0ec07d
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
32 changes: 32 additions & 0 deletions db/migrations/state/validium-001.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-- +migrate Up

CREATE TABLE IF NOT EXISTS state.batch_data_backup
(
batch_num BIGINT,
data BYTEA,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (batch_num, created_at)
);

-- +migrate StatementBegin
CREATE OR REPLACE FUNCTION backup_batch() RETURNS trigger AS $$
BEGIN
INSERT INTO state.batch_data_backup (batch_num, data)
VALUES (OLD.batch_num, OLD.raw_txs_data)
ON CONFLICT (batch_num, created_at) DO UPDATE SET
data = EXCLUDED.data;
RETURN OLD;
END;
$$
LANGUAGE plpgsql;
-- +migrate StatementEnd

CREATE TRIGGER backup_batch
BEFORE DELETE ON state.batch FOR EACH ROW
EXECUTE PROCEDURE backup_batch();

-- +migrate Down

DROP TRIGGER IF EXISTS backup_batch ON state.batch;
DROP FUNCTION IF EXISTS backup_batch();
DROP TABLE IF EXISTS state.batch_data_backup;
18 changes: 18 additions & 0 deletions state/pgstatestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,25 @@ func (p *PostgresStorage) GetBatchL2DataByNumber(ctx context.Context, batchNumbe
q := p.getExecQuerier(dbTx)
var batchL2Data []byte
err := q.QueryRow(ctx, getBatchL2DataByBatchNumber, batchNumber).Scan(&batchL2Data)
if errors.Is(err, pgx.ErrNoRows) {
return p.GetBatchL2DataByNumberFromBackup(ctx, batchNumber, dbTx)
} else if err != nil {
return nil, err
}
return batchL2Data, nil
}

// GetBatchL2DataByNumberFromBackup returns the batch L2 data of the given batch number from the backup table
func (p *PostgresStorage) GetBatchL2DataByNumberFromBackup(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error) {
getBatchL2DataByBatchNumber := `
SELECT data FROM state.batch_data_backup
WHERE batch_num = $1
ORDER BY created_at DESC
LIMIT 1
`
q := p.getExecQuerier(dbTx)
var batchL2Data []byte
err := q.QueryRow(ctx, getBatchL2DataByBatchNumber, batchNumber).Scan(&batchL2Data)
if errors.Is(err, pgx.ErrNoRows) {
return nil, ErrNotFound
} else if err != nil {
Expand Down
26 changes: 26 additions & 0 deletions state/pgstatestorage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,32 @@ func TestGetBatchL2DataByNumber(t *testing.T) {
actualData, err := testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
require.NoError(t, err)
assert.Equal(t, expectedData, actualData)

// Force backup
_, err = tx.Exec(ctx, "DELETE FROM state.batch")
require.NoError(t, err)

// Get batch 4 from backup
batchNum = 4
data, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
require.NoError(t, err)
assert.Nil(t, data)

// Get batch 5 from backup
batchNum = 5
actualData, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
require.NoError(t, err)
assert.Equal(t, expectedData, actualData)

// Update batch 5 and get it from backup
expectedData = []byte("new foo bar")
_, err = tx.Exec(ctx, openBatchSQL, batchNum, expectedData)
require.NoError(t, err)
_, err = tx.Exec(ctx, "DELETE FROM state.batch")
require.NoError(t, err)
actualData, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
require.NoError(t, err)
assert.Equal(t, expectedData, actualData)
}
func TestForkIDs(t *testing.T) {
initOrResetDB()
Expand Down

0 comments on commit a0ec07d

Please sign in to comment.