From 0c766803996410243422c482242c9da97ac9481c Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Thu, 20 Nov 2025 00:50:58 +0800 Subject: [PATCH] fix: refine Arc params to avoid unnecessary clone(s) --- src/chain/store/chain_store.rs | 26 ++-- src/chain_sync/chain_follower.rs | 2 +- src/chain_sync/sync_status.rs | 2 +- src/chain_sync/tipset_syncer.rs | 171 +++++++++++++----------- src/fil_cns/validation.rs | 95 ++++++------- src/interpreter/fvm2.rs | 6 +- src/interpreter/fvm3.rs | 6 +- src/interpreter/fvm4.rs | 6 +- src/libp2p/service.rs | 4 +- src/rpc/methods/eth/filter/mod.rs | 2 +- src/rpc/methods/f3.rs | 2 +- src/rpc/methods/gas.rs | 7 +- src/rpc/methods/miner.rs | 6 +- src/rpc/methods/state.rs | 4 +- src/rpc/methods/wallet.rs | 2 +- src/rpc/mod.rs | 2 +- src/state_manager/circulating_supply.rs | 2 +- src/state_manager/mod.rs | 32 +++-- 18 files changed, 192 insertions(+), 185 deletions(-) diff --git a/src/chain/store/chain_store.rs b/src/chain/store/chain_store.rs index 9433737b2b90..7e597d8be59e 100644 --- a/src/chain/store/chain_store.rs +++ b/src/chain/store/chain_store.rs @@ -319,9 +319,9 @@ where /// is usually 900. The `heaviest_tipset` is a reference point in the /// blockchain. It must be a child of the look-back tipset. pub fn get_lookback_tipset_for_round( - chain_index: Arc>>, - chain_config: Arc, - heaviest_tipset: Arc, + chain_index: &Arc>>, + chain_config: &Arc, + heaviest_tipset: &Arc, round: ChainEpoch, ) -> Result<(Arc, Cid), Error> where @@ -343,19 +343,19 @@ where let beacon = Arc::new(chain_config.get_beacon_schedule(genesis_timestamp)); let StateOutput { state_root, .. } = crate::state_manager::apply_block_messages( genesis_timestamp, - Arc::clone(&chain_index), - Arc::clone(&chain_config), + Arc::clone(chain_index), + Arc::clone(chain_config), beacon, // Using shared WASM engine here as creating new WASM engines is expensive // (takes seconds to minutes). It's only acceptable here because this situation is // so rare (may happen in dev-networks, doesn't happen in calibnet or mainnet.) &crate::shim::machine::GLOBAL_MULTI_ENGINE, - Arc::clone(&heaviest_tipset), + Arc::clone(heaviest_tipset), crate::state_manager::NO_CALLBACK, VMTrace::NotTraced, ) .map_err(|e| Error::Other(e.to_string()))?; - return Ok((heaviest_tipset, state_root)); + return Ok((heaviest_tipset.clone(), state_root)); } let next_ts = chain_index @@ -616,9 +616,9 @@ impl Default for MsgsInTipsetCache { /// Same as [`messages_for_tipset`] but uses a cache to store messages for each tipset. pub fn messages_for_tipset_with_cache( - db: Arc, + db: &Arc, ts: &Tipset, - cache: Arc, + cache: &MsgsInTipsetCache, ) -> Result, Error> where DB: Blockstore, @@ -626,7 +626,7 @@ where let key = ts.key(); cache .get_or_insert_with(key, || { - messages_for_tipset(Arc::clone(&db), ts).context("failed to get messages for tipset") + messages_for_tipset(db, ts).context("failed to get messages for tipset") }) .map_err(Into::into) } @@ -634,18 +634,18 @@ where /// Given a tipset this function will return all unique messages in that tipset. /// Note: This function is resource-intensive and can be a bottleneck for certain use-cases. /// Consider using [`messages_for_tipset_with_cache`] for better performance. -pub fn messages_for_tipset(db: Arc, ts: &Tipset) -> Result, Error> +pub fn messages_for_tipset(db: &Arc, ts: &Tipset) -> Result, Error> where DB: Blockstore, { let mut applied: HashMap = HashMap::new(); let mut balances: HashMap = HashMap::new(); - let state = StateTree::new_from_tipset(Arc::clone(&db), ts)?; + let state = StateTree::new_from_tipset(Arc::clone(db), ts)?; // message to get all messages for block_header into a single iterator let mut get_message_for_block_header = |b: &CachingBlockHeader| -> Result, Error> { - let (unsigned, signed) = block_messages(&db, b)?; + let (unsigned, signed) = block_messages(db, b)?; let mut messages = Vec::with_capacity(unsigned.len() + signed.len()); let unsigned_box = unsigned.into_iter().map(ChainMessage::Unsigned); let signed_box = signed.into_iter().map(ChainMessage::Signed); diff --git a/src/chain_sync/chain_follower.rs b/src/chain_sync/chain_follower.rs index 651761b55c76..af567d85e238 100644 --- a/src/chain_sync/chain_follower.rs +++ b/src/chain_sync/chain_follower.rs @@ -849,7 +849,7 @@ impl SyncTask { } => { let genesis = cs.genesis_tipset(); match validate_tipset( - state_manager.clone(), + &state_manager, cs, tipset.deref().clone(), &genesis, diff --git a/src/chain_sync/sync_status.rs b/src/chain_sync/sync_status.rs index e8f423f7f5de..ad889dda6c3b 100644 --- a/src/chain_sync/sync_status.rs +++ b/src/chain_sync/sync_status.rs @@ -140,7 +140,7 @@ impl SyncStatusReport { pub(crate) fn update( &mut self, - state_manager: &Arc>, + state_manager: &StateManager, current_active_forks: Vec, stateless_mode: bool, ) { diff --git a/src/chain_sync/tipset_syncer.rs b/src/chain_sync/tipset_syncer.rs index 4322d851f13b..f77c5fa14762 100644 --- a/src/chain_sync/tipset_syncer.rs +++ b/src/chain_sync/tipset_syncer.rs @@ -98,7 +98,7 @@ impl TipsetSyncerError { /// ones to the bad block cache, depending on strategy. Any bad block fails /// validation. pub async fn validate_tipset( - state_manager: Arc>, + state_manager: &Arc>, chainstore: &ChainStore, full_tipset: FullTipset, genesis: &Tipset, @@ -205,9 +205,9 @@ async fn validate_block( // Retrieve lookback tipset for validation let lookback_state = ChainStore::get_lookback_tipset_for_round( - state_manager.chain_store().chain_index().clone(), - state_manager.chain_config().clone(), - base_tipset.clone(), + state_manager.chain_store().chain_index(), + state_manager.chain_config(), + &base_tipset, block.header().epoch, ) .map_err(|e| (*block_cid, e.into())) @@ -224,100 +224,109 @@ async fn validate_block( // Check block messages validations.spawn(check_block_messages( - Arc::clone(&state_manager), - Arc::clone(&block), - Arc::clone(&base_tipset), + state_manager.clone(), + block.clone(), + base_tipset.clone(), )); // Base fee check - let smoke_height = state_manager.chain_config().epoch(Height::Smoke); - let v_base_tipset = Arc::clone(&base_tipset); - let v_block_store = state_manager.blockstore_owned(); - let v_block = Arc::clone(&block); - validations.spawn_blocking(move || { - let base_fee = crate::chain::compute_base_fee(&v_block_store, &v_base_tipset, smoke_height) - .map_err(|e| { - TipsetSyncerError::Validation(format!("Could not compute base fee: {e}")) - })?; - let parent_base_fee = &v_block.header.parent_base_fee; - if &base_fee != parent_base_fee { - return Err(TipsetSyncerError::Validation(format!( - "base fee doesn't match: {parent_base_fee} (header), {base_fee} (computed)" - ))); + validations.spawn_blocking({ + let smoke_height = state_manager.chain_config().epoch(Height::Smoke); + let base_tipset = Arc::clone(&base_tipset); + let block_store = state_manager.blockstore_owned(); + let block = Arc::clone(&block); + move || { + let base_fee = crate::chain::compute_base_fee(&block_store, &base_tipset, smoke_height) + .map_err(|e| { + TipsetSyncerError::Validation(format!("Could not compute base fee: {e}")) + })?; + let parent_base_fee = &block.header.parent_base_fee; + if &base_fee != parent_base_fee { + return Err(TipsetSyncerError::Validation(format!( + "base fee doesn't match: {parent_base_fee} (header), {base_fee} (computed)" + ))); + } + Ok(()) } - Ok(()) }); // Parent weight calculation check - let v_block_store = state_manager.blockstore_owned(); - let v_base_tipset = Arc::clone(&base_tipset); - let weight = header.weight.clone(); - validations.spawn_blocking(move || { - let calc_weight = fil_cns::weight(&v_block_store, &v_base_tipset).map_err(|e| { - TipsetSyncerError::Calculation(format!("Error calculating weight: {e}")) - })?; - if weight != calc_weight { - return Err(TipsetSyncerError::Validation(format!( - "Parent weight doesn't match: {weight} (header), {calc_weight} (computed)" - ))); + validations.spawn_blocking({ + let block_store = state_manager.blockstore_owned(); + let base_tipset = base_tipset.clone(); + let weight = header.weight.clone(); + move || { + let calc_weight = fil_cns::weight(&block_store, &base_tipset).map_err(|e| { + TipsetSyncerError::Calculation(format!("Error calculating weight: {e}")) + })?; + if weight != calc_weight { + return Err(TipsetSyncerError::Validation(format!( + "Parent weight doesn't match: {weight} (header), {calc_weight} (computed)" + ))); + } + Ok(()) } - Ok(()) }); // State root and receipt root validations - let v_state_manager = Arc::clone(&state_manager); - let v_base_tipset = Arc::clone(&base_tipset); - let v_block = Arc::clone(&block); - validations.spawn(async move { - let header = v_block.header(); - let (state_root, receipt_root) = v_state_manager - .tipset_state(&v_base_tipset) - .await - .map_err(|e| { - TipsetSyncerError::Calculation(format!("Failed to calculate state: {e}")) - })?; + validations.spawn({ + let state_manager = state_manager.clone(); + let block = block.clone(); + async move { + let header = block.header(); + let (state_root, receipt_root) = state_manager + .tipset_state(&base_tipset) + .await + .map_err(|e| { + TipsetSyncerError::Calculation(format!("Failed to calculate state: {e}")) + })?; - if state_root != header.state_root { - return Err(TipsetSyncerError::Validation(format!( - "Parent state root did not match computed state: {} (header), {} (computed)", - header.state_root, state_root, - ))); - } + if state_root != header.state_root { + return Err(TipsetSyncerError::Validation(format!( + "Parent state root did not match computed state: {} (header), {} (computed)", + header.state_root, state_root, + ))); + } - if receipt_root != header.message_receipts { - return Err(TipsetSyncerError::Validation(format!( - "Parent receipt root did not match computed root: {} (header), {} (computed)", - header.message_receipts, receipt_root - ))); + if receipt_root != header.message_receipts { + return Err(TipsetSyncerError::Validation(format!( + "Parent receipt root did not match computed root: {} (header), {} (computed)", + header.message_receipts, receipt_root + ))); + } + Ok(()) } - Ok(()) }); // Block signature check - let v_block = block.clone(); - validations.spawn_blocking(move || { - v_block.header().verify_signature_against(&work_addr)?; - Ok(()) + validations.spawn_blocking({ + let block = block.clone(); + move || { + block.header().verify_signature_against(&work_addr)?; + Ok(()) + } }); - let v_block = block.clone(); - validations.spawn(async move { - consensus - .validate_block(state_manager, v_block) - .map_err(|errs| { - // NOTE: Concatenating errors here means the wrapper type of error - // never surfaces, yet we always pay the cost of the generic argument. - // But there's no reason `validate_block` couldn't return a list of all - // errors instead of a single one that has all the error messages, - // removing the caller's ability to distinguish between them. - - TipsetSyncerError::concat( - errs.into_iter_ne() - .map(TipsetSyncerError::ConsensusError) - .collect_vec(), - ) - }) - .await + validations.spawn({ + let block = block.clone(); + async move { + consensus + .validate_block(state_manager, block) + .map_err(|errs| { + // NOTE: Concatenating errors here means the wrapper type of error + // never surfaces, yet we always pay the cost of the generic argument. + // But there's no reason `validate_block` couldn't return a list of all + // errors instead of a single one that has all the error messages, + // removing the caller's ability to distinguish between them. + + TipsetSyncerError::concat( + errs.into_iter_ne() + .map(TipsetSyncerError::ConsensusError) + .collect_vec(), + ) + }) + .await + } }); // Collect the errors from the async validations @@ -355,9 +364,9 @@ async fn check_block_messages( // check block message and signatures in them let mut pub_keys = Vec::with_capacity(block.bls_msgs().len()); let mut cids = Vec::with_capacity(block.bls_msgs().len()); - let db = state_manager.blockstore_owned(); + let db = state_manager.blockstore(); for m in block.bls_msgs() { - let pk = StateManager::get_bls_public_key(&db, &m.from, *base_tipset.parent_state())?; + let pk = StateManager::get_bls_public_key(db, &m.from, *base_tipset.parent_state())?; pub_keys.push(pk); cids.push(m.cid().to_bytes()); } diff --git a/src/fil_cns/validation.rs b/src/fil_cns/validation.rs index 35ab90a5fcfe..5c793109feed 100644 --- a/src/fil_cns/validation.rs +++ b/src/fil_cns/validation.rs @@ -72,9 +72,9 @@ pub(in crate::fil_cns) async fn validate_block( &state_manager, win_p_nv, - v_block.header(), - &v_prev_beacon, + block.header(), + &prev_beacon, &lookback_state, )?; Ok(()) diff --git a/src/interpreter/fvm2.rs b/src/interpreter/fvm2.rs index 97f4d627b812..334aaebf5e2d 100644 --- a/src/interpreter/fvm2.rs +++ b/src/interpreter/fvm2.rs @@ -62,9 +62,9 @@ impl ForestExternsV2 { fn get_lookback_tipset_state_root_for_round(&self, height: ChainEpoch) -> anyhow::Result { let (_, st) = ChainStore::get_lookback_tipset_for_round( - self.chain_index.clone(), - Arc::clone(&self.chain_config), - Arc::clone(&self.heaviest_tipset), + &self.chain_index, + &self.chain_config, + &self.heaviest_tipset, height, )?; Ok(st) diff --git a/src/interpreter/fvm3.rs b/src/interpreter/fvm3.rs index 595af639cc0e..a8377a0f4650 100644 --- a/src/interpreter/fvm3.rs +++ b/src/interpreter/fvm3.rs @@ -66,9 +66,9 @@ impl ForestExterns { fn get_lookback_tipset_state_root_for_round(&self, height: ChainEpoch) -> anyhow::Result { let (_, st) = ChainStore::get_lookback_tipset_for_round( - self.chain_index.clone(), - Arc::clone(&self.chain_config), - Arc::clone(&self.heaviest_tipset), + &self.chain_index, + &self.chain_config, + &self.heaviest_tipset, height, )?; Ok(st) diff --git a/src/interpreter/fvm4.rs b/src/interpreter/fvm4.rs index 948095fa112d..d6b0ddc1198b 100644 --- a/src/interpreter/fvm4.rs +++ b/src/interpreter/fvm4.rs @@ -66,9 +66,9 @@ impl ForestExterns { fn get_lookback_tipset_state_root_for_round(&self, height: ChainEpoch) -> anyhow::Result { let (_, st) = ChainStore::get_lookback_tipset_for_round( - self.chain_index.clone(), - Arc::clone(&self.chain_config), - Arc::clone(&self.heaviest_tipset), + &self.chain_index, + &self.chain_config, + &self.heaviest_tipset, height, )?; Ok(st) diff --git a/src/libp2p/service.rs b/src/libp2p/service.rs index 77c36ec7c052..b42d9ed36a2a 100644 --- a/src/libp2p/service.rs +++ b/src/libp2p/service.rs @@ -442,7 +442,7 @@ async fn handle_network_message( bitswap_request_manager: Arc, message: NetworkMessage, network_sender_out: &Sender, - peer_manager: &Arc, + peer_manager: &PeerManager, ) { match message { NetworkMessage::PubsubMessage { topic, message } => { @@ -865,7 +865,7 @@ async fn handle_chain_exchange_event( async fn handle_forest_behaviour_event( swarm: &mut Swarm, bitswap_request_manager: &Arc, - peer_manager: &Arc, + peer_manager: &PeerManager, event: ForestBehaviourEvent, db: &Arc>, genesis_cid: &Cid, diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index 3df180f5d11c..36b2e917cf98 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -295,7 +295,7 @@ impl EthEventHandler { let id_addr = Address::new_id(event.emitter()); let result = ctx .state_manager - .resolve_to_deterministic_address(id_addr, tipset.clone()) + .resolve_to_deterministic_address(id_addr, tipset) .await .with_context(|| { format!( diff --git a/src/rpc/methods/f3.rs b/src/rpc/methods/f3.rs index dedae257c2fc..5f0e6702d8e5 100644 --- a/src/rpc/methods/f3.rs +++ b/src/rpc/methods/f3.rs @@ -448,7 +448,7 @@ impl GetPowerTable { for (id, power, worker) in id_power_worker_mappings { let waddr = ctx .state_manager - .resolve_to_deterministic_address(worker, ts.clone()) + .resolve_to_deterministic_address(worker, ts) .await?; if waddr.protocol() != Protocol::BLS { anyhow::bail!("wrong type of worker address"); diff --git a/src/rpc/methods/gas.rs b/src/rpc/methods/gas.rs index 341d31898948..9e2584be644b 100644 --- a/src/rpc/methods/gas.rs +++ b/src/rpc/methods/gas.rs @@ -118,11 +118,8 @@ pub async fn estimate_gas_premium( } let pts = data.chain_index().load_required_tipset(ts.parents())?; blocks += pts.block_headers().len(); - let msgs = crate::chain::messages_for_tipset_with_cache( - data.store_owned(), - &pts, - data.msgs_in_tipset.clone(), - )?; + let msgs = + crate::chain::messages_for_tipset_with_cache(data.store(), &pts, &data.msgs_in_tipset)?; prices.append( &mut msgs diff --git a/src/rpc/methods/miner.rs b/src/rpc/methods/miner.rs index 2f1f276fed87..c878d213f7c6 100644 --- a/src/rpc/methods/miner.rs +++ b/src/rpc/methods/miner.rs @@ -118,9 +118,9 @@ impl RpcMethod<1> for MinerCreateBlock { .load_required_tipset(&block_template.parents)?; let lookback_state = ChainStore::get_lookback_tipset_for_round( - ctx.chain_index().clone(), - ctx.chain_config().clone(), - parent_tipset.clone(), + ctx.chain_index(), + ctx.chain_config(), + &parent_tipset, block_template.epoch, ) .map(|(_, s)| Arc::new(s))?; diff --git a/src/rpc/methods/state.rs b/src/rpc/methods/state.rs index 232ceb86497f..6898584a213b 100644 --- a/src/rpc/methods/state.rs +++ b/src/rpc/methods/state.rs @@ -83,7 +83,7 @@ pub enum StateCall {} impl StateCall { pub fn run( - state_manager: &Arc>, + state_manager: &StateManager, message: &Message, tsk: Option, ) -> anyhow::Result { @@ -200,7 +200,7 @@ impl RpcMethod<2> for StateAccountKey { let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?; Ok(ctx .state_manager - .resolve_to_deterministic_address(address, ts) + .resolve_to_deterministic_address(address, &ts) .await?) } } diff --git a/src/rpc/methods/wallet.rs b/src/rpc/methods/wallet.rs index 222564ae685d..b1d7640d161e 100644 --- a/src/rpc/methods/wallet.rs +++ b/src/rpc/methods/wallet.rs @@ -250,7 +250,7 @@ impl RpcMethod<2> for WalletSignMessage { let ts = ctx.chain_store().heaviest_tipset(); let key_addr = ctx .state_manager - .resolve_to_deterministic_address(address, ts) + .resolve_to_deterministic_address(address, &ts) .await?; let keystore = &mut *ctx.keystore.write(); diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index 97539a397efa..15b80d5d712e 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -483,7 +483,7 @@ impl RPCState { self.state_manager.chain_config() } - pub fn store(&self) -> &DB { + pub fn store(&self) -> &Arc { self.chain_store().blockstore() } diff --git a/src/state_manager/circulating_supply.rs b/src/state_manager/circulating_supply.rs index 016ef498c165..878272d739c2 100644 --- a/src/state_manager/circulating_supply.rs +++ b/src/state_manager/circulating_supply.rs @@ -152,7 +152,7 @@ impl GenesisInfo { if network_version >= NetworkVersion::V23 { circ += actor_balance; } else { - let ms = market::State::load(&db, actor.code, actor.state)?; + let ms = market::State::load(db, actor.code, actor.state)?; let locked_balance: TokenAmount = ms.total_locked().into(); circ += actor_balance - &locked_balance; un_circ += locked_balance; diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 516a0a59ec73..69e7a33b7e77 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -439,7 +439,7 @@ where // Returns all sectors pub fn get_all_sectors( - self: &Arc, + &self, addr: &Address, ts: &Tipset, ) -> anyhow::Result> { @@ -483,9 +483,7 @@ where // First, try to look up the state and receipt if not found in the blockstore // compute it - if let Some(state_from_child) = - self.try_lookup_state_from_next_tipset(tipset.as_ref()) - { + if let Some(state_from_child) = self.try_lookup_state_from_next_tipset(tipset) { return Ok(state_from_child); } @@ -583,7 +581,7 @@ where #[instrument(skip(self, rand))] fn call_raw( - self: &Arc, + &self, msg: &Message, rand: ChainRand, tipset: &Arc, @@ -614,7 +612,7 @@ where base_fee: tipset.block_headers().first().parent_base_fee.clone(), circ_supply: genesis_info.get_vm_circulating_supply( height, - &self.blockstore_owned(), + self.blockstore(), state_cid, )?, chain_config: self.chain_config().clone(), @@ -660,7 +658,7 @@ where /// runs the given message and returns its result without any persisted /// changes. pub fn call( - self: &Arc, + &self, message: &Message, tipset: Option>, ) -> Result { @@ -741,7 +739,7 @@ where base_fee: ts.block_headers().first().parent_base_fee.clone(), circ_supply: genesis_info.get_vm_circulating_supply( epoch, - &self.blockstore_owned(), + self.blockstore(), &st, )?, chain_config: self.chain_config().clone(), @@ -1244,7 +1242,7 @@ where } pub async fn search_for_message( - self: &Arc, + &self, from: Option>, msg_cid: Cid, look_back_limit: Option, @@ -1449,9 +1447,9 @@ where let base = entries.last().unwrap_or(&prev_beacon); let (lb_tipset, lb_state_root) = ChainStore::get_lookback_tipset_for_round( - self.chain_index().clone(), - self.chain_config().clone(), - tipset.clone(), + self.chain_index(), + self.chain_config(), + &tipset, epoch, )?; @@ -1493,7 +1491,7 @@ where let info = miner_state.info(self.blockstore())?; let worker_key = self - .resolve_to_deterministic_address(info.worker.into(), tipset.clone()) + .resolve_to_deterministic_address(info.worker.into(), &tipset) .await?; let eligible = self.eligible_to_mine(&addr, &tipset, &lb_tipset)?; @@ -1549,7 +1547,7 @@ where /// This function is blocking, but we do observe threads waiting and synchronizing. /// This is suspected to be due something in the VM or its `WASM` runtime. #[tracing::instrument(skip(self))] - pub fn validate_range(self: &Arc, epochs: RangeInclusive) -> anyhow::Result<()> { + pub fn validate_range(&self, epochs: RangeInclusive) -> anyhow::Result<()> { let heaviest = self.heaviest_tipset(); let heaviest_epoch = heaviest.epoch(); let end = self @@ -1571,7 +1569,7 @@ where self.validate_tipsets(tipsets) } - pub fn validate_tipsets(self: &Arc, tipsets: T) -> anyhow::Result<()> + pub fn validate_tipsets(&self, tipsets: T) -> anyhow::Result<()> where T: Iterator> + Send, { @@ -1660,7 +1658,7 @@ where pub async fn resolve_to_deterministic_address( self: &Arc, address: Address, - ts: Arc, + ts: &Arc, ) -> anyhow::Result
{ use crate::shim::address::Protocol::*; match address.protocol() { @@ -1677,7 +1675,7 @@ where } // If that fails, compute the tip-set and try again. - let (state_root, _) = self.tipset_state(&ts).await?; + let (state_root, _) = self.tipset_state(ts).await?; let state = StateTree::new_from_root(self.blockstore_owned(), &state_root)?; state.resolve_to_deterministic_addr(self.chain_store().blockstore(), address) }