From d5ab85ccf5724c9c1dc52cd1e4a64f76447f2155 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 10 Jun 2026 11:02:35 +0800 Subject: [PATCH 1/4] fix: perfer `HashSet::contains` over `Vec::contains` in eth filters --- .clippy.toml | 8 +++ src/chain/store/base_fee.rs | 4 +- src/db/blockstore_with_write_buffer.rs | 2 +- src/interpreter/vm.rs | 4 +- src/lib.rs | 1 + src/libp2p_bitswap/request_manager.rs | 7 +-- src/message_pool/msgpool/republish.rs | 5 +- src/message_pool/msgpool/selection.rs | 2 +- src/rpc/auth_layer.rs | 2 +- src/rpc/methods/eth.rs | 4 +- src/rpc/methods/eth/filter/event.rs | 11 ++-- src/rpc/methods/eth/filter/mempool.rs | 6 +-- src/rpc/methods/eth/filter/mod.rs | 70 ++++++++++++++----------- src/rpc/methods/eth/filter/store.rs | 4 +- src/rpc/methods/eth/filter/tipset.rs | 6 +-- src/rpc/methods/eth/trace/geth.rs | 3 +- src/rpc/methods/eth/trace/state_diff.rs | 5 +- src/rpc/methods/eth/types.rs | 2 +- src/rpc/methods/eth/utils.rs | 6 +-- src/rpc/methods/mpool.rs | 4 +- src/rpc/methods/state.rs | 2 +- src/rpc/registry/actors_reg.rs | 7 ++- src/rpc/registry/methods_reg.rs | 6 +-- src/state_manager/message_search.rs | 3 +- src/tool/subcommands/api_cmd/report.rs | 7 ++- 25 files changed, 90 insertions(+), 91 deletions(-) diff --git a/.clippy.toml b/.clippy.toml index d23c5c6306ef..c6cef69a447b 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -9,6 +9,14 @@ path = "std::collections::HashSet" reason = """the standard library hasher is secure by default, but not very fast. use ahash::HashSet instead.""" +[[disallowed-types]] +path = "ahash::AHashMap" +reason = """use ahash::HashMap instead.""" + +[[disallowed-types]] +path = "ahash::AHashSet" +reason = """use ahash::HashSet instead.""" + # Banned in #2600, presumably so that poisoning won't need to be user-handled [[disallowed-types]] path = "std::sync::RwLock" diff --git a/src/chain/store/base_fee.rs b/src/chain/store/base_fee.rs index 6e618f324db3..534bc2e0a9b7 100644 --- a/src/chain/store/base_fee.rs +++ b/src/chain/store/base_fee.rs @@ -3,10 +3,10 @@ use crate::blocks::Tipset; use crate::message::MessageReadWrite; +use crate::prelude::*; use crate::shim::clock::ChainEpoch; use crate::shim::econ::{BLOCK_GAS_LIMIT, TokenAmount}; -use ahash::{HashSet, HashSetExt}; -use fvm_ipld_blockstore::Blockstore; +use ahash::HashSet; use super::weighted_quick_select::weighted_quick_select; diff --git a/src/db/blockstore_with_write_buffer.rs b/src/db/blockstore_with_write_buffer.rs index 2f050ef383bb..afb4b99acf60 100644 --- a/src/db/blockstore_with_write_buffer.rs +++ b/src/db/blockstore_with_write_buffer.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0, MIT use crate::prelude::*; -use ahash::{HashMap, HashMapExt}; +use ahash::HashMap; use parking_lot::RwLock; pub struct BlockstoreWithWriteBuffer { diff --git a/src/interpreter/vm.rs b/src/interpreter/vm.rs index 38c372734672..3e86a5c13f72 100644 --- a/src/interpreter/vm.rs +++ b/src/interpreter/vm.rs @@ -1,8 +1,6 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use std::sync::Arc; - use crate::blocks::Tipset; use crate::chain::block_messages; use crate::chain::index::ChainIndex; @@ -24,7 +22,7 @@ use crate::shim::{ state_tree::ActorState, version::NetworkVersion, }; -use ahash::{HashMap, HashMapExt, HashSet}; +use ahash::{HashMap, HashSet}; use anyhow::bail; use fvm_ipld_encoding::{RawBytes, to_vec}; use fvm_shared2::clock::ChainEpoch; diff --git a/src/lib.rs b/src/lib.rs index 90e8f24c2b47..5bfb5eb06a37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,6 +80,7 @@ mod prelude { db::Blockstore, utils::{ShallowClone, get_size::CidWrapper}, }; + pub use ahash::{HashMapExt as _, HashSetExt as _}; pub use anyhow::Context as _; pub use cid::Cid; pub use itertools::Itertools as _; diff --git a/src/libp2p_bitswap/request_manager.rs b/src/libp2p_bitswap/request_manager.rs index 5b84b8ea5f07..10604a190b34 100644 --- a/src/libp2p_bitswap/request_manager.rs +++ b/src/libp2p_bitswap/request_manager.rs @@ -4,14 +4,11 @@ //! Request manager implementation that is optimized for `filecoin` network //! usage -use std::{ - sync::Arc, - time::{Duration, Instant}, -}; +use std::time::{Duration, Instant}; use crate::cid_collections::CidHashMap; use crate::prelude::*; -use ahash::{HashSet, HashSetExt}; +use ahash::HashSet; use flume::TryRecvError; use futures::StreamExt; use libp2p::PeerId; diff --git a/src/message_pool/msgpool/republish.rs b/src/message_pool/msgpool/republish.rs index 7dd8fb92d249..651bc8245973 100644 --- a/src/message_pool/msgpool/republish.rs +++ b/src/message_pool/msgpool/republish.rs @@ -12,10 +12,9 @@ use crate::message_pool::{ provider::Provider, utils::get_base_fee_lower_bound, }; -use crate::prelude::ShallowClone; +use crate::prelude::*; use crate::shim::address::Address; -use ahash::{HashMap, HashMapExt, HashSet}; -use cid::Cid; +use ahash::{HashMap, HashSet}; use parking_lot::RwLock as SyncRwLock; const REPUB_TRIGGER_CAPACITY: usize = 1; diff --git a/src/message_pool/msgpool/selection.rs b/src/message_pool/msgpool/selection.rs index 180a8e475f07..66b8b6a345e7 100644 --- a/src/message_pool/msgpool/selection.rs +++ b/src/message_pool/msgpool/selection.rs @@ -23,7 +23,7 @@ use crate::shim::crypto::{Signature, SignatureType}; use crate::shim::{address::Address, econ::TokenAmount}; use crate::state_manager::IdToAddressCache; use crate::utils::cache::SizeTrackingCache; -use ahash::{HashMap, HashMapExt}; +use ahash::HashMap; use anyhow::{bail, ensure}; use rand::prelude::SliceRandom; use tracing::{debug, error, warn}; diff --git a/src/rpc/auth_layer.rs b/src/rpc/auth_layer.rs index 280354d96ca6..a52c0aa572a5 100644 --- a/src/rpc/auth_layer.rs +++ b/src/rpc/auth_layer.rs @@ -5,7 +5,7 @@ use crate::auth::{JWT_IDENTIFIER, verify_token}; use crate::key_management::KeyStore; use crate::prelude::*; use crate::rpc::{CANCEL_METHOD_NAME, Permission, RpcMethod as _, chain}; -use ahash::{HashMap, HashMapExt as _}; +use ahash::HashMap; use futures::future::Either; use http::{ HeaderMap, diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 0e319b7e36da..177b7dabdfcb 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -61,7 +61,7 @@ use crate::utils::encoding::from_slice_with_fallback; use crate::utils::get_size::big_int_heap_size_helper; use crate::utils::misc::env::env_or_default; use crate::utils::multihash::prelude::*; -use ahash::HashSet; +use ahash::{HashMap, HashSet}; use anyhow::{Error, Result, anyhow, bail, ensure}; use enumflags2::{BitFlags, make_bitflags}; use filter::{ParsedFilter, ParsedFilterTipsets}; @@ -3168,8 +3168,6 @@ fn eth_filter_logs_from_events( ctx: &Ctx, events: &[CollectedEvent], ) -> anyhow::Result> { - use ahash::AHashMap as HashMap; - let chain_id = ctx.state_manager.chain_config().eth_chain_id; let mut tx_hash_by_msg: HashMap = HashMap::new(); let mut block_hash_by_tipset: HashMap = HashMap::new(); diff --git a/src/rpc/methods/eth/filter/event.rs b/src/rpc/methods/eth/filter/event.rs index 45b49ee2732a..6bfb6f215607 100644 --- a/src/rpc/methods/eth/filter/event.rs +++ b/src/rpc/methods/eth/filter/event.rs @@ -1,16 +1,15 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use crate::rpc::Arc; +use crate::prelude::*; use crate::rpc::eth::filter::{ActorEventBlock, ParsedFilter, ParsedFilterTipsets}; use crate::rpc::eth::{CollectedEvent, FilterID, filter::Filter}; use crate::shim::address::Address; -use ahash::AHashMap as HashMap; -use anyhow::{Context, Result}; +use ahash::{HashMap, HashSet}; +use anyhow::Result; use parking_lot::RwLock; use std::any::Any; -#[allow(dead_code)] #[derive(Debug, PartialEq)] pub struct EventFilter { // Unique id used to identify the filter @@ -18,7 +17,7 @@ pub struct EventFilter { // Tipsets to filter pub tipsets: ParsedFilterTipsets, // list of actor addresses that are extpected to emit the event - pub addresses: Vec
, + pub addresses: HashSet
, // Map of key names to a list of alternate values that may match pub keys_with_codec: HashMap>, // Maximum number of results to collect @@ -101,7 +100,7 @@ mod tests { let parsed_filter = ParsedFilter { tipsets: ParsedFilterTipsets::Range(RangeInclusive::new(0, 100)), - addresses: vec![Address::new_id(123)], + addresses: HashSet::from_iter([Address::new_id(123)]), keys: HashMap::new(), msg_cid: None, }; diff --git a/src/rpc/methods/eth/filter/mempool.rs b/src/rpc/methods/eth/filter/mempool.rs index 1c2e11c75d28..885979814432 100644 --- a/src/rpc/methods/eth/filter/mempool.rs +++ b/src/rpc/methods/eth/filter/mempool.rs @@ -1,11 +1,11 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use crate::rpc::Arc; +use crate::prelude::*; use crate::rpc::eth::{FilterID, filter::Filter, filter::FilterManager}; use crate::shim::fvm_shared_latest::clock::ChainEpoch; -use ahash::AHashMap as HashMap; -use anyhow::{Context, Result}; +use ahash::HashMap; +use anyhow::Result; use parking_lot::RwLock; use std::any::Any; diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index ce7fed6e4dbd..faf8758df94c 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -45,7 +45,7 @@ use crate::state_manager::StateManager; use crate::state_manager::{ExecutedMessage, ExecutedTipset}; use crate::utils::misc::env::env_or_default; use crate::utils::task::AbortHandles; -use ahash::AHashMap as HashMap; +use ahash::{HashMap, HashSet}; use anyhow::{Error, anyhow, bail, ensure}; use futures::{TryStreamExt as _, stream::FuturesOrdered}; use fvm_ipld_encoding::IPLD_RAW; @@ -538,22 +538,22 @@ impl EthFilterSpec { ParsedFilterTipsets::Range(RangeInclusive::new(min, max)) }; - let addresses: Vec<_> = if let Some(ref address_list) = self.address { + let addresses = if let Some(ref address_list) = self.address { address_list .iter() .map(|ea| { ea.to_filecoin_address() .map_err(|e| anyhow!("invalid address {}", e)) }) - .collect::, _>>()? + .collect::, _>>()? } else { - vec![] + Default::default() }; let keys = if let Some(topics) = &self.topics { keys_to_keys_with_codec(parse_eth_topics(topics)?) } else { - HashMap::new() + Default::default() }; Ok(ParsedFilter { @@ -593,7 +593,7 @@ impl Matcher for EthFilterSpec { if let Some(slice) = get_word(entry.value()) { let hash: EthHash = (*slice).into(); match spec.0.get(i) { - Some(EthHashList::List(vec)) => vec.contains(&hash), + Some(EthHashList::List(set)) => set.contains(&hash), Some(EthHashList::Single(Some(h))) => h == &hash, _ => true, /* wildcard */ } @@ -738,7 +738,7 @@ pub enum ParsedFilterTipsets { #[derive(Debug)] pub struct ParsedFilter { pub(crate) tipsets: ParsedFilterTipsets, - pub(crate) addresses: Vec
, + pub(crate) addresses: HashSet
, pub(crate) keys: HashMap>, /// When set, only events emitted by this message CID are returned. Mirrors /// Lotus's `index.EventFilter.MsgCid`: @@ -751,8 +751,8 @@ impl ParsedFilter { pub fn new_with_tipset(tipsets: ParsedFilterTipsets) -> Self { ParsedFilter { tipsets, - addresses: vec![], - keys: HashMap::new(), + addresses: Default::default(), + keys: Default::default(), msg_cid: None, } } @@ -760,8 +760,8 @@ impl ParsedFilter { pub fn new_with_tipset_and_msg(tipsets: ParsedFilterTipsets, msg_cid: Option) -> Self { ParsedFilter { tipsets, - addresses: vec![], - keys: HashMap::new(), + addresses: Default::default(), + keys: Default::default(), msg_cid, } } @@ -782,7 +782,7 @@ impl ParsedFilter { ParsedFilterTipsets::Range(RangeInclusive::new(min, max)) }; - let addresses: Vec<_> = filter.addresses.iter().map(|addr| addr.0).collect(); + let addresses: HashSet<_> = filter.addresses.iter().map(|addr| addr.0).collect(); let mut keys: HashMap> = Default::default(); for (k, v) in filter.fields.into_iter() { @@ -854,13 +854,11 @@ impl Matcher for EventFilter { #[cfg(test)] mod tests { - use ahash::AHashMap; + use super::*; + use crate::rpc::eth::{EthAddress, EthFilterSpec, EthTopicSpec}; use base64::{Engine, prelude::BASE64_STANDARD}; use fvm_ipld_encoding::DAG_CBOR; use fvm_shared4::event::Flags; - - use super::*; - use crate::rpc::eth::{EthAddress, EthFilterSpec, EthTopicSpec}; use std::str::FromStr; #[test] @@ -1247,7 +1245,9 @@ mod tests { #[test] fn test_parse_eth_topics() { - let topics = EthTopicSpec(vec![EthHashList::List(vec![EthHash::default()])]); + let topics = EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ + EthHash::default(), + ]))]); let actual = parse_eth_topics(&topics).expect("Failed to parse topics"); let mut expected = HashMap::with_capacity(4); @@ -1490,14 +1490,18 @@ mod tests { assert!(spec2.matches(&addr0, &entries0).unwrap()); let spec3 = EthFilterSpec { - topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic0])])), + topics: Some(EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ + topic0, + ]))])), ..Default::default() }; assert!(spec3.matches(&addr0, &entries0).unwrap()); let spec4 = EthFilterSpec { - topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic1, topic0])])), + topics: Some(EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ + topic1, topic0, + ]))])), ..Default::default() }; @@ -1511,7 +1515,9 @@ mod tests { assert!(!spec5.matches(&addr0, &entries0).unwrap()); let spec6 = EthFilterSpec { - topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic2, topic3])])), + topics: Some(EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ + topic2, topic3, + ]))])), ..Default::default() }; @@ -1546,7 +1552,7 @@ mod tests { let empty_filter = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![], + addresses: Default::default(), keys: Default::default(), msg_cid: None, }; @@ -1590,7 +1596,7 @@ mod tests { // Matching the given address 0 let filter0 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![addr0], + addresses: HashSet::from_iter([addr0]), keys: Default::default(), msg_cid: None, }; @@ -1602,7 +1608,7 @@ mod tests { // Matching the given address 0 or 1 let filter1 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![addr0, addr1], + addresses: HashSet::from_iter([addr0, addr1]), keys: Default::default(), msg_cid: None, }; @@ -1648,14 +1654,14 @@ mod tests { let empty_filter = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![], + addresses: Default::default(), keys: Default::default(), msg_cid: None, }; assert!(empty_filter.matches(&addr0, &entries0).unwrap()); - let mut keys: AHashMap> = Default::default(); + let mut keys: HashMap> = Default::default(); keys.insert( "t1".into(), vec![ActorEventBlock { @@ -1668,14 +1674,14 @@ mod tests { let filter1 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![], + addresses: Default::default(), keys, msg_cid: None, }; assert!(filter1.matches(&addr0, &entries0).unwrap()); - let mut keys: AHashMap> = Default::default(); + let mut keys: HashMap> = Default::default(); keys.insert( "t1".into(), vec![ActorEventBlock { @@ -1688,14 +1694,14 @@ mod tests { let filter2 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![], + addresses: Default::default(), keys, msg_cid: None, }; assert!(!filter2.matches(&addr0, &entries0).unwrap()); - let mut keys: AHashMap> = Default::default(); + let mut keys: HashMap> = Default::default(); keys.insert( "t1".into(), vec![ActorEventBlock { @@ -1708,14 +1714,14 @@ mod tests { let filter2 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![], + addresses: Default::default(), keys, msg_cid: None, }; assert!(!filter2.matches(&addr0, &entries0).unwrap()); - let mut keys: AHashMap> = Default::default(); + let mut keys: HashMap> = Default::default(); keys.insert( "t1".into(), vec![ActorEventBlock { @@ -1737,7 +1743,7 @@ mod tests { let filter3 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: vec![], + addresses: Default::default(), keys, msg_cid: None, }; diff --git a/src/rpc/methods/eth/filter/store.rs b/src/rpc/methods/eth/filter/store.rs index 5ff3e2c30d77..fca935bc9f84 100644 --- a/src/rpc/methods/eth/filter/store.rs +++ b/src/rpc/methods/eth/filter/store.rs @@ -1,9 +1,9 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use crate::rpc::Arc; +use crate::prelude::*; use crate::rpc::eth::FilterID; -use ahash::AHashMap as HashMap; +use ahash::HashMap; use anyhow::Result; use anyhow::anyhow; use parking_lot::RwLock; diff --git a/src/rpc/methods/eth/filter/tipset.rs b/src/rpc/methods/eth/filter/tipset.rs index c65e0d2d3a8f..4a2e5d51c2a3 100644 --- a/src/rpc/methods/eth/filter/tipset.rs +++ b/src/rpc/methods/eth/filter/tipset.rs @@ -1,11 +1,11 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use crate::rpc::Arc; +use crate::prelude::*; use crate::rpc::eth::{FilterID, filter::Filter, filter::FilterManager}; use crate::shim::fvm_shared_latest::clock::ChainEpoch; -use ahash::AHashMap as HashMap; -use anyhow::{Context, Result}; +use ahash::HashMap; +use anyhow::Result; use parking_lot::RwLock; use std::any::Any; diff --git a/src/rpc/methods/eth/trace/geth.rs b/src/rpc/methods/eth/trace/geth.rs index 3b31ad6536df..01b0991f65b3 100644 --- a/src/rpc/methods/eth/trace/geth.rs +++ b/src/rpc/methods/eth/trace/geth.rs @@ -20,13 +20,13 @@ use super::types::{ }; use super::utils::{ZERO_HASH, trace_to_address, u256_to_eth_hash}; use crate::eth::EAMMethod; +use crate::prelude::*; use crate::rpc::state::ExecutionTrace; use crate::shim::actors::is_evm_actor; use crate::shim::address::Address; use crate::shim::state_tree::{ActorState, StateTree}; use ahash::{HashMap, HashSet}; use fil_actor_evm_state::evm_shared::v17::uints::U256; -use fvm_ipld_blockstore::Blockstore; use num::FromPrimitive as _; use std::collections::BTreeMap; @@ -267,7 +267,6 @@ mod tests { use super::super::types::{PreStateConfig, PreStateFrame}; use super::*; use crate::rpc::eth::{EthBigInt, EthUint64}; - use ahash::HashSetExt as _; use num::BigInt; #[test] diff --git a/src/rpc/methods/eth/trace/state_diff.rs b/src/rpc/methods/eth/trace/state_diff.rs index 1033c67e5cde..3eefb669e5b7 100644 --- a/src/rpc/methods/eth/trace/state_diff.rs +++ b/src/rpc/methods/eth/trace/state_diff.rs @@ -11,12 +11,11 @@ use super::super::types::{EthAddress, EthHash}; use super::super::utils::ActorStateEthExt as _; use super::types::{AccountDiff, ChangedType, Delta, StateDiff}; use super::utils::{ZERO_HASH, u256_to_eth_hash}; +use crate::prelude::*; 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}; use std::borrow::Cow; use std::collections::BTreeMap; @@ -278,9 +277,7 @@ mod tests { use crate::rpc::eth::types::EthBytes; use crate::shim::address::Address as FilecoinAddress; use crate::shim::state_tree::StateTreeVersion; - use ahash::HashSetExt as _; use num::BigInt; - use std::sync::Arc; #[test] fn test_build_state_diff_empty_touched_addresses() { diff --git a/src/rpc/methods/eth/types.rs b/src/rpc/methods/eth/types.rs index df380c1d9c9a..9a9be3170aa7 100644 --- a/src/rpc/methods/eth/types.rs +++ b/src/rpc/methods/eth/types.rs @@ -488,7 +488,7 @@ impl IdProvider for RandomHexStringIdProvider { #[derive(PartialEq, Serialize, Deserialize, Debug, Clone, JsonSchema)] #[serde(untagged)] pub enum EthHashList { - List(Vec), + List(HashSet), Single(Option), } diff --git a/src/rpc/methods/eth/utils.rs b/src/rpc/methods/eth/utils.rs index 8e2a1c252753..2e21100fc989 100644 --- a/src/rpc/methods/eth/utils.rs +++ b/src/rpc/methods/eth/utils.rs @@ -2,18 +2,18 @@ // SPDX-License-Identifier: Apache-2.0, MIT use super::types::{EthAddress, EthBytes}; +use crate::prelude::*; use crate::rpc::state::{MessageTrace, ReturnTrace}; use crate::shim::actors::{EVMActorStateLoad as _, evm, is_evm_actor}; use crate::shim::address::Address as FilecoinAddress; use crate::shim::fvm_shared_latest::IDENTITY_HASH; use crate::shim::state_tree::{ActorState, StateTree}; -use ahash::{HashMap, HashMapExt}; +use ahash::HashMap; use crate::rpc::eth::{EVM_WORD_LENGTH, EthUint64}; -use anyhow::{Context as _, Result, bail}; +use anyhow::{Result, bail}; use cbor4ii::core::Value; use cbor4ii::core::dec::Decode as _; -use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::{CBOR, DAG_CBOR, IPLD_RAW, RawBytes}; use serde::de; use std::sync::LazyLock; diff --git a/src/rpc/methods/mpool.rs b/src/rpc/methods/mpool.rs index 7ff6a30b5789..cebd11d72d16 100644 --- a/src/rpc/methods/mpool.rs +++ b/src/rpc/methods/mpool.rs @@ -4,6 +4,7 @@ use super::gas::estimate_message_gas; use crate::lotus_json::{LotusJson, NotNullVec, lotus_json_with_self}; use crate::message::SignedMessage; +use crate::prelude::*; use crate::rpc::error::ServerError; use crate::rpc::types::{ApiTipsetKey, MessageSendSpec}; use crate::rpc::{ApiPaths, Ctx, Permission, RpcMethod}; @@ -12,8 +13,7 @@ use crate::shim::{ message::Message, percent::Percent, }; -use ahash::{HashSet, HashSetExt as _}; -use cid::Cid; +use ahash::HashSet; use enumflags2::BitFlags; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/src/rpc/methods/state.rs b/src/rpc/methods/state.rs index 1a3f45b0181a..236119e6ff62 100644 --- a/src/rpc/methods/state.rs +++ b/src/rpc/methods/state.rs @@ -51,7 +51,7 @@ use crate::{ beacon::BeaconEntry, rpc::{ApiPaths, Ctx, Permission, RpcMethod, ServerError, types::*}, }; -use ahash::{HashMap, HashMapExt, HashSet}; +use ahash::{HashMap, HashSet}; use anyhow::Result; use enumflags2::{BitFlags, make_bitflags}; use fil_actor_miner_state::v10::{qa_power_for_weight, qa_power_max}; diff --git a/src/rpc/registry/actors_reg.rs b/src/rpc/registry/actors_reg.rs index fb81de3269ad..04023fa30cff 100644 --- a/src/rpc/registry/actors_reg.rs +++ b/src/rpc/registry/actors_reg.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0, MIT use crate::lotus_json::HasLotusJson; use crate::networks::ACTOR_BUNDLES_METADATA; +use crate::prelude::*; use crate::shim::actors::{ AccountActorStateLoad, CronActorStateLoad, DataCapActorStateLoad, EVMActorStateLoad, InitActorStateLoad, MarketActorStateLoad, MinerActorStateLoad, MultisigActorStateLoad, @@ -10,11 +11,9 @@ use crate::shim::actors::{ paymentchannel, power, reward, system, verifreg, }; use crate::shim::machine::BuiltinActor; -use ahash::{HashMap, HashMapExt}; -use anyhow::{Context, Result, anyhow}; -use cid::Cid; +use ahash::HashMap; +use anyhow::{Result, anyhow}; use fil_actors_shared::actor_versions::ActorVersion; -use fvm_ipld_blockstore::Blockstore; use serde_json::Value; use std::sync::LazyLock; diff --git a/src/rpc/registry/methods_reg.rs b/src/rpc/registry/methods_reg.rs index d96c759482ba..169d11ea629d 100644 --- a/src/rpc/registry/methods_reg.rs +++ b/src/rpc/registry/methods_reg.rs @@ -2,12 +2,12 @@ // SPDX-License-Identifier: Apache-2.0, MIT use crate::lotus_json::HasLotusJson; +use crate::prelude::*; use crate::rpc::registry::actors_reg::{ACTOR_REGISTRY, ActorRegistry}; use crate::shim::machine::BuiltinActor; use crate::shim::message::MethodNum; -use ahash::{HashMap, HashMapExt}; -use anyhow::{Context, Result, bail}; -use cid::Cid; +use ahash::HashMap; +use anyhow::{Result, bail}; use fil_actors_shared::v11::runtime::builtins::Type; use serde::de::DeserializeOwned; use serde_json::Value; diff --git a/src/state_manager/message_search.rs b/src/state_manager/message_search.rs index c8231a80c093..5f06615ccb2e 100644 --- a/src/state_manager/message_search.rs +++ b/src/state_manager/message_search.rs @@ -4,8 +4,7 @@ use super::*; use crate::blocks::TipsetKey; use crate::message::MessageRead as _; -use ahash::{HashMap, HashMapExt as _}; -use anyhow::Context as _; +use ahash::HashMap; use futures::{FutureExt, channel::oneshot, select}; use tokio::sync::{RwLock, broadcast::error::RecvError}; use tracing::warn; diff --git a/src/tool/subcommands/api_cmd/report.rs b/src/tool/subcommands/api_cmd/report.rs index e7a8a38e110c..f40cf987151a 100644 --- a/src/tool/subcommands/api_cmd/report.rs +++ b/src/tool/subcommands/api_cmd/report.rs @@ -2,12 +2,11 @@ // SPDX-License-Identifier: Apache-2.0, MIT use super::ReportMode; -use crate::rpc; -use crate::rpc::{FilterList, Permission}; +use crate::prelude::*; +use crate::rpc::{self, FilterList, Permission}; use crate::tool::subcommands::api_cmd::api_compare_tests::TestSummary; -use ahash::{HashMap, HashMapExt, HashSet, HashSetExt}; +use ahash::{HashMap, HashSet}; use chrono::{DateTime, Utc}; -use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_with::{DisplayFromStr, DurationMilliSeconds, DurationSeconds, serde_as}; use similar::{ChangeTag, TextDiff}; From 6a08eadad39f5e4dcdce6381fb5158fe2c6d1ac7 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 10 Jun 2026 13:11:13 +0800 Subject: [PATCH 2/4] fix insta tests --- src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap | 1 + src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap | 1 + src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap | 1 + 3 files changed, 3 insertions(+) diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap index ae8bde5fcb6e..da86bf239b41 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap @@ -5784,6 +5784,7 @@ components: - type: array items: $ref: "#/components/schemas/EthHash" + uniqueItems: true - anyOf: - $ref: "#/components/schemas/EthHash" - type: "null" diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap index d69ca5921eb3..99ba83c2bf5d 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap @@ -5874,6 +5874,7 @@ components: - type: array items: $ref: "#/components/schemas/EthHash" + uniqueItems: true - anyOf: - $ref: "#/components/schemas/EthHash" - type: "null" diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap index df3a185f000f..a8dad5d85172 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap @@ -2337,6 +2337,7 @@ components: - type: array items: $ref: "#/components/schemas/EthHash" + uniqueItems: true - anyOf: - $ref: "#/components/schemas/EthHash" - type: "null" From c488a0e23e361920dda888e635711b27a9dc0091 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 10 Jun 2026 18:01:42 +0800 Subject: [PATCH 3/4] revert vec->set change --- src/rpc/methods/eth/filter/event.rs | 6 +++--- src/rpc/methods/eth/filter/mod.rs | 30 +++++++++++------------------ src/rpc/methods/eth/types.rs | 2 +- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/rpc/methods/eth/filter/event.rs b/src/rpc/methods/eth/filter/event.rs index 6bfb6f215607..605ba069c949 100644 --- a/src/rpc/methods/eth/filter/event.rs +++ b/src/rpc/methods/eth/filter/event.rs @@ -5,7 +5,7 @@ use crate::prelude::*; use crate::rpc::eth::filter::{ActorEventBlock, ParsedFilter, ParsedFilterTipsets}; use crate::rpc::eth::{CollectedEvent, FilterID, filter::Filter}; use crate::shim::address::Address; -use ahash::{HashMap, HashSet}; +use ahash::HashMap; use anyhow::Result; use parking_lot::RwLock; use std::any::Any; @@ -17,7 +17,7 @@ pub struct EventFilter { // Tipsets to filter pub tipsets: ParsedFilterTipsets, // list of actor addresses that are extpected to emit the event - pub addresses: HashSet
, + pub addresses: Vec
, // Map of key names to a list of alternate values that may match pub keys_with_codec: HashMap>, // Maximum number of results to collect @@ -100,7 +100,7 @@ mod tests { let parsed_filter = ParsedFilter { tipsets: ParsedFilterTipsets::Range(RangeInclusive::new(0, 100)), - addresses: HashSet::from_iter([Address::new_id(123)]), + addresses: vec![Address::new_id(123)], keys: HashMap::new(), msg_cid: None, }; diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index faf8758df94c..b97a14bf7a36 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -45,7 +45,7 @@ use crate::state_manager::StateManager; use crate::state_manager::{ExecutedMessage, ExecutedTipset}; use crate::utils::misc::env::env_or_default; use crate::utils::task::AbortHandles; -use ahash::{HashMap, HashSet}; +use ahash::HashMap; use anyhow::{Error, anyhow, bail, ensure}; use futures::{TryStreamExt as _, stream::FuturesOrdered}; use fvm_ipld_encoding::IPLD_RAW; @@ -545,7 +545,7 @@ impl EthFilterSpec { ea.to_filecoin_address() .map_err(|e| anyhow!("invalid address {}", e)) }) - .collect::, _>>()? + .collect::, _>>()? } else { Default::default() }; @@ -593,7 +593,7 @@ impl Matcher for EthFilterSpec { if let Some(slice) = get_word(entry.value()) { let hash: EthHash = (*slice).into(); match spec.0.get(i) { - Some(EthHashList::List(set)) => set.contains(&hash), + Some(EthHashList::List(vec)) => vec.contains(&hash), Some(EthHashList::Single(Some(h))) => h == &hash, _ => true, /* wildcard */ } @@ -738,7 +738,7 @@ pub enum ParsedFilterTipsets { #[derive(Debug)] pub struct ParsedFilter { pub(crate) tipsets: ParsedFilterTipsets, - pub(crate) addresses: HashSet
, + pub(crate) addresses: Vec
, pub(crate) keys: HashMap>, /// When set, only events emitted by this message CID are returned. Mirrors /// Lotus's `index.EventFilter.MsgCid`: @@ -782,7 +782,7 @@ impl ParsedFilter { ParsedFilterTipsets::Range(RangeInclusive::new(min, max)) }; - let addresses: HashSet<_> = filter.addresses.iter().map(|addr| addr.0).collect(); + let addresses = filter.addresses.iter().map(|addr| addr.0).collect_vec(); let mut keys: HashMap> = Default::default(); for (k, v) in filter.fields.into_iter() { @@ -1245,9 +1245,7 @@ mod tests { #[test] fn test_parse_eth_topics() { - let topics = EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ - EthHash::default(), - ]))]); + let topics = EthTopicSpec(vec![EthHashList::List(vec![EthHash::default()])]); let actual = parse_eth_topics(&topics).expect("Failed to parse topics"); let mut expected = HashMap::with_capacity(4); @@ -1490,18 +1488,14 @@ mod tests { assert!(spec2.matches(&addr0, &entries0).unwrap()); let spec3 = EthFilterSpec { - topics: Some(EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ - topic0, - ]))])), + topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic0])])), ..Default::default() }; assert!(spec3.matches(&addr0, &entries0).unwrap()); let spec4 = EthFilterSpec { - topics: Some(EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ - topic1, topic0, - ]))])), + topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic1, topic0])])), ..Default::default() }; @@ -1515,9 +1509,7 @@ mod tests { assert!(!spec5.matches(&addr0, &entries0).unwrap()); let spec6 = EthFilterSpec { - topics: Some(EthTopicSpec(vec![EthHashList::List(HashSet::from_iter([ - topic2, topic3, - ]))])), + topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic2, topic3])])), ..Default::default() }; @@ -1596,7 +1588,7 @@ mod tests { // Matching the given address 0 let filter0 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: HashSet::from_iter([addr0]), + addresses: vec![addr0], keys: Default::default(), msg_cid: None, }; @@ -1608,7 +1600,7 @@ mod tests { // Matching the given address 0 or 1 let filter1 = ParsedFilter { tipsets: ParsedFilterTipsets::Range(0..=0), - addresses: HashSet::from_iter([addr0, addr1]), + addresses: vec![addr0, addr1], keys: Default::default(), msg_cid: None, }; diff --git a/src/rpc/methods/eth/types.rs b/src/rpc/methods/eth/types.rs index 9a9be3170aa7..df380c1d9c9a 100644 --- a/src/rpc/methods/eth/types.rs +++ b/src/rpc/methods/eth/types.rs @@ -488,7 +488,7 @@ impl IdProvider for RandomHexStringIdProvider { #[derive(PartialEq, Serialize, Deserialize, Debug, Clone, JsonSchema)] #[serde(untagged)] pub enum EthHashList { - List(HashSet), + List(Vec), Single(Option), } From 59b080197eaddb40cd78fa8b561b60034e3d6c0d Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 10 Jun 2026 18:11:45 +0800 Subject: [PATCH 4/4] fix insta tests --- src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap | 1 - src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap | 1 - src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap | 1 - 3 files changed, 3 deletions(-) diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap index da86bf239b41..ae8bde5fcb6e 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap @@ -5784,7 +5784,6 @@ components: - type: array items: $ref: "#/components/schemas/EthHash" - uniqueItems: true - anyOf: - $ref: "#/components/schemas/EthHash" - type: "null" diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap index 99ba83c2bf5d..d69ca5921eb3 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap @@ -5874,7 +5874,6 @@ components: - type: array items: $ref: "#/components/schemas/EthHash" - uniqueItems: true - anyOf: - $ref: "#/components/schemas/EthHash" - type: "null" diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap index a8dad5d85172..df3a185f000f 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap @@ -2337,7 +2337,6 @@ components: - type: array items: $ref: "#/components/schemas/EthHash" - uniqueItems: true - anyOf: - $ref: "#/components/schemas/EthHash" - type: "null"