Perf/batch shape optimization - #105
Open
Bigg770 wants to merge 4 commits into
Open
Conversation
Change pair_to_pool from Map<(Symbol,Symbol), u64> to Map<(Symbol,Symbol), Vec<u64>> so multiple pools (e.g. different fee tiers or depths) can be registered for the same token pair without reverting. find_best_route now iterates every pool in the list for both direct and two-hop legs, selecting the one that produces the highest output for the given amount_in. Tests (lp_tests.rs): - test_two_pools_same_pair_route_chooses_optimal: registers a shallow (1k) and a deep (100k) XLM/USDC pool; asserts the deep pool is chosen. - test_register_second_pool_same_pair_succeeds: verifies that a second register_pool call for the same pair no longer reverts.
Add on-chain swap-size histogram published as a SwapDistribution event. events.rs: - SwapDistribution contracttype struct with four buckets: size_0_100 / size_100_1k / size_1k_10k / size_10k_plus + total_swaps. - SWAP_COUNT_KEY and SWAP_BUCKETS_KEY instance-storage constants. - Events::record_swap() increments counter and bucket, auto-emits the SwapDistribution event every SWAP_DISTRIBUTION_CADENCE (1 000) swaps. - Events::emit_swap_distribution() for admin-triggered flush + bucket reset. - Events::swap_count() helper for tests and analytics. lib.rs: - CounterContract::emit_swap_distribution() entry point (admin-gated). - swap() now calls Events::record_swap() after every successful swap. Also includes BatchShape optimisation (Issue OpenPeerX#3) and its tests — both land in the same lib.rs file. Tests (batch_tests.rs): - test_swap_count_increments: asserts counter is 1 after one swap, 2 after two. - test_admin_trigger_emit_swap_distribution: admin can trigger flush without panic. - test_batch_shape_ten_op_batch_correct_counts: 10-op batch executes correctly. - test_batch_shape_mixed_operations: mixed swap/mint batch executes correctly.
Replace the double filter-iteration pattern in execute_batch_atomic and
execute_batch_best_effort with a pre-computed BatchShape.
Problem: both functions called
operations.iter().filter(|op| matches!(op, BatchOperation::Swap(…))).count()
twice — once for the rate-limit check and once for recording usage.
Fix: introduce BatchShape { swap_count, mint_count, lp_add_count,
lp_remove_count } computed in a single O(n) pass via BatchShape::compute().
The result is stored before the portfolio load and reused for both the
rate-limit gate and the record step, eliminating the redundant iteration.
Tests (batch_tests.rs):
- test_batch_shape_ten_op_batch_correct_counts: 10-op all-swap batch
completes with operations_executed == 10.
- test_batch_shape_mixed_operations: 3 swaps + 2 mints returns
operations_executed == 5 with no failures.
Note: BatchShape code lands in the same lib.rs commit as Issue OpenPeerX#2
because both touch the same file. This commit records the intent and
acceptance criteria.
Contributor
|
Excellent perf pass on the batch shape — measurable win and the benchmark notes make the trade-offs easy to follow. CI is green (Quality, Build, Test). Thanks for the rigor. Merging 🚀 |
Contributor
|
First — really nice work on the perf pass, the benchmark notes made the trade-offs easy to follow 👏 Heads up: while working through the queue, I merged PRs #101, #102, #103, #104-attempt, and #110 ahead of yours. Several of those modified Could you rebase onto the latest |
This was referenced Jul 19, 2026
Contributor
Author
|
all done sir |
Contributor
Author
|
@ameeribro4-sudo done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
issue fixed a performance inefficiency in the batch execution hot
path.
When a user submitted a batch of operations, the contract needed to know how
many swaps were in the batch — once to check the rate limit before executing,
and again to record the rate limit usage after executing. Both times it did
this by scanning the entire operation list with a filter().count() call. So for
every batch, the same list was walked twice for no reason, since the contents
never changed between those two points.
The fix pre-computes the shape of the batch — swap count, mint count, LP add
count, LP remove count — in a single pass before any execution begins, stores
the result, and reuses it in both places. The list is now walked exactly once
per batch regardless of size.
closes #66