Skip to content

Commit

Permalink
fix: last_checked_block retrieval (#138)
Browse files Browse the repository at this point in the history
* Fix last_checked_block retrieval

* Fix single duplicate block check, add automated tests

* Fix erroneous merges

* Update observer/bin/dry-run.js

* Update observer/bin/dry-run.js

---------

Co-authored-by: Julian Gruber <[email protected]>
  • Loading branch information
PatrickNercessian and juliangruber authored Jun 13, 2024
1 parent c3261ca commit 648189b
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 10 deletions.
2 changes: 1 addition & 1 deletion observer/bin/dry-run.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ await Promise.all([
observeScheduledRewards(pgPools, ieContract)
])

await pgPools.end()
await pgPools.stats.end()
6 changes: 4 additions & 2 deletions observer/lib/observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import * as Sentry from '@sentry/node'
*/
export const observeTransferEvents = async (pgPoolStats, ieContract, provider) => {
const { rows } = await pgPoolStats.query(
'SELECT MAX(last_checked_block) FROM daily_reward_transfers'
'SELECT MAX(last_checked_block) AS last_checked_block FROM daily_reward_transfers'
)
let queryFromBlock = rows[0].last_checked_block
let queryFromBlock = rows[0].last_checked_block + 1
const currentBlockNumber = await provider.getBlockNumber()

if (!queryFromBlock || queryFromBlock < currentBlockNumber - 1900) {
Expand All @@ -31,6 +31,8 @@ export const observeTransferEvents = async (pgPoolStats, ieContract, provider) =
console.log('Transfer event:', transferEvent)
await updateDailyTransferStats(pgPoolStats, transferEvent, currentBlockNumber)
}

return events.length
}

/**
Expand Down
127 changes: 120 additions & 7 deletions observer/test/observer.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,132 @@
import assert from 'node:assert'
import { observeScheduledRewards } from '../lib/observer.js'
import { beforeEach, describe, it } from 'mocha'
import { getPgPools } from '@filecoin-station/spark-stats-db'
import { givenDailyParticipants } from 'spark-evaluate/test/helpers/queries.js'

const getDayAsISOString = d => d.toISOString().split('T')[0]
const today = () => getDayAsISOString(new Date())
import { observeTransferEvents, observeScheduledRewards } from '../lib/observer.js'

describe('observer', () => {
describe('observeScheduledRewards', () => {
let pgPools
let pgPools
const getDayAsISOString = d => d.toISOString().split('T')[0]
const today = () => getDayAsISOString(new Date())

before(async () => {
pgPools = await getPgPools()
})

after(async () => {
await pgPools.end()
})

describe('observeTransferEvents', () => {
let ieContractMock
let providerMock

before(async () => {
pgPools = await getPgPools()
beforeEach(async () => {
await pgPools.stats.query('DELETE FROM daily_reward_transfers')

ieContractMock = {
filters: {
Transfer: () => 'TransferEventFilter'
},
queryFilter: async () => []
}
providerMock = {
getBlockNumber: async () => 2000
}
})

it('should correctly observe and update transfer events', async () => {
ieContractMock.queryFilter = async (eventName, fromBlock) => {
const events = [
{ args: { to: 'address1', amount: 100 }, blockNumber: 2000 },
{ args: { to: 'address1', amount: 200 }, blockNumber: 2000 }
]
return events.filter((event) => event.blockNumber >= fromBlock)
}

await observeTransferEvents(pgPools.stats, ieContractMock, providerMock)

const { rows } = await pgPools.stats.query(`
SELECT day::TEXT, to_address, amount, last_checked_block FROM daily_reward_transfers
`)
assert.strictEqual(rows.length, 1)
assert.deepStrictEqual(rows, [{
day: today(), to_address: 'address1', amount: '300', last_checked_block: 2000
}])
})

it('should handle multiple addresses in transfer events', async () => {
ieContractMock.queryFilter = async (eventName, fromBlock) => {
const events = [
{ args: { to: 'address1', amount: 50 }, blockNumber: 2000 },
{ args: { to: 'address2', amount: 150 }, blockNumber: 2000 }
]
return events.filter((event) => event.blockNumber >= fromBlock)
}

await observeTransferEvents(pgPools.stats, ieContractMock, providerMock)

const { rows } = await pgPools.stats.query(`
SELECT day::TEXT, to_address, amount, last_checked_block FROM daily_reward_transfers
ORDER BY to_address
`)
assert.strictEqual(rows.length, 2)
assert.deepStrictEqual(rows, [
{ day: today(), to_address: 'address1', amount: '50', last_checked_block: 2000 },
{ day: today(), to_address: 'address2', amount: '150', last_checked_block: 2000 }
])
})

it('should not duplicate transfer events', async () => {
ieContractMock.queryFilter = async (eventName, fromBlock) => {
const events = [
{ args: { to: 'address1', amount: 50 }, blockNumber: 2000 },
{ args: { to: 'address1', amount: 50 }, blockNumber: 2000 }
]
return events.filter((event) => event.blockNumber >= fromBlock)
}

const numEvents1 = await observeTransferEvents(pgPools.stats, ieContractMock, providerMock)
assert.strictEqual(numEvents1, 2)

const numEvents2 = await observeTransferEvents(pgPools.stats, ieContractMock, providerMock)
assert.strictEqual(numEvents2, 0)

const { rows } = await pgPools.stats.query(`
SELECT day::TEXT, to_address, amount, last_checked_block FROM daily_reward_transfers
`)
assert.strictEqual(rows.length, 1)
assert.deepStrictEqual(rows, [{
day: today(), to_address: 'address1', amount: '100', last_checked_block: 2000
}])
})

it('should avoid querying too old blocks', async () => {
providerMock.getBlockNumber = async () => 2500
ieContractMock.queryFilter = async (eventName, fromBlock) => {
const events = [
{ args: { to: 'address1', amount: 50 }, blockNumber: 400 },
{ args: { to: 'address2', amount: 150 }, blockNumber: 400 },
{ args: { to: 'address1', amount: 250 }, blockNumber: 2000 }
]
return events.filter((event) => event.blockNumber >= fromBlock)
}

await observeTransferEvents(pgPools.stats, ieContractMock, providerMock)

const { rows } = await pgPools.stats.query(`
SELECT day::TEXT, to_address, amount, last_checked_block FROM daily_reward_transfers
ORDER BY to_address
`)
assert.strictEqual(rows.length, 1)
assert.deepStrictEqual(rows, [
{ day: today(), to_address: 'address1', amount: '250', last_checked_block: 2500 }
])
})
})

describe('observeScheduledRewards', () => {
beforeEach(async () => {
await pgPools.evaluate.query('DELETE FROM daily_participants')
await pgPools.evaluate.query('DELETE FROM participants')
Expand Down

0 comments on commit 648189b

Please sign in to comment.