Skip to content

Commit

Permalink
fix: delegation events dates (#1606)
Browse files Browse the repository at this point in the history
* chore: log finishable proposals only in prod envs, just id and title

* chore: use block timestamp and event index as creation date for delegation events
  • Loading branch information
1emu authored Jan 31, 2024
1 parent ebaeabf commit fc22123
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
5 changes: 2 additions & 3 deletions src/back/routes/webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ export default routes((route) => {
async function delegationUpdate(req: Request) {
try {
validateAlchemyWebhookSignature(req)

const block = req.body.event.data.block as AlchemyBlock
if (block.logs.length === 0) {
if (block.transactions.length === 0) {
return
}
return await EventsService.delegationUpdate(block.logs)
return await EventsService.delegationUpdate(block)
} catch (error) {
ErrorService.report('Something failed on delegation update webhook', { error, category: ErrorCategory.Webhook })
}
Expand Down
64 changes: 43 additions & 21 deletions src/back/services/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ErrorService } from '../../services/ErrorService'
import { DiscourseWebhookPost } from '../../shared/types/discourse'
import {
ActivityTickerEvent,
AlchemyBlock,
AlchemyLog,
CommentedEvent,
DelegationClearEvent,
Expand Down Expand Up @@ -130,29 +131,34 @@ export class EventsService {
}
}

static async delegationSet(new_delegate: string, delegator: string, transaction_hash: string) {
static async delegationSet(new_delegate: string, delegator: string, transaction_hash: string, created_at: Date) {
try {
const delegationSetEvent: DelegationSetEvent = {
id: crypto.randomUUID(),
address: delegator,
event_type: EventType.DelegationSet,
event_data: { new_delegate, transaction_hash },
created_at: new Date(),
created_at,
}
await EventModel.create(delegationSetEvent)
} catch (error) {
this.reportEventError(error as Error, EventType.DelegationSet, { delegator, new_delegate })
}
}

static async delegationClear(removed_delegate: string, delegator: string, transaction_hash: string) {
static async delegationClear(
removed_delegate: string,
delegator: string,
transaction_hash: string,
created_at: Date
) {
try {
const delegationClearEvent: DelegationClearEvent = {
id: crypto.randomUUID(),
address: delegator,
event_type: EventType.DelegationClear,
event_data: { removed_delegate, transaction_hash },
created_at: new Date(),
created_at,
}
await EventModel.create(delegationClearEvent)
} catch (error) {
Expand Down Expand Up @@ -258,29 +264,45 @@ export class EventsService {
}
}

static async delegationUpdate(alchemyLogs: AlchemyLog[]) {
const txHash = alchemyLogs[0].transaction.hash
if (await EventModel.isDelegationTxRegistered(txHash)) {
return
}
for (const log of alchemyLogs) {
const spaceId = ethers.utils.parseBytes32String(log.topics[2])
if (spaceId !== SNAPSHOT_SPACE) {
static async delegationUpdate(block: AlchemyBlock) {
const blockTimestamp = block.timestamp
for (const transaction of block.transactions) {
const txHash = transaction.hash
if (await EventModel.isDelegationTxRegistered(txHash)) {
continue
}
const methodSignature = log.topics[0]
const delegator = this.decodeTopicToAddress(log.topics[1])
const delegate = this.decodeTopicToAddress(log.topics[3])

if (methodSignature === CLEAR_DELEGATE_SIGNATURE_HASH) {
await this.delegationClear(delegate, delegator, txHash)
}
if (methodSignature === SET_DELEGATE_SIGNATURE_HASH) {
await this.delegationSet(delegate, delegator, txHash)
for (const log of transaction.logs) {
const { spaceId, methodSignature, delegator, delegate } = this.decodeLogTopics(log.topics)
if (spaceId !== SNAPSHOT_SPACE) {
continue
}
const creationDate = this.getContractEventDate(blockTimestamp, log)
if (methodSignature === CLEAR_DELEGATE_SIGNATURE_HASH) {
await this.delegationClear(delegate, delegator, txHash, creationDate)
}
if (methodSignature === SET_DELEGATE_SIGNATURE_HASH) {
await this.delegationSet(delegate, delegator, txHash, creationDate)
}
}
}
}

private static decodeLogTopics(topics: string[]) {
const methodSignature = topics[0]
const delegator = this.decodeTopicToAddress(topics[1])
const spaceId = ethers.utils.parseBytes32String(topics[2])
const delegate = this.decodeTopicToAddress(topics[3])
return { spaceId, methodSignature, delegator, delegate }
}

/**
* This is so each log event is chronologically ordered, and has the closest date
* to the block timestamp
*/
private static getContractEventDate(blockTimestamp: number, log: AlchemyLog) {
return new Date(blockTimestamp * 1000 + log.index)
}

private static decodeTopicToAddress(topic: string) {
const address = '0x' + topic.slice(topic.length - 40)
if (!isEthereumAddress(address)) {
Expand Down
11 changes: 10 additions & 1 deletion src/entities/Proposal/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,21 @@ async function prepareProposalsAndBudgetsUpdates(
}
}

function logFinishableProposals(finishableProposals: ProposalAttributes[]) {
if (isProdEnv()) {
logger.log(`Finishable proposals:`)
finishableProposals.forEach((proposal, index) => {
console.log(`${index}: ${proposal.id} - ${proposal.title}`)
})
}
}

export async function finishProposal() {
logger.log(`Running finish proposal job...`)

try {
const finishableProposals = await ProposalModel.getFinishableProposals()
logger.log(`Finishable proposals`, finishableProposals)
logFinishableProposals(finishableProposals)
if (finishableProposals.length === 0) {
return
}
Expand Down
3 changes: 2 additions & 1 deletion src/shared/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export type AlchemyBlock = {
hash: string
number: number
timestamp: number
logs: AlchemyLog[]
transactions: AlchemyTransaction[]
}

export type AlchemyLog = {
Expand All @@ -105,4 +105,5 @@ export type AlchemyTransaction = {
from: {
address: string
}
logs: AlchemyLog[]
}

0 comments on commit fc22123

Please sign in to comment.