Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions client/network/common/src/request_responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub struct ProtocolConfig {
/// Name of the protocol on the wire. Should be something like `/foo/bar`.
pub name: Cow<'static, str>,

/// Fallback on the wire protocol names to support.
pub fallback_names: Vec<Cow<'static, str>>,

/// Maximum allowed size, in bytes, of a request.
///
/// Any request larger than this value will be declined as a way to avoid allocating too
Expand Down
1 change: 1 addition & 0 deletions client/network/light/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", features = [
"derive",
] }
futures = "0.3.21"
hex = "0.4.0"
libp2p = "0.46.1"
log = "0.4.16"
prost = "0.10"
Expand Down
23 changes: 19 additions & 4 deletions client/network/light/src/light_client_requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,31 @@ use sc_network_common::{config::ProtocolId, request_responses::ProtocolConfig};

use std::time::Duration;

/// Generate the light client protocol name from chain specific protocol identifier.
fn generate_protocol_name(protocol_id: &ProtocolId) -> String {
/// Generate the light client protocol name from the genesis hash and fork id.
fn generate_protocol_name<Hash: AsRef<[u8]>>(genesis_hash: Hash, fork_id: Option<&str>) -> String {
if let Some(fork_id) = fork_id {
format!("/{}/{}/light/2", hex::encode(genesis_hash), fork_id)
} else {
format!("/{}/light/2", hex::encode(genesis_hash))
}
}

/// Generate the legacy light client protocol name from chain specific protocol identifier.
fn generate_legacy_protocol_name(protocol_id: &ProtocolId) -> String {
format!("/{}/light/2", protocol_id.as_ref())
}

/// Generates a [`ProtocolConfig`] for the light client request protocol, refusing incoming
/// requests.
pub fn generate_protocol_config(protocol_id: &ProtocolId) -> ProtocolConfig {
pub fn generate_protocol_config<Hash: AsRef<[u8]>>(
protocol_id: &ProtocolId,
genesis_hash: Hash,
fork_id: Option<&str>,
) -> ProtocolConfig {
ProtocolConfig {
name: generate_protocol_name(protocol_id).into(),
name: generate_protocol_name(genesis_hash, fork_id).into(),
fallback_names: std::iter::once(generate_legacy_protocol_name(protocol_id).into())
.collect(),
max_request_size: 1 * 1024 * 1024,
max_response_size: 16 * 1024 * 1024,
request_timeout: Duration::from_secs(15),
Expand Down
20 changes: 16 additions & 4 deletions client/network/light/src/light_client_requests/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use futures::{channel::mpsc, prelude::*};
use libp2p::PeerId;
use log::{debug, trace};
use prost::Message;
use sc_client_api::{ProofProvider, StorageProof};
use sc_client_api::{BlockBackend, ProofProvider, StorageProof};
use sc_network_common::{
config::ProtocolId,
request_responses::{IncomingRequest, OutgoingResponse, ProtocolConfig},
Expand All @@ -54,15 +54,27 @@ pub struct LightClientRequestHandler<B, Client> {
impl<B, Client> LightClientRequestHandler<B, Client>
where
B: Block,
Client: ProofProvider<B> + Send + Sync + 'static,
Client: BlockBackend<B> + ProofProvider<B> + Send + Sync + 'static,
{
/// Create a new [`LightClientRequestHandler`].
pub fn new(protocol_id: &ProtocolId, client: Arc<Client>) -> (Self, ProtocolConfig) {
pub fn new(
protocol_id: &ProtocolId,
fork_id: Option<&str>,
client: Arc<Client>,
) -> (Self, ProtocolConfig) {
// For now due to lack of data on light client request handling in production systems, this
// value is chosen to match the block request limit.
let (tx, request_receiver) = mpsc::channel(20);

let mut protocol_config = super::generate_protocol_config(protocol_id);
let mut protocol_config = super::generate_protocol_config(
protocol_id,
client
.block_hash(0u32.into())
.ok()
.flatten()
.expect("Genesis block exists; qed"),
fork_id,
);
protocol_config.inbound_queue = Some(tx);

(Self { client, request_receiver, _block: PhantomData::default() }, protocol_config)
Expand Down
6 changes: 5 additions & 1 deletion client/network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,13 @@ where
/// the network.
pub transaction_pool: Arc<dyn TransactionPool<H, B>>,

/// Name of the protocol to use on the wire. Should be different for each chain.
/// Legacy name of the protocol to use on the wire. Should be different for each chain.
pub protocol_id: ProtocolId,

/// Fork ID to distinguish protocols of different hard forks. Part of the standard protocol
/// name on the wire.
pub fork_id: Option<String>,

/// Import queue to use.
///
/// The import queue is the component that verifies that blocks received from other nodes are
Expand Down
18 changes: 14 additions & 4 deletions client/network/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ where
roles: Roles,
chain: Arc<Client>,
protocol_id: ProtocolId,
fork_id: &Option<String>,
network_config: &config::NetworkConfiguration,
notifications_protocols_handshakes: Vec<Vec<u8>>,
metrics_registry: Option<&Registry>,
Expand Down Expand Up @@ -371,8 +372,17 @@ where
sc_peerset::Peerset::from_config(sc_peerset::PeersetConfig { sets })
};

let block_announces_protocol: Cow<'static, str> =
format!("/{}/block-announces/1", protocol_id.as_ref()).into();
let block_announces_protocol = {
let genesis_hash =
chain.block_hash(0u32.into()).ok().flatten().expect("Genesis block exists; qed");
if let Some(fork_id) = fork_id {
format!("/{}/{}/block-announces/1", hex::encode(genesis_hash), fork_id)
} else {
format!("/{}/block-announces/1", hex::encode(genesis_hash))
}
};

let legacy_ba_protocol_name = format!("/{}/block-announces/1", protocol_id.as_ref());

let behaviour = {
let best_number = info.best_number;
Expand All @@ -384,8 +394,8 @@ where
.encode();

let sync_protocol_config = notifications::ProtocolConfig {
name: block_announces_protocol,
fallback_names: Vec::new(),
name: block_announces_protocol.into(),
fallback_names: iter::once(legacy_ba_protocol_name.into()).collect(),
handshake: block_announces_handshake,
max_notification_size: MAX_BLOCK_ANNOUNCE_SIZE,
};
Expand Down
10 changes: 9 additions & 1 deletion client/network/src/request_responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ impl RequestResponsesBehaviour {
max_request_size: protocol.max_request_size,
max_response_size: protocol.max_response_size,
},
iter::once((protocol.name.as_bytes().to_vec(), protocol_support)),
iter::once(protocol.name.as_bytes().to_vec())
.chain(protocol.fallback_names.iter().map(|name| name.as_bytes().to_vec()))
.zip(iter::repeat(protocol_support)),
cfg,
);

Expand Down Expand Up @@ -1027,6 +1029,7 @@ mod tests {

let protocol_config = ProtocolConfig {
name: From::from(protocol_name),
fallback_names: Vec::new(),
max_request_size: 1024,
max_response_size: 1024 * 1024,
request_timeout: Duration::from_secs(30),
Expand Down Expand Up @@ -1127,6 +1130,7 @@ mod tests {

let protocol_config = ProtocolConfig {
name: From::from(protocol_name),
fallback_names: Vec::new(),
max_request_size: 1024,
max_response_size: 8, // <-- important for the test
request_timeout: Duration::from_secs(30),
Expand Down Expand Up @@ -1223,13 +1227,15 @@ mod tests {
let protocol_configs = vec![
ProtocolConfig {
name: From::from(protocol_name_1),
fallback_names: Vec::new(),
max_request_size: 1024,
max_response_size: 1024 * 1024,
request_timeout: Duration::from_secs(30),
inbound_queue: None,
},
ProtocolConfig {
name: From::from(protocol_name_2),
fallback_names: Vec::new(),
max_request_size: 1024,
max_response_size: 1024 * 1024,
request_timeout: Duration::from_secs(30),
Expand All @@ -1247,13 +1253,15 @@ mod tests {
let protocol_configs = vec![
ProtocolConfig {
name: From::from(protocol_name_1),
fallback_names: Vec::new(),
max_request_size: 1024,
max_response_size: 1024 * 1024,
request_timeout: Duration::from_secs(30),
inbound_queue: Some(tx_1),
},
ProtocolConfig {
name: From::from(protocol_name_2),
fallback_names: Vec::new(),
max_request_size: 1024,
max_response_size: 1024 * 1024,
request_timeout: Duration::from_secs(30),
Expand Down
13 changes: 11 additions & 2 deletions client/network/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,16 @@ where
fs::create_dir_all(path)?;
}

let transactions_handler_proto =
transactions::TransactionsHandlerPrototype::new(params.protocol_id.clone());
let transactions_handler_proto = transactions::TransactionsHandlerPrototype::new(
params.protocol_id.clone(),
params
.chain
.block_hash(0u32.into())
.ok()
.flatten()
.expect("Genesis block exists; qed"),
params.fork_id.clone(),
);
params
.network_config
.extra_sets
Expand All @@ -243,6 +251,7 @@ where
From::from(&params.role),
params.chain.clone(),
params.protocol_id.clone(),
&params.fork_id,
&params.network_config,
iter::once(Vec::new())
.chain(
Expand Down
11 changes: 8 additions & 3 deletions client/network/src/service/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,25 @@ fn build_test_full_node(

let protocol_id = ProtocolId::from("/test-protocol-name");

let fork_id = Some(String::from("test-fork-id"));

let block_request_protocol_config = {
let (handler, protocol_config) = BlockRequestHandler::new(&protocol_id, client.clone(), 50);
let (handler, protocol_config) =
BlockRequestHandler::new(&protocol_id, None, client.clone(), 50);
async_std::task::spawn(handler.run().boxed());
protocol_config
};

let state_request_protocol_config = {
let (handler, protocol_config) = StateRequestHandler::new(&protocol_id, client.clone(), 50);
let (handler, protocol_config) =
StateRequestHandler::new(&protocol_id, None, client.clone(), 50);
async_std::task::spawn(handler.run().boxed());
protocol_config
};

let light_client_request_protocol_config = {
let (handler, protocol_config) =
LightClientRequestHandler::new(&protocol_id, client.clone());
LightClientRequestHandler::new(&protocol_id, None, client.clone());
async_std::task::spawn(handler.run().boxed());
protocol_config
};
Expand Down Expand Up @@ -134,6 +138,7 @@ fn build_test_full_node(
chain: client.clone(),
transaction_pool: Arc::new(config::EmptyTransactionPool),
protocol_id,
fork_id,
import_queue,
chain_sync: Box::new(chain_sync),
metrics_registry: None,
Expand Down
21 changes: 18 additions & 3 deletions client/network/src/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,34 @@ impl<H: ExHashT> Future for PendingTransaction<H> {
/// Prototype for a [`TransactionsHandler`].
pub struct TransactionsHandlerPrototype {
protocol_name: Cow<'static, str>,
fallback_protocol_names: Vec<Cow<'static, str>>,
}

impl TransactionsHandlerPrototype {
/// Create a new instance.
pub fn new(protocol_id: ProtocolId) -> Self {
Self { protocol_name: format!("/{}/transactions/1", protocol_id.as_ref()).into() }
pub fn new<Hash: AsRef<[u8]>>(
protocol_id: ProtocolId,
genesis_hash: Hash,
fork_id: Option<String>,
) -> Self {
let protocol_name = if let Some(fork_id) = fork_id {
format!("/{}/{}/transactions/1", hex::encode(genesis_hash), fork_id)
} else {
format!("/{}/transactions/1", hex::encode(genesis_hash))
};
let legacy_protocol_name = format!("/{}/transactions/1", protocol_id.as_ref());

Self {
protocol_name: protocol_name.into(),
fallback_protocol_names: iter::once(legacy_protocol_name.into()).collect(),
}
}

/// Returns the configuration of the set to put in the network configuration.
pub fn set_config(&self) -> config::NonDefaultSetConfig {
config::NonDefaultSetConfig {
notifications_protocol: self.protocol_name.clone(),
fallback_names: Vec::new(),
fallback_names: self.fallback_protocol_names.clone(),
max_notification_size: MAX_TRANSACTIONS_SIZE,
set_config: config::SetConfig {
in_peers: 0,
Expand Down
1 change: 1 addition & 0 deletions client/network/sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", features = [
"derive",
] }
futures = "0.3.21"
hex = "0.4.0"
libp2p = "0.46.1"
log = "0.4.17"
lru = "0.7.5"
Expand Down
34 changes: 29 additions & 5 deletions client/network/sync/src/block_request_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,33 @@ mod rep {
}

/// Generates a [`ProtocolConfig`] for the block request protocol, refusing incoming requests.
pub fn generate_protocol_config(protocol_id: &ProtocolId) -> ProtocolConfig {
pub fn generate_protocol_config<Hash: AsRef<[u8]>>(
protocol_id: &ProtocolId,
genesis_hash: Hash,
fork_id: Option<&str>,
) -> ProtocolConfig {
ProtocolConfig {
name: generate_protocol_name(protocol_id).into(),
name: generate_protocol_name(genesis_hash, fork_id).into(),
fallback_names: std::iter::once(generate_legacy_protocol_name(protocol_id).into())
.collect(),
max_request_size: 1024 * 1024,
max_response_size: 16 * 1024 * 1024,
request_timeout: Duration::from_secs(20),
inbound_queue: None,
}
}

/// Generate the block protocol name from chain specific protocol identifier.
fn generate_protocol_name(protocol_id: &ProtocolId) -> String {
/// Generate the block protocol name from the genesis hash and fork id.
fn generate_protocol_name<Hash: AsRef<[u8]>>(genesis_hash: Hash, fork_id: Option<&str>) -> String {
if let Some(fork_id) = fork_id {
format!("/{}/{}/sync/2", hex::encode(genesis_hash), fork_id)
} else {
format!("/{}/sync/2", hex::encode(genesis_hash))
}
}

/// Generate the legacy block protocol name from chain specific protocol identifier.
fn generate_legacy_protocol_name(protocol_id: &ProtocolId) -> String {
format!("/{}/sync/2", protocol_id.as_ref())
}

Expand Down Expand Up @@ -129,14 +144,23 @@ where
/// Create a new [`BlockRequestHandler`].
pub fn new(
protocol_id: &ProtocolId,
fork_id: Option<&str>,
client: Arc<Client>,
num_peer_hint: usize,
) -> (Self, ProtocolConfig) {
// Reserve enough request slots for one request per peer when we are at the maximum
// number of peers.
let (tx, request_receiver) = mpsc::channel(num_peer_hint);

let mut protocol_config = generate_protocol_config(protocol_id);
let mut protocol_config = generate_protocol_config(
protocol_id,
client
.block_hash(0u32.into())
.ok()
.flatten()
.expect("Genesis block exists; qed"),
fork_id,
);
protocol_config.inbound_queue = Some(tx);

let seen_requests = LruCache::new(num_peer_hint * 2);
Expand Down
Loading