Skip to content

Commit

Permalink
feat: check escrow balance before rav redeem
Browse files Browse the repository at this point in the history
Signed-off-by: Gustavo Inacio <[email protected]>
  • Loading branch information
gusinacio committed Oct 7, 2024
1 parent 331b7e5 commit 6275848
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
64 changes: 64 additions & 0 deletions packages/indexer-common/src/allocations/escrow-accounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Address, toAddress } from '@graphprotocol/common-ts'
import { TAPSubgraph } from '../tap-subgraph'
import gql from 'graphql-tag'

type U256 = bigint

type EscrowAccountResponse = {
escrowAccounts: {
balance: string
sender: {
id: string
}
}[]
}

export class EscrowAccounts {
constructor(private sendersBalances: Map<Address, U256>) {}

getBalanceForSender(sender: Address): U256 {
const balance = this.sendersBalances.get(sender)
if (balance === undefined) {
throw new Error(`No balance found for sender: ${sender}`)
}
return balance
}

subtractSenderBalance(sender: Address, ravValue: U256) {
const balance = this.getBalanceForSender(sender)
const newBalance = balance - ravValue
this.sendersBalances.set(sender, newBalance)
}

static fromResponse(response: EscrowAccountResponse): EscrowAccounts {
const sendersBalances = new Map<Address, U256>()
response.escrowAccounts.forEach((account) => {
sendersBalances.set(toAddress(account.sender.id), BigInt(account.balance))
})

return new EscrowAccounts(sendersBalances)
}
}

export const getEscrowAccounts = async (
tapSubgraph: TAPSubgraph,
indexer: Address,
): Promise<EscrowAccounts> => {
const result = await tapSubgraph.query<EscrowAccountResponse>(
gql`
query EscrowAccountQuery($indexer: ID!) {
escrowAccounts(where: { receiver_: { id: $indexer } }) {
balance
sender {
id
}
}
}
`,
{ indexer },
)
if (!result.data) {
throw `There was an error while querying Tap Subgraph. Errors: ${result.error}`
}
return EscrowAccounts.fromResponse(result.data)
}
23 changes: 23 additions & 0 deletions packages/indexer-common/src/allocations/tap-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import pReduce from 'p-reduce'
import { TAPSubgraph } from '../tap-subgraph'
import { NetworkSubgraph } from '../network-subgraph'
import gql from 'graphql-tag'
import { getEscrowAccounts } from './escrow-accounts'

const RAV_CHECK_INTERVAL_MS = 30_000

Expand Down Expand Up @@ -452,10 +453,28 @@ export class TapCollector {
logger.info(`Redeem last RAVs on chain individually`, {
signedRavs,
})
const escrowAccounts = await getEscrowAccounts(this.tapSubgraph, toAddress(''))

// Redeem RAV one-by-one as no plual version available
for (const { rav: signedRav, allocation, sender } of signedRavs) {
const { rav } = signedRav

// verify escrow balances
const ravValue = BigInt(rav.valueAggregate.toString())
const senderBalance = escrowAccounts.getBalanceForSender(sender)
if (senderBalance < ravValue) {
this.logger.warn(
'RAV was not sent to the blockchain \
because its value aggregate is lower than escrow balance.',
{
rav,
sender,
senderBalance,
},
)
continue
}

const stopTimer = this.metrics.ravsRedeemDuration.startTimer({
allocation: rav.allocationId,
})
Expand Down Expand Up @@ -486,6 +505,10 @@ export class TapCollector {
this.metrics.ravRedeemsInvalid.inc({ allocation: rav.allocationId })
return
}
// subtract from the escrow account
// THIS IS A MUT OPERATION
escrowAccounts.subtractSenderBalance(sender, ravValue)

this.metrics.ravCollectedFees.set(
{ allocation: rav.allocationId },
parseFloat(rav.valueAggregate.toString()),
Expand Down

0 comments on commit 6275848

Please sign in to comment.