diff --git a/Cargo.lock b/Cargo.lock index 5bd3e580f6..9c6446cfce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3007,9 +3007,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hashlink" @@ -3431,7 +3431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", ] [[package]] diff --git a/network/src/network.rs b/network/src/network.rs index 6134e7cb12..f49bd6f0ac 100644 --- a/network/src/network.rs +++ b/network/src/network.rs @@ -1163,30 +1163,53 @@ impl NetworkService { let p2p_control: ServiceAsyncControl = p2p_control.clone().into(); handle.spawn_task(async move { #[cfg(not(target_family = "wasm"))] - for addr in &config.listen_addresses { - match p2p_service.listen(addr.to_owned()).await { - Ok(listen_address) => { - info!("Listen on address: {}", listen_address); - network_state - .listened_addrs - .write() - .push(listen_address.clone()); - } - Err(err) => { - warn!( - "Listen on address {} failed, due to error: {}", - addr.clone(), - err - ); - start_sender - .send(Err(Error::P2P(P2PError::Transport(err)))) - .expect("channel abnormal shutdown"); - return; + { + let listen_addresses = { + let mut addresses = config.listen_addresses.clone(); + if config.reuse_tcp_with_ws { + let ws_listens = addresses + .iter() + .cloned() + .filter_map(|mut addr| { + if matches!(find_type(&addr), TransportType::Tcp) { + addr.push(Protocol::Ws); + Some(addr) + } else { + None + } + }) + .collect::>(); + + addresses.extend(ws_listens); } + addresses.into_iter().collect::>() }; + + for addr in &listen_addresses { + match p2p_service.listen(addr.to_owned()).await { + Ok(listen_address) => { + info!("Listen on address: {}", listen_address); + network_state + .listened_addrs + .write() + .push(listen_address.clone()); + } + Err(err) => { + warn!( + "Listen on address {} failed, due to error: {}", + addr.clone(), + err + ); + start_sender + .send(Err(Error::P2P(P2PError::Transport(err)))) + .expect("channel abnormal shutdown"); + return; + } + }; + } + start_sender.send(Ok(())).unwrap(); } - #[cfg(not(target_family = "wasm"))] - start_sender.send(Ok(())).unwrap(); + p2p::runtime::spawn(async move { p2p_service.run().await }); tokio::select! { _ = receiver.cancelled() => { diff --git a/resource/ckb.toml b/resource/ckb.toml index 3df8e09dde..95240520df 100644 --- a/resource/ckb.toml +++ b/resource/ckb.toml @@ -63,8 +63,8 @@ cache_size = 268435456 options_file = "default.db-options" [network] -listen_addresses = ["/ip4/0.0.0.0/tcp/8115", "/ip4/0.0.0.0/tcp/8115/ws"] # {{ -# _ => listen_addresses = ["/ip4/0.0.0.0/tcp/{p2p_port}", "/ip4/0.0.0.0/tcp/{p2p_port}/ws"] +listen_addresses = ["/ip4/0.0.0.0/tcp/8115"] # {{ +# _ => listen_addresses = ["/ip4/0.0.0.0/tcp/{p2p_port}"] # }} ### Specify the public and routable network addresses # public_addresses = [] @@ -84,6 +84,8 @@ bootnodes = [] # {{ # whitelist_peers = [] ### Enable `SO_REUSEPORT` feature to reuse port on Linux, not supported on other OS yet # reuse_port_on_linux = true +### Allow ckb to upgrade tcp listening to tcp + ws listening when only tcp listening is found +# reuse_tcp_with_ws = true max_peers = 125 max_outbound_peers = 8 diff --git a/util/app-config/src/configs/network.rs b/util/app-config/src/configs/network.rs index 70d8cb3550..34eac57790 100644 --- a/util/app-config/src/configs/network.rs +++ b/util/app-config/src/configs/network.rs @@ -83,6 +83,9 @@ pub struct Config { /// Network use reuse port or not #[serde(default = "default_reuse")] pub reuse_port_on_linux: bool, + /// Allow ckb to upgrade tcp listening to tcp + ws listening + #[serde(default = "default_reuse_tcp_with_ws")] + pub reuse_tcp_with_ws: bool, /// Chain synchronization config options. #[serde(default)] pub sync: SyncConfig, @@ -353,3 +356,8 @@ impl Config { const fn default_reuse() -> bool { true } + +/// By default, allow ckb to upgrade tcp listening to tcp + ws listening +const fn default_reuse_tcp_with_ws() -> bool { + true +} diff --git a/util/app-config/src/tests/app_config.rs b/util/app-config/src/tests/app_config.rs index 68d1de7218..52fcd4b163 100644 --- a/util/app-config/src/tests/app_config.rs +++ b/util/app-config/src/tests/app_config.rs @@ -55,10 +55,7 @@ fn test_export_dev_config_files() { ); assert_eq!( ckb_config.network.listen_addresses, - vec![ - "/ip4/0.0.0.0/tcp/8000".parse().unwrap(), - "/ip4/0.0.0.0/tcp/8000/ws".parse().unwrap() - ] + vec!["/ip4/0.0.0.0/tcp/8000".parse().unwrap()] ); assert_eq!(ckb_config.network.connect_outbound_interval_secs, 15); assert_eq!(ckb_config.rpc.listen_address, "127.0.0.1:7000"); @@ -151,10 +148,7 @@ fn test_export_testnet_config_files() { ); assert_eq!( ckb_config.network.listen_addresses, - vec![ - "/ip4/0.0.0.0/tcp/8000".parse().unwrap(), - "/ip4/0.0.0.0/tcp/8000/ws".parse().unwrap() - ] + vec!["/ip4/0.0.0.0/tcp/8000".parse().unwrap()] ); assert_eq!(ckb_config.network.connect_outbound_interval_secs, 15); assert_eq!(ckb_config.rpc.listen_address, "127.0.0.1:7000"); @@ -206,10 +200,7 @@ fn test_export_integration_config_files() { ); assert_eq!( ckb_config.network.listen_addresses, - vec![ - "/ip4/0.0.0.0/tcp/8000".parse().unwrap(), - "/ip4/0.0.0.0/tcp/8000/ws".parse().unwrap() - ] + vec!["/ip4/0.0.0.0/tcp/8000".parse().unwrap()] ); assert_eq!(ckb_config.rpc.listen_address, "127.0.0.1:7000"); } @@ -261,10 +252,7 @@ fn test_export_dev_config_files_assembly() { ); assert_eq!( ckb_config.network.listen_addresses, - vec![ - "/ip4/0.0.0.0/tcp/8000".parse().unwrap(), - "/ip4/0.0.0.0/tcp/8000/ws".parse().unwrap() - ] + vec!["/ip4/0.0.0.0/tcp/8000".parse().unwrap()] ); assert_eq!(ckb_config.network.connect_outbound_interval_secs, 15); assert_eq!(ckb_config.rpc.listen_address, "127.0.0.1:7000");