Skip to content

Commit 880ddcd

Browse files
MoonBoi9001claude
andauthored
fix(actions): add missing PRESENT_POI case to isValidActionInput (#1180)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3129aac commit 880ddcd

4 files changed

Lines changed: 122 additions & 4 deletions

File tree

packages/indexer-common/src/__tests__/actions.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,61 @@ describe('Action Validation', () => {
111111
expect(isValidActionInput(missingDeploymentID)).toBe(false)
112112
})
113113

114+
test('validates PRESENT_POI action', () => {
115+
const validPresentPOI: ActionInput = {
116+
...baseAction,
117+
type: ActionType.PRESENT_POI,
118+
deploymentID: 'Qmtest',
119+
allocationID: '0x1234567890123456789012345678901234567890',
120+
} as ActionInput
121+
122+
expect(isValidActionInput(validPresentPOI)).toBe(true)
123+
124+
// Missing allocationID
125+
const missingAllocationID: ActionInput = {
126+
...baseAction,
127+
type: ActionType.PRESENT_POI,
128+
deploymentID: 'Qmtest',
129+
} as ActionInput
130+
131+
expect(isValidActionInput(missingAllocationID)).toBe(false)
132+
133+
// Missing deploymentID
134+
const missingDeploymentID: ActionInput = {
135+
...baseAction,
136+
type: ActionType.PRESENT_POI,
137+
allocationID: '0x1234567890123456789012345678901234567890',
138+
} as ActionInput
139+
140+
expect(isValidActionInput(missingDeploymentID)).toBe(false)
141+
142+
// With POI provided, must also have publicPOI and poiBlockNumber
143+
const withPoiButMissingPublicPOI = {
144+
...baseAction,
145+
type: ActionType.PRESENT_POI,
146+
deploymentID: 'Qmtest',
147+
allocationID: '0x1234567890123456789012345678901234567890',
148+
poi: '0x' + 'ab'.repeat(32),
149+
isLegacy: false,
150+
}
151+
152+
expect(isValidActionInput(withPoiButMissingPublicPOI)).toBe(false)
153+
154+
// With all POI fields provided
155+
const withAllPoiFields = {
156+
...baseAction,
157+
type: ActionType.PRESENT_POI,
158+
deploymentID: 'Qmtest',
159+
allocationID: '0x1234567890123456789012345678901234567890',
160+
poi: '0x' + 'ab'.repeat(32),
161+
publicPOI: '0x' + 'cd'.repeat(32),
162+
poiBlockNumber: 12345,
163+
isLegacy: false,
164+
}
165+
166+
expect(isValidActionInput(withAllPoiFields)).toBe(true)
167+
})
168+
114169
test('validates common required fields (source, reason, status, priority)', () => {
115170
// Missing status
116171
const missingStatus = {

packages/indexer-common/src/actions.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ export const isValidActionInput = (
101101
'allocationID' in variableToCheck &&
102102
'amount' in variableToCheck
103103
break
104+
case ActionType.PRESENT_POI:
105+
hasActionParams =
106+
'deploymentID' in variableToCheck && 'allocationID' in variableToCheck
107+
108+
if (!variableToCheck.isLegacy && variableToCheck.poi !== undefined) {
109+
hasActionParams =
110+
hasActionParams &&
111+
'poi' in variableToCheck &&
112+
'publicPOI' in variableToCheck &&
113+
'poiBlockNumber' in variableToCheck
114+
}
115+
break
104116
}
105117
return (
106118
hasActionParams &&
@@ -164,11 +176,14 @@ export const validateActionInputs = async (
164176
)
165177
}
166178

167-
// Unallocate, reallocate, and resize actions must target an active allocationID
179+
// Unallocate, reallocate, resize, and presentPOI actions must target an active allocationID
168180
if (
169-
[ActionType.UNALLOCATE, ActionType.REALLOCATE, ActionType.RESIZE].includes(
170-
action.type,
171-
)
181+
[
182+
ActionType.UNALLOCATE,
183+
ActionType.REALLOCATE,
184+
ActionType.RESIZE,
185+
ActionType.PRESENT_POI,
186+
].includes(action.type)
172187
) {
173188
// allocationID must belong to active allocation
174189
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion

packages/indexer-common/src/indexer-management/__tests__/resolvers/actions.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {
3232
invalidReallocateAction,
3333
invalidUnallocateAction,
3434
queuedAllocateAction,
35+
queuedResizeAction,
36+
queuedPresentPOIAction,
3537
subgraphDeployment1,
3638
subgraphDeployment2,
3739
subgraphDeployment3,
@@ -871,4 +873,38 @@ describe.skip('Actions', () => {
871873
.toPromise(),
872874
).resolves.toHaveProperty('data.updateActions', updatedExpecteds)
873875
})
876+
877+
test('Queue and retrieve resize action', async () => {
878+
const inputAction = queuedResizeAction
879+
const expected = await actionInputToExpected(inputAction, 1)
880+
881+
await expect(
882+
client.mutation(QUEUE_ACTIONS_MUTATION, { actions: [inputAction] }).toPromise(),
883+
).resolves.toHaveProperty('data.queueActions', [expected])
884+
885+
await expect(
886+
client
887+
.query(ACTIONS_QUERY, {
888+
filter: { status: ActionStatus.QUEUED, type: ActionType.RESIZE },
889+
})
890+
.toPromise(),
891+
).resolves.toHaveProperty('data.actions', [expected])
892+
})
893+
894+
test('Queue and retrieve presentPOI action', async () => {
895+
const inputAction = queuedPresentPOIAction
896+
const expected = await actionInputToExpected(inputAction, 1)
897+
898+
await expect(
899+
client.mutation(QUEUE_ACTIONS_MUTATION, { actions: [inputAction] }).toPromise(),
900+
).resolves.toHaveProperty('data.queueActions', [expected])
901+
902+
await expect(
903+
client
904+
.query(ACTIONS_QUERY, {
905+
filter: { status: ActionStatus.QUEUED, type: ActionType.PRESENT_POI },
906+
})
907+
.toPromise(),
908+
).resolves.toHaveProperty('data.actions', [expected])
909+
})
874910
})

packages/indexer-common/src/indexer-management/__tests__/util.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,15 @@ export const queuedResizeAction = {
147147
priority: 0,
148148
protocolNetwork: 'arbitrum-sepolia',
149149
} as ActionInput
150+
151+
export const queuedPresentPOIAction = {
152+
status: ActionStatus.QUEUED,
153+
type: ActionType.PRESENT_POI,
154+
deploymentID: subgraphDeployment1,
155+
allocationID: '0x8f63930129e585c69482b56390a09b6b176f4a4c',
156+
force: false,
157+
source: 'indexerAgent',
158+
reason: 'indexingRule',
159+
priority: 0,
160+
protocolNetwork: 'arbitrum-sepolia',
161+
} as ActionInput

0 commit comments

Comments
 (0)