use bitcoin_hashes::cmp::fixed_time_eq;
use secp256k1::key::{SecretKey,PublicKey};
-use secp256k1::{Secp256k1,Message};
+use secp256k1::Secp256k1;
use secp256k1::ecdh::SharedSecret;
use secp256k1;
pub fn dummy() -> Self {
HTLCSource::OutboundRoute {
route: Route { hops: Vec::new() },
- session_priv: SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[1; 32]).unwrap(),
+ session_priv: SecretKey::from_slice(&[1; 32]).unwrap(),
first_hop_htlc_msat: 0,
}
}
}
}
#[inline]
+ fn ignore_no_close(err: &'static str) -> Self {
+ Self {
+ err: HandleError {
+ err,
+ action: Some(msgs::ErrorAction::IgnoreError),
+ },
+ shutdown_finish: None,
+ }
+ }
+ #[inline]
fn from_no_close(err: msgs::HandleError) -> Self {
Self { err, shutdown_finish: None }
}
/// probably increase this significantly.
const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u32 = 50;
-pub(super) struct HTLCForwardInfo {
- prev_short_channel_id: u64,
- prev_htlc_id: u64,
- #[cfg(test)]
- pub(super) forward_info: PendingForwardHTLCInfo,
- #[cfg(not(test))]
- forward_info: PendingForwardHTLCInfo,
+pub(super) enum HTLCForwardInfo {
+ AddHTLC {
+ prev_short_channel_id: u64,
+ prev_htlc_id: u64,
+ forward_info: PendingForwardHTLCInfo,
+ },
+ FailHTLC {
+ htlc_id: u64,
+ err_packet: msgs::OnionErrorPacket,
+ },
}
/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
}
macro_rules! handle_error {
- ($self: ident, $internal: expr, $their_node_id: expr) => {
+ ($self: ident, $internal: expr) => {
match $internal {
Ok(msg) => Ok(msg),
Err(MsgHandleErrInternal { err, shutdown_finish }) => {
}
macro_rules! return_monitor_err {
- ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path) => {
- return_monitor_err!($self, $err, $channel_state, $entry, $action_type, Vec::new(), Vec::new())
- };
- ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $raa_first_dropped_cs: expr) => {
- if $action_type != RAACommitmentOrder::RevokeAndACKFirst { panic!("Bad return_monitor_err call!"); }
- return_monitor_err!($self, $err, $channel_state, $entry, $action_type, Vec::new(), Vec::new(), $raa_first_dropped_cs)
+ ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => {
+ return_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment, Vec::new(), Vec::new())
};
- ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $failed_forwards: expr, $failed_fails: expr) => {
- return_monitor_err!($self, $err, $channel_state, $entry, $action_type, $failed_forwards, $failed_fails, false)
- };
- ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $failed_forwards: expr, $failed_fails: expr, $raa_first_dropped_cs: expr) => {
+ ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $failed_forwards: expr, $failed_fails: expr) => {
match $err {
ChannelMonitorUpdateErr::PermanentFailure => {
let (channel_id, mut chan) = $entry.remove_entry();
return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
},
ChannelMonitorUpdateErr::TemporaryFailure => {
- $entry.get_mut().monitor_update_failed($action_type, $failed_forwards, $failed_fails, $raa_first_dropped_cs);
+ $entry.get_mut().monitor_update_failed($action_type, $resend_raa, $resend_commitment, $failed_forwards, $failed_fails);
return Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore("Failed to update ChannelMonitor"), *$entry.key()));
},
}
// Does not break in case of TemporaryFailure!
macro_rules! maybe_break_monitor_err {
- ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path) => {
+ ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => {
match $err {
ChannelMonitorUpdateErr::PermanentFailure => {
let (channel_id, mut chan) = $entry.remove_entry();
break Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
},
ChannelMonitorUpdateErr::TemporaryFailure => {
- $entry.get_mut().monitor_update_failed($action_type, Vec::new(), Vec::new(), false);
+ $entry.get_mut().monitor_update_failed($action_type, $resend_raa, $resend_commitment, Vec::new(), Vec::new());
},
}
}
let shared_secret = {
let mut arr = [0; 32];
- arr.copy_from_slice(&SharedSecret::new(&self.secp_ctx, &msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key)[..]);
+ arr.copy_from_slice(&SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key)[..]);
arr
};
let (rho, mu) = onion_utils::gen_rho_mu_from_shared_secret(&shared_secret);
let mut sha = Sha256::engine();
sha.input(&new_pubkey.serialize()[..]);
sha.input(&shared_secret);
- SecretKey::from_slice(&self.secp_ctx, &Sha256::from_engine(sha).into_inner()).expect("SHA-256 is broken?")
+ Sha256::from_engine(sha).into_inner()
};
- let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor) {
+ let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor[..]) {
Err(e)
} else { Ok(new_pubkey) };
};
let msg_hash = Sha256dHash::from_data(&unsigned.encode()[..]);
- let sig = self.secp_ctx.sign(&Message::from_slice(&msg_hash[..]).unwrap(), &self.our_network_key);
+ let sig = self.secp_ctx.sign(&hash_to_message!(&msg_hash[..]), &self.our_network_key);
Ok(msgs::ChannelUpdate {
signature: sig,
} {
Some((update_add, commitment_signed, chan_monitor)) => {
if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
- maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst);
+ maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true);
// Note that MonitorUpdateFailed here indicates (per function docs)
// that we will resent the commitment update once we unfree monitor
// updating, so we have to take special care that we don't return
return Ok(());
};
- match handle_error!(self, err, route.hops.first().unwrap().pubkey) {
+ match handle_error!(self, err) {
Ok(_) => unreachable!(),
Err(e) => {
if let Some(msgs::ErrorAction::IgnoreError) = e.action {
None => return
}
};
- match handle_error!(self, res, chan.get_their_node_id()) {
+ match handle_error!(self, res) {
Ok(funding_msg) => {
(chan, funding_msg.0, funding_msg.1)
},
Ok(res) => res,
Err(_) => return None, // Only in case of state precondition violations eg channel is closing
};
- let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap();
+ let msghash = hash_to_message!(&Sha256dHash::from_data(&announcement.encode()[..])[..]);
let our_node_sig = self.secp_ctx.sign(&msghash, &self.our_network_key);
Some(msgs::AnnouncementSignatures {
Some(chan_id) => chan_id.clone(),
None => {
failed_forwards.reserve(pending_forwards.len());
- for HTLCForwardInfo { prev_short_channel_id, prev_htlc_id, forward_info } in pending_forwards.drain(..) {
- let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
- short_channel_id: prev_short_channel_id,
- htlc_id: prev_htlc_id,
- incoming_packet_shared_secret: forward_info.incoming_shared_secret,
- });
- failed_forwards.push((htlc_source, forward_info.payment_hash, 0x4000 | 10, None));
+ for forward_info in pending_forwards.drain(..) {
+ match forward_info {
+ HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
+ let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
+ short_channel_id: prev_short_channel_id,
+ htlc_id: prev_htlc_id,
+ incoming_packet_shared_secret: forward_info.incoming_shared_secret,
+ });
+ failed_forwards.push((htlc_source, forward_info.payment_hash, 0x4000 | 10, None));
+ },
+ HTLCForwardInfo::FailHTLC { .. } => {
+ // Channel went away before we could fail it. This implies
+ // the channel is now on chain and our counterparty is
+ // trying to broadcast the HTLC-Timeout, but that's their
+ // problem, not ours.
+ }
+ }
}
continue;
}
let forward_chan = &mut channel_state.by_id.get_mut(&forward_chan_id).unwrap();
let mut add_htlc_msgs = Vec::new();
- for HTLCForwardInfo { prev_short_channel_id, prev_htlc_id, forward_info } in pending_forwards.drain(..) {
- let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
- short_channel_id: prev_short_channel_id,
- htlc_id: prev_htlc_id,
- incoming_packet_shared_secret: forward_info.incoming_shared_secret,
- });
- match forward_chan.send_htlc(forward_info.amt_to_forward, forward_info.payment_hash, forward_info.outgoing_cltv_value, htlc_source.clone(), forward_info.onion_packet.unwrap()) {
- Err(_e) => {
- let chan_update = self.get_channel_update(forward_chan).unwrap();
- failed_forwards.push((htlc_source, forward_info.payment_hash, 0x1000 | 7, Some(chan_update)));
- continue;
+ let mut fail_htlc_msgs = Vec::new();
+ for forward_info in pending_forwards.drain(..) {
+ match forward_info {
+ HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
+ log_trace!(self, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(forward_info.payment_hash.0), prev_short_channel_id, short_chan_id);
+ let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
+ short_channel_id: prev_short_channel_id,
+ htlc_id: prev_htlc_id,
+ incoming_packet_shared_secret: forward_info.incoming_shared_secret,
+ });
+ match forward_chan.send_htlc(forward_info.amt_to_forward, forward_info.payment_hash, forward_info.outgoing_cltv_value, htlc_source.clone(), forward_info.onion_packet.unwrap()) {
+ Err(e) => {
+ if let ChannelError::Ignore(msg) = e {
+ log_trace!(self, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(forward_info.payment_hash.0), msg);
+ } else {
+ panic!("Stated return value requirements in send_htlc() were not met");
+ }
+ let chan_update = self.get_channel_update(forward_chan).unwrap();
+ failed_forwards.push((htlc_source, forward_info.payment_hash, 0x1000 | 7, Some(chan_update)));
+ continue;
+ },
+ Ok(update_add) => {
+ match update_add {
+ Some(msg) => { add_htlc_msgs.push(msg); },
+ None => {
+ // Nothing to do here...we're waiting on a remote
+ // revoke_and_ack before we can add anymore HTLCs. The Channel
+ // will automatically handle building the update_add_htlc and
+ // commitment_signed messages when we can.
+ // TODO: Do some kind of timer to set the channel as !is_live()
+ // as we don't really want others relying on us relaying through
+ // this channel currently :/.
+ }
+ }
+ }
+ }
},
- Ok(update_add) => {
- match update_add {
- Some(msg) => { add_htlc_msgs.push(msg); },
- None => {
+ HTLCForwardInfo::FailHTLC { htlc_id, err_packet } => {
+ log_trace!(self, "Failing HTLC back to channel with short id {} after delay", short_chan_id);
+ match forward_chan.get_update_fail_htlc(htlc_id, err_packet) {
+ Err(e) => {
+ if let ChannelError::Ignore(msg) = e {
+ log_trace!(self, "Failed to fail backwards to short_id {}: {}", short_chan_id, msg);
+ } else {
+ panic!("Stated return value requirements in get_update_fail_htlc() were not met");
+ }
+ // fail-backs are best-effort, we probably already have one
+ // pending, and if not that's OK, if not, the channel is on
+ // the chain and sending the HTLC-Timeout is their problem.
+ continue;
+ },
+ Ok(Some(msg)) => { fail_htlc_msgs.push(msg); },
+ Ok(None) => {
// Nothing to do here...we're waiting on a remote
- // revoke_and_ack before we can add anymore HTLCs. The Channel
- // will automatically handle building the update_add_htlc and
- // commitment_signed messages when we can.
- // TODO: Do some kind of timer to set the channel as !is_live()
- // as we don't really want others relying on us relaying through
- // this channel currently :/.
+ // revoke_and_ack before we can update the commitment
+ // transaction. The Channel will automatically handle
+ // building the update_fail_htlc and commitment_signed
+ // messages when we can.
+ // We don't need any kind of timer here as they should fail
+ // the channel onto the chain if they can't get our
+ // update_fail_htlc in time, its not our problem.
}
}
- }
+ },
}
}
- if !add_htlc_msgs.is_empty() {
+ if !add_htlc_msgs.is_empty() || !fail_htlc_msgs.is_empty() {
let (commitment_msg, monitor) = match forward_chan.send_commitment() {
Ok(res) => res,
Err(e) => {
updates: msgs::CommitmentUpdate {
update_add_htlcs: add_htlc_msgs,
update_fulfill_htlcs: Vec::new(),
- update_fail_htlcs: Vec::new(),
+ update_fail_htlcs: fail_htlc_msgs,
update_fail_malformed_htlcs: Vec::new(),
update_fee: None,
commitment_signed: commitment_msg,
});
}
} else {
- for HTLCForwardInfo { prev_short_channel_id, prev_htlc_id, forward_info } in pending_forwards.drain(..) {
- let prev_hop_data = HTLCPreviousHopData {
- short_channel_id: prev_short_channel_id,
- htlc_id: prev_htlc_id,
- incoming_packet_shared_secret: forward_info.incoming_shared_secret,
- };
- match channel_state.claimable_htlcs.entry(forward_info.payment_hash) {
- hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(prev_hop_data),
- hash_map::Entry::Vacant(entry) => { entry.insert(vec![prev_hop_data]); },
- };
- new_events.push(events::Event::PaymentReceived {
- payment_hash: forward_info.payment_hash,
- amt: forward_info.amt_to_forward,
- });
+ for forward_info in pending_forwards.drain(..) {
+ match forward_info {
+ HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
+ let prev_hop_data = HTLCPreviousHopData {
+ short_channel_id: prev_short_channel_id,
+ htlc_id: prev_htlc_id,
+ incoming_packet_shared_secret: forward_info.incoming_shared_secret,
+ };
+ match channel_state.claimable_htlcs.entry(forward_info.payment_hash) {
+ hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(prev_hop_data),
+ hash_map::Entry::Vacant(entry) => { entry.insert(vec![prev_hop_data]); },
+ };
+ new_events.push(events::Event::PaymentReceived {
+ payment_hash: forward_info.payment_hash,
+ amt: forward_info.amt_to_forward,
+ });
+ },
+ HTLCForwardInfo::FailHTLC { .. } => {
+ panic!("Got pending fail of our own HTLC");
+ }
+ }
}
}
}
/// drop it). In other words, no assumptions are made that entries in claimable_htlcs point to
/// still-available channels.
fn fail_htlc_backwards_internal(&self, mut channel_state_lock: MutexGuard<ChannelHolder>, source: HTLCSource, payment_hash: &PaymentHash, onion_error: HTLCFailReason) {
+ //TODO: There is a timing attack here where if a node fails an HTLC back to us they can
+ //identify whether we sent it or not based on the (I presume) very different runtime
+ //between the branches here. We should make this async and move it into the forward HTLCs
+ //timer handling.
match source {
HTLCSource::OutboundRoute { ref route, .. } => {
log_trace!(self, "Failing outbound payment HTLC with payment_hash {}", log_bytes!(payment_hash.0));
}
};
- let channel_state = channel_state_lock.borrow_parts();
-
- let chan_id = match channel_state.short_to_id.get(&short_channel_id) {
- Some(chan_id) => chan_id.clone(),
- None => return
- };
-
- let chan = channel_state.by_id.get_mut(&chan_id).unwrap();
- match chan.get_update_fail_htlc_and_commit(htlc_id, err_packet) {
- Ok(Some((msg, commitment_msg, chan_monitor))) => {
- if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
- unimplemented!();
- }
- channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
- node_id: chan.get_their_node_id(),
- updates: msgs::CommitmentUpdate {
- update_add_htlcs: Vec::new(),
- update_fulfill_htlcs: Vec::new(),
- update_fail_htlcs: vec![msg],
- update_fail_malformed_htlcs: Vec::new(),
- update_fee: None,
- commitment_signed: commitment_msg,
- },
- });
- },
- Ok(None) => {},
- Err(_e) => {
- //TODO: Do something with e?
- return;
+ let mut forward_event = None;
+ if channel_state_lock.forward_htlcs.is_empty() {
+ forward_event = Some(Instant::now() + Duration::from_millis(((rng::rand_f32() * 4.0 + 1.0) * MIN_HTLC_RELAY_HOLDING_CELL_MILLIS as f32) as u64));
+ channel_state_lock.next_forward = forward_event.unwrap();
+ }
+ match channel_state_lock.forward_htlcs.entry(short_channel_id) {
+ hash_map::Entry::Occupied(mut entry) => {
+ entry.get_mut().push(HTLCForwardInfo::FailHTLC { htlc_id, err_packet });
},
+ hash_map::Entry::Vacant(entry) => {
+ entry.insert(vec!(HTLCForwardInfo::FailHTLC { htlc_id, err_packet }));
+ }
+ }
+ mem::drop(channel_state_lock);
+ if let Some(time) = forward_event {
+ let mut pending_events = self.pending_events.lock().unwrap();
+ pending_events.push(events::Event::PendingHTLCsForwardable {
+ time_forwardable: time
+ });
}
},
}
let (revoke_and_ack, commitment_signed, closing_signed, chan_monitor) =
try_chan_entry!(self, chan.get_mut().commitment_signed(&msg, &*self.fee_estimator), channel_state, chan);
if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
- return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, commitment_signed.is_some());
+ return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, true, commitment_signed.is_some());
//TODO: Rebroadcast closing_signed if present on monitor update restoration
}
channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK {
for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
match channel_state.forward_htlcs.entry(forward_info.short_channel_id) {
hash_map::Entry::Occupied(mut entry) => {
- entry.get_mut().push(HTLCForwardInfo { prev_short_channel_id, prev_htlc_id, forward_info });
+ entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info });
},
hash_map::Entry::Vacant(entry) => {
- entry.insert(vec!(HTLCForwardInfo { prev_short_channel_id, prev_htlc_id, forward_info }));
+ entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info }));
}
}
}
//TODO: here and below MsgHandleErrInternal, #153 case
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
+ let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update();
let (commitment_update, pending_forwards, pending_failures, closing_signed, chan_monitor) =
try_chan_entry!(self, chan.get_mut().revoke_and_ack(&msg, &*self.fee_estimator), channel_state, chan);
if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
- return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, pending_forwards, pending_failures);
+ if was_frozen_for_monitor {
+ assert!(commitment_update.is_none() && closing_signed.is_none() && pending_forwards.is_empty() && pending_failures.is_empty());
+ return Err(MsgHandleErrInternal::ignore_no_close("Previous monitor update failure prevented responses to RAA"));
+ } else {
+ return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, commitment_update.is_some(), pending_forwards, pending_failures);
+ }
}
if let Some(updates) = commitment_update {
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
try_chan_entry!(self, chan.get_mut().get_channel_announcement(our_node_id.clone(), self.genesis_hash.clone()), channel_state, chan);
let were_node_one = announcement.node_id_1 == our_node_id;
- let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap();
+ let msghash = hash_to_message!(&Sha256dHash::from_data(&announcement.encode()[..])[..]);
if self.secp_ctx.verify(&msghash, &msg.node_signature, if were_node_one { &announcement.node_id_2 } else { &announcement.node_id_1 }).is_err() ||
self.secp_ctx.verify(&msghash, &msg.bitcoin_signature, if were_node_one { &announcement.bitcoin_key_2 } else { &announcement.bitcoin_key_1 }).is_err() {
try_chan_entry!(self, Err(ChannelError::Close("Bad announcement_signatures node_signature")), channel_state, chan);
if commitment_update.is_none() {
order = RAACommitmentOrder::RevokeAndACKFirst;
}
- return_monitor_err!(self, e, channel_state, chan, order);
+ return_monitor_err!(self, e, channel_state, chan, order, revoke_and_ack.is_some(), commitment_update.is_some());
//TODO: Resend the funding_locked if needed once we get the monitor running again
}
}
return Ok(())
};
- match handle_error!(self, err, their_node_id) {
+ match handle_error!(self, err) {
Ok(_) => unreachable!(),
Err(e) => {
if let Some(msgs::ErrorAction::IgnoreError) = e.action {
//TODO: Handle errors and close channel (or so)
fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_open_channel(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_open_channel(their_node_id, msg))
}
fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannel) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_accept_channel(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_accept_channel(their_node_id, msg))
}
fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_funding_created(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_funding_created(their_node_id, msg))
}
fn handle_funding_signed(&self, their_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_funding_signed(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_funding_signed(their_node_id, msg))
}
fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_funding_locked(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_funding_locked(their_node_id, msg))
}
fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_shutdown(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_shutdown(their_node_id, msg))
}
fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_closing_signed(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_closing_signed(their_node_id, msg))
}
fn handle_update_add_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC) -> Result<(), msgs::HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_update_add_htlc(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_update_add_htlc(their_node_id, msg))
}
fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_update_fulfill_htlc(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_update_fulfill_htlc(their_node_id, msg))
}
fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_update_fail_htlc(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_update_fail_htlc(their_node_id, msg))
}
fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_update_fail_malformed_htlc(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_update_fail_malformed_htlc(their_node_id, msg))
}
fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_commitment_signed(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_commitment_signed(their_node_id, msg))
}
fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_revoke_and_ack(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_revoke_and_ack(their_node_id, msg))
}
fn handle_update_fee(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFee) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_update_fee(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_update_fee(their_node_id, msg))
}
fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_announcement_signatures(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_announcement_signatures(their_node_id, msg))
}
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), HandleError> {
let _ = self.total_consistency_lock.read().unwrap();
- handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id)
+ handle_error!(self, self.internal_channel_reestablish(their_node_id, msg))
}
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) {
impl Writeable for PendingForwardHTLCInfo {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
- if let &Some(ref onion) = &self.onion_packet {
- 1u8.write(writer)?;
- onion.write(writer)?;
- } else {
- 0u8.write(writer)?;
- }
+ self.onion_packet.write(writer)?;
self.incoming_shared_secret.write(writer)?;
self.payment_hash.write(writer)?;
self.short_channel_id.write(writer)?;
impl<R: ::std::io::Read> Readable<R> for PendingForwardHTLCInfo {
fn read(reader: &mut R) -> Result<PendingForwardHTLCInfo, DecodeError> {
- let onion_packet = match <u8 as Readable<R>>::read(reader)? {
- 0 => None,
- 1 => Some(msgs::OnionPacket::read(reader)?),
- _ => return Err(DecodeError::InvalidValue),
- };
Ok(PendingForwardHTLCInfo {
- onion_packet,
+ onion_packet: Readable::read(reader)?,
incoming_shared_secret: Readable::read(reader)?,
payment_hash: Readable::read(reader)?,
short_channel_id: Readable::read(reader)?,
}
}
-impl_writeable!(HTLCForwardInfo, 0, {
- prev_short_channel_id,
- prev_htlc_id,
- forward_info
-});
+impl Writeable for HTLCForwardInfo {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+ match self {
+ &HTLCForwardInfo::AddHTLC { ref prev_short_channel_id, ref prev_htlc_id, ref forward_info } => {
+ 0u8.write(writer)?;
+ prev_short_channel_id.write(writer)?;
+ prev_htlc_id.write(writer)?;
+ forward_info.write(writer)?;
+ },
+ &HTLCForwardInfo::FailHTLC { ref htlc_id, ref err_packet } => {
+ 1u8.write(writer)?;
+ htlc_id.write(writer)?;
+ err_packet.write(writer)?;
+ },
+ }
+ Ok(())
+ }
+}
+
+impl<R: ::std::io::Read> Readable<R> for HTLCForwardInfo {
+ fn read(reader: &mut R) -> Result<HTLCForwardInfo, DecodeError> {
+ match <u8 as Readable<R>>::read(reader)? {
+ 0 => Ok(HTLCForwardInfo::AddHTLC {
+ prev_short_channel_id: Readable::read(reader)?,
+ prev_htlc_id: Readable::read(reader)?,
+ forward_info: Readable::read(reader)?,
+ }),
+ 1 => Ok(HTLCForwardInfo::FailHTLC {
+ htlc_id: Readable::read(reader)?,
+ err_packet: Readable::read(reader)?,
+ }),
+ _ => Err(DecodeError::InvalidValue),
+ }
+ }
+}
impl Writeable for ChannelManager {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {