test(test-suite): add e2e block cap tests for HCU metering#2046
test(test-suite): add e2e block cap tests for HCU metering#2046
Conversation
Add 5 block-cap scenarios to the E2E test suite exercising HCULimit through real EncryptedERC20 FHE operations on the deployed stack: multi-user accumulation, cap exhaustion, block rollover, whitelist removal, and non-owner rejection. Wire into CI via `fhevm-cli test hcu-block-cap` and a new workflow step.
🧪 CI InsightsHere's what we observed from your CI run for 1d11f82. 🟢 All jobs passed!But CI Insights is watching 👀 |
- Rework block rollover test to actually block a caller in block N, then verify that same caller succeeds after rollover in block N+1 - Add missing DEPLOYER_PRIVATE_KEY to .env.example
- Accumulation test: use greaterThan instead of exact equality (block meter vs receipt HCU have a small discrepancy on real infra) - Cap exhaustion + rollover tests: pass explicit gasLimit to bypass estimateGas, which reverts against pending state when cap is filled
Local E2E Test ResultsAll 5 block cap tests pass on a locally deployed stack: ERC20 regression test also passes. Issues found and fixed during local testing
|
Replace loose greaterThan check with near-sum assertion allowing ~2% drift between receipt-reported HCU and on-chain block meter.
…ion assertion The receipt parser reconstructs HCU from the @fhevm/solidity npm price table while the block meter uses the deployed contract's hardcoded prices. A version skew between the two causes a small discrepancy. Instead of cross-comparing with tolerance, assert the block meter exceeds each individual tx's HCU — proving accumulation without depending on price table parity.
Add NotHostOwner error to HCU_LIMIT_ABI and assert the specific custom error instead of generic revert.
- Scope save/restore of HCU limits to only the 2 tests that lower them (nested describe with its own beforeEach/afterEach) - Extract mintAndDistribute helper for repeated mint+transfer preamble - Remove blanket whitelist cleanup from afterEach (test cleans up itself) - Parallelize 3 sequential view calls with Promise.all
Replace receipt-based HCU comparison with three block meter readings: 1. Single-tx block → baseline meter 2. Two-tx block → meter exceeds baseline (proves accumulation) 3. Single-tx block → meter resets and matches baseline No cross-comparison of price tables, no getTxHCUFromTxReceipt needed.
- Assert meter2 == 2 * meter1 (exact, same ops in both txs) - Remove unnecessary mineNBlocks between blocks (meter resets automatically in each new block)
DO NOT MERGE — revert before merge. Added `if: false` to all test steps except HCU block cap to validate in isolation.
The CI was pulling the pre-built test-suite Docker image (v0.11.0-1) which doesn't contain the new block cap scenarios tests. Use --build so the image is built from the current checkout.
…rtion - NotHostOwner takes an address parameter: error NotHostOwner(address) - Relax meter2 == meter1*2 to meter2 > meter1 since alice→bob and bob→alice can differ slightly in HCU due to balance init paths
The same alice→bob transfer produces slightly different HCU across runs due to balance state changes from intermediate transfers. Assert reset behavior (meter3 > 0 and meter3 < meter2) instead of exact equality with meter1.
Anvil runs with --block-time 1, so blocks keep getting mined even with evm_setAutomine(false). Use evm_setIntervalMining(0) to fully pause block production, then restore both after mining.
…rEach Disable interval mining once in beforeEach (deterministic blocks), restore in afterEach. Tests only toggle automine for batching.
Disabling interval mining in beforeEach hangs because Anvil's evm_setIntervalMining(0) overrides automine. Revert to the per-test pattern (disable interval+automine before batching, restore after) which passed in CI run 22733231829.
Restore workflow to match main, keeping only the new HCU block cap test step addition.
|
Added E2E HCU block-cap coverage for accumulation, cap exhaustion, rollover, whitelist removal, and non-owner rejection. Also hardened test cleanup so HCU limits, whitelist state, and mining settings are restored after each case, which avoids leaking state into later tests. Local validation:
|
|
@claude /pr-review |
The automine=true + intervalMining=0 combo is unreliable in CI — Anvil hangs for ~5min before mining the mint tx, causing Mocha timeout. Switch to automine=false + explicit evm_mine after each tx, matching the proven pattern used by the "with lowered limits" tests that pass consistently. Also add gasLimit overrides to bypass estimateGas against pending state.
…ploy Forward --resume STEP and --only STEP flags from fhevm-cli to the underlying deploy-fhevm-stack.sh script, with step validation and mutual exclusivity check. Use --only test-suite in CI when deploy-build is set, so only the test-suite image is rebuilt from the branch instead of the entire stack.
cleanup_single_step and cleanup_from_step used --remove-orphans with a single compose file, causing Docker Compose to tear down every container in the project not defined in that file. This destroyed the entire stack when running e.g. --only test-suite.
The --only test-suite approach rebuilds only the test container but uses pre-built host-sc images that lack the HCULimit contract. The HCU block cap tests need host-sc built from the branch, so we must use the full --build deploy for now. The --resume/--only CLI flags and the --remove-orphans fix in the deploy script are kept — they're useful for local development and future CI optimizations.
Keep the PR scoped to the HCU whitelist test fix and the deploy-build workflow input. The --resume/--only CLI flags and --remove-orphans fix can be submitted in a separate PR.
|
@Mergifyio queue |
Merge Queue Status
Required conditions to enter a queue
|
|
@Mergifyio refresh |
✅ Pull request refreshed |
|
@Mergifyio queue |
☑️ Command
|
Summary
test-suite/e2e/test/encryptedERC20/EncryptedERC20.HCU.tsexercising HCULimit through real EncryptedERC20 FHE operations on the deployed stackfhevm-cli test hcu-block-capand a new workflow step intest-suite-e2e-tests.ymlHCU_LIMIT_CONTRACT_ADDRESSandDEPLOYER_PRIVATE_KEYenv vars to staging configTest scenarios
setHCUPerBlockreverts when called by non-ownerCloses zama-ai/fhevm-internal#1099
Test plan
fhevm-cli test hcu-block-capon a deployed local stack (see below)workflow_dispatchon this branchLocal testing strategy