Skip to content

Commit

Permalink
fix: handle legislator badges errors when accepting proposals (#1284)
Browse files Browse the repository at this point in the history
* fix: handle legislator badges errors when accepting proposals

* chore: notify finish proposal job errors
  • Loading branch information
1emu authored Sep 21, 2023
1 parent 856ac43 commit 9cfe455
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 33 deletions.
2 changes: 2 additions & 0 deletions src/entities/Coauthor/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export default class CoauthorModel extends Model<CoauthorAttributes> {
}

static async findAllByProposals(proposals: ProposalAttributes[], status?: CoauthorStatus): Promise<string[]> {
if (proposals.length === 0) return []

const query = SQL`
SELECT address
FROM ${table(this)}
Expand Down
68 changes: 40 additions & 28 deletions src/entities/Proposal/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,15 @@ async function updateAcceptedProposals(acceptedProposals: ProposalWithOutcome[],
ProposalStatus.Passed
)

await BadgesService.giveLegislatorBadges(acceptedProposals)
try {
await BadgesService.giveLegislatorBadges(acceptedProposals)
} catch (error) {
ErrorService.report('Error while attempting to give badges', {
error,
category: ErrorCategory.Badges,
acceptedProposals,
})
}
}
}

Expand Down Expand Up @@ -195,35 +203,39 @@ async function categorizeProposals(
}

export async function finishProposal(context: JobContext) {
const finishableProposals = await ProposalModel.getFinishableProposals()
if (finishableProposals.length === 0) {
return
}
try {
const finishableProposals = await ProposalModel.getFinishableProposals()
if (finishableProposals.length === 0) {
return
}

const currentBudgets = await BudgetService.getBudgetsForProposals(finishableProposals)

context.log(`Updating ${finishableProposals.length} proposals...`)
const { finishedProposals, acceptedProposals, outOfBudgetProposals, rejectedProposals, updatedBudgets } =
await categorizeProposals(finishableProposals, currentBudgets, context)

await updateFinishedProposals(finishedProposals, context)
await updateAcceptedProposals(acceptedProposals, context)
await updateOutOfBudgetProposals(outOfBudgetProposals, context)
await updateRejectedProposals(rejectedProposals, context)
await BudgetService.updateBudgets(updatedBudgets)

const proposals = [...finishedProposals, ...acceptedProposals, ...rejectedProposals]
context.log(`Updating ${proposals.length} proposals in discourse... \n\n`)
for (const { id, title, winnerChoice, outcomeStatus } of proposals) {
ProposalService.commentProposalUpdateInDiscourse(id)
if (outcomeStatus) {
DiscordService.finishProposal(
id,
title,
outcomeStatus,
outcomeStatus === ProposalOutcome.FINISHED ? winnerChoice : undefined
)
const currentBudgets = await BudgetService.getBudgetsForProposals(finishableProposals)

context.log(`Updating ${finishableProposals.length} proposals...`)
const { finishedProposals, acceptedProposals, outOfBudgetProposals, rejectedProposals, updatedBudgets } =
await categorizeProposals(finishableProposals, currentBudgets, context)

await updateFinishedProposals(finishedProposals, context)
await updateAcceptedProposals(acceptedProposals, context)
await updateOutOfBudgetProposals(outOfBudgetProposals, context)
await updateRejectedProposals(rejectedProposals, context)
await BudgetService.updateBudgets(updatedBudgets)

const proposals = [...finishedProposals, ...acceptedProposals, ...rejectedProposals]
context.log(`Updating ${proposals.length} proposals in discourse... \n\n`)
for (const { id, title, winnerChoice, outcomeStatus } of proposals) {
ProposalService.commentProposalUpdateInDiscourse(id)
if (outcomeStatus) {
DiscordService.finishProposal(
id,
title,
outcomeStatus,
outcomeStatus === ProposalOutcome.FINISHED ? winnerChoice : undefined
)
}
}
} catch (error) {
ErrorService.report('Error finishing proposals', { error, category: ErrorCategory.Job })
}
}

Expand Down
13 changes: 8 additions & 5 deletions src/services/BadgesService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@ jest.mock('../constants', () => ({

const COAUTHORS = ['0x56d0b5ed3d525332f00c9bc938f93598ab16aaa7', '0x49e4dbff86a2e5da27c540c9a9e8d2c3726e278f']
describe('giveLegislatorBadges', () => {
beforeAll(() => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
it('should call queueAirdropJob with correct arguments for governance proposals', async () => {
jest.spyOn(AirdropJobModel, 'create').mockResolvedValue(async () => {})
jest.spyOn(CoauthorModel, 'findAllByProposals').mockResolvedValue(COAUTHORS)
})

it('should call queueAirdropJob with correct arguments for governance proposals', async () => {
const proposal = createTestProposal(ProposalType.Governance, ProposalStatus.Passed)
proposal.user = '0x4757ce43dc5429b8f1a132dc29ef970e55ae722b'
const expectedAuthorsAndCoauthors = [proposal.user, ...COAUTHORS].map(getChecksumAddress)
Expand All @@ -29,4 +25,11 @@ describe('giveLegislatorBadges', () => {
recipients: expectedAuthorsAndCoauthors,
})
})

it('does not try to airdrop any badge when there are no governance proposals', async () => {
jest.clearAllMocks()
const proposal = createTestProposal(ProposalType.Draft, ProposalStatus.Passed)
await BadgesService.giveLegislatorBadges([proposal])
expect(AirdropJobModel.create).not.toHaveBeenCalled()
})
})
3 changes: 3 additions & 0 deletions src/services/BadgesService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ export class BadgesService {

static async giveLegislatorBadges(acceptedProposals: ProposalAttributes[]) {
const governanceProposals = acceptedProposals.filter((proposal) => proposal.type === ProposalType.Governance)
if (governanceProposals.length === 0) {
return
}
const coauthors = await CoauthorModel.findAllByProposals(governanceProposals, CoauthorStatus.APPROVED)
const authors = governanceProposals.map((proposal) => proposal.user)
const authorsAndCoauthors = new Set([...authors.map(getChecksumAddress), ...coauthors.map(getChecksumAddress)])
Expand Down

0 comments on commit 9cfe455

Please sign in to comment.