Skip to content
Closed
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
33 changes: 31 additions & 2 deletions smite/src/oracles/accept_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,10 @@ fn verify_accept_channel(
return Err("accept_channel does not include a channel_type".to_string());
};

// Check that the channel type matches the one in open_channel.
if open_channel.tlvs.channel_type != accept_channel.tlvs.channel_type {
// Check that the channel type matches the one in open_channel. Convert
// feature vectors to minimal form before comparing.
let open_channel_type = open_channel.tlvs.channel_type.as_deref();
if open_channel_type.map(trim_features) != Some(trim_features(channel_type)) {
return Err("accept_channel channel_type does not match open_channel".to_string());
}

Expand Down Expand Up @@ -202,6 +204,13 @@ fn verify_accept_channel(
)
}

/// Strips the leading zero padding from a feature vector, yielding the smallest
/// bitmap that represents the same set of feature bits.
fn trim_features(features: &[u8]) -> &[u8] {
let padding = features.iter().take_while(|byte| **byte == 0).count();
&features[padding..]
}

/// Verifies that the initial commitment can cover its fee and satisfies the
/// channel reserve requirement, returning an error if it breaches either, or
/// `Ok(())` if both are met.
Expand Down Expand Up @@ -495,6 +504,26 @@ mod tests {
);
}

#[test]
fn accept_channel_channel_type_padded_differently_than_open_channel() {
let mut oc = open_channel();
oc.tlvs.channel_type = Some(vec![0x00, 0x00, 0x10, 0x00]);
let mut ac = accept_channel();
ac.tlvs.channel_type = Some(vec![0x10, 0x00]);

assert_pass(&ac, Some(&pending_negotiation(oc)));
}

#[test]
fn accept_channel_empty_channel_type_padded_differently_than_open_channel() {
let mut oc = open_channel();
oc.tlvs.channel_type = Some(vec![0x00]);
let mut ac = accept_channel();
ac.tlvs.channel_type = Some(vec![]);

assert_pass(&ac, Some(&pending_negotiation(oc)));
}

#[test]
fn accept_channel_reserve_below_the_open_channel_dust_limit() {
let oc = open_channel();
Expand Down