From 1c84c6140b2ce983e78a56b9961a8bf46069dfe4 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 25 Mar 2026 21:19:45 +0800 Subject: [PATCH 1/4] fix: log full context of anyhow::Error --- src/beacon/drand.rs | 18 ++---- src/beacon/mock_beacon.rs | 4 +- src/blocks/header.rs | 53 ++++++++------- src/blocks/mod.rs | 5 +- src/chain/store/chain_store.rs | 2 +- src/chain/store/errors.rs | 2 +- src/chain_sync/chain_follower.rs | 2 +- src/chain_sync/network_context.rs | 64 ++++++++++--------- src/chain_sync/tipset_syncer.rs | 14 ++-- src/cli/subcommands/f3_cmd.rs | 6 +- src/cli_shared/cli/mod.rs | 2 +- src/daemon/context.rs | 2 +- src/daemon/db_util.rs | 2 +- src/daemon/mod.rs | 6 +- src/db/blockstore_with_write_buffer.rs | 2 +- src/db/car/forest.rs | 2 +- src/db/gc/snapshot.rs | 6 +- src/db/parity_db.rs | 10 ++- src/dev/subcommands/mod.rs | 6 +- src/dev/subcommands/update_checkpoints_cmd.rs | 2 +- src/fil_cns/mod.rs | 2 +- src/fil_cns/validation.rs | 2 +- src/genesis/mod.rs | 4 +- src/interpreter/mod.rs | 2 +- src/interpreter/vm.rs | 8 +-- src/libp2p/behaviour.rs | 2 +- src/libp2p/chain_exchange/message.rs | 32 ++++++---- src/libp2p/discovery.rs | 6 +- src/libp2p/service.rs | 8 +-- src/libp2p_bitswap/request_manager.rs | 4 +- src/message/mod.rs | 2 +- src/message_pool/config.rs | 4 +- src/message_pool/errors.rs | 2 +- src/message_pool/msgpool/selection.rs | 4 +- src/rpc/error.rs | 6 +- src/rpc/methods/chain.rs | 2 +- src/rpc/methods/eth.rs | 13 ++-- src/rpc/methods/eth/trace/state_diff.rs | 7 +- src/rpc/methods/gas.rs | 2 +- src/rpc/methods/state.rs | 8 +-- src/shim/actors/builtin/market/mod.rs | 2 +- src/shim/actors/builtin/miner/mod.rs | 4 +- src/shim/crypto.rs | 2 +- src/shim/state_tree.rs | 33 ++++------ src/state_manager/circulating_supply.rs | 20 +++--- src/state_manager/errors.rs | 2 +- src/state_manager/mod.rs | 27 ++++---- src/state_manager/utils.rs | 4 +- src/state_migration/common/state_migration.rs | 6 +- src/state_migration/nv19/power.rs | 4 +- .../type_migrations/init/state_v9_to_v10.rs | 3 +- src/statediff/mod.rs | 10 +-- src/statediff/resolve.rs | 8 +-- src/tool/subcommands/api_cmd.rs | 4 +- src/tool/subcommands/snapshot_cmd.rs | 2 +- src/utils/proofs_api/paramfetch.rs | 6 +- src/utils/sqlite/mod.rs | 2 +- 57 files changed, 226 insertions(+), 243 deletions(-) diff --git a/src/beacon/drand.rs b/src/beacon/drand.rs index db18eda2b887..bc709ae9e043 100644 --- a/src/beacon/drand.rs +++ b/src/beacon/drand.rs @@ -78,7 +78,7 @@ impl BeaconSchedule { epoch: ChainEpoch, parent_epoch: ChainEpoch, prev: &BeaconEntry, - ) -> Result, anyhow::Error> { + ) -> anyhow::Result> { let (cb_epoch, curr_beacon) = self.beacon_for_epoch(epoch)?; // Before quicknet upgrade, we had "chained" beacons, and so required two entries at a fork if curr_beacon.network().is_chained() { @@ -154,11 +154,7 @@ impl Beacon for BeaconImpl { } /// Verify beacon entries that are sorted by round. - fn verify_entries( - &self, - entries: &[BeaconEntry], - prev: &BeaconEntry, - ) -> Result { + fn verify_entries(&self, entries: &[BeaconEntry], prev: &BeaconEntry) -> anyhow::Result { delegate_beacon_impl!(self.verify_entries(entries, prev)) } @@ -199,11 +195,7 @@ pub trait Beacon { fn network(&self) -> DrandNetwork; /// Verify beacon entries that are sorted by round. - fn verify_entries( - &self, - entries: &[BeaconEntry], - prev: &BeaconEntry, - ) -> Result; + fn verify_entries(&self, entries: &[BeaconEntry], prev: &BeaconEntry) -> anyhow::Result; /// Returns a `BeaconEntry` given a round. It fetches the `BeaconEntry` from a `Drand` node over [`gRPC`](https://grpc.io/) /// In the future, we will cache values, and support streaming. @@ -295,7 +287,7 @@ impl Beacon for DrandBeacon { &self, entries: &'a [BeaconEntry], prev: &'a BeaconEntry, - ) -> Result { + ) -> anyhow::Result { let mut validated = vec![]; let is_valid = if self.network.is_unchained() { let mut messages = vec![]; @@ -404,7 +396,7 @@ impl Beacon for DrandBeacon { .retry(ExponentialBuilder::default()) .notify(|err, dur| { debug!( - "retrying fetch_entry {err} after {}", + "retrying fetch_entry after {}: {err:#}", humantime::format_duration(dur) ); }) diff --git a/src/beacon/mock_beacon.rs b/src/beacon/mock_beacon.rs index 68299d591540..3b970b78b59e 100644 --- a/src/beacon/mock_beacon.rs +++ b/src/beacon/mock_beacon.rs @@ -28,7 +28,7 @@ impl Beacon for MockBeacon { &self, entries: &'a [BeaconEntry], mut prev: &'a BeaconEntry, - ) -> Result { + ) -> anyhow::Result { for curr in entries.iter() { let oe = Self::entry_for_index(prev.round()); if oe.signature() != curr.signature() { @@ -41,7 +41,7 @@ impl Beacon for MockBeacon { Ok(true) } - async fn entry(&self, round: u64) -> Result { + async fn entry(&self, round: u64) -> anyhow::Result { Ok(Self::entry_for_index(round)) } diff --git a/src/blocks/header.rs b/src/blocks/header.rs index 1e59f85c5d5d..0fb850a755de 100644 --- a/src/blocks/header.rs +++ b/src/blocks/header.rs @@ -85,11 +85,11 @@ impl RawBlockHeader { let signature = self .signature .as_ref() - .ok_or_else(|| Error::InvalidSignature("Signature is nil in header".to_owned()))?; + .ok_or_else(|| Error::InvalidSignature("Signature is nil in header".into()))?; - signature - .verify(&self.signing_bytes(), addr) - .map_err(|e| Error::InvalidSignature(format!("Block signature invalid: {e}")))?; + signature.verify(&self.signing_bytes(), addr).map_err(|e| { + Error::InvalidSignature(format!("Block signature invalid: {e:#}").into()) + })?; Ok(()) } @@ -105,7 +105,7 @@ impl RawBlockHeader { ) -> Result<(), Error> { let (cb_epoch, curr_beacon) = b_schedule .beacon_for_epoch(self.epoch) - .map_err(|e| Error::Validation(e.to_string()))?; + .map_err(|e| Error::Validation(format!("{e:#}").into()))?; tracing::trace!( "beacon network at {}: {:?}, is_chained: {}", self.epoch, @@ -116,20 +116,23 @@ impl RawBlockHeader { if curr_beacon.network().is_chained() { let (pb_epoch, _) = b_schedule .beacon_for_epoch(parent_epoch) - .map_err(|e| Error::Validation(e.to_string()))?; + .map_err(|e| Error::Validation(format!("{e:#}").into()))?; if cb_epoch != pb_epoch { // Fork logic if self.beacon_entries.len() != 2 { - return Err(Error::Validation(format!( - "Expected two beacon entries at beacon fork, got {}", - self.beacon_entries.len() - ))); + return Err(Error::Validation( + format!( + "Expected two beacon entries at beacon fork, got {}", + self.beacon_entries.len() + ) + .into(), + )); } #[allow(clippy::indexing_slicing)] curr_beacon .verify_entries(&self.beacon_entries[1..], &self.beacon_entries[0]) - .map_err(|e| Error::Validation(e.to_string()))?; + .map_err(|e| Error::Validation(format!("{e:#}").into()))?; return Ok(()); } @@ -139,10 +142,13 @@ impl RawBlockHeader { // We don't expect to ever actually meet this condition if max_round == prev_entry.round() { if !self.beacon_entries.is_empty() { - return Err(Error::Validation(format!( - "expected not to have any beacon entries in this block, got: {}", - self.beacon_entries.len() - ))); + return Err(Error::Validation( + format!( + "expected not to have any beacon entries in this block, got: {}", + self.beacon_entries.len() + ) + .into(), + )); } return Ok(()); } @@ -158,22 +164,25 @@ impl RawBlockHeader { Some(last) => last, None => { return Err(Error::Validation( - "Block must include at least 1 beacon entry".to_string(), + "Block must include at least 1 beacon entry".into(), )); } }; if last.round() != max_round { - return Err(Error::Validation(format!( - "expected final beacon entry in block to be at round {}, got: {}", - max_round, - last.round() - ))); + return Err(Error::Validation( + format!( + "expected final beacon entry in block to be at round {}, got: {}", + max_round, + last.round() + ) + .into(), + )); } if !curr_beacon .verify_entries(&self.beacon_entries, prev_entry) - .map_err(|e| Error::Validation(e.to_string()))? + .map_err(|e| Error::Validation(format!("{e:#}").into()))? { return Err(Error::Validation("beacon entry was invalid".into())); } diff --git a/src/blocks/mod.rs b/src/blocks/mod.rs index c3211be3bc02..3a3f15b18b4d 100644 --- a/src/blocks/mod.rs +++ b/src/blocks/mod.rs @@ -1,6 +1,7 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT +use std::borrow::Cow; use thiserror::Error; mod block; @@ -29,10 +30,10 @@ pub use vrf_proof::VRFProof; pub enum Error { /// Invalid signature #[error("Invalid signature: {0}")] - InvalidSignature(String), + InvalidSignature(Cow<'static, str>), /// Error in validating arbitrary data #[error("Error validating data: {0}")] - Validation(String), + Validation(Cow<'static, str>), } #[cfg(test)] diff --git a/src/chain/store/chain_store.rs b/src/chain/store/chain_store.rs index abe6b760891f..d78ce51bb220 100644 --- a/src/chain/store/chain_store.rs +++ b/src/chain/store/chain_store.rs @@ -207,7 +207,7 @@ where Err(e) => { // Do not warn when the old head is genesis if old_head.epoch() > 0 { - error!("failed to get chain path changes: {e}"); + error!("failed to get chain path changes: {e:#}"); } // Fallback to single apply PathChanges { diff --git a/src/chain/store/errors.rs b/src/chain/store/errors.rs index 27999c7d2d2d..957f8bf40f90 100644 --- a/src/chain/store/errors.rs +++ b/src/chain/store/errors.rs @@ -55,7 +55,7 @@ impl From for Error { impl From for Error { fn from(e: anyhow::Error) -> Self { - Error::Other(e.to_string()) + Error::Other(format!("{e:#}")) } } diff --git a/src/chain_sync/chain_follower.rs b/src/chain_sync/chain_follower.rs index dc097e15e952..828b4b1da0c8 100644 --- a/src/chain_sync/chain_follower.rs +++ b/src/chain_sync/chain_follower.rs @@ -865,7 +865,7 @@ impl SyncTask { { Ok(parents) => Some(SyncEvent::NewFullTipsets(parents)), Err(e) => { - tracing::warn!(%key, %epoch, "failed to fetch tipset: {e}"); + tracing::warn!(%key, %epoch, "failed to fetch tipset: {e:#}"); None } } diff --git a/src/chain_sync/network_context.rs b/src/chain_sync/network_context.rs index 5bd8debe51d6..cddc70873288 100644 --- a/src/chain_sync/network_context.rs +++ b/src/chain_sync/network_context.rs @@ -71,7 +71,7 @@ impl Clone for SyncNetworkContext { /// Race tasks to completion while limiting the number of tasks that may execute concurrently. /// Once a task finishes without error, the rest of the tasks are canceled. struct RaceBatch { - tasks: JoinSet>, + tasks: JoinSet>, semaphore: Arc, } @@ -86,13 +86,13 @@ where } } - pub fn add(&mut self, future: impl Future> + Send + 'static) { + pub fn add(&mut self, future: impl Future> + Send + 'static) { let sem = self.semaphore.clone(); self.tasks.spawn(async move { let permit = sem .acquire_owned() .await - .map_err(|_| "Semaphore unexpectedly closed")?; + .context("Semaphore unexpectedly closed")?; let result = future.await; drop(permit); result @@ -138,7 +138,7 @@ where peer_id: Option, tsk: &TipsetKey, count: NonZeroU64, - ) -> Result, String> { + ) -> anyhow::Result> { self.handle_chain_exchange_request(peer_id, tsk, count, HEADERS, |tipsets: &Vec| { validate_network_tipsets(tipsets, tsk) }) @@ -151,16 +151,16 @@ where &self, peer_id: Option, ts: &Tipset, - ) -> Result { + ) -> anyhow::Result { let mut bundles: Vec = self .handle_chain_exchange_request(peer_id, ts.key(), nonzero!(1_u64), MESSAGES, |_| true) .await?; if bundles.len() != 1 { - return Err(format!( + anyhow::bail!( "chain exchange request returned {} tipsets, 1 expected.", bundles.len() - )); + ); } let mut bundle = bundles.remove(0); bundle.blocks = ts.block_headers().to_vec(); @@ -174,7 +174,7 @@ where &self, peer_id: Option, tsk: &TipsetKey, - ) -> Result { + ) -> anyhow::Result { let mut fts = self .handle_chain_exchange_request( peer_id, @@ -185,12 +185,12 @@ where ) .await?; - if fts.len() != 1 { - return Err(format!( - "Full tipset request returned {} tipsets, 1 expected.", - fts.len() - )); - } + anyhow::ensure!( + fts.len() == 1, + "Full tipset request returned {} tipsets, 1 expected.", + fts.len() + ); + Ok(fts.remove(0)) } @@ -198,7 +198,7 @@ where &self, peer_id: Option, tsk: &TipsetKey, - ) -> Result, String> { + ) -> anyhow::Result> { self.handle_chain_exchange_request( peer_id, tsk, @@ -218,7 +218,7 @@ where request_len: NonZeroU64, options: u64, validate: F, - ) -> Result, String> + ) -> anyhow::Result> where T: TryFrom + Send + Sync + 'static, >::Error: std::fmt::Display, @@ -247,9 +247,11 @@ where // No specific peer set, send requests to a shuffled set of top peers until // a request succeeds. let peers = self.peer_manager.top_peers_shuffled(); - if peers.is_empty() { - return Err("chain exchange failed: no peers are available".into()); - } + anyhow::ensure!( + !peers.is_empty(), + "chain exchange failed: no peers are available" + ); + let n_peers = peers.len(); let mut batch = RaceBatch::new(MAX_CONCURRENT_CHAIN_EXCHANGE_REQUESTS); let success_time_cost_millis_stats = Arc::new(Mutex::new(Stats::new())); @@ -310,8 +312,8 @@ where "{} lookup failures, ", lookup_failures.load(Ordering::Relaxed) )); - message.push_str(&format!("request:\n{request:?}",)); - message + message.push_str(&format!("request:\n{request:?}")); + anyhow::anyhow!(message) }; let v = batch @@ -345,7 +347,7 @@ where network_send: flume::Sender, peer_id: PeerId, request: ChainExchangeRequest, - ) -> Result { + ) -> anyhow::Result { trace!("Sending ChainExchange Request to {peer_id}"); let req_pre_time = Instant::now(); @@ -360,7 +362,7 @@ where .await .is_err() { - return Err("Failed to send chain exchange request to network".to_string()); + anyhow::bail!("Failed to send chain exchange request to network"); }; // Add timeout to receiving response from p2p service to avoid stalling. @@ -401,14 +403,14 @@ where } } debug!("Failed: ChainExchange Request to {peer_id}"); - Err(format!("Internal libp2p error: {e:?}")) + anyhow::bail!("Internal libp2p error: {e:?}"); } Ok(Err(_)) | Err(_) => { // Sender channel internally dropped or timeout, both should log failure which // will negatively score the peer, but not drop yet. peer_manager.log_failure(&peer_id, res_duration); debug!("Timeout: ChainExchange Request to {peer_id}"); - Err(format!("Chain exchange request to {peer_id} timed out")) + anyhow::bail!("Chain exchange request to {peer_id} timed out"); } } } @@ -485,7 +487,7 @@ mod tests { async fn race_batch_ok() { let mut batch = RaceBatch::new(3); batch.add(async move { Ok(1) }); - batch.add(async move { Err("kaboom".into()) }); + batch.add(async move { anyhow::bail!("kaboom") }); assert_eq!(batch.get_ok().await, Some(1)); } @@ -498,7 +500,7 @@ mod tests { Ok(1) }); batch.add(async move { Ok(2) }); - batch.add(async move { Err("kaboom".into()) }); + batch.add(async move { anyhow::bail!("kaboom") }); assert_eq!(batch.get_ok().await, Some(2)); } @@ -506,8 +508,8 @@ mod tests { #[tokio::test] async fn race_batch_none() { let mut batch: RaceBatch = RaceBatch::new(3); - batch.add(async move { Err("kaboom".into()) }); - batch.add(async move { Err("banana".into()) }); + batch.add(async move { anyhow::bail!("kaboom") }); + batch.add(async move { anyhow::bail!("banana") }); assert_eq!(batch.get_ok().await, None); } @@ -531,7 +533,7 @@ mod tests { tokio::task::yield_now().await; c.fetch_sub(1, Ordering::Relaxed); - Err("banana".into()) + anyhow::bail!("banana") }); } @@ -559,7 +561,7 @@ mod tests { tokio::task::yield_now().await; c.fetch_sub(1, Ordering::Relaxed); - Err("banana".into()) + anyhow::bail!("banana") }); } diff --git a/src/chain_sync/tipset_syncer.rs b/src/chain_sync/tipset_syncer.rs index 04f647c1734e..418a8ba64881 100644 --- a/src/chain_sync/tipset_syncer.rs +++ b/src/chain_sync/tipset_syncer.rs @@ -263,7 +263,7 @@ async fn validate_block( 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}")) + TipsetSyncerError::Calculation(format!("Error calculating weight: {e:#}")) })?; if weight != calc_weight { return Err(TipsetSyncerError::Validation(format!( @@ -288,7 +288,7 @@ async fn validate_block( .load_executed_tipset(&base_tipset) .await .map_err(|e| { - TipsetSyncerError::Calculation(format!("Failed to calculate state: {e}")) + TipsetSyncerError::Calculation(format!("Failed to calculate state: {e:#}")) })?; if state_root != header.state_root { @@ -402,7 +402,7 @@ async fn check_block_messages( let mut check_msg = |msg: &Message, account_sequences: &mut HashMap, tree: &StateTree| - -> Result<(), anyhow::Error> { + -> anyhow::Result<()> { // Phase 1: Syntactic validation let min_gas = price_list.on_chain_message(to_vec(msg).unwrap().len()); valid_for_block_inclusion(msg, min_gas.total(), network_version) @@ -448,11 +448,11 @@ async fn check_block_messages( let ExecutedTipset { state_root, .. } = state_manager .load_executed_tipset(&base_tipset) .await - .map_err(|e| TipsetSyncerError::Calculation(format!("Could not update state: {e}")))?; + .map_err(|e| TipsetSyncerError::Calculation(format!("Could not update state: {e:#}")))?; let tree = StateTree::new_from_root(state_manager.blockstore_owned(), &state_root).map_err(|e| { TipsetSyncerError::Calculation(format!( - "Could not load from new state root in state manager: {e}" + "Could not load from new state root in state manager: {e:#}" )) })?; @@ -460,7 +460,7 @@ async fn check_block_messages( for (i, msg) in block.bls_msgs().iter().enumerate() { check_msg(msg, &mut account_sequences, &tree).map_err(|e| { TipsetSyncerError::Validation(format!( - "Block had invalid BLS message at index {i}: {e}" + "Block had invalid BLS message at index {i}: {e:#}" )) })?; } @@ -476,7 +476,7 @@ async fn check_block_messages( } check_msg(msg.message(), &mut account_sequences, &tree).map_err(|e| { TipsetSyncerError::Validation(format!( - "block had an invalid secp message at index {i}: {e}" + "block had an invalid secp message at index {i}: {e:#}" )) })?; // Resolve key address for signature verification diff --git a/src/cli/subcommands/f3_cmd.rs b/src/cli/subcommands/f3_cmd.rs index ae7ff4cadcc6..ddea7f3beb5a 100644 --- a/src/cli/subcommands/f3_cmd.rs +++ b/src/cli/subcommands/f3_cmd.rs @@ -205,15 +205,15 @@ impl F3Commands { } Err(e) => { if !wait { - anyhow::bail!("Failed to check F3 sync status: {e}"); + return Err(e.context("Failed to check F3 sync status")); } num_consecutive_fetch_failtures += 1; if num_consecutive_fetch_failtures >= 3 { - eprintln!("Warning: Failed to fetch heads: {e}. Exiting..."); + eprintln!("Warning: Failed to fetch heads: {e:#}. Exiting..."); std::process::exit(EXIT_CODE_F3_FAIL_TO_FETCH_HEAD); } else { - eprintln!("Warning: Failed to fetch heads: {e}. Retrying..."); + eprintln!("Warning: Failed to fetch heads: {e:#}. Retrying..."); } } } diff --git a/src/cli_shared/cli/mod.rs b/src/cli_shared/cli/mod.rs index 94ade262b1a4..63c65de3e16f 100644 --- a/src/cli_shared/cli/mod.rs +++ b/src/cli_shared/cli/mod.rs @@ -154,7 +154,7 @@ pub struct CliOpts { } impl CliOpts { - pub fn to_config(&self) -> Result<(Config, Option), anyhow::Error> { + pub fn to_config(&self) -> anyhow::Result<(Config, Option)> { let (path, mut cfg) = read_config(self.config.as_ref(), self.chain.clone())?; if let Some(genesis_file) = &self.genesis { diff --git a/src/daemon/context.rs b/src/daemon/context.rs index 2593ef282a24..af12c582e379 100644 --- a/src/daemon/context.rs +++ b/src/daemon/context.rs @@ -174,7 +174,7 @@ fn maybe_migrate_db(config: &Config) { // to avoid breaking the node. let db_migration = crate::db::migration::DbMigration::new(config); if let Err(e) = db_migration.migrate() { - warn!("Failed to migrate database: {e}"); + warn!("Failed to migrate database: {e:#}"); } } diff --git a/src/daemon/db_util.rs b/src/daemon/db_util.rs index 8261d0f380f0..8f9b2dfdc3e8 100644 --- a/src/daemon/db_util.rs +++ b/src/daemon/db_util.rs @@ -270,7 +270,7 @@ pub async fn import_chain_as_forest_car( temp_f3_snap.path().display().to_string(), ) { // Do not make it a hard error if anything is wrong with F3 snapshot - tracing::error!("Failed to import F3 snapshot: {e}"); + tracing::error!("Failed to import F3 snapshot: {e:#}"); } } } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index d1c125afebfc..f4a12ff6fa8e 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -513,7 +513,7 @@ fn maybe_start_f3_service(opts: &CliOpts, config: &Config, ctx: &AppContext) -> } } Err(e) => { - tracing::error!("Failed to get F3 latest certificate: {e}"); + tracing::error!("Failed to get F3 latest certificate: {e:#}"); } } } @@ -638,7 +638,7 @@ pub(super) async fn start_services( && !opts.skip_load_actors && let Err(e) = ctx.state_manager.maybe_rewind_heaviest_tipset() { - tracing::warn!("error in maybe_rewind_heaviest_tipset: {e}"); + tracing::warn!("error in maybe_rewind_heaviest_tipset: {e:#}"); } let p2p_service = create_p2p_service(&mut services, &mut config, &ctx).await?; let mpool = create_mpool(&mut services, &p2p_service, &ctx)?; @@ -796,7 +796,7 @@ async fn maybe_set_snapshot_path( /// returns the first error with which any of the services end, or never returns at all // This should return anyhow::Result once the `Never` type is stabilized async fn propagate_error( - services: &mut JoinSet>, + services: &mut JoinSet>, ) -> anyhow::Result { while let Some(result) = services.join_next().await { if let Ok(Err(error_message)) = result { diff --git a/src/db/blockstore_with_write_buffer.rs b/src/db/blockstore_with_write_buffer.rs index ff5523708bae..e4cc9677e7a1 100644 --- a/src/db/blockstore_with_write_buffer.rs +++ b/src/db/blockstore_with_write_buffer.rs @@ -63,7 +63,7 @@ impl BlockstoreWithWriteBuffer { impl Drop for BlockstoreWithWriteBuffer { fn drop(&mut self) { if let Err(e) = self.flush_buffer() { - tracing::warn!("{e}"); + tracing::warn!("{e:#}"); } } } diff --git a/src/db/car/forest.rs b/src/db/car/forest.rs index 28512d926a40..0b37e9ac79c1 100644 --- a/src/db/car/forest.rs +++ b/src/db/car/forest.rs @@ -408,7 +408,7 @@ impl Encoder { // Pass errors through Some(Err(e)) => { return Poll::Ready(Some(Err(anyhow::anyhow!( - "error polling CarBlock from stream: {e}" + "error polling CarBlock from stream: {e:#}" )))); } // Got element, add to encoder and emit block position diff --git a/src/db/gc/snapshot.rs b/src/db/gc/snapshot.rs index 60c53e266b63..726ce75d4d52 100644 --- a/src/db/gc/snapshot.rs +++ b/src/db/gc/snapshot.rs @@ -161,7 +161,7 @@ where self.running.store(true, Ordering::Relaxed); if let Err(e) = self.export_snapshot().await { self.running.store(false, Ordering::Relaxed); - tracing::warn!("{e}"); + tracing::warn!("{e:#}"); } } } @@ -301,7 +301,7 @@ where pub async fn cleanup_before_reboot(&self) { drop(self.progress_tx.write().take()); if let Err(e) = self.cleanup_before_reboot_inner().await { - tracing::warn!("{e}"); + tracing::warn!("{e:#}"); } self.running.store(false, Ordering::Relaxed); } @@ -373,7 +373,7 @@ where }; let start = Instant::now(); if let Err(e) = db.put_many_keyed(mem_db) { - tracing::warn!("{e}"); + tracing::warn!("{e:#}"); } tracing::info!( "backfilled {count} new db records since snapshot epoch, approximate heap size: {}, took {}", diff --git a/src/db/parity_db.rs b/src/db/parity_db.rs index 7823c8c798dc..40c679c538c6 100644 --- a/src/db/parity_db.rs +++ b/src/db/parity_db.rs @@ -7,7 +7,7 @@ use crate::db::{DBStatistics, parity_db_config::ParityDbConfig}; use crate::libp2p_bitswap::{BitswapStoreRead, BitswapStoreReadWrite}; use crate::rpc::eth::types::EthHash; use crate::utils::{broadcast::has_subscribers, multihash::prelude::*}; -use anyhow::{Context as _, anyhow}; +use anyhow::Context as _; use cid::Cid; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::DAG_CBOR; @@ -130,7 +130,7 @@ impl ParityDb { { self.db .get(column as u8, key.as_ref()) - .map_err(|e| anyhow!("error from column {column}: {e}")) + .with_context(|| format!("error from column {column}")) } fn write_to_column(&self, key: K, value: V, column: DbColumn) -> anyhow::Result<()> @@ -141,7 +141,7 @@ impl ParityDb { let tx = [(column as u8, key.as_ref(), Some(value.as_ref().to_vec()))]; self.db .commit(tx) - .map_err(|e| anyhow!("error writing to column {column}: {e}")) + .with_context(|| format!("error writing to column {column}")) } } @@ -264,9 +264,7 @@ impl Blockstore for ParityDb { let tx = values .into_iter() .map(|(col, k, v)| (col as u8, Operation::Set(k, v))); - self.db - .commit_changes(tx) - .map_err(|e| anyhow!("error bulk writing: {e}"))?; + self.db.commit_changes(tx).context("error bulk writing")?; if let Some(tx) = tx_opt { for i in values_for_subscriber { let _ = tx.send(i); diff --git a/src/dev/subcommands/mod.rs b/src/dev/subcommands/mod.rs index 971e816b0795..9f7fbf42e858 100644 --- a/src/dev/subcommands/mod.rs +++ b/src/dev/subcommands/mod.rs @@ -92,7 +92,7 @@ pub async fn fetch_state_tests() -> anyhow::Result<()> { } for result in joinset.join_all().await { if let Err(e) = result { - tracing::warn!("{e}"); + tracing::warn!("{e:#}"); } } Ok(()) @@ -112,7 +112,7 @@ async fn fetch_rpc_tests() -> anyhow::Result<()> { } for result in joinset.join_all().await { if let Err(e) = result { - tracing::warn!("{e}"); + tracing::warn!("{e:#}"); } } Ok(()) @@ -135,7 +135,7 @@ pub async fn fetch_rpc_test_snapshot<'a>(name: Cow<'a, str>) -> anyhow::Result

{ - println!(" ✗ Epoch {requested_epoch}: {e}"); + println!(" ✗ Epoch {requested_epoch}: {e:#}"); } } } diff --git a/src/fil_cns/mod.rs b/src/fil_cns/mod.rs index c84247960423..c2e7335c1cc7 100644 --- a/src/fil_cns/mod.rs +++ b/src/fil_cns/mod.rs @@ -85,7 +85,7 @@ impl Debug for FilecoinConsensus { } } -pub fn weight(db: &DB, ts: &Tipset) -> Result +pub fn weight(db: &DB, ts: &Tipset) -> anyhow::Result where DB: Blockstore, { diff --git a/src/fil_cns/validation.rs b/src/fil_cns/validation.rs index ffb6ddd17328..e612bf511349 100644 --- a/src/fil_cns/validation.rs +++ b/src/fil_cns/validation.rs @@ -425,7 +425,7 @@ fn verify_winning_post( proofs: &[PoStProof], challenge_sectors: &[SectorInfo], prover: u64, -) -> Result<(), anyhow::Error> { +) -> anyhow::Result<()> { // Necessary to be valid bls12 381 element. if let Some(b31) = rand.0.get_mut(31) { *b31 &= 0x3f; diff --git a/src/genesis/mod.rs b/src/genesis/mod.rs index 2d1134e7bd68..21cd241ef29b 100644 --- a/src/genesis/mod.rs +++ b/src/genesis/mod.rs @@ -22,7 +22,7 @@ pub async fn read_genesis_header( genesis_fp: Option<&Path>, genesis_bytes: Option<&[u8]>, db: &DB, -) -> Result +) -> anyhow::Result where DB: Blockstore, { @@ -43,7 +43,7 @@ where Ok(genesis) } -async fn process_car(reader: R, db: &BS) -> Result +async fn process_car(reader: R, db: &BS) -> anyhow::Result where R: AsyncBufRead + AsyncSeek + Unpin, BS: Blockstore, diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 479b06587fe0..059ec080327c 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -23,7 +23,7 @@ pub fn resolve_to_key_addr( st: &StateTree, store: &BS, addr: &Address, -) -> Result +) -> anyhow::Result

where BS: Blockstore, S: Blockstore, diff --git a/src/interpreter/vm.rs b/src/interpreter/vm.rs index f2e2baf334be..f469244310db 100644 --- a/src/interpreter/vm.rs +++ b/src/interpreter/vm.rs @@ -185,7 +185,7 @@ where }: ExecutionContext, multi_engine: &MultiEngine, enable_tracing: VMTrace, - ) -> Result { + ) -> anyhow::Result { let network_version = chain_config.network_version(epoch); if network_version >= NetworkVersion::V21 { let mut config = NetworkConfig_v4::new(network_version.into()); @@ -275,7 +275,7 @@ where } /// Get actor state from an address. Will be resolved to ID address. - pub fn get_actor(&self, addr: &Address) -> Result, anyhow::Error> { + pub fn get_actor(&self, addr: &Address) -> anyhow::Result> { match self { VM::VM2(fvm_executor) => Ok(fvm_executor .state_tree() @@ -359,7 +359,7 @@ where let mut penalty = TokenAmount::zero(); let mut gas_reward = TokenAmount::zero(); - let mut process_msg = |message: &ChainMessage| -> Result<(), anyhow::Error> { + let mut process_msg = |message: &ChainMessage| -> anyhow::Result<()> { let cid = message.cid(); // Ensure no duplicate processing of a message if processed.contains(&cid) { @@ -529,7 +529,7 @@ where win_count: i64, penalty: TokenAmount, gas_reward: TokenAmount, - ) -> Result, anyhow::Error> { + ) -> anyhow::Result> { let params = RawBytes::serialize(AwardBlockRewardParams { miner: miner.into(), penalty: penalty.into(), diff --git a/src/libp2p/behaviour.rs b/src/libp2p/behaviour.rs index d44c50dedf0d..0baa3f3efaa6 100644 --- a/src/libp2p/behaviour.rs +++ b/src/libp2p/behaviour.rs @@ -179,7 +179,7 @@ impl ForestBehaviour { } /// Bootstrap Kademlia network - pub fn bootstrap(&mut self) -> Result { + pub fn bootstrap(&mut self) -> anyhow::Result { self.discovery.bootstrap() } diff --git a/src/libp2p/chain_exchange/message.rs b/src/libp2p/chain_exchange/message.rs index 4a7cca552558..a17e3ecd586a 100644 --- a/src/libp2p/chain_exchange/message.rs +++ b/src/libp2p/chain_exchange/message.rs @@ -6,6 +6,7 @@ use std::convert::TryFrom; use crate::blocks::{BLOCK_MESSAGE_LIMIT, Block, CachingBlockHeader, FullTipset, Tipset}; use crate::message::SignedMessage; use crate::shim::message::Message; +use anyhow::Context as _; use cid::Cid; use fvm_ipld_encoding::tuple::*; use nunny::Vec as NonEmpty; @@ -123,7 +124,7 @@ impl ChainExchangeResponse { /// Returns an error if the response status is not `Ok`. /// Tipset bundle is converted into generic return type with `TryFrom` trait /// implementation. - pub fn into_result(self) -> Result, String> + pub fn into_result(self) -> anyhow::Result> where T: TryFrom, >::Error: std::fmt::Display, @@ -131,12 +132,15 @@ impl ChainExchangeResponse { if self.status != ChainExchangeResponseStatus::Success && self.status != ChainExchangeResponseStatus::PartialResponse { - return Err(format!("Status {:?}: {}", self.status, self.message)); + anyhow::bail!("Status {:?}: {}", self.status, self.message); } self.chain .into_iter() - .map(|i| T::try_from(i).map_err(|e| e.to_string())) + .map(|i| { + T::try_from(i) + .map_err(|e| anyhow::anyhow!("failed to convert from tipset bundle: {e}")) + }) .collect() } } @@ -183,7 +187,7 @@ impl TryFrom for CompactedMessages { } impl TryFrom for FullTipset { - type Error = String; + type Error = anyhow::Error; fn try_from(tsb: TipsetBundle) -> Result { fts_from_bundle_parts(tsb.blocks, tsb.messages.as_ref()) @@ -191,7 +195,7 @@ impl TryFrom for FullTipset { } impl TryFrom<&TipsetBundle> for FullTipset { - type Error = String; + type Error = anyhow::Error; fn try_from(tsb: &TipsetBundle) -> Result { fts_from_bundle_parts(tsb.blocks.clone(), tsb.messages.as_ref()) @@ -203,35 +207,35 @@ impl TryFrom<&TipsetBundle> for FullTipset { fn fts_from_bundle_parts( headers: Vec, messages: Option<&CompactedMessages>, -) -> Result { +) -> anyhow::Result { let CompactedMessages { bls_msgs, bls_msg_includes, secp_msg_includes, secp_msgs, - } = messages.ok_or("Tipset bundle did not contain message bundle")?; + } = messages.context("Tipset bundle did not contain message bundle")?; if headers.len() != bls_msg_includes.len() || headers.len() != secp_msg_includes.len() { - return Err(format!( + anyhow::bail!( "Invalid formed Tipset bundle, lengths of includes does not match blocks. Header len: {}, bls_msg len: {}, secp_msg len: {}", headers.len(), bls_msg_includes.len(), secp_msg_includes.len() - )); + ); } let zipped = headers .into_iter() .zip(bls_msg_includes.iter()) .zip(secp_msg_includes.iter()); - fn values_from_indexes(indexes: &[u64], values: &[T]) -> Result, String> { + fn values_from_indexes(indexes: &[u64], values: &[T]) -> anyhow::Result> { indexes .iter() .map(|idx| { values .get(*idx as usize) .cloned() - .ok_or_else(|| "Invalid message index".to_string()) + .context("Invalid message index") }) .collect() } @@ -241,9 +245,9 @@ fn fts_from_bundle_parts( .map(|(i, ((header, bls_msg_include), secp_msg_include))| { let message_count = bls_msg_include.len() + secp_msg_include.len(); if message_count > BLOCK_MESSAGE_LIMIT { - return Err(format!( + anyhow::bail!( "Block {i} in bundle has too many messages ({message_count} > {BLOCK_MESSAGE_LIMIT})" - )); + ); } let bls_messages = values_from_indexes(bls_msg_include, bls_msgs)?; let secp_messages = values_from_indexes(secp_msg_include, secp_msgs)?; @@ -256,7 +260,7 @@ fn fts_from_bundle_parts( }) .collect::, _>>()?; - FullTipset::new(blocks).map_err(|e| e.to_string()) + Ok(FullTipset::new(blocks)?) } #[cfg(test)] diff --git a/src/libp2p/discovery.rs b/src/libp2p/discovery.rs index bd4810a9b4ef..9335debfe550 100644 --- a/src/libp2p/discovery.rs +++ b/src/libp2p/discovery.rs @@ -269,9 +269,9 @@ impl DiscoveryBehaviour { } /// Bootstrap Kademlia network - pub fn bootstrap(&mut self) -> Result { + pub fn bootstrap(&mut self) -> anyhow::Result { if let Some(active_kad) = self.discovery.kademlia.as_mut() { - active_kad.bootstrap().map_err(|e| e.to_string()) + Ok(active_kad.bootstrap()?) } else { // Manually dial to seed peers when kademlia is disabled for (peer_id, address) in &self.custom_seed_peers { @@ -282,7 +282,7 @@ impl DiscoveryBehaviour { .build(), ); } - Err("Kademlia is not activated".to_string()) + anyhow::bail!("Kademlia is not activated") } } diff --git a/src/libp2p/service.rs b/src/libp2p/service.rs index ab7fb019330e..f87a4638d7c4 100644 --- a/src/libp2p/service.rs +++ b/src/libp2p/service.rs @@ -280,7 +280,7 @@ where // Bootstrap with Kademlia if let Err(e) = self.swarm.behaviour_mut().bootstrap() { - warn!("Failed to bootstrap with Kademlia: {e}"); + warn!("Failed to bootstrap with Kademlia: {e:#}"); } let bitswap_request_manager = self.swarm.behaviour().bitswap.request_manager(); @@ -647,7 +647,7 @@ async fn handle_gossip_event( .await; } Err(e) => { - warn!("Gossip Block from peer {source:?} could not be deserialized: {e}",); + warn!("Gossip Block from peer {source:?} could not be deserialized: {e:#}",); } } } else if topic == pubsub_msg_str { @@ -662,7 +662,7 @@ async fn handle_gossip_event( .await; } Err(e) => { - warn!("Gossip Message from peer {source:?} could not be deserialized: {e}"); + warn!("Gossip Message from peer {source:?} could not be deserialized: {e:#}"); } } } else { @@ -908,7 +908,7 @@ async fn handle_forest_behaviour_event( db.blockstore(), event, ) { - warn!("bitswap: {e}"); + warn!("bitswap: {e:#}"); } } ForestBehaviourEvent::Ping(ping_event) => handle_ping_event(ping_event).await, diff --git a/src/libp2p_bitswap/request_manager.rs b/src/libp2p_bitswap/request_manager.rs index 5c0d7b99ef58..0c990fea633d 100644 --- a/src/libp2p_bitswap/request_manager.rs +++ b/src/libp2p_bitswap/request_manager.rs @@ -236,14 +236,14 @@ impl BitswapRequestManager { Err(e) => { metrics::message_counter_inbound_response_block_update_db_failure().inc(); warn!( - "Failed to update db: {e}, cid: {cid}, data: {:?}", + "Failed to update db, cid: {cid}, data: {:?}, error: {e:#}", block.data() ); false } }, Err(e) => { - warn!("Failed to construct block: {e}, cid: {cid}"); + warn!("Failed to construct block, cid: {cid}, error: {e:#}"); false } }; diff --git a/src/message/mod.rs b/src/message/mod.rs index 682878d2f6f3..8448650dee48 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -115,7 +115,7 @@ pub fn valid_for_block_inclusion( msg: &ShimMessage, min_gas: Gas, version: NetworkVersion, -) -> Result<(), anyhow::Error> { +) -> anyhow::Result<()> { use crate::shim::address::ZERO_ADDRESS; use crate::shim::econ::{BLOCK_GAS_LIMIT, TOTAL_FILECOIN}; if msg.version != 0 { diff --git a/src/message_pool/config.rs b/src/message_pool/config.rs index eb9a313f8bc1..7bc03cc7c6df 100644 --- a/src/message_pool/config.rs +++ b/src/message_pool/config.rs @@ -45,7 +45,7 @@ impl Default for MpoolConfig { impl MpoolConfig { #[cfg(test)] /// Saves message pool `config` to the database, to easily reload. - pub fn save_config(&self, store: &DB) -> Result<(), anyhow::Error> { + pub fn save_config(&self, store: &DB) -> anyhow::Result<()> { store.write_bin(MPOOL_CONFIG_KEY, &fvm_ipld_encoding::to_vec(&self)?) } @@ -63,7 +63,7 @@ impl MpoolConfig { impl MpoolConfig { /// Load `config` from store, if exists. If there is no `config`, uses /// default. - pub fn load_config(store: &DB) -> Result { + pub fn load_config(store: &DB) -> anyhow::Result { match store.read_bin(MPOOL_CONFIG_KEY)? { Some(v) => Ok(from_slice_with_fallback(&v)?), None => Ok(Default::default()), diff --git a/src/message_pool/errors.rs b/src/message_pool/errors.rs index 0002d25641dc..0fe67c0f107f 100644 --- a/src/message_pool/errors.rs +++ b/src/message_pool/errors.rs @@ -50,6 +50,6 @@ impl From for Error { impl From for Error { fn from(e: anyhow::Error) -> Self { - Error::Other(e.to_string()) + Error::Other(format!("{e:#}")) } } diff --git a/src/message_pool/msgpool/selection.rs b/src/message_pool/msgpool/selection.rs index 3b66947aedd8..10d6d9827a82 100644 --- a/src/message_pool/msgpool/selection.rs +++ b/src/message_pool/msgpool/selection.rs @@ -511,7 +511,7 @@ where continue; } Err(e) => { - debug!("Failed to add message chain with dependencies: {e}"); + debug!("Failed to add message chain with dependencies: {e:#}"); } } @@ -570,7 +570,7 @@ where match selected_msgs.try_to_add_with_deps(i, &mut chains, &base_fee) { Ok(_) => continue, - Err(e) => debug!("Failed to add message chain with dependencies: {e}"), + Err(e) => debug!("Failed to add message chain with dependencies: {e:#}"), } continue 'tail_loop; diff --git a/src/rpc/error.rs b/src/rpc/error.rs index 42397c031d63..93edbe4450fe 100644 --- a/src/rpc/error.rs +++ b/src/rpc/error.rs @@ -98,14 +98,14 @@ impl From for ServerError { // Default implementation for anyhow::Error to handle downcasting once impl From for ServerError { - fn from(error: anyhow::Error) -> Self { + fn from(e: anyhow::Error) -> Self { // Try to downcast to known RpcErrorData implementations - if let Some(eth_error) = error.downcast_ref::() { + if let Some(eth_error) = e.downcast_ref::() { return eth_error.clone().into(); } // Default fallback - Self::internal_error(error.to_string(), None) + Self::internal_error(format!("{e:#}"), None) } } diff --git a/src/rpc/methods/chain.rs b/src/rpc/methods/chain.rs index 3e2d96f8162b..d4cc050644f8 100644 --- a/src/rpc/methods/chain.rs +++ b/src/rpc/methods/chain.rs @@ -493,7 +493,7 @@ impl RpcMethod<1> for ForestChainExport { { Ok(cid) => Some((cid, File::open(&f3_snap_tmp_path)?)), Err(e) => { - tracing::error!("Failed to export F3 snapshot: {e}"); + tracing::error!("Failed to export F3 snapshot: {e:#}"); None } } diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 9f09bd2c63d0..6d0707a943af 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -1750,7 +1750,7 @@ where .state_manager .apply_on_state_with_gas(tipset, msg, VMFlush::Skip) .await - .map_err(|e| anyhow::anyhow!("failed to apply on state with gas: {e}"))?; + .context("failed to apply on state with gas")?; // Extract receipt or return early if none match &invoc_res.msg_rct { @@ -3459,14 +3459,14 @@ impl RpcMethod<3> for EthTraceCall { .state_manager .load_tipset_state(&ts) .await - .map_err(|e| anyhow::anyhow!("failed to get tipset state: {e}"))?; + .context("failed to get tipset state")?; let pre_state = StateTree::new_from_root(ctx.store_owned(), &pre_state_root)?; let (invoke_result, post_state_root) = ctx .state_manager .apply_on_state_with_gas(Some(ts.clone()), msg.clone(), VMFlush::Flush) .await - .map_err(|e| anyhow::anyhow!("failed to apply message: {e}"))?; + .context("failed to apply message")?; let post_state_root = post_state_root.context("post-execution state root required for trace call")?; let post_state = StateTree::new_from_root(ctx.store_owned(), &post_state_root)?; @@ -3488,7 +3488,7 @@ impl RpcMethod<3> for EthTraceCall { && let Some(exec_trace) = invoke_result.execution_trace { let mut env = trace::base_environment(&post_state, &msg.from()) - .map_err(|e| anyhow::anyhow!("failed to create trace environment: {e}"))?; + .context("failed to create trace environment")?; trace::build_traces(&mut env, &[], exec_trace)?; trace_results.trace = env.traces; } @@ -3529,10 +3529,7 @@ fn get_trace_output(msg: &Message, invoke_result: &ApiInvocResult) -> Result Ok(payload), - Err(e) => Err(anyhow::anyhow!("failed to decode return data: {e}")), - } + decode_payload(&return_data, CBOR).context("failed to decode return data") } /// Extract all unique Ethereum addresses touched during execution from the trace. diff --git a/src/rpc/methods/eth/trace/state_diff.rs b/src/rpc/methods/eth/trace/state_diff.rs index 9eec5949ca1d..a8ca38a0247d 100644 --- a/src/rpc/methods/eth/trace/state_diff.rs +++ b/src/rpc/methods/eth/trace/state_diff.rs @@ -13,6 +13,7 @@ use crate::rpc::eth::EthBigInt; use crate::shim::actors::{EVMActorStateLoad as _, evm, is_evm_actor}; use crate::shim::state_tree::{ActorState, StateTree}; use ahash::{HashMap, HashSet}; +use anyhow::Context as _; use fil_actor_evm_state::evm_shared::v17::uints::U256; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_kamt::{AsHashedKey, Config as KamtConfig, HashedKey, Kamt}; @@ -64,11 +65,11 @@ pub(crate) fn build_state_diff( // Get actor state before and after let pre_actor = pre_state .get_actor(&fil_addr) - .map_err(|e| anyhow::anyhow!("failed to get actor state: {e}"))?; + .context("failed to get actor state")?; let post_actor = post_state .get_actor(&fil_addr) - .map_err(|e| anyhow::anyhow!("failed to get actor state: {e}"))?; + .context("failed to get actor state")?; let account_diff = build_account_diff(store, pre_actor.as_ref(), post_actor.as_ref())?; @@ -220,7 +221,7 @@ fn extract_evm_storage_entries( let evm_state = match evm::State::load(store, actor.code, actor.state) { Ok(state) => state, Err(e) => { - debug!("failed to load EVM state for storage extraction: {e}"); + debug!("failed to load EVM state for storage extraction: {e:#}"); return HashMap::default(); } }; diff --git a/src/rpc/methods/gas.rs b/src/rpc/methods/gas.rs index ce071348f70d..f4a14ea51e0f 100644 --- a/src/rpc/methods/gas.rs +++ b/src/rpc/methods/gas.rs @@ -277,7 +277,7 @@ impl GasEstimateGasLimit { { let (res, ..) = Self::estimate_call_with_gas(data, msg, tsk) .await - .map_err(|e| anyhow::anyhow!("gas estimation failed: {e}"))?; + .context("gas estimation failed")?; match res.msg_rct { Some(rct) => { anyhow::ensure!( diff --git a/src/rpc/methods/state.rs b/src/rpc/methods/state.rs index c8fd0c9e73f8..faa9e57f5449 100644 --- a/src/rpc/methods/state.rs +++ b/src/rpc/methods/state.rs @@ -1573,11 +1573,9 @@ impl RpcMethod<2> for ForestStateCompute { Err(_) => continue, } } - Err("unreachable chain exchange error in ForestStateCompute".into()) + anyhow::bail!("unreachable chain exchange error in ForestStateCompute") } - .map_err(|e| { - anyhow::anyhow!("failed to download messages@{}: {e}", ts.epoch()) - })?; + .with_context(|| format!("failed to download messages@{}", ts.epoch()))?; fts.persist(chain_store.blockstore())?; } anyhow::Ok(ts) @@ -3272,7 +3270,7 @@ fn get_pledge_ramp_params( ctx: &Ctx, height: ChainEpoch, ts: &Tipset, -) -> Result<(ChainEpoch, u64), anyhow::Error> { +) -> anyhow::Result<(ChainEpoch, u64)> { let state_tree = ctx.state_manager.get_state_tree(ts.parent_state())?; let power_state: power::State = state_tree diff --git a/src/shim/actors/builtin/market/mod.rs b/src/shim/actors/builtin/market/mod.rs index fc827e3bf771..96369e719b1d 100644 --- a/src/shim/actors/builtin/market/mod.rs +++ b/src/shim/actors/builtin/market/mod.rs @@ -367,7 +367,7 @@ where { pub fn for_each( &self, - mut f: impl FnMut(u64, Result) -> anyhow::Result<(), anyhow::Error>, + mut f: impl FnMut(u64, anyhow::Result) -> anyhow::Result<()>, ) -> anyhow::Result<()> { delegate_deal_proposals!(self => |deal_array| Ok(deal_array .for_each(|key, deal_proposal| f(key, deal_proposal.try_into()))?)) diff --git a/src/shim/actors/builtin/miner/mod.rs b/src/shim/actors/builtin/miner/mod.rs index cc4e49f18a00..e0d38df5859a 100644 --- a/src/shim/actors/builtin/miner/mod.rs +++ b/src/shim/actors/builtin/miner/mod.rs @@ -99,7 +99,7 @@ impl State { &self, policy: &Policy, store: &BS, - mut f: impl FnMut(u64, Deadline) -> Result<(), anyhow::Error>, + mut f: impl FnMut(u64, Deadline) -> anyhow::Result<()>, ) -> anyhow::Result<()> { match self { State::V8(st) => { @@ -883,7 +883,7 @@ impl Deadline { pub fn for_each( &self, store: &BS, - mut f: impl FnMut(u64, Partition) -> Result<(), anyhow::Error>, + mut f: impl FnMut(u64, Partition) -> anyhow::Result<()>, ) -> anyhow::Result<()> { delegate_deadline!(self.for_each(&store, |idx, part| f(idx, Cow::Borrowed(part).into()))) } diff --git a/src/shim/crypto.rs b/src/shim/crypto.rs index b505c129065c..c6d4f8531fa8 100644 --- a/src/shim/crypto.rs +++ b/src/shim/crypto.rs @@ -95,7 +95,7 @@ impl Signature { } /// Creates a signature from bytes. - pub fn from_bytes(bytes: Vec) -> Result { + pub fn from_bytes(bytes: Vec) -> anyhow::Result { if bytes.is_empty() { anyhow::bail!("Empty signature bytes"); } diff --git a/src/shim/state_tree.rs b/src/shim/state_tree.rs index 5b31dfa203af..2921ee40cc71 100644 --- a/src/shim/state_tree.rs +++ b/src/shim/state_tree.rs @@ -10,7 +10,7 @@ use crate::{ networks::{ACTOR_BUNDLES_METADATA, ActorBundleMetadata}, shim::actors::account, }; -use anyhow::{Context as _, anyhow, bail}; +use anyhow::{Context as _, bail}; use cid::Cid; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::{ @@ -211,18 +211,12 @@ where addr.protocol() != crate::shim::address::Protocol::Delegated, "Delegated addresses are not supported in FVMv2 state trees" ); - Ok(st - .get_actor(&addr.into()) - .map_err(|e| anyhow!("{e}"))? - .map(Into::into)) + Ok(st.get_actor(&addr.into())?.map(Into::into)) } StateTree::FvmV3(st) => { let id = st.lookup_id(&addr.into())?; if let Some(id) = id { - Ok(st - .get_actor(id) - .map_err(|e| anyhow!("{e}"))? - .map(Into::into)) + Ok(st.get_actor(id)?.map(Into::into)) } else { Ok(None) } @@ -230,10 +224,7 @@ where StateTree::FvmV4(st) => { let id = st.lookup_id(addr)?; if let Some(id) = id { - Ok(st - .get_actor(id) - .map_err(|e| anyhow!("{e}"))? - .map(Into::into)) + Ok(st.get_actor(id)?.map(Into::into)) } else { Ok(None) } @@ -241,10 +232,7 @@ where StateTree::V0(st) => { let id = st.lookup_id(addr)?; if let Some(id) = id { - Ok(st - .get_actor(&id) - .map_err(|e| anyhow!("{e}"))? - .map(Into::into)) + Ok(st.get_actor(&id)?.map(Into::into)) } else { Ok(None) } @@ -281,7 +269,7 @@ where /// Get an ID address from any Address pub fn lookup_id(&self, addr: &Address) -> anyhow::Result> { match self { - StateTree::FvmV2(st) => st.lookup_id(&addr.into()).map_err(|e| anyhow!("{e}")), + StateTree::FvmV2(st) => Ok(st.lookup_id(&addr.into())?), StateTree::FvmV3(st) => Ok(st.lookup_id(&addr.into())?), StateTree::FvmV4(st) => Ok(st.lookup_id(&addr.into())?), StateTree::V0(_) => bail!("StateTree::lookup_id not supported on old state trees"), @@ -315,7 +303,7 @@ where /// Flush state tree and return Cid root. pub fn flush(&mut self) -> anyhow::Result { match self { - StateTree::FvmV2(st) => st.flush().map_err(|e| anyhow!("{e}")), + StateTree::FvmV2(st) => Ok(st.flush()?), StateTree::FvmV3(st) => Ok(st.flush()?), StateTree::FvmV4(st) => Ok(st.flush()?), StateTree::V0(_) => bail!("StateTree::flush not supported on old state trees"), @@ -325,9 +313,10 @@ where /// Set actor state with an actor ID. pub fn set_actor(&mut self, addr: &Address, actor: ActorState) -> anyhow::Result<()> { match self { - StateTree::FvmV2(st) => st - .set_actor(&addr.into(), actor.into()) - .map_err(|e| anyhow!("{e}")), + StateTree::FvmV2(st) => { + st.set_actor(&addr.into(), actor.into())?; + Ok(()) + } StateTree::FvmV3(st) => { let id = st .lookup_id(&addr.into())? diff --git a/src/state_manager/circulating_supply.rs b/src/state_manager/circulating_supply.rs index d32c3171492b..b6e6c9bbd5cd 100644 --- a/src/state_manager/circulating_supply.rs +++ b/src/state_manager/circulating_supply.rs @@ -73,7 +73,7 @@ impl GenesisInfo { height: ChainEpoch, db: &Arc, root: &Cid, - ) -> Result { + ) -> anyhow::Result { let detailed = self.get_vm_circulating_supply_detailed(height, db, root)?; Ok(detailed.fil_circulating) @@ -124,7 +124,7 @@ impl GenesisInfo { height: ChainEpoch, db: &Arc, root: &Cid, - ) -> Result { + ) -> anyhow::Result { let mut circ = TokenAmount::default(); let mut un_circ = TokenAmount::default(); @@ -228,7 +228,7 @@ impl GenesisInfoVesting { fn get_actor_state( state_tree: &StateTree, addr: &Address, -) -> Result { +) -> anyhow::Result { state_tree .get_actor(addr)? .with_context(|| format!("Failed to get Actor for address {addr}")) @@ -265,14 +265,14 @@ fn get_fil_vested(genesis_info: &GenesisInfo, height: ChainEpoch) -> TokenAmount return_value } -fn get_fil_mined(state_tree: &StateTree) -> Result { +fn get_fil_mined(state_tree: &StateTree) -> anyhow::Result { let state: reward::State = state_tree.get_actor_state()?; Ok(state.into_total_storage_power_reward()) } fn get_fil_market_locked( state_tree: &StateTree, -) -> Result { +) -> anyhow::Result { let actor = state_tree .get_actor(&Address::MARKET_ACTOR)? .ok_or_else(|| Error::state("Market actor address could not be resolved"))?; @@ -281,9 +281,7 @@ fn get_fil_market_locked( Ok(state.total_locked()) } -fn get_fil_power_locked( - state_tree: &StateTree, -) -> Result { +fn get_fil_power_locked(state_tree: &StateTree) -> anyhow::Result { let actor = state_tree .get_actor(&Address::POWER_ACTOR)? .ok_or_else(|| Error::state("Power actor address could not be resolved"))?; @@ -295,7 +293,7 @@ fn get_fil_reserve_disbursed( chain_config: &ChainConfig, height: ChainEpoch, state_tree: &StateTree, -) -> Result { +) -> anyhow::Result { // FIP-0100 introduced a different hard-coded reserved amount for testnets. // See // for details. @@ -309,7 +307,7 @@ fn get_fil_reserve_disbursed( fn get_fil_locked( state_tree: &StateTree, network_version: NetworkVersion, -) -> Result { +) -> anyhow::Result { let total = if network_version >= NetworkVersion::V23 { get_fil_power_locked(state_tree)? } else { @@ -319,7 +317,7 @@ fn get_fil_locked( Ok(total) } -fn get_fil_burnt(state_tree: &StateTree) -> Result { +fn get_fil_burnt(state_tree: &StateTree) -> anyhow::Result { let burnt_actor = get_actor_state(state_tree, &Address::BURNT_FUNDS_ACTOR)?; Ok(TokenAmount::from(&burnt_actor.balance)) diff --git a/src/state_manager/errors.rs b/src/state_manager/errors.rs index 0d70eb8f4f12..d10d8ae9b4ee 100644 --- a/src/state_manager/errors.rs +++ b/src/state_manager/errors.rs @@ -35,7 +35,7 @@ impl From for Error { impl From for Error { fn from(e: anyhow::Error) -> Self { - Error::other(e) + Error::other(format!("{e:#}")) } } diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 2dd2477a2ffa..0786e79d2e6e 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -201,14 +201,14 @@ impl StateManager where DB: Blockstore, { - pub fn new(cs: Arc>) -> Result { + pub fn new(cs: Arc>) -> anyhow::Result { Self::new_with_engine(cs, GLOBAL_MULTI_ENGINE.clone()) } pub fn new_with_engine( cs: Arc>, engine: Arc, - ) -> Result { + ) -> anyhow::Result { let genesis = cs.genesis_block_header(); let beacon = Arc::new(cs.chain_config().get_beacon_schedule(genesis.timestamp)); @@ -703,7 +703,7 @@ where let TipsetState { state_root, .. } = self .load_tipset_state(&ts) .await - .map_err(|e| Error::Other(format!("Could not load tipset state: {e}")))?; + .map_err(|e| Error::Other(format!("Could not load tipset state: {e:#}")))?; let chain_rand = self.chain_rand(ts.clone()); // Since we're simulating a future message, pretend we're applying it in the @@ -738,7 +738,7 @@ where } let from_actor = vm .get_actor(&message.from()) - .map_err(|e| Error::Other(format!("Could not get actor from state: {e}")))? + .map_err(|e| Error::Other(format!("Could not get actor from state: {e:#}")))? .ok_or_else(|| Error::Other("cant find actor in state tree".to_string()))?; message.set_sequence(from_actor.sequence); @@ -762,9 +762,7 @@ where /// indicated message, assuming it was executed in the indicated tipset. pub async fn replay(self: &Arc, ts: Tipset, mcid: Cid) -> Result { let this = Arc::clone(self); - tokio::task::spawn_blocking(move || this.replay_blocking(ts, mcid)) - .await - .map_err(|e| Error::Other(format!("{e}")))? + tokio::task::spawn_blocking(move || this.replay_blocking(ts, mcid)).await? } /// Blocking version of `replay` @@ -923,7 +921,7 @@ where if has_callback { e } else { - anyhow::anyhow!("Failed to compute tipset state@{epoch}: {e}") + e.context(format!("Failed to compute tipset state@{epoch}")) } })?) } @@ -1283,12 +1281,13 @@ where ) -> Result { let state = StateTree::new_from_root(Arc::clone(db), &state_cid) .map_err(|e| Error::Other(e.to_string()))?; - let kaddr = resolve_to_key_addr(&state, db, addr) - .map_err(|e| format!("Failed to resolve key address, error: {e}"))?; + let kaddr = + resolve_to_key_addr(&state, db, addr).context("Failed to resolve key address")?; match kaddr.into_payload() { Payload::BLS(key) => BlsPublicKey::from_bytes(&key) - .map_err(|e| Error::Other(format!("Failed to construct bls public key: {e}"))), + .context("Failed to construct bls public key") + .map_err(Error::from), _ => Err(Error::state( "Address must be BLS address to load bls public key", )), @@ -1409,7 +1408,7 @@ where self: &Arc, addr: &Address, ts: &Tipset, - ) -> Result { + ) -> anyhow::Result
{ match addr.protocol() { Protocol::BLS | Protocol::Secp256k1 | Protocol::Delegated => return Ok(*addr), Protocol::Actor => { @@ -1764,7 +1763,7 @@ where NO_CALLBACK, VMTrace::NotTraced, ) - .map_err(|e| anyhow::anyhow!("couldn't compute tipset state: {e}"))?; + .context("couldn't compute tipset state")?; let expected_receipt = child.min_ticket_block().message_receipts; let expected_state = child.parent_state(); match (expected_state, expected_receipt) == (&actual_state, actual_receipt) { @@ -1878,7 +1877,7 @@ impl<'a, DB: Blockstore + Send + Sync + 'static> TipsetExecutor<'a, DB> { let mut vm = self.create_vm(parent_state, epoch_i, timestamp, null_epoch_trace)?; if let Err(e) = vm.run_cron(epoch_i, cron_callback.as_mut()) { - error!("Beginning of epoch cron failed to run: {e}"); + error!("Beginning of epoch cron failed to run: {e:#}"); return Err(e); } vm.flush() diff --git a/src/state_manager/utils.rs b/src/state_manager/utils.rs index 23997b80920e..916725c1d6dc 100644 --- a/src/state_manager/utils.rs +++ b/src/state_manager/utils.rs @@ -31,7 +31,7 @@ where nv: NetworkVersion, miner_address: &Address, rand: Randomness, - ) -> Result, anyhow::Error> { + ) -> anyhow::Result> { let store = self.blockstore(); let actor = self @@ -162,7 +162,7 @@ fn generate_winning_post_sector_challenge( prover_id: u64, mut rand: Randomness, eligible_sector_count: u64, -) -> Result, anyhow::Error> { +) -> anyhow::Result> { // Necessary to be valid bls12 381 element. if let Some(b31) = rand.0.get_mut(31) { *b31 &= 0x3f; diff --git a/src/state_migration/common/state_migration.rs b/src/state_migration/common/state_migration.rs index da42a6bb7a5a..fced09e99e5e 100644 --- a/src/state_migration/common/state_migration.rs +++ b/src/state_migration/common/state_migration.rs @@ -132,7 +132,7 @@ impl StateMigration { let job_output = job.run(store, prior_epoch, cache_clone).unwrap_or_else(|e| { panic!( - "failed executing job for address: {address}, Reason: {e}" + "failed executing job for address: {address}, Reason: {e:#}" ) }); @@ -153,7 +153,7 @@ impl StateMigration { .set_actor(&address, actor_state) .unwrap_or_else(|e| { panic!( - "Failed setting new actor state at given address: {address}, Reason: {e}" + "Failed setting new actor state at given address: {address}, Reason: {e:#}" ) }); job_counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed); @@ -197,7 +197,7 @@ impl StateMigration { .set_actor(&address, actor_state) .unwrap_or_else(|e| { panic!( - "Failed setting new actor state at given address: {address}, Reason: {e}" + "Failed setting new actor state at given address: {address}, Reason: {e:#}" ) }); } diff --git a/src/state_migration/nv19/power.rs b/src/state_migration/nv19/power.rs index bcd640ad2db2..10d5c78445c1 100644 --- a/src/state_migration/nv19/power.rs +++ b/src/state_migration/nv19/power.rs @@ -42,8 +42,8 @@ impl ActorMigration for PowerMigrator { let mut out_claims = make_map_with_root_and_bitwidth(&empty_claims, store, HAMT_BIT_WIDTH)?; in_claims.for_each(|key, claim: &ClaimV10| { - let new_proof_type = convert_window_post_proof_v1_to_v1p1(claim.window_post_proof_type) - .map_err(|e| anyhow::anyhow!("{e}"))?; + let new_proof_type = + convert_window_post_proof_v1_to_v1p1(claim.window_post_proof_type)?; let out_claim = ClaimV11 { window_post_proof_type: new_proof_type, raw_byte_power: claim.raw_byte_power.clone(), diff --git a/src/state_migration/type_migrations/init/state_v9_to_v10.rs b/src/state_migration/type_migrations/init/state_v9_to_v10.rs index 0afdd2b69a20..1ba847893155 100644 --- a/src/state_migration/type_migrations/init/state_v9_to_v10.rs +++ b/src/state_migration/type_migrations/init/state_v9_to_v10.rs @@ -13,8 +13,7 @@ use crate::state_migration::common::{TypeMigration, TypeMigrator}; impl TypeMigration for TypeMigrator { fn migrate_type(from: InitStateV9, store: &impl Blockstore) -> anyhow::Result { - let mut in_addr_map: Map<_, ActorID> = - make_map_with_root(&from.address_map, &store).map_err(|e| anyhow::anyhow!("{e}"))?; + let mut in_addr_map: Map<_, ActorID> = make_map_with_root(&from.address_map, &store)?; let actor_id = from.next_id; let eth_zero_addr = Address::new_delegated( diff --git a/src/statediff/mod.rs b/src/statediff/mod.rs index 4c3c6847336d..65d0ad636e78 100644 --- a/src/statediff/mod.rs +++ b/src/statediff/mod.rs @@ -61,7 +61,7 @@ fn actor_to_resolved( fn root_to_state_map( bs: &Arc, root: &Cid, -) -> Result, anyhow::Error> { +) -> anyhow::Result> { let mut actors = HashMap::default(); let state_tree = StateTree::new_from_root(bs.clone(), root)?; state_tree.for_each(|addr: Address, actor: &ActorState| { @@ -81,7 +81,7 @@ fn try_print_actor_states( root: &Cid, expected_root: &Cid, depth: Option, -) -> Result<(), anyhow::Error> { +) -> anyhow::Result<()> { // For now, resolving to a map, because we need to use go implementation's // inefficient caching this would probably be faster in most cases. let mut e_state = root_to_state_map(bs, expected_root)?; @@ -131,7 +131,7 @@ fn pp_actor_state( bs: &impl Blockstore, actor_state: &ActorState, depth: Option, -) -> Result { +) -> anyhow::Result { let mut buffer = String::new(); writeln!(&mut buffer, "{actor_state:?}")?; if let Ok(miner_state) = MinerState::load(bs, actor_state.code, actor_state.state) { @@ -206,12 +206,12 @@ pub fn print_state_diff( root: &Cid, expected_root: &Cid, depth: Option, -) -> Result<(), anyhow::Error> +) -> anyhow::Result<()> where BS: Blockstore, { if let Err(e) = try_print_actor_states(bs, root, expected_root, depth) { - println!("Could not resolve actor states: {e}\nUsing default resolution:"); + println!("Could not resolve actor states: {e:#}\nUsing default resolution:"); let expected = resolve_cids_recursive(bs, expected_root, depth)?; let actual = resolve_cids_recursive(bs, root, depth)?; diff --git a/src/statediff/resolve.rs b/src/statediff/resolve.rs index ab075b3c9fd5..953c022af181 100644 --- a/src/statediff/resolve.rs +++ b/src/statediff/resolve.rs @@ -9,11 +9,7 @@ use fvm_ipld_encoding::DAG_CBOR; use ipld_core::ipld::Ipld; /// Resolves link to recursively resolved [`Ipld`] with no hash links. -pub fn resolve_cids_recursive( - bs: &BS, - cid: &Cid, - depth: Option, -) -> Result +pub fn resolve_cids_recursive(bs: &BS, cid: &Cid, depth: Option) -> anyhow::Result where BS: Blockstore, { @@ -24,7 +20,7 @@ where /// Resolves [`Ipld`] links recursively, building an [`Ipld`] structure with no /// hash links. -fn resolve_ipld(bs: &BS, ipld: &mut Ipld, mut depth: Option) -> Result<(), anyhow::Error> +fn resolve_ipld(bs: &BS, ipld: &mut Ipld, mut depth: Option) -> anyhow::Result<()> where BS: Blockstore, { diff --git a/src/tool/subcommands/api_cmd.rs b/src/tool/subcommands/api_cmd.rs index be17feac6c72..7c62058096b4 100644 --- a/src/tool/subcommands/api_cmd.rs +++ b/src/tool/subcommands/api_cmd.rs @@ -383,7 +383,7 @@ impl ApiCommands { println!(" Succeeded"); } Err(e) => { - println!(" Failed: {e}"); + println!(" Failed: {e:#}"); } }; } @@ -400,7 +400,7 @@ impl ApiCommands { ); } Err(e) => { - println!(" Failed: {e}"); + println!(" Failed: {e:#}"); } }; } diff --git a/src/tool/subcommands/snapshot_cmd.rs b/src/tool/subcommands/snapshot_cmd.rs index f0b2913221a3..4da186e70b44 100644 --- a/src/tool/subcommands/snapshot_cmd.rs +++ b/src/tool/subcommands/snapshot_cmd.rs @@ -143,7 +143,7 @@ impl SnapshotCommands { println!("{}", out.display()); Ok(()) } - Err(e) => cli_error_and_die(format!("Failed fetching the snapshot: {e}"), 1), + Err(e) => cli_error_and_die(format!("Failed fetching the snapshot: {e:#}"), 1), }, Self::ValidateDiffs { check_links, diff --git a/src/utils/proofs_api/paramfetch.rs b/src/utils/proofs_api/paramfetch.rs index ad456245dc4a..d16833de36b8 100644 --- a/src/utils/proofs_api/paramfetch.rs +++ b/src/utils/proofs_api/paramfetch.rs @@ -84,7 +84,7 @@ pub async fn get_params( param_json: &str, storage_size: SectorSizeOpt, dry_run: bool, -) -> Result<(), anyhow::Error> { +) -> anyhow::Result<()> { // Just print out the parameters download directory path and exit. if dry_run { println!("{}", param_dir(data_dir).to_string_lossy()); @@ -123,7 +123,7 @@ pub async fn get_params_default( data_dir: &Path, storage_size: SectorSizeOpt, dry_run: bool, -) -> Result<(), anyhow::Error> { +) -> anyhow::Result<()> { get_params(data_dir, DEFAULT_PARAMETERS, storage_size, dry_run).await } @@ -131,7 +131,7 @@ async fn fetch_verify_params( data_dir: &Path, name: &str, info: Arc, -) -> Result<(), anyhow::Error> { +) -> anyhow::Result<()> { crate::def_is_env_truthy!(force_ipfs_gateway, PROOFS_ONLY_IPFS_GATEWAY_ENV); let path: PathBuf = param_dir(data_dir).join(name); diff --git a/src/utils/sqlite/mod.rs b/src/utils/sqlite/mod.rs index 0a252649d291..817d2b5c7de2 100644 --- a/src/utils/sqlite/mod.rs +++ b/src/utils/sqlite/mod.rs @@ -92,7 +92,7 @@ pub async fn init_db<'q>( if sqlx::query("SELECT name FROM sqlite_master WHERE type='table' AND name='_meta';") .fetch_optional(db) .await - .map_err(|e| anyhow::anyhow!("error looking for {name} database _meta table: {e}"))? + .with_context(|| format!("error looking for {name} database _meta table"))? .is_none() { init(db, schema_version).await?; From 964e314bc16b634a3b7ed917afbff4aa2c5c1d2d Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 25 Mar 2026 21:49:18 +0800 Subject: [PATCH 2/4] address AI comment --- src/chain_sync/network_context.rs | 2 +- src/libp2p/chain_exchange/message.rs | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/chain_sync/network_context.rs b/src/chain_sync/network_context.rs index cddc70873288..802cd178e04a 100644 --- a/src/chain_sync/network_context.rs +++ b/src/chain_sync/network_context.rs @@ -221,7 +221,7 @@ where ) -> anyhow::Result> where T: TryFrom + Send + Sync + 'static, - >::Error: std::fmt::Display, + >::Error: Into, F: Fn(&Vec) -> bool, { let request = ChainExchangeRequest { diff --git a/src/libp2p/chain_exchange/message.rs b/src/libp2p/chain_exchange/message.rs index a17e3ecd586a..08c72dbbf4f9 100644 --- a/src/libp2p/chain_exchange/message.rs +++ b/src/libp2p/chain_exchange/message.rs @@ -127,7 +127,7 @@ impl ChainExchangeResponse { pub fn into_result(self) -> anyhow::Result> where T: TryFrom, - >::Error: std::fmt::Display, + >::Error: Into, { if self.status != ChainExchangeResponseStatus::Success && self.status != ChainExchangeResponseStatus::PartialResponse @@ -138,8 +138,7 @@ impl ChainExchangeResponse { self.chain .into_iter() .map(|i| { - T::try_from(i) - .map_err(|e| anyhow::anyhow!("failed to convert from tipset bundle: {e}")) + T::try_from(i).map_err(|e| e.into().context("failed to convert from tipset bundle")) }) .collect() } @@ -170,19 +169,18 @@ pub struct TipsetBundle { } impl TryFrom for Tipset { - type Error = String; + type Error = anyhow::Error; fn try_from(tsb: TipsetBundle) -> Result { - Tipset::new(tsb.blocks).map_err(|e| e.to_string()) + Ok(Tipset::new(tsb.blocks)?) } } impl TryFrom for CompactedMessages { - type Error = String; + type Error = anyhow::Error; fn try_from(tsb: TipsetBundle) -> Result { - tsb.messages - .ok_or_else(|| "Request contained no messages".to_string()) + tsb.messages.context("Request contained no messages") } } From a5e858c69263bf36c23c5c378dcef57a1c53a594 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Thu, 26 Mar 2026 04:34:20 +0800 Subject: [PATCH 3/4] resolve comments --- src/rpc/error.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rpc/error.rs b/src/rpc/error.rs index 93edbe4450fe..ec79eab527b9 100644 --- a/src/rpc/error.rs +++ b/src/rpc/error.rs @@ -98,14 +98,14 @@ impl From for ServerError { // Default implementation for anyhow::Error to handle downcasting once impl From for ServerError { - fn from(e: anyhow::Error) -> Self { + fn from(error: anyhow::Error) -> Self { // Try to downcast to known RpcErrorData implementations - if let Some(eth_error) = e.downcast_ref::() { + if let Some(eth_error) = error.downcast_ref::() { return eth_error.clone().into(); } - // Default fallback - Self::internal_error(format!("{e:#}"), None) + // Default fallback, not using `format!("{e:#}")` here to match Lotus error + Self::internal_error(error.to_string(), None) } } From 9361c91797abee8df10e9788f21c5b5910386558 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Thu, 26 Mar 2026 17:32:57 +0800 Subject: [PATCH 4/4] fix --- src/db/car/many.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/car/many.rs b/src/db/car/many.rs index 6a2f54484292..1db57933e6aa 100644 --- a/src/db/car/many.rs +++ b/src/db/car/many.rs @@ -136,7 +136,7 @@ impl ManyCar { file.as_ref(), )?)?) })() - .map_err(|e| anyhow::anyhow!("failed to load CAR at {}: {e}", file.as_ref().display())) + .with_context(|| format!("failed to load CAR at {}", file.as_ref().display())) } pub fn heaviest_tipset_key(&self) -> anyhow::Result> {