Skip to content

feat(reputation): accumulate per-address reputation deltas in memory … - #2168

Open
Chigybillionz wants to merge 1 commit into
EarnQuestOne:mainfrom
Chigybillionz:feat/batched-reputation-updates
Open

feat(reputation): accumulate per-address reputation deltas in memory …#2168
Chigybillionz wants to merge 1 commit into
EarnQuestOne:mainfrom
Chigybillionz:feat/batched-reputation-updates

Conversation

@Chigybillionz

Copy link
Copy Markdown

Close #2154

Summary of the Issue

contracts/earn-quest/src/reputation.rs updated reputation per submission with an individual storage read and write for each entry. During batch approvals or batch XP awards, this pattern executed redundant storage operations per submission, burning significant gas and CPU instructions on Soroban.

Root Cause

reputation.rs lacked an in-memory batch accumulation utility to group reputation updates by target address prior to storage persistence. As a result, processing $N$ entries for an address executed $N$ instance storage reads (get_user_stats_or_default) and $N$ instance storage writes (set_user_stats) instead of consolidating updates into a single atomic read-modify-write cycle.

Solution Implemented

Implemented award_xp_batch in contracts/earn-quest/src/reputation.rs (and exposed it via EarnQuestContract in lib.rs). The function aggregates per-address experience points (XP) and completed quest counts in memory using a soroban_sdk::Map<Address, (u64, u32)> during batch processing. Once accumulated, a single storage read + write is executed for each unique affected user address.

Key Changes Made

  • contracts/earn-quest/src/reputation.rs:
    • Implemented pub fn award_xp_batch(env: &Env, grants: &Vec<(Address, u64)>) -> Result<(), Error> using in-memory delta accumulation.
    • Reduced storage operations to 1 read + 1 write per unique address per batch.
  • contracts/earn-quest/src/lib.rs:
    • Exposed award_xp_batch entrypoint in #[contractimpl] with bump_instance_ttl.
  • contracts/earn-quest/tests/test_reputation.rs:
    • Added unit tests (test_award_xp_batch_equivalence_single_user_multiple_grants, test_award_xp_batch_equivalence_multiple_users, and test_award_xp_batch_empty_grant_list) confirming final user state (XP, level, quests completed) is mathematically identical between batched and sequential writes.
  • contracts/earn-quest/tests/gas_benchmarks.rs:
    • Added benchmark_award_xp_batch_impact test demonstrating a 78.66% CPU instruction cost reduction (1,190,537 instructions saved for 5 awards).

Any Trade-offs or Considerations

  • Event Granularity: xp_awarded events are emitted once per unique user address per batch with the aggregate XP delta awarded, rather than emitting individual events for each sub-entry. This further minimizes event logging gas without losing accounting fidelity.
  • Backward Compatibility: Single-user award_xp calls remain fully preserved for non-batched flows.

Testing Steps (How to Verify the Fix)

  1. Run Reputation & Equivalence Tests:
    cargo test --test test_reputation
    

Run Gas Impact Benchmarks:
bash
cargo test --test gas_benchmarks -- --nocapture
Run Full Test Suite:
bash
cargo test

Please kindly review this task. If there are any corrections, improvements, adjustments, or merge conflicts that you notice regarding my implementation, I'd really appreciate your feedback. I'd also love to hear your overall review of my work on this branch.Thank you!

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Well done on the job done so far!
Kindly fix workflow to pass

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.

Batch reputation/XP storage writes during batch approval

2 participants