Skip to content

Commit

Permalink
Updated reaper to reap old confirmed transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
amit-momin committed Jul 10, 2024
1 parent 005d972 commit db94c84
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 71 deletions.
60 changes: 30 additions & 30 deletions common/txmgr/types/mocks/tx_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 34 additions & 2 deletions core/chains/evm/txmgr/evm_tx_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -1882,7 +1882,7 @@ AND evm.txes.created_at < $2
AND evm.txes.state = 'finalized'
AND evm_chain_id = $3`, limit, timeThreshold, chainID.String())
if err != nil {
return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old confirmed evm.txes")
return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old finalized evm.txes")
}
rowsAffected, err := res.RowsAffected()
if err != nil {
Expand All @@ -1891,7 +1891,7 @@ AND evm_chain_id = $3`, limit, timeThreshold, chainID.String())
return uint(rowsAffected), err
}, batchSize)
if err != nil {
return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of confirmed evm.txes failed")
return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of finalized evm.txes failed")
}
// Delete old 'fatal_error' evm.txes
err = sqlutil.Batch(func(_, limit uint) (count uint, err error) {
Expand All @@ -1912,6 +1912,38 @@ AND evm_chain_id = $2`, timeThreshold, chainID.String())
if err != nil {
return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of fatally errored evm.txes failed")
}
// Delete old 'confirmed' evm.txes that were never finalized
// This query should never result in changes but added just in case transactions slip through the cracks
// to avoid them building up in the DB
err = sqlutil.Batch(func(_, limit uint) (count uint, err error) {
res, err := o.q.ExecContext(ctx, `
WITH old_enough_receipts AS (
SELECT tx_hash FROM evm.receipts
ORDER BY block_number ASC, id ASC
LIMIT $1
)
DELETE FROM evm.txes
USING old_enough_receipts, evm.tx_attempts
WHERE evm.tx_attempts.eth_tx_id = evm.txes.id
AND evm.tx_attempts.hash = old_enough_receipts.tx_hash
AND evm.txes.created_at < $2
AND evm.txes.state = 'confirmed'
AND evm_chain_id = $3`, limit, timeThreshold, chainID.String())
if err != nil {
return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old confirmed evm.txes")
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return count, pkgerrors.Wrap(err, "ReapTxes failed to get rows affected")
}
if rowsAffected > 0 {
o.logger.Criticalf("%d confirmed transactions were reaped before being marked as finalized. This should never happen unless the threshold is set too low or the transactions were lost track of", rowsAffected)
}
return uint(rowsAffected), err
}, batchSize)
if err != nil {
return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of confirmed evm.txes failed")
}

return nil
}
Expand Down
60 changes: 30 additions & 30 deletions core/chains/evm/txmgr/mocks/evm_tx_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 22 additions & 9 deletions core/chains/evm/txmgr/reaper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,11 @@ func TestReaper_ReapTxes(t *testing.T) {
// Didn't delete because eth_tx was not old enough
cltest.AssertCount(t, db, "evm.txes", 1)

pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1`, oneDayAgo)

err = r.ReapTxes(12)
assert.NoError(t, err)
// Didn't delete because eth_tx although old enough, was not marked as finalized
cltest.AssertCount(t, db, "evm.txes", 1)

pgtest.MustExec(t, db, `UPDATE evm.txes SET state='finalized'`)
pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1, state='finalized'`, oneDayAgo)

err = r.ReapTxes(42)
assert.NoError(t, err)
// Now it deleted because the eth_tx was past EVM.FinalityDepth
// Now it deleted because the eth_tx was past the age threshold
cltest.AssertCount(t, db, "evm.txes", 0)
})

Expand All @@ -127,4 +120,24 @@ func TestReaper_ReapTxes(t *testing.T) {
// Deleted because it is old enough now
cltest.AssertCount(t, db, "evm.txes", 0)
})

mustInsertConfirmedEthTxWithReceipt(t, txStore, from, 0, 42)

t.Run("deletes confirmed evm.txes that exceed the age threshold", func(t *testing.T) {
tc := &reaperConfig{reaperThreshold: 1 * time.Hour}

r := newReaper(t, txStore, tc)

err := r.ReapTxes(42)
assert.NoError(t, err)
// Didn't delete because eth_tx was not old enough
cltest.AssertCount(t, db, "evm.txes", 1)

pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1`, oneDayAgo)

err = r.ReapTxes(42)
assert.NoError(t, err)
// Now it deleted because the eth_tx was past the age threshold
cltest.AssertCount(t, db, "evm.txes", 0)
})
}

0 comments on commit db94c84

Please sign in to comment.