Skip to content

Commit

Permalink
feat! differentiate swarms based on network_id (#575)
Browse files Browse the repository at this point in the history
This PR introduces a network_id field in ConnectNodeSend message. It's used to prevent nodes from different networks from connecting to each other.

There is a breaking change in config file.
User must specify network_id in config file now.
  • Loading branch information
Ma233 authored Apr 28, 2024
1 parent ab651b9 commit 318ac4a
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 47 deletions.
4 changes: 4 additions & 0 deletions crates/core/src/message/handlers/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ impl HandleMsg<QueryForTopoInfoReport> for MessageHandler {
#[cfg_attr(not(feature = "wasm"), async_trait)]
impl HandleMsg<ConnectNodeSend> for MessageHandler {
async fn handle(&self, ctx: &MessagePayload, msg: &ConnectNodeSend) -> Result<()> {
if msg.network_id != self.transport.network_id {
return Ok(());
}

if self.dht.did != ctx.relay.destination {
self.transport.forward_payload(ctx, None).await
} else {
Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/message/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub trait Then {
pub struct ConnectNodeSend {
/// sdp offer of webrtc
pub sdp: String,
/// The network_id is used to distinguish different networks.
/// Use 1 for main network.
pub network_id: u32,
}

/// MessageType report to origin with own transport_uuid and handshake_info.
Expand Down
10 changes: 9 additions & 1 deletion crates/core/src/swarm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl SwarmCallback for DefaultCallback {}

/// Creates a SwarmBuilder to configure a Swarm.
pub struct SwarmBuilder {
network_id: u32,
ice_servers: String,
external_address: Option<String>,
dht_succ_max: u8,
Expand All @@ -31,8 +32,14 @@ pub struct SwarmBuilder {

impl SwarmBuilder {
/// Creates new instance of [SwarmBuilder]
pub fn new(ice_servers: &str, dht_storage: VNodeStorage, session_sk: SessionSk) -> Self {
pub fn new(
network_id: u32,
ice_servers: &str,
dht_storage: VNodeStorage,
session_sk: SessionSk,
) -> Self {
SwarmBuilder {
network_id,
ice_servers: ice_servers.to_string(),
external_address: None,
dht_succ_max: 3,
Expand Down Expand Up @@ -91,6 +98,7 @@ impl SwarmBuilder {
);

let transport = Arc::new(SwarmTransport::new(
self.network_id,
&self.ice_servers,
self.external_address,
self.session_sk,
Expand Down
8 changes: 7 additions & 1 deletion crates/core/src/swarm/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::session::SessionSk;
use crate::swarm::callback::InnerSwarmCallback;

pub struct SwarmTransport {
pub(crate) network_id: u32,
transport: Transport,
session_sk: SessionSk,
pub(crate) dht: Arc<PeerRing>,
Expand All @@ -54,13 +55,15 @@ pub struct SwarmConnection {

impl SwarmTransport {
pub fn new(
network_id: u32,
ice_servers: &str,
external_address: Option<String>,
session_sk: SessionSk,
dht: Arc<PeerRing>,
measure: Option<MeasureImpl>,
) -> Self {
Self {
network_id,
transport: Transport::new(ice_servers, external_address),
session_sk,
dht,
Expand Down Expand Up @@ -184,7 +187,10 @@ impl SwarmTransport {

let offer = conn.webrtc_create_offer().await.map_err(Error::Transport)?;
let offer_str = serde_json::to_string(&offer).map_err(|_| Error::SerializeToString)?;
let offer_msg = ConnectNodeSend { sdp: offer_str };
let offer_msg = ConnectNodeSend {
sdp: offer_str,
network_id: self.network_id,
};

Ok(offer_msg)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/tests/default/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub async fn prepare_node(key: SecretKey) -> Node {
let storage = Box::new(MemStorage::new());

let session_sk = SessionSk::new_with_seckey(&key).unwrap();
let swarm = Arc::new(SwarmBuilder::new(stun, storage, session_sk).build());
let swarm = Arc::new(SwarmBuilder::new(0, stun, storage, session_sk).build());

println!("key: {:?}", key.to_string());
println!("did: {:?}", swarm.did());
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/tests/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub async fn prepare_node(key: SecretKey) -> Arc<Swarm> {
.unwrap(),
);

let swarm = Arc::new(SwarmBuilder::new(stun, storage, session_sk).build());
let swarm = Arc::new(SwarmBuilder::new(0, stun, storage, session_sk).build());

println!("key: {:?}", key.to_string());
println!("did: {:?}", swarm.did());
Expand Down
30 changes: 17 additions & 13 deletions crates/node/src/native/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ lazy_static::lazy_static! {
};
}

pub const DEFAULT_NETWORK_ID: u32 = 1;
pub const DEFAULT_INTERNAL_API_PORT: u16 = 50000;
pub const DEFAULT_EXTERNAL_API_ADDR: &str = "127.0.0.1:50001";
pub const DEFAULT_ENDPOINT_URL: &str = "http://127.0.0.1:50000";
Expand All @@ -48,6 +49,7 @@ where P: AsRef<std::path::Path> {

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config {
pub network_id: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub ecdsa_key: Option<SecretKey>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -94,20 +96,20 @@ impl TryFrom<Config> for ProcessorConfigSerialized {
})
};

if let Some(ext_ip) = config.external_ip {
Ok(Self::new_with_ext_addr(
config.ice_servers,
session_sk,
config.stabilize_interval,
ext_ip,
))
let mut cs = Self::new(
config.network_id,
config.ice_servers,
session_sk,
config.stabilize_interval,
);

cs = if let Some(ext_ip) = config.external_ip {
cs.external_address(ext_ip)
} else {
Ok(Self::new(
config.ice_servers,
session_sk,
config.stabilize_interval,
))
}
cs
};

Ok(cs)
}
}

Expand All @@ -132,6 +134,7 @@ impl Config {
where P: AsRef<std::path::Path> {
let session_sk = session_sk.as_ref().to_string_lossy().to_string();
Self {
network_id: DEFAULT_NETWORK_ID,
ecdsa_key: None,
session_manager: None,
session_sk: Some(session_sk),
Expand Down Expand Up @@ -191,6 +194,7 @@ mod tests {
#[test]
fn test_deserialization_with_missed_field() {
let yaml = r#"
network_id: 1
session_sk: session_sk
internal_api_port: 50000
external_api_addr: 127.0.0.1:50001
Expand Down
54 changes: 27 additions & 27 deletions crates/node/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ use crate::prelude::SessionSk;
#[derive(Clone, Debug)]
#[wasm_export]
pub struct ProcessorConfig {
/// The network_id is used to distinguish different networks.
/// Use 1 for main network.
network_id: u32,
/// ICE servers for webrtc
ice_servers: String,
/// External address for webrtc
Expand All @@ -49,25 +52,16 @@ pub struct ProcessorConfig {
#[wasm_export]
impl ProcessorConfig {
/// Creates a new `ProcessorConfig` instance without an external address.
pub fn new(ice_servers: String, session_sk: SessionSk, stabilize_interval: u64) -> Self {
Self {
ice_servers,
external_address: None,
session_sk,
stabilize_interval: Duration::from_secs(stabilize_interval),
}
}

/// Creates a new `ProcessorConfig` instance with an external address.
pub fn new_with_ext_addr(
pub fn new(
network_id: u32,
ice_servers: String,
session_sk: SessionSk,
stabilize_interval: u64,
external_address: String,
) -> Self {
Self {
network_id,
ice_servers,
external_address: Some(external_address),
external_address: None,
session_sk,
stabilize_interval: Duration::from_secs(stabilize_interval),
}
Expand All @@ -92,6 +86,9 @@ impl FromStr for ProcessorConfig {
#[derive(Serialize, Deserialize, Clone)]
#[wasm_export]
pub struct ProcessorConfigSerialized {
/// The network_id is used to distinguish different networks.
/// Use 1 for main network.
network_id: u32,
/// A string representing ICE servers for WebRTC
ice_servers: String,
/// An optional string representing the external address for WebRTC
Expand All @@ -104,35 +101,34 @@ pub struct ProcessorConfigSerialized {

impl ProcessorConfigSerialized {
/// Creates a new `ProcessorConfigSerialized` instance without an external address.
pub fn new(ice_servers: String, session_sk: String, stabilize_interval: u64) -> Self {
Self {
ice_servers,
external_address: None,
session_sk,
stabilize_interval,
}
}

/// Creates a new `ProcessorConfigSerialized` instance with an external address.
pub fn new_with_ext_addr(
pub fn new(
network_id: u32,
ice_servers: String,
session_sk: String,
stabilize_interval: u64,
external_address: String,
) -> Self {
Self {
network_id,
ice_servers,
external_address: Some(external_address),
external_address: None,
session_sk,
stabilize_interval,
}
}

/// Sets up the external address for WebRTC.
/// This will be used to configure the transport to listen for WebRTC connections in "HOST" mode.
pub fn external_address(mut self, external_address: String) -> Self {
self.external_address = Some(external_address);
self
}
}

impl TryFrom<ProcessorConfig> for ProcessorConfigSerialized {
type Error = Error;
fn try_from(ins: ProcessorConfig) -> Result<Self> {
Ok(Self {
network_id: ins.network_id,
ice_servers: ins.ice_servers.clone(),
external_address: ins.external_address.clone(),
session_sk: ins.session_sk.dump()?,
Expand All @@ -145,6 +141,7 @@ impl TryFrom<ProcessorConfigSerialized> for ProcessorConfig {
type Error = Error;
fn try_from(ins: ProcessorConfigSerialized) -> Result<Self> {
Ok(Self {
network_id: ins.network_id,
ice_servers: ins.ice_servers.clone(),
external_address: ins.external_address.clone(),
session_sk: SessionSk::from_str(&ins.session_sk)?,
Expand Down Expand Up @@ -183,6 +180,7 @@ impl<'de> serde::de::Deserialize<'de> for ProcessorConfig {

/// ProcessorBuilder is used to initialize a [Processor] instance.
pub struct ProcessorBuilder {
network_id: u32,
ice_servers: String,
external_address: Option<String>,
session_sk: SessionSk,
Expand Down Expand Up @@ -210,6 +208,7 @@ impl ProcessorBuilder {
/// initialize a [ProcessorBuilder] with a [ProcessorConfig].
pub fn from_config(config: &ProcessorConfig) -> Result<Self> {
Ok(Self {
network_id: config.network_id,
ice_servers: config.ice_servers.clone(),
external_address: config.external_address.clone(),
session_sk: config.session_sk.clone(),
Expand Down Expand Up @@ -240,7 +239,8 @@ impl ProcessorBuilder {

let storage = self.storage.unwrap_or_else(|| Box::new(MemStorage::new()));

let mut swarm_builder = SwarmBuilder::new(&self.ice_servers, storage, self.session_sk);
let mut swarm_builder =
SwarmBuilder::new(self.network_id, &self.ice_servers, storage, self.session_sk);

if let Some(external_address) = self.external_address {
swarm_builder = swarm_builder.external_address(external_address);
Expand Down
2 changes: 2 additions & 0 deletions crates/node/src/provider/browser/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl Provider {
/// Signer should function as same as account_type declared, Eg: eip191 or secp256k1 or ed25519.
#[wasm_bindgen(constructor)]
pub fn new_instance(
network_id: u32,
ice_servers: String,
stabilize_interval: u64,
account: String,
Expand Down Expand Up @@ -124,6 +125,7 @@ impl Provider {
);

let provider = Provider::new_provider_internal(
network_id,
ice_servers,
stabilize_interval,
account,
Expand Down
2 changes: 2 additions & 0 deletions crates/node/src/provider/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ pub extern "C" fn request(
/// * This function cast CStr into Str
#[no_mangle]
pub unsafe extern "C" fn new_provider_with_callback(
network_id: u32,
ice_server: *const c_char,
stabilize_interval: u64,
account: *const c_char,
Expand Down Expand Up @@ -254,6 +255,7 @@ pub unsafe extern "C" fn new_provider_with_callback(
let acc_ty: String = c_char_to_string(account_type)?;

executor::block_on(Provider::new_provider_internal(
network_id,
ice,
stabilize_interval,
acc,
Expand Down
4 changes: 3 additions & 1 deletion crates/node/src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ impl Provider {
/// please check [rings_core::ecc]
/// Signer should accept a String and returns bytes.
/// Signer should function as same as account_type declared, Eg: eip191 or secp256k1 or ed25519.
#[allow(clippy::too_many_arguments)]
pub(crate) async fn new_provider_internal(
network_id: u32,
ice_servers: String,
stabilize_interval: u64,
account: String,
Expand All @@ -114,7 +116,7 @@ impl Provider {
};
sk_builder = sk_builder.set_session_sig(sig.to_vec());
let session_sk = sk_builder.build().map_err(Error::InternalError)?;
let config = ProcessorConfig::new(ice_servers, session_sk, stabilize_interval);
let config = ProcessorConfig::new(network_id, ice_servers, session_sk, stabilize_interval);
Self::new_provider_with_storage_internal(config, vnode_storage, measure_storage).await
}

Expand Down
1 change: 1 addition & 0 deletions crates/node/src/tests/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub async fn prepare_processor() -> Processor {
let sm = SessionSk::new_with_seckey(&key).unwrap();

let config = serde_yaml::to_string(&ProcessorConfig::new(
0,
"stun://stun.l.google.com:19302".to_string(),
sm,
3,
Expand Down
1 change: 1 addition & 0 deletions crates/node/src/tests/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub async fn prepare_processor() -> Processor {
let sm = SessionSk::new_with_seckey(&key).unwrap();

let config = serde_yaml::to_string(&ProcessorConfig::new(
0,
"stun://stun.l.google.com:19302".to_string(),
sm,
200,
Expand Down
3 changes: 2 additions & 1 deletion examples/ffi/rings.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ const char *request(const struct ProviderPtr *provider_ptr, const char *method,
*
* * This function cast CStr into Str
*/
struct ProviderPtr new_provider_with_callback(const char *ice_server,
struct ProviderPtr new_provider_with_callback(uint32_t network_id,
const char *ice_server,
uint64_t stabilize_interval,
const char *account,
const char *account_type,
Expand Down
1 change: 1 addition & 0 deletions examples/ffi/rings.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def create_provider(acc,
rings.init_logging(rings.Debug)
callback = rings.new_ffi_backend_behaviour(on_paintext_message, on_service_message, on_extension_message)
provider = rings.new_provider_with_callback(
0,
"stun://stun.l.google.com".encode(),
10,
acc.address.encode(),
Expand Down
Loading

0 comments on commit 318ac4a

Please sign in to comment.