-
Notifications
You must be signed in to change notification settings - Fork 411
Implement DisconnectPeer event + test #43
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// This file is auto-generated by gen_target.sh based on msg_target_template.txt | ||
// To modify it, modify msg_target_template.txt and run gen_target.sh instead. | ||
|
||
extern crate lightning; | ||
|
||
use lightning::ln::msgs; | ||
use lightning::util::reset_rng_state; | ||
|
||
use lightning::ln::msgs::{MsgEncodable, MsgDecodable}; | ||
|
||
mod utils; | ||
|
||
#[inline] | ||
pub fn do_test(data: &[u8]) { | ||
reset_rng_state(); | ||
test_msg!(msgs::ErrorMessage, data); | ||
} | ||
|
||
#[cfg(feature = "afl")] | ||
extern crate afl; | ||
#[cfg(feature = "afl")] | ||
fn main() { | ||
afl::read_stdio_bytes(|data| { | ||
do_test(&data); | ||
}); | ||
} | ||
|
||
#[cfg(feature = "honggfuzz")] | ||
#[macro_use] extern crate honggfuzz; | ||
#[cfg(feature = "honggfuzz")] | ||
fn main() { | ||
loop { | ||
fuzz!(|data| { | ||
do_test(data); | ||
}); | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use utils::extend_vec_from_hex; | ||
#[test] | ||
fn duplicate_crash() { | ||
let mut a = Vec::new(); | ||
extend_vec_from_hex("00", &mut a); | ||
super::do_test(&a); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -328,7 +328,7 @@ macro_rules! secp_call { | |
match $res { | ||
Ok(key) => key, | ||
//TODO: make the error a parameter | ||
Err(_) => return Err(HandleError{err: $err, action: Some(msgs::ErrorAction::DisconnectPeer{})}) | ||
Err(_) => return Err(HandleError{err: $err, action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}) | ||
} | ||
}; | ||
} | ||
|
@@ -433,10 +433,10 @@ impl Channel { | |
|
||
fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), HandleError> { | ||
if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background) * 250 { | ||
return Err(HandleError{err: "Peer's feerate much too low", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "Peer's feerate much too low", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::HighPriority) * 375 { // 375 = 250 * 1.5x | ||
return Err(HandleError{err: "Peer's feerate much too high", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "Peer's feerate much too high", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
Ok(()) | ||
} | ||
|
@@ -448,29 +448,32 @@ impl Channel { | |
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> { | ||
// Check sanity of message fields: | ||
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS { | ||
return Err(HandleError{err: "funding value > 2^24", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "funding value > 2^24", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if msg.channel_reserve_satoshis > msg.funding_satoshis { | ||
return Err(HandleError{err: "Bogus channel_reserve_satoshis", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "Bogus channel_reserve_satoshis", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if msg.push_msat > (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 { | ||
return Err(HandleError{err: "push_msat more than highest possible value", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "push_msat more than highest possible value", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if msg.dust_limit_satoshis > msg.funding_satoshis { | ||
return Err(HandleError{err: "Peer never wants payout outputs?", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "Peer never wants payout outputs?", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if msg.max_htlc_value_in_flight_msat > msg.funding_satoshis * 1000 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rebase error here - this if was removed on master. |
||
return Err(HandleError{err: "Bogus max_htlc_value_in_flight_satoshis", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if msg.htlc_minimum_msat >= (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 { | ||
return Err(HandleError{err: "Minimum htlc value is full channel value", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "Minimum htlc value is full channel value", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?; | ||
if msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT { | ||
return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if msg.max_accepted_htlcs < 1 { | ||
return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
if (msg.channel_flags & 254) != 0 { | ||
return Err(HandleError{err: "unknown channel_flags", action: Some(msgs::ErrorAction::DisconnectPeer{})}); | ||
return Err(HandleError{err: "unknown channel_flags", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); | ||
} | ||
|
||
// Convert things into internal flags and prep our state: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,6 +138,11 @@ pub struct Init { | |
pub local_features: LocalFeatures, | ||
} | ||
|
||
pub struct ErrorMessage { | ||
pub channel_id: [u8; 32], | ||
pub data: String, | ||
} | ||
|
||
pub struct Ping { | ||
pub ponglen: u16, | ||
pub byteslen: u16, | ||
|
@@ -372,9 +377,15 @@ pub enum ErrorAction { | |
msg: UpdateFailHTLC | ||
}, | ||
/// The peer took some action which made us think they were useless. Disconnect them. | ||
DisconnectPeer, | ||
DisconnectPeer { | ||
msg: Option<ErrorMessage> | ||
}, | ||
/// The peer did something harmless that we weren't able to process, just log and ignore | ||
IgnoreError, | ||
/// The peer did something incorrect. Tell them. | ||
SendErrorMessage { | ||
msg: ErrorMessage | ||
}, | ||
} | ||
|
||
pub struct HandleError { //TODO: rename me | ||
|
@@ -1562,3 +1573,35 @@ impl MsgEncodable for OnionErrorPacket { | |
res | ||
} | ||
} | ||
|
||
impl MsgEncodable for ErrorMessage { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a TODO for MsgDecodable for ErrorMessage? We should obviously also support receiving them. |
||
fn encode(&self) -> Vec<u8> { | ||
let mut res = Vec::with_capacity(34 + self.data.len()); | ||
res.extend_from_slice(&self.channel_id); | ||
res.extend_from_slice(&byte_utils::be16_to_array(self.data.len() as u16)); | ||
res.extend_from_slice(&self.data.as_bytes()); | ||
res | ||
} | ||
} | ||
|
||
impl MsgDecodable for ErrorMessage { | ||
fn decode(v: &[u8]) -> Result<Self,DecodeError> { | ||
if v.len() < 34 { | ||
return Err(DecodeError::WrongLength); | ||
} | ||
let len = byte_utils::slice_to_be16(&v[33..34]); | ||
let mut data = String::new(); | ||
if len > 0 { | ||
data = String::from_utf8(v[35..len as usize].to_vec()).unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unwrap() here can panic if the message contains non-utf-8 crap. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, some of the indexing is off in the decoder here. |
||
if len != data.len() as u16 { | ||
return Err(DecodeError::WrongLength); | ||
} | ||
} | ||
let mut channel_id = [0; 32]; | ||
channel_id[..].copy_from_slice(&v[0..32]); | ||
Ok(Self { | ||
channel_id, | ||
data: data, | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry didn't get you on this one, disconnect_socket is used by the network provider to notify that we want to disconnect the peer, right ? So what do we want here is setting a bool in SocketDescriptor object and let the network provider disconnect peer, block further disconnect_event and remove peer infos. Why do we need RefCell ?