Description
The codebase has no performance benchmarks, no gas usage regression tracking, and no systematic optimization profiling. The gas_metrics.rs (20KB) and gas_metrics_examples.rs (15KB) provide some gas measurement utilities, but they are not integrated into CI, not tracked over time, and not used to set performance budgets. As the contract grows in complexity, gas costs will increase, potentially making the contract uneconomical for users without anyone noticing.
Performance gaps:
- No gas benchmark suite (
benchmark.rs) with standardized scenarios
- No gas budget enforcement in CI (PRs that increase gas beyond threshold are rejected)
- No optimization of hot paths (meter reading submission, stream creation, dust sweep)
- No storage optimization (some fields use i128 when u32 or u64 would suffice)
- No event size optimization (events emit full addresses even when short-form IDs would work)
- No batch processing for meter reading submissions (each reading is a separate transaction)
- No lazy computation patterns (some values recomputed every call instead of cached)
Technical Context & Impact
- Affected Components/Files:
contracts/utility_contracts/src/gas_metrics.rs, contracts/utility_contracts/src/gas_estimator.rs, contracts/utility_contracts/src/lib.rs (all public functions)
- Impact: User Experience (Transaction Fees), Protocol Accessibility, Competitive Advantage
Step-by-Step Implementation Guide
- Create gas benchmark harness:
benches/gas_benchmarks.rs with criterion or divan benchmark framework, measuring:
bench_register_meter: Register 100 meters, measure average gas
bench_submit_reading: Submit 1000 readings, measure gas per reading
bench_create_stream: Create 100 streams, measure gas per stream
bench_collect_dust: Sweep dust for 1000 meters, measure total gas
bench_claim_insurance: Full insurance claim lifecycle
- Add CI gas tracking: Create
.github/workflows/benchmark.yml that runs benchmarks on every PR and compares with main branch
- Set gas budgets: Define
MAX_GAS_REGISTER_METER, MAX_GAS_SUBMIT_READING, MAX_GAS_CREATE_STREAM constants; add #[inline(never)] profiling markers
- Optimize storage layout: Audit all structs for field ordering to minimize storage footprint (Rust optimizes by largest field first)
- Implement batch meter reading:
submit_readings(Vec<MeterReading>) that processes multiple readings in one call, amortizing overhead
- Add lazy computation: Cache oracle prices for the current ledger (
DataKey::CachedPrice) to avoid repeated cross-contract calls
- Optimize event emissions: Batch events where possible; use
Bytes instead of Address where address will be re-encoded anyway
- Create performance dashboard: Export benchmark results to
gh-pages or S3 for historical trend visualization
Verification & Testing Steps
- Run baseline benchmarks:
cargo bench --package utility_contracts
- Apply optimizations (storage layout, batch processing, lazy computation)
- Run benchmarks again and compare: gas reduction > 20% on hot paths
- Verify all tests still pass after optimization:
cargo test --package utility_contracts
- Deploy optimized contract to testnet and measure actual transaction fees
- Create gas budget PR gate: PRs that increase gas >5% on any benchmark are flagged
Description
The codebase has no performance benchmarks, no gas usage regression tracking, and no systematic optimization profiling. The
gas_metrics.rs(20KB) andgas_metrics_examples.rs(15KB) provide some gas measurement utilities, but they are not integrated into CI, not tracked over time, and not used to set performance budgets. As the contract grows in complexity, gas costs will increase, potentially making the contract uneconomical for users without anyone noticing.Performance gaps:
benchmark.rs) with standardized scenariosTechnical Context & Impact
contracts/utility_contracts/src/gas_metrics.rs,contracts/utility_contracts/src/gas_estimator.rs,contracts/utility_contracts/src/lib.rs(all public functions)Step-by-Step Implementation Guide
benches/gas_benchmarks.rswithcriterionordivanbenchmark framework, measuring:bench_register_meter: Register 100 meters, measure average gasbench_submit_reading: Submit 1000 readings, measure gas per readingbench_create_stream: Create 100 streams, measure gas per streambench_collect_dust: Sweep dust for 1000 meters, measure total gasbench_claim_insurance: Full insurance claim lifecycle.github/workflows/benchmark.ymlthat runs benchmarks on every PR and compares with main branchMAX_GAS_REGISTER_METER,MAX_GAS_SUBMIT_READING,MAX_GAS_CREATE_STREAMconstants; add#[inline(never)]profiling markerssubmit_readings(Vec<MeterReading>)that processes multiple readings in one call, amortizing overheadDataKey::CachedPrice) to avoid repeated cross-contract callsBytesinstead ofAddresswhere address will be re-encoded anywaygh-pagesor S3 for historical trend visualizationVerification & Testing Steps
cargo bench --package utility_contractscargo test --package utility_contracts