diff --git a/Cargo.lock b/Cargo.lock index 18b4c1da40ea4..c3af8e1618c70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2140,17 +2140,6 @@ dependencies = [ "constant_time_eq 0.3.0", ] -[[package]] -name = "blake2s_simd" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" -dependencies = [ - "arrayref", - "arrayvec 0.7.6", - "constant_time_eq 0.2.6", -] - [[package]] name = "blake3" version = "1.5.4" @@ -3265,19 +3254,6 @@ dependencies = [ "half", ] -[[package]] -name = "cid" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b68e3193982cd54187d71afdb2a271ad4cf8af157858e9cb911b91321de143" -dependencies = [ - "core2", - "multibase", - "multihash 0.17.0", - "serde", - "unsigned-varint 0.7.2", -] - [[package]] name = "cid" version = "0.11.1" @@ -3723,12 +3699,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "constant_time_eq" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" - [[package]] name = "constant_time_eq" version = "0.3.0" @@ -10050,14 +10020,14 @@ checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "litep2p" -version = "0.12.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1da54ffe750994080fe48ccf5dd298a528406b26b3b544032ae9505ff4d7cbea" +checksum = "bcda6c1f442def15b5e73228ebf669e36f4f7d9d154a0b0190d43a29c4cbeadf" dependencies = [ "async-trait", "bs58", "bytes", - "cid 0.11.1", + "cid", "ed25519-dalek", "enum-display", "futures", @@ -10610,13 +10580,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" dependencies = [ "blake2b_simd", - "blake2s_simd", - "blake3", "core2", "digest 0.10.7", "multihash-derive", "sha2 0.10.9", - "sha3", "unsigned-varint 0.7.2", ] @@ -20476,7 +20443,7 @@ dependencies = [ "async-trait", "asynchronous-codec 0.6.2", "bytes", - "cid 0.9.0", + "cid", "criterion", "either", "fnv", @@ -21956,9 +21923,9 @@ dependencies = [ [[package]] name = "simple-dns" -version = "0.9.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee851d0e5e7af3721faea1843e8015e820a234f81fda3dea9247e15bac9a86a" +checksum = "f8cba3b4c122239e3b4473674cb7c79ad2693f008f0746bfe2fc3fe1ffcd936a" dependencies = [ "bitflags 2.9.4", ] diff --git a/Cargo.toml b/Cargo.toml index c83e57fdae3a3..054f8ed0f46e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -723,7 +723,7 @@ cfg-if = { version = "1.0" } chain-spec-builder = { path = "substrate/bin/utils/chain-spec-builder", default-features = false, package = "staging-chain-spec-builder" } chain-spec-guide-runtime = { path = "docs/sdk/src/reference_docs/chain_spec_runtime" } chrono = { version = "0.4.31" } -cid = { version = "0.9.0" } +cid = { version = "0.11.1" } clap = { version = "4.5.13" } clap_complete = { version = "4.5.13" } cmd_lib = { version = "1.9.5" } @@ -906,7 +906,7 @@ linked-hash-map = { version = "0.5.4" } linked_hash_set = { version = "0.1.4" } linregress = { version = "0.5.1" } lite-json = { version = "0.2.0", default-features = false } -litep2p = { version = "0.12.0", features = ["rsa", "websocket"] } +litep2p = { version = "0.12.2", features = ["rsa", "websocket"] } log = { version = "0.4.22", default-features = false } macro_magic = { version = "0.5.1" } maplit = { version = "1.0.2" } diff --git a/prdoc/pr_10416.prdoc b/prdoc/pr_10416.prdoc new file mode 100644 index 0000000000000..6a8682b0b5c36 --- /dev/null +++ b/prdoc/pr_10416.prdoc @@ -0,0 +1,10 @@ +title: 'Added CID filtering to Bitswap server' +doc: +- audience: Node Dev + description: |- + This PR adds CID (Content Identifier) validation and filtering to the Bitswap server + implementation. The server now validates incoming CID requests before processing them. + +crates: +- name: sc-network + bump: minor diff --git a/substrate/client/network/Cargo.toml b/substrate/client/network/Cargo.toml index 70c2c59d5541f..15bb9ff87b2be 100644 --- a/substrate/client/network/Cargo.toml +++ b/substrate/client/network/Cargo.toml @@ -30,7 +30,6 @@ async-channel = { workspace = true } async-trait = { workspace = true } asynchronous-codec = { workspace = true } bytes = { workspace = true, default-features = true } -cid = { workspace = true } codec = { features = ["derive"], workspace = true, default-features = true } either = { workspace = true, default-features = true } fnv = { workspace = true } @@ -70,6 +69,7 @@ zeroize = { workspace = true, default-features = true } [dev-dependencies] assert_matches = { workspace = true } +cid = { workspace = true } multistream-select = { workspace = true } sc-block-builder = { workspace = true, default-features = true } sp-consensus = { workspace = true, default-features = true } diff --git a/substrate/client/network/src/bitswap/mod.rs b/substrate/client/network/src/bitswap/mod.rs index 36c32b4b059eb..80f99432283b8 100644 --- a/substrate/client/network/src/bitswap/mod.rs +++ b/substrate/client/network/src/bitswap/mod.rs @@ -27,8 +27,8 @@ use crate::{ MAX_RESPONSE_SIZE, }; -use cid::{self, Version}; use futures::StreamExt; +use litep2p::types::cid::{Cid, Error as CidError, Version as CidVersion}; use log::{debug, error, trace}; use prost::Message; use sc_client_api::BlockBackend; @@ -60,11 +60,16 @@ const MAX_WANTED_BLOCKS: usize = 16; /// Bitswap protocol name const PROTOCOL_NAME: &'static str = "/ipfs/bitswap/1.2.0"; +/// Check if a CID is supported by the bitswap protocol. +pub fn is_cid_supported(cid: &Cid) -> bool { + cid.version() != CidVersion::V0 && cid.hash().size() == 32 +} + /// Prefix represents all metadata of a CID, without the actual content. #[derive(PartialEq, Eq, Clone, Debug)] struct Prefix { /// The version of CID. - pub version: Version, + pub version: CidVersion, /// The codec of CID. pub codec: u64, /// The multihash type of CID. @@ -189,7 +194,7 @@ impl BitswapRequestHandler { } for entry in wantlist.entries { - let cid = match cid::Cid::read_bytes(entry.block.as_slice()) { + let cid = match Cid::read_bytes(entry.block.as_slice()) { Ok(cid) => cid, Err(e) => { trace!(target: LOG_TARGET, "Bad CID {:?}: {:?}", entry.block, e); @@ -197,11 +202,8 @@ impl BitswapRequestHandler { }, }; - if cid.version() != cid::Version::V1 || - cid.hash().code() != u64::from(cid::multihash::Code::Blake2b256) || - cid.hash().size() != 32 - { - debug!(target: LOG_TARGET, "Ignoring unsupported CID {}: {}", peer, cid); + if !is_cid_supported(&cid) { + trace!(target: LOG_TARGET, "Ignoring unsupported CID {}: {}", peer, cid); continue } @@ -270,7 +272,7 @@ pub enum BitswapError { /// Error parsing CID #[error(transparent)] - BadCid(#[from] cid::Error), + BadCid(#[from] CidError), /// Packet read error. #[error(transparent)] @@ -293,6 +295,7 @@ pub enum BitswapError { mod tests { use super::*; use futures::channel::oneshot; + use litep2p::types::multihash::Code; use sc_block_builder::BlockBuilderBuilder; use schema::bitswap::{ message::{wantlist::Entry, Wantlist}, @@ -441,7 +444,7 @@ mod tests { block: cid::Cid::new_v1( 0x70, cid::multihash::Multihash::wrap( - u64::from(cid::multihash::Code::Blake2b256), + u64::from(Code::Blake2b256), &[0u8; 32], ) .unwrap(), @@ -502,7 +505,7 @@ mod tests { block: cid::Cid::new_v1( 0x70, cid::multihash::Multihash::wrap( - u64::from(cid::multihash::Code::Blake2b256), + u64::from(Code::Blake2b256), &sp_crypto_hashing::blake2_256(&ext.encode()[pattern_index..]), ) .unwrap(), diff --git a/substrate/client/network/src/litep2p/shim/bitswap.rs b/substrate/client/network/src/litep2p/shim/bitswap.rs index d347317ae9f98..66a54e0b005f2 100644 --- a/substrate/client/network/src/litep2p/shim/bitswap.rs +++ b/substrate/client/network/src/litep2p/shim/bitswap.rs @@ -18,6 +18,7 @@ //! Shim for litep2p's Bitswap implementation to make it work with `sc-network`. +use crate::bitswap::is_cid_supported; use futures::StreamExt; use litep2p::protocol::libp2p::bitswap::{ BitswapEvent, BitswapHandle, BlockPresenceType, Config, ResponseType, WantType, @@ -60,6 +61,7 @@ impl BitswapServer { let response: Vec = cids .into_iter() + .filter(|(cid, _)| is_cid_supported(&cid)) .map(|(cid, want_type)| { let mut hash = Block::Hash::default(); hash.as_mut().copy_from_slice(&cid.hash().digest()[0..32]);