diff --git a/crates/core/component/dex/src/component/action_handler/swap.rs b/crates/core/component/dex/src/component/action_handler/swap.rs index cbffd75b4d..86d4591c8c 100644 --- a/crates/core/component/dex/src/component/action_handler/swap.rs +++ b/crates/core/component/dex/src/component/action_handler/swap.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use anyhow::{ensure, Result}; use async_trait::async_trait; use cnidarium::StateWrite; @@ -68,8 +70,12 @@ impl ActionHandler for Swap { .await; // Mark the assets for the swap's trading pair as accessed during this block. - state.add_recently_accessed_asset(swap.body.trading_pair.asset_1()); - state.add_recently_accessed_asset(swap.body.trading_pair.asset_2()); + let fixed_candidates = Arc::new(dex_params.fixed_candidates.clone()); + state.add_recently_accessed_asset( + swap.body.trading_pair.asset_1(), + fixed_candidates.clone(), + ); + state.add_recently_accessed_asset(swap.body.trading_pair.asset_2(), fixed_candidates); metrics::histogram!(crate::component::metrics::DEX_SWAP_DURATION) .record(swap_start.elapsed()); diff --git a/crates/core/component/dex/src/component/position_manager.rs b/crates/core/component/dex/src/component/position_manager.rs index b34094c63c..b807815870 100644 --- a/crates/core/component/dex/src/component/position_manager.rs +++ b/crates/core/component/dex/src/component/position_manager.rs @@ -11,9 +11,12 @@ use penumbra_asset::{asset, Balance}; use penumbra_proto::DomainType; use penumbra_proto::{StateReadProto, StateWriteProto}; -use crate::component::position_manager::{ - base_liquidity_index::AssetByLiquidityIndex, inventory_index::PositionByInventoryIndex, - price_index::PositionByPriceIndex, +use crate::component::{ + dex::StateReadExt as _, + position_manager::{ + base_liquidity_index::AssetByLiquidityIndex, inventory_index::PositionByInventoryIndex, + price_index::PositionByPriceIndex, + }, }; use crate::lp::Reserves; use crate::{ @@ -253,8 +256,15 @@ pub trait PositionManager: StateWrite + PositionRead { // Add the asset IDs from the new position's trading pair // to the candidate set for this block. - self.add_recently_accessed_asset(position.phi.pair.asset_1()); - self.add_recently_accessed_asset(position.phi.pair.asset_2()); + let routing_params = self.routing_params().await?; + self.add_recently_accessed_asset( + position.phi.pair.asset_1(), + routing_params.fixed_candidates.clone(), + ); + self.add_recently_accessed_asset( + position.phi.pair.asset_2(), + routing_params.fixed_candidates, + ); // Finally, record the new position state. self.record_proto(event::position_open(&position)); @@ -269,7 +279,11 @@ pub trait PositionManager: StateWrite + PositionRead { /// This ensures that assets associated with recently active positions /// will be eligible for arbitrage if mispriced positions are opened. #[tracing::instrument(level = "debug", skip_all)] - fn add_recently_accessed_asset(&mut self, asset_id: asset::Id) { + fn add_recently_accessed_asset( + &mut self, + asset_id: asset::Id, + fixed_candidates: Arc>, + ) { let mut assets = self.recently_accessed_assets(); // Limit the number of recently accessed assets to prevent blowing @@ -278,6 +292,11 @@ pub trait PositionManager: StateWrite + PositionRead { return; } + // If the asset is already in the fixed candidate list, don't insert it. + if fixed_candidates.contains(&asset_id) { + return; + } + assets.insert(asset_id); self.object_put(state_key::recently_accessed_assets(), assets); }