Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sim-node: validate channel policy and enforce unique scid #201

Merged
merged 1 commit into from
Nov 15, 2024
Merged
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
50 changes: 48 additions & 2 deletions sim-lib/src/sim_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,25 @@ pub struct ChannelPolicy {
pub fee_rate_prop: u64,
}

impl ChannelPolicy {
/// Validates that the channel policy is acceptable for the size of the channel.
fn validate(&self, capacity_msat: u64) -> Result<(), SimulationError> {
if self.max_in_flight_msat > capacity_msat {
return Err(SimulationError::SimulatedNetworkError(format!(
"max_in_flight_msat {} > capacity {}",
self.max_in_flight_msat, capacity_msat
)));
}
if self.max_htlc_size_msat > capacity_msat {
return Err(SimulationError::SimulatedNetworkError(format!(
"max_htlc_size_msat {} > capacity {}",
self.max_htlc_size_msat, capacity_msat
)));
}
Ok(())
}
}

/// Fails with the forwarding error provided if the value provided fails its inequality check.
macro_rules! fail_forwarding_inequality {
($value_1:expr, $op:tt, $value_2:expr, $error_variant:ident $(, $opt:expr)*) => {
Expand Down Expand Up @@ -291,6 +310,21 @@ impl SimulatedChannel {
}
}

/// Validates that a simulated channel has distinct node pairs and valid routing policies.
fn validate(&self) -> Result<(), SimulationError> {
if self.node_1.policy.pubkey == self.node_2.policy.pubkey {
return Err(SimulationError::SimulatedNetworkError(format!(
"Channel should have distinct node pubkeys, got: {} for both nodes.",
self.node_1.policy.pubkey
)));
}

self.node_1.policy.validate(self.capacity_msat)?;
self.node_2.policy.validate(self.capacity_msat)?;

bjohnson5 marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}

fn get_node_mut(&mut self, pubkey: &PublicKey) -> Result<&mut ChannelState, ForwardingError> {
if pubkey == &self.node_1.policy.pubkey {
Ok(&mut self.node_1)
Expand Down Expand Up @@ -617,13 +651,25 @@ impl SimGraph {
pub fn new(
graph_channels: Vec<SimulatedChannel>,
shutdown_trigger: Trigger,
) -> Result<Self, LdkError> {
) -> Result<Self, SimulationError> {
let mut nodes: HashMap<PublicKey, Vec<u64>> = HashMap::new();
let mut channels = HashMap::new();

for channel in graph_channels.iter() {
channels.insert(channel.short_channel_id, channel.clone());
// Assert that the channel is valid and that its short channel ID is unique within the simulation, required
// because we use scid to identify the channel.
channel.validate()?;
match channels.entry(channel.short_channel_id) {
Entry::Occupied(_) => {
return Err(SimulationError::SimulatedNetworkError(format!(
"Simulated short channel ID should be unique: {} duplicated",
channel.short_channel_id
)))
},
Entry::Vacant(v) => v.insert(channel.clone()),
};

// It's okay to have duplicate pubkeys because one node can have many channels.
for pubkey in [channel.node_1.policy.pubkey, channel.node_2.policy.pubkey] {
match nodes.entry(pubkey) {
Entry::Occupied(o) => o.into_mut().push(channel.capacity_msat),
Expand Down