Skip to content

Commit

Permalink
Ensure static entries don't block dynamic entries
Browse files Browse the repository at this point in the history
There was an issue during troubleshooting where the static overrides
exhausted the space available in the map for dynamic entries.  This
reserves a buffer for incoming entries.

Also, move leader tracking slot buffer to 12 from 10.
  • Loading branch information
helius-kurt committed Aug 7, 2024
1 parent f73a78d commit 23e5ee3
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 10 deletions.
3 changes: 2 additions & 1 deletion validator-firewall-ebpf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ use network_types::{
udp::UdpHdr,
};

const DENY_LIST_SIZE: u32 = 524288;

//These are our data structures that we use to communicate with userspace
#[map(name = "hvf_deny_list")]
static LEADER_SLOT_DENY_LIST: HashMap<u32, u8> = HashMap::<u32, u8>::with_max_entries(8192, 0);
static LEADER_SLOT_DENY_LIST: HashMap<u32, u8> = HashMap::<u32, u8>::with_max_entries(DENY_LIST_SIZE, 0);
#[map(name = "hvf_always_allow")]
static FULL_SCHEDULE_ALLOW_LIST: HashMap<u32, u8> = HashMap::<u32, u8>::with_max_entries(8192, 0);
#[map(name = "hvf_stats")]
Expand Down
28 changes: 27 additions & 1 deletion validator-firewall/src/ip_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ use log::{debug, error, info};
use rangemap::RangeInclusiveSet;
use solana_rpc_client::nonblocking::rpc_client::RpcClient;
use std::collections::HashSet;
use std::net::{Ipv4Addr};
use std::net::Ipv4Addr;
use std::ops::RangeInclusive;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;
use tokio::time::sleep;

const DENY_LIST_SIZE: u32 = 524288;
const DYNAMIC_LIST_BUFFER: u32 = 1024;

pub struct HttpDenyListClient {
url: String,
}
Expand Down Expand Up @@ -119,6 +122,7 @@ pub struct DenyListStateUpdater<T: DenyListClient> {
allow_service: Arc<DenyListService<T>>,
allow_ranges: RangeInclusiveSet<u32>,
deny_ranges: RangeInclusiveSet<u32>,
deny_cidrs: Arc<HashSet<Ipv4Cidr>>,
}

pub fn to_range(ip: Ipv4Cidr) -> RangeInclusive<u32> {
Expand All @@ -144,6 +148,7 @@ impl<T: DenyListClient> DenyListStateUpdater<T> {
deny_ranges: {
RangeInclusiveSet::from_iter(static_overrides.1.iter().map(|ip| to_range(*ip)))
},
deny_cidrs: Arc::new(static_overrides.1.clone()),
}
}

Expand All @@ -158,6 +163,26 @@ impl<T: DenyListClient> DenyListStateUpdater<T> {
pub async fn run(&self, allow_list: Map) {
let mut deny_list: HashMap<_, u32, u8> = HashMap::try_from(allow_list).unwrap();
let mut dynamic_deny_set = HashSet::new();
{
let ips: Vec<Ipv4Addr> = self
.deny_cidrs
.iter()
.flat_map(|ip| ip.into_iter().addresses())
.collect();
if ips.len() > (DENY_LIST_SIZE - DYNAMIC_LIST_BUFFER) as usize {
error!("Deny list is too large to fit in map, static overrides will be truncated.");
}

for ip in ips
.iter()
.take((DENY_LIST_SIZE - DYNAMIC_LIST_BUFFER) as usize)
{
let ip_numeric: u32 = u32::from(*ip);
if !self.is_allowed(&ip_numeric) {
deny_list.insert(ip_numeric, 0, 0).unwrap();
}
}
}

while !self.exit_flag.load(Ordering::Relaxed) {
if let Ok(nodes) = self.allow_service.get_deny_list().await {
Expand All @@ -169,6 +194,7 @@ impl<T: DenyListClient> DenyListStateUpdater<T> {
}
}

dynamic_deny_set.retain(|x| !self.is_allowed(x));
let to_remove = {
deny_list
.iter()
Expand Down
1 change: 0 additions & 1 deletion validator-firewall/src/ip_service_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

let app_state = Arc::new(IPState::new());


for node in static_overrides.0.iter() {
app_state.add_http_node(node.clone()).await;
}
Expand Down
3 changes: 1 addition & 2 deletions validator-firewall/src/leader_tracker.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::ops::Range;
use aya::maps::{Array, Map};
use log::{error, info, warn};
use rangemap::RangeInclusiveSet;
use solana_rpc_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel};
use solana_sdk::epoch_info::EpochInfo;
use std::ops::Range;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use tokio::sync::RwLock;
Expand Down Expand Up @@ -182,7 +182,6 @@ impl RPCLeaderTracker {
for slot in my_slots {
let end: u64 = *slot as u64;


let range = end.saturating_sub(self.slot_buffer)..=end;
leader_ranges.insert(range);
}
Expand Down
11 changes: 6 additions & 5 deletions validator-firewall/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ mod config;
mod leader_tracker;

use crate::config::{load_static_overrides, NameAddressPair};
use crate::ip_service::{ DenyListService, DenyListStateUpdater, HttpDenyListClient, DuckDbDenyListClient, NoOpDenyListClient};
use crate::ip_service::{
DenyListService, DenyListStateUpdater, DuckDbDenyListClient, HttpDenyListClient,
NoOpDenyListClient,
};
use crate::leader_tracker::{CommandControlService, RPCLeaderTracker};
use anyhow::Context;
use aya::{
Expand Down Expand Up @@ -154,9 +157,7 @@ async fn main() -> Result<(), anyhow::Error> {

let s_updater = DenyListStateUpdater::new(
gossip_exit,
Arc::new(DenyListService::new(DuckDbDenyListClient::new(
query,
))),
Arc::new(DenyListService::new(DuckDbDenyListClient::new(query))),
static_overrides.clone(),
);

Expand Down Expand Up @@ -187,7 +188,7 @@ async fn main() -> Result<(), anyhow::Error> {
let tracker = Arc::new(RPCLeaderTracker::new(
exit.clone(),
RpcClient::new(config.rpc_endpoint.clone()),
10,
12,
config.leader_id,
));
let bg_tracker = tracker.clone();
Expand Down

0 comments on commit 23e5ee3

Please sign in to comment.