Skip to content

[Performance] Establish Gas Benchmark Suite with CI Regression Tracking and Storage Layout Optimization #30

Description

@KarenZita01

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

  1. 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
  2. Add CI gas tracking: Create .github/workflows/benchmark.yml that runs benchmarks on every PR and compares with main branch
  3. Set gas budgets: Define MAX_GAS_REGISTER_METER, MAX_GAS_SUBMIT_READING, MAX_GAS_CREATE_STREAM constants; add #[inline(never)] profiling markers
  4. Optimize storage layout: Audit all structs for field ordering to minimize storage footprint (Rust optimizes by largest field first)
  5. Implement batch meter reading: submit_readings(Vec<MeterReading>) that processes multiple readings in one call, amortizing overhead
  6. Add lazy computation: Cache oracle prices for the current ledger (DataKey::CachedPrice) to avoid repeated cross-contract calls
  7. Optimize event emissions: Batch events where possible; use Bytes instead of Address where address will be re-encoded anyway
  8. Create performance dashboard: Export benchmark results to gh-pages or S3 for historical trend visualization

Verification & Testing Steps

  1. Run baseline benchmarks: cargo bench --package utility_contracts
  2. Apply optimizations (storage layout, batch processing, lazy computation)
  3. Run benchmarks again and compare: gas reduction > 20% on hot paths
  4. Verify all tests still pass after optimization: cargo test --package utility_contracts
  5. Deploy optimized contract to testnet and measure actual transaction fees
  6. Create gas budget PR gate: PRs that increase gas >5% on any benchmark are flagged

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions