Skip to content

Commit

Permalink
feat: p2p whitelist ips
Browse files Browse the repository at this point in the history
  • Loading branch information
Vid201 committed Nov 10, 2024
1 parent bbdc5c4 commit dc97ad5
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
11 changes: 9 additions & 2 deletions bin/silius/src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,13 @@ pub struct P2PArgs {

/// List of whitelisted ENRs (for permissioned mempools).
/// If empty, all ENRs are allowed.
#[clap(long = "p2p.whitelist", value_delimiter = ',', value_parser=parse_enr)]
#[clap(long = "p2p.whitelist-enrs", value_delimiter = ',', value_parser=parse_enr)]
pub peers_whitelist: Vec<Enr>,

/// List of whitelisted IPs (for permissioned mempools).
/// If empty, all IPs are allowed.
#[clap(long = "p2p.whitelist-ips", value_delimiter = ',')]
pub ips_whitelist: Vec<IpAddr>,
}

impl P2PArgs {
Expand Down Expand Up @@ -340,6 +345,7 @@ impl P2PArgs {
.chain_spec(ChainSpec::from_chain_id(chain.id()))
.bootnodes(self.bootnodes.clone())
.peers_whitelist(self.peers_whitelist.clone())
.ips_whitelist(self.ips_whitelist.clone())
.gs_config(gossipsub_config())
.discv5_config(discv5::ConfigBuilder::new(listen_addr.to_listen_config()).build());

Expand Down Expand Up @@ -784,7 +790,7 @@ mod tests {
"~/.silius/p2p/node-key",
"--nodeenr",
"~/.silius/p2p/node-enr",
"--p2p.whitelist",
"--p2p.whitelist-enrs",
&binding,
];
assert_eq!(
Expand All @@ -798,6 +804,7 @@ mod tests {
node_key: Some(PathBuf::from("~/.silius/p2p/node-key")),
node_enr: Some(PathBuf::from("~/.silius/p2p/node-enr")),
peers_whitelist: vec![enr],
ips_whitelist: vec![],
},
P2PArgs::try_parse_from(args).unwrap()
)
Expand Down
12 changes: 11 additions & 1 deletion crates/p2p/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use silius_primitives::{
},
};
use std::{
net::{Ipv4Addr, Ipv6Addr},
net::{IpAddr, Ipv4Addr, Ipv6Addr},
path::PathBuf,
};

Expand Down Expand Up @@ -60,6 +60,9 @@ pub struct Config {

/// List of whitelisted peer ENRs
pub peers_whitelist: Vec<Enr>,

/// List of whitelisted IP addresses
pub ips_whitelist: Vec<IpAddr>,
}

impl Default for Config {
Expand Down Expand Up @@ -89,6 +92,7 @@ impl Default for Config {
target_peers: TARGET_PEERS,
bootnodes: vec![],
peers_whitelist: vec![],
ips_whitelist: vec![],
}
}
}
Expand Down Expand Up @@ -204,6 +208,12 @@ impl ConfigBuilder {
self.config.peers_whitelist = peers_whitelist;
self
}

/// Set the IPs whitelist.
pub fn ips_whitelist(mut self, ips_whitelist: Vec<IpAddr>) -> Self {
self.config.ips_whitelist = ips_whitelist;
self
}
}

/// Create a `GossipsubConfig`.
Expand Down
11 changes: 9 additions & 2 deletions crates/p2p/src/peer_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use libp2p::{Multiaddr, PeerId};
use silius_primitives::constants::p2p::{
HEARTBEAT_INTERVAL, PING_INTERVAL_INBOUND, PING_INTERVAL_OUTBOUND, TARGET_PEERS,
};
use std::{collections::VecDeque, sync::Arc, time::Duration};
use std::{collections::VecDeque, net::IpAddr, sync::Arc, time::Duration};
use tracing::debug;

/// The events that the `PeerManager` outputs (requests).
Expand Down Expand Up @@ -57,12 +57,18 @@ pub struct PeerManager {
peers_to_dial: Vec<Enr>,
/// The list of whitelisted ENRs.
peers_whitelist: Vec<Enr>,
/// The list of whitelisted IPs.
ips_whitelist: Vec<IpAddr>,
/// The heartbeat interval for peer management.
heartbeat: tokio::time::Interval,
}

impl PeerManager {
pub fn new(network_globals: Arc<NetworkGlobals>, peers_whitelist: Vec<Enr>) -> Self {
pub fn new(
network_globals: Arc<NetworkGlobals>,
peers_whitelist: Vec<Enr>,
ips_whitelist: Vec<IpAddr>,
) -> Self {
Self {
network_globals,
events: Default::default(),
Expand All @@ -71,6 +77,7 @@ impl PeerManager {
target_peers: TARGET_PEERS,
peers_to_dial: Vec::new(),
peers_whitelist,
ips_whitelist,
heartbeat: tokio::time::interval(Duration::from_secs(HEARTBEAT_INTERVAL)),
}
}
Expand Down
26 changes: 23 additions & 3 deletions crates/p2p/src/peer_manager/network_behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use libp2p::{
behaviour::ConnectionEstablished,
dial_opts::{DialOpts, PeerCondition},
dummy::ConnectionHandler,
ConnectionClosed, DialFailure, FromSwarm, NetworkBehaviour, ToSwarm,
ConnectionClosed, ConnectionDenied, DialFailure, FromSwarm, NetworkBehaviour, ToSwarm,
},
PeerId,
};
use std::task::Poll;
use std::{net::IpAddr, task::Poll};
use tracing::error;

impl NetworkBehaviour for PeerManager {
Expand Down Expand Up @@ -85,8 +85,28 @@ impl NetworkBehaviour for PeerManager {
&mut self,
_connection_id: libp2p::swarm::ConnectionId,
_local_addr: &libp2p::Multiaddr,
_remote_addr: &libp2p::Multiaddr,
remote_addr: &libp2p::Multiaddr,
) -> Result<(), libp2p::swarm::ConnectionDenied> {
// get the IP address to verify it's whitelisted
let ip = match remote_addr.iter().next() {
Some(libp2p::multiaddr::Protocol::Ip6(ip)) => IpAddr::V6(ip),
Some(libp2p::multiaddr::Protocol::Ip4(ip)) => IpAddr::V4(ip),
_ => {
return Err(ConnectionDenied::new(format!(
"Connection to peer rejected: invalid multiaddr: {remote_addr}"
)))
}
};

// check if whitelist exists and if the IP is in the whitelist
if !self.ips_whitelist.is_empty() &&
self.ips_whitelist.iter().filter(|&&whitelist_ip| whitelist_ip == ip).count() == 0
{
return Err(ConnectionDenied::new(format!(
"Connection to peer rejected: IP {ip} not in the whitelist"
)));
}

Ok(())
}

Expand Down
7 changes: 5 additions & 2 deletions crates/p2p/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,11 @@ impl Network {

let rpc = RPC::new();

let peer_manager =
PeerManager::new(network_globals.clone(), config.clone().peers_whitelist);
let peer_manager = PeerManager::new(
network_globals.clone(),
config.clone().peers_whitelist,
config.clone().ips_whitelist,
);

let mut discovery =
Discovery::new(combined_key, config.clone(), network_globals.clone()).await?;
Expand Down
1 change: 1 addition & 0 deletions crates/p2p/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async fn build_p2p_instance(bootnode: Option<Enr>) -> eyre::Result<Network> {
target_peers: TARGET_PEERS,
bootnodes: if let Some(bootnode) = bootnode { vec![bootnode] } else { vec![] },
peers_whitelist: vec![],
ips_whitelist: vec![],
};

let (_, receiver) = unbounded();
Expand Down

0 comments on commit dc97ad5

Please sign in to comment.