Skip to content

Commit

Permalink
common: accout rewards when resolving unallocate action delta
Browse files Browse the repository at this point in the history
  • Loading branch information
tilacog committed Mar 22, 2023
1 parent 3b48b06 commit c38a73c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1051,14 +1051,18 @@ describe('Allocation Manager', () => {
beforeEach(setupEach)
afterEach(teardownEach)
afterAll(teardownAll)
jest.setTimeout(10_000)

// We have been rate-limited on CI as this test uses RPC providers,
// so we set its timeout to a higher value than usual.
jest.setTimeout(30_000)

// Reuse an existing allocation with 25 sextillion allocated GRT
const allocationID = '0x96737b6a31f40edaf96c567efbb98935aa906ab9'

// Redefine test actions to use that allocation ID
const unallocateAction = {
...invalidUnallocateAction,
poi: '0x1', // non-zero POI
allocationID,
}
const reallocateAction = {
Expand All @@ -1073,9 +1077,34 @@ describe('Allocation Manager', () => {
const mapper = (x: Action) => allocationManager.resolveActionDelta(x)
const balances = await Promise.all(actions.map(mapper))

expect(balances[0].balance).toStrictEqual(parseGRT('10000')) // (allocate)
expect(balances[1].balance).toStrictEqual(parseGRT('-25000')) // (unallocate)
expect(balances[2].balance).toStrictEqual(parseGRT('-15000')) // (reallocate)
console.table(balances)

const allocate = balances[0]
const unallocate = balances[1]
const reallocate = balances[2]

// Allocate test action
expect(allocate.action.type).toBe(ActionType.ALLOCATE)
expect(allocate.allocates).toStrictEqual(parseGRT('10000'))
expect(allocate.rewards.isZero()).toBeTruthy()
expect(allocate.unallocates.isZero()).toBeTruthy()
expect(allocate.balance).toStrictEqual(parseGRT('10000'))

// Unallocate test action
expect(unallocate.action.type).toBe(ActionType.UNALLOCATE)
expect(unallocate.allocates.isZero()).toBeTruthy()
expect(unallocate.rewards.isZero()).toBeFalsy()
expect(unallocate.unallocates).toStrictEqual(parseGRT('25000'))
expect(unallocate.balance).toStrictEqual(
unallocate.allocates.sub(unallocate.unallocates).sub(unallocate.rewards),
)

// This Reallocate test Action intentionally uses a null or zeroed POI, so it should not accrue rewards.
expect(reallocate.action.type).toBe(ActionType.REALLOCATE)
expect(reallocate.allocates).toStrictEqual(parseGRT('10000'))
expect(reallocate.rewards.isZero()).toBeTruthy()
expect(reallocate.unallocates).toStrictEqual(parseGRT('25000'))
expect(reallocate.balance).toStrictEqual(parseGRT('-15000'))
})

test('validateActionBatchFeasibility() validates and correctly sorts actions based on net token balance', async () => {
Expand Down
22 changes: 17 additions & 5 deletions packages/indexer-common/src/indexer-management/allocations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface ResolvedAction {
action: Action
allocates: BigNumber
unallocates: BigNumber
rewards: BigNumber
balance: BigNumber
}

Expand Down Expand Up @@ -1127,6 +1128,7 @@ export class AllocationManager {
// Calculates the balance (GRT delta) of a single Action.
async resolveActionDelta(action: Action): Promise<ResolvedAction> {
let unallocates = BigNumber.from(0)
let rewards = BigNumber.from(0)

// Handle allocations
let allocates
Expand All @@ -1136,27 +1138,37 @@ export class AllocationManager {
allocates = BigNumber.from(0)
}

// Handle unallocations
// Handle unallocations.
// We intentionally don't check if the allocation is active now because it will be checked
// later, when we prepare the transaction.

if (action.type === ActionType.UNALLOCATE || action.type === ActionType.REALLOCATE) {
// ensure this Action have a valid allocationID
// Ensure this Action have a valid allocationID
if (action.allocationID === null || action.allocationID === undefined) {
throw Error(
`SHOULD BE UNREACHABLE: Unallocate or Reallocate action must have an allocationID field: ${action}`,
)
}

// Fetch the allocation on chain to inspect its amount
const allocation = await this.networkMonitor.allocation(action.allocationID)

/* We intentionally don't check if the allocation is active now because it will be checked
* later when we prepare the transaction */
// Accrue rewards, except for null or zeroed POI
const zeroHexString = utils.hexlify(Array(32).fill(0))
rewards =
!action.poi || action.poi === zeroHexString
? BigNumber.from(0)
: await this.contracts.rewardsManager.getRewards(action.allocationID)

unallocates = unallocates.add(allocation.allocatedTokens)
}

const balance = allocates.sub(unallocates)
const balance = allocates.sub(unallocates).sub(rewards)
return {
action,
allocates,
unallocates,
rewards,
balance,
}
}
Expand Down

0 comments on commit c38a73c

Please sign in to comment.