Skip to content

feat(local-env): end-to-end stress harness covering all merged PRs (132-138)#143

Open
tangletools wants to merge 1 commit into
mainfrom
feat/local-stress-harness
Open

feat(local-env): end-to-end stress harness covering all merged PRs (132-138)#143
tangletools wants to merge 1 commit into
mainfrom
feat/local-stress-harness

Conversation

@tangletools
Copy link
Copy Markdown
Contributor

Summary

Single-file local stress harness at scripts/local-env/stress-test.sh plus a runbook at scripts/local-env/STRESS-TEST.md. Boots a fresh anvil + LocalTestnet.s.sol deployment in subscription mode and walks 17 ordered economic checks against the merged-PR surface. Average wall time on a warm-cache checkout: ~40-85s.

  • Idempotent: re-runs tear down anvil, broadcast artifacts, indexer docker volumes, and persisted state.
  • Per-step [OK] / [FAIL] lines with timing + a one-line headline metric (e.g. draw1=80909090909090909 wei, actualSlashed=3150000000000000000 wei).
  • Single final RESULT: N / 17 OK in Xs summary; exit 0 ⇔ all green.
  • Optional --with-indexer / --with-dapp / --with-operator for the off-chain side processes; none required for the 17 protocol-surface assertions.

Steps + which PR each step validates

# Step Validates
01 prerequisites tools + soldeer deps present
02 idempotent cleanup re-runnable
03 anvil + contracts deployed LocalTestnet.s.sol runs in subscription mode (#132 baseline)
04 resolve deployed addresses broadcast artifact parses to Tangle + staking proxies
05 optional services launched indexer / dApp / operator flags are best-effort
06 operator2 registered isOperatorRegistered(0, op2) (#132 setup)
07 subscription service Active isServiceActive(0) + baseline pinned (#132)
08 operator on service operator set isServiceOperator(0, op2) — ApprovalsViews split clean (#133)
09 escrow funded > 0 getServiceEscrow(0).balance > 0
10 billSubscription #1 multi-asset TWAP draw executes (#133)
11 second staker grows pool MultiAssetDelegation.depositAndDelegate lifts getOperatorDelegatedStake (#134 O(1) aggregate)
12 billSubscription #2 (post-stake) bill still accurate after pool growth (#133 + #134)
13 proposeSlash + executeSlash 7-day dispute window + TIMESTAMP_BUFFER respected, actualSlashed > 0 (#134 share-pool slashing)
14 operator stake reduced post-slash getOperatorDelegatedStake strictly drops (#134)
15 claimRewardsAll (native) native sweep zeroes pendingRewards(op2, 0x0)
16 griefing token skipped RevertingTransferERC20 seeded via anvil_setStorageAt into _pendingRewards[op2][grief] + _pendingRewardTokens[op2]; claimRewardsAll iterates, isolates the revert, emits RewardsClaimSkipped and leaves the entry intact for retry (#136)
17 indexer entities present with --with-indexer: at least one row each in Operator, Service, ServiceOperator, SubscriptionBilling, PaymentDistribution, RewardClaim, RewardsClaimSkip (#138), SlashProposal, OperatorPoolSlash (#138)

Implementation notes worth flagging at review:

  • vm.store from a broadcast forge script does not propagate to anvil. The griefing seed (step 16) needs anvil_setStorageAt to actually mutate live storage — so the slot computation runs from bash and the forge helper (script/StressGriefingSeed.s.sol) only deploys the reverting ERC20.
  • Storage slots are pinned from forge inspect Tangle storage-layout at this commit (_pendingRewards at slot 44, _pendingRewardTokens at slot 64). If those move, step 16 will print the discovered value so the slot constant can be re-derived. Runbook documents the procedure.

Test plan

  • Cold-cache full run completes 17/17 (~85s).
  • Warm-cache subsequent runs complete 17/17 (~40-50s).
  • Three consecutive idempotent runs all 17/17 (no state bleed).
  • --with-indexer flag runs 17/17 including indexer entity checks. (Out of scope for this PR — the worktree's pnpm/envio bootstrap is finicky; runbook documents the workaround.)
  • --with-dapp / --with-operator smoke (these are best-effort; failures do not affect the harness pass/fail).

Single-file harness at scripts/local-env/stress-test.sh that boots a fresh
anvil + LocalTestnet deployment and walks 17 ordered economic checks against
the merged-PR surface (#132 subscription billing rearchitecture, #133
multi-asset bill weighting + EIP-170 facet split, #134 O(1) operator stake
aggregate + share-pool slashing, #136 claimRewardsAll griefing isolation,
#138 indexer event handlers).

Highlights:
- Idempotent: clean cleanup of anvil, broadcast artifacts, indexer state.
- Per-step pass/fail with timing + headline metric. Single-line summary.
- Optional --with-indexer / --with-dapp / --with-operator flags for the
  off-chain side processes; none required for the 17-step protocol surface.
- Griefing-token isolation step deploys a RevertingTransferERC20 and seeds
  Tangle's _pendingRewards + _pendingRewardTokens AddressSet via
  anvil_setStorageAt (vm.store from a broadcast script doesn't propagate
  to anvil; the harness drives the seed via curl directly).

Companion docs at scripts/local-env/STRESS-TEST.md cover prereqs, per-step
PR mapping, log locations, debugging recipes, and an extension guide.

A full green run takes ~40-85s on a warm-cache checkout.
@tangletools
Copy link
Copy Markdown
Contributor Author

tangletools commented May 16, 2026

🔍 Reviewing f7695d20

Pass Status ETA
Kimi Code K2.6 Running (2 min) ~5-15 min
opencode GLM 5.1 Running (2 min) ~5-15 min

Agent review running. Reads the actual code. This comment updates in place.

tangletools · #143 · model: kimi-for-coding · started 2026-05-16T10:41:32Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants