Skip to content

Commit 14823af

Browse files
committed
docs(reo): add verification checks and missing eligibility/denial test coverage
Verification gaps: - Add getRevertOnIneligible() to the env checks (IndexerTestGuide, ReoTestPlan 1.4) so the load-bearing revert assumption is confirmed before testing. - Expand TestnetDetails with the issuance/reclaim contract addresses, a Key Parameters table (revertOnIneligible, eligibility/timeout/retention defaults), and a Roles table. - Qualify "reclaimed to the protocol" (dropped/not minted if no reclaim address). - Reconcile cleanup to the mock as the testnet default; note that production-REO validation is performed separately (a live REO-A exists on Arbitrum One). New test coverage: - ReoTestPlan 3.6-3.8: indexer tracking (renewal adds to set, retention period, permissionless removeExpiredIndexer, IndexerTrackingUpdated). - ReoTestPlan 7.4-7.5: setProviderEligibilityOracle(address(0)) disables eligibility; interface-support guard rejects a non-IProviderEligibility oracle. - IndexerTestGuide 3.3: STALE_POI while ineligible (limit of "no rewards lost"). - SubgraphDenial 4.4 + 4.1 note: condition precedence — a stale/zero POI on a denied subgraph reclaims (denial does not precede STALE_POI/ZERO_POI/TOO_YOUNG). - Update overview tables and README test counts.
1 parent e15b5c6 commit 14823af

5 files changed

Lines changed: 268 additions & 33 deletions

File tree

packages/issuance/docs/testing/reo/IndexerTestGuide.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ Confirm what RewardsManager points at before starting:
6767
cast call $REWARDS_MANAGER "getProviderEligibilityOracle()(address)" --rpc-url $RPC
6868
# Default (mock): 0x69b0f3c6a19beaf1ba59405f7179e188c64b4e06 -> run Sets 2m-4m
6969
# Production (Oracle A): 0x6ba849fbd33257162552578b2a432d30784f2f80 -> run Sets 2-4
70+
71+
# Confirm the revert behaviour these tests assume:
72+
cast call $REWARDS_MANAGER "getRevertOnIneligible()(bool)" --rpc-url $RPC
73+
# Expected: true -> an ineligible close reverts (Set 3 / 3m).
74+
# If false, the close instead succeeds with 0 rewards (reclaim path) and Set 3's
75+
# pass criteria do not apply — coordinate before proceeding.
7076
```
7177

7278
### Verify Environment (production REO path only)
@@ -95,7 +101,7 @@ cast call $REO "getEligibilityPeriod()(uint256)" --rpc-url $RPC
95101
| --- | ------------------------------ | --------- |
96102
| 1 | Prepare Allocations | 1.1 |
97103
| 2 | Eligible — Receive Rewards | 2.1 - 2.2 |
98-
| 3 | Ineligible — Close Reverts | 3.1 - 3.2 |
104+
| 3 | Ineligible — Close Reverts | 3.1 - 3.3 |
99105
| 4 | Optimistic Recovery | 4.1 - 4.2 |
100106
| 5 | Validation Disabled | 5.1 |
101107
| 2m | Eligible — Mock REO | 2m.1 |
@@ -308,6 +314,32 @@ The indexer-agent close action fails when the transaction reverts. To observe th
308314

309315
---
310316

317+
### 3.3 Prolonged ineligibility → STALE_POI reclaim (the limit of "no rewards lost")
318+
319+
**Objective**: Verify the one case where the optimistic guarantee breaks: because you cannot present a POI while ineligible (3.2 reverts), the staleness clock keeps running. If an allocation goes past `maxPOIStaleness`, its accrued rewards become reclaimable as STALE_POI — so eligibility must be renewed before that window elapses.
320+
321+
**Prerequisites**: `isEligible` returns `false`. An active allocation whose last POI was presented long enough ago that it can cross `maxPOIStaleness` while you stay ineligible. Note `maxPOIStaleness` first:
322+
323+
```bash
324+
cast call <SUBGRAPH_SERVICE> "maxPOIStaleness()(uint256)" --rpc-url $RPC
325+
```
326+
327+
**Steps**:
328+
329+
1. Confirm ineligible (`isEligible` = `false`); note the allocation's last POI time
330+
2. Stay ineligible until `lastPOIPresentedAt + maxPOIStaleness` has elapsed (POI presentation reverts in the meantime, so the clock cannot be reset)
331+
3. Observe the outcome: once stale, the allocation's rewards are reclaimed as STALE_POI — either when a third party force-closes the stale allocation, or on the next POI/close after renewal
332+
333+
**Verification**: Look for a `RewardsReclaimed` event with reason `STALE_POI` on the RewardsManager for the allocation, and confirm the indexer's `indexingRewards` for it is `0`.
334+
335+
**Pass Criteria**:
336+
337+
- While ineligible and before `maxPOIStaleness`: rewards still preserved (3.2 behaviour)
338+
- After crossing `maxPOIStaleness`: accrued rewards are reclaimed as STALE_POI, **not** paid to the indexer even after re-renewal
339+
- Confirms the operational rule: renew (or restore eligibility) before `maxPOIStaleness` elapses
340+
341+
---
342+
311343
## Set 4: Optimistic Recovery
312344

313345
Eligibility denial is **optimistic**: rewards accrue to allocations during ineligible periods, and because closing while ineligible reverts (Set 3.2), no rewards are ever lost. Once the indexer renews eligibility, the close succeeds and pays out in full for the entire duration — including the epochs spent ineligible. This is the key behavioral difference from subgraph denial, where denial-period rewards are permanently reclaimed.
@@ -499,7 +531,7 @@ After a coordinator undenies a subgraph:
499531

500532
- Accumulators resume growing
501533
- Close allocation normally — rewards include pre-denial + post-undeny amounts
502-
- Denial-period rewards were reclaimed to the protocol (not included in your claim)
534+
- Denial-period rewards were reclaimed to the configured reclaim address (or, if none is configured, simply not minted) — either way not included in your claim
503535

504536
**Verification after undeny:**
505537

packages/issuance/docs/testing/reo/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Comprehensive test plans for validating The Graph Network after an upgrade. Thre
2424
BaselineTestPlan (7 cycles, 22 tests)
2525
│ Covers: setup, staking, provisions, allocations, queries, health
2626
27-
├──▶ ReoTestPlan (8 cycles + mock path, 36 tests)
27+
├──▶ ReoTestPlan (8 cycles + mock path, 41 tests)
2828
│ Covers: deployment, eligibility, oracle, rewards, emergency, UI
2929
│ Depends on: Baseline Cycles 1-7 pass first
3030
│ Cycle 2.3 opens allocations reused in Cycle 6
@@ -36,12 +36,12 @@ BaselineTestPlan (7 cycles, 22 tests)
3636
│ Depends on: Baseline Cycles 1-7 pass first
3737
│ Cycle 1 configures reclaim addresses used by all reclaim tests
3838
39-
├──▶ SubgraphDenialTestPlan (6 cycles, 21 tests)
39+
├──▶ SubgraphDenialTestPlan (6 cycles, 22 tests)
4040
│ Covers: deny/undeny state, accumulator freeze, allocation deferral,
4141
│ pre-denial reward recovery, edge cases
4242
│ Depends on: Baseline + RewardsConditionsTestPlan Cycle 1 (reclaim setup)
4343
44-
└──▶ IndexerTestGuide (5 sets + 3 mock sets, 11 tests)
44+
└──▶ IndexerTestGuide (5 sets + 3 mock sets, 12 tests)
4545
Covers: eligible/ineligible/recovery flows
4646
Depends on: Baseline Cycles 1-4 (staked, provisioned, can allocate)
4747
Subset of ReoTestPlan focused on per-indexer eligibility
@@ -55,10 +55,10 @@ BaselineTestPlan (7 cycles, 22 tests)
5555
| Document | Purpose |
5656
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
5757
| [BaselineTestPlan.md](BaselineTestPlan.md) | Detailed baseline indexer operational tests (7 cycles, 22 tests) |
58-
| [ReoTestPlan.md](ReoTestPlan.md) | REO eligibility, oracle, and rewards integration (8 cycles + mock path, 36 tests) |
58+
| [ReoTestPlan.md](ReoTestPlan.md) | REO eligibility, oracle, and rewards integration (8 cycles + mock path, 41 tests) |
5959
| [RewardsConditionsTestPlan.md](RewardsConditionsTestPlan.md) | Reclaim system, signal conditions, POI paths, allocation lifecycle (7 cycles, 25 tests) |
60-
| [SubgraphDenialTestPlan.md](SubgraphDenialTestPlan.md) | Subgraph denial: accumulator freeze, deferral, recovery (6 cycles, 21 tests) |
61-
| [IndexerTestGuide.md](IndexerTestGuide.md) | Condensed indexer eligibility tests (5 sets + 3 mock sets, 11 tests) |
60+
| [SubgraphDenialTestPlan.md](SubgraphDenialTestPlan.md) | Subgraph denial: accumulator freeze, deferral, recovery (6 cycles, 22 tests) |
61+
| [IndexerTestGuide.md](IndexerTestGuide.md) | Condensed indexer eligibility tests (5 sets + 3 mock sets, 12 tests) |
6262

6363
## Test Coverage
6464

0 commit comments

Comments
 (0)