mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
Merge pull request #364 from TheBlueMatt/2019-07-no-unimpl
Implement the last three (relevant) unimplemented()s in ChannelManager
This commit is contained in:
commit
283d40f2e4
4 changed files with 299 additions and 61 deletions
|
@ -6,7 +6,7 @@
|
|||
use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash};
|
||||
use ln::channelmonitor::ChannelMonitorUpdateErr;
|
||||
use ln::msgs;
|
||||
use ln::msgs::{ChannelMessageHandler, LocalFeatures};
|
||||
use ln::msgs::{ChannelMessageHandler, LocalFeatures, RoutingMessageHandler};
|
||||
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
|
||||
use util::errors::APIError;
|
||||
|
||||
|
@ -1553,3 +1553,132 @@ fn monitor_update_claim_fail_no_response() {
|
|||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
|
||||
}
|
||||
|
||||
// Note that restore_between_fails with !fail_on_generate is useless
|
||||
// Also note that !fail_on_generate && !fail_on_signed is useless
|
||||
// Finally, note that !fail_on_signed is not possible with fail_on_generate && !restore_between_fails
|
||||
// confirm_a_first and restore_b_before_conf are wholly unrelated to earlier bools and
|
||||
// restore_b_before_conf has no meaning if !confirm_a_first
|
||||
fn do_during_funding_monitor_fail(fail_on_generate: bool, restore_between_fails: bool, fail_on_signed: bool, confirm_a_first: bool, restore_b_before_conf: bool) {
|
||||
// Test that if the monitor update generated by funding_transaction_generated fails we continue
|
||||
// the channel setup happily after the update is restored.
|
||||
let mut nodes = create_network(2, &[None, None]);
|
||||
|
||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43).unwrap();
|
||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), LocalFeatures::new(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id())).unwrap();
|
||||
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), LocalFeatures::new(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())).unwrap();
|
||||
|
||||
let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 43);
|
||||
|
||||
if fail_on_generate {
|
||||
*nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
|
||||
}
|
||||
nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
|
||||
*nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
|
||||
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id())).unwrap();
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
if restore_between_fails {
|
||||
assert!(fail_on_generate);
|
||||
*nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(());
|
||||
nodes[0].node.test_restore_channel_monitor();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
|
||||
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
|
||||
}
|
||||
|
||||
if fail_on_signed {
|
||||
*nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
|
||||
} else {
|
||||
assert!(restore_between_fails || !fail_on_generate); // We can't switch to good now (there's no monitor update)
|
||||
assert!(fail_on_generate); // Somebody has to fail
|
||||
}
|
||||
let funding_signed_res = nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id()));
|
||||
if fail_on_signed || !restore_between_fails {
|
||||
if let msgs::HandleError { err, action: Some(msgs::ErrorAction::IgnoreError) } = funding_signed_res.unwrap_err() {
|
||||
if fail_on_generate && !restore_between_fails {
|
||||
assert_eq!(err, "Previous monitor update failure prevented funding_signed from allowing funding broadcast");
|
||||
check_added_monitors!(nodes[0], 0);
|
||||
} else {
|
||||
assert_eq!(err, "Failed to update ChannelMonitor");
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
} else { panic!(); }
|
||||
|
||||
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
|
||||
*nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(());
|
||||
nodes[0].node.test_restore_channel_monitor();
|
||||
} else {
|
||||
funding_signed_res.unwrap();
|
||||
}
|
||||
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
|
||||
let events = nodes[0].node.get_and_clear_pending_events();
|
||||
assert_eq!(events.len(), 1);
|
||||
match events[0] {
|
||||
Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => {
|
||||
assert_eq!(user_channel_id, 43);
|
||||
assert_eq!(*funding_txo, funding_output);
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
};
|
||||
|
||||
if confirm_a_first {
|
||||
confirm_transaction(&nodes[0].chain_monitor, &funding_tx, funding_tx.version);
|
||||
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id())).unwrap();
|
||||
} else {
|
||||
assert!(!restore_b_before_conf);
|
||||
confirm_transaction(&nodes[1].chain_monitor, &funding_tx, funding_tx.version);
|
||||
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
|
||||
}
|
||||
|
||||
// Make sure nodes[1] isn't stupid enough to re-send the FundingLocked on reconnect
|
||||
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
|
||||
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
|
||||
reconnect_nodes(&nodes[0], &nodes[1], (false, confirm_a_first), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
|
||||
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
|
||||
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
|
||||
|
||||
if !restore_b_before_conf {
|
||||
confirm_transaction(&nodes[1].chain_monitor, &funding_tx, funding_tx.version);
|
||||
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
|
||||
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
|
||||
}
|
||||
|
||||
*nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(());
|
||||
nodes[1].node.test_restore_channel_monitor();
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
let (channel_id, (announcement, as_update, bs_update)) = if !confirm_a_first {
|
||||
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingLocked, nodes[0].node.get_our_node_id())).unwrap();
|
||||
|
||||
confirm_transaction(&nodes[0].chain_monitor, &funding_tx, funding_tx.version);
|
||||
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
|
||||
(channel_id, create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked))
|
||||
} else {
|
||||
if restore_b_before_conf {
|
||||
confirm_transaction(&nodes[1].chain_monitor, &funding_tx, funding_tx.version);
|
||||
}
|
||||
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[0], &nodes[1]);
|
||||
(channel_id, create_chan_between_nodes_with_value_b(&nodes[1], &nodes[0], &funding_locked))
|
||||
};
|
||||
for node in nodes.iter() {
|
||||
assert!(node.router.handle_channel_announcement(&announcement).unwrap());
|
||||
node.router.handle_channel_update(&as_update).unwrap();
|
||||
node.router.handle_channel_update(&bs_update).unwrap();
|
||||
}
|
||||
|
||||
send_payment(&nodes[0], &[&nodes[1]], 8000000);
|
||||
close_channel(&nodes[0], &nodes[1], &channel_id, funding_tx, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn during_funding_monitor_fail() {
|
||||
do_during_funding_monitor_fail(false, false, true, true, true);
|
||||
do_during_funding_monitor_fail(true, false, true, false, false);
|
||||
do_during_funding_monitor_fail(true, true, true, true, false);
|
||||
do_during_funding_monitor_fail(true, true, false, false, false);
|
||||
}
|
||||
|
|
|
@ -181,9 +181,9 @@ enum ChannelState {
|
|||
/// "disconnected" and no updates are allowed until after we've done a channel_reestablish
|
||||
/// dance.
|
||||
PeerDisconnected = (1 << 7),
|
||||
/// Flag which is set on ChannelFunded and FundingSent indicating the user has told us they
|
||||
/// failed to update our ChannelMonitor somewhere and we should pause sending any outbound
|
||||
/// messages until they've managed to do so.
|
||||
/// Flag which is set on ChannelFunded, FundingCreated, and FundingSent indicating the user has
|
||||
/// told us they failed to update our ChannelMonitor somewhere and we should pause sending any
|
||||
/// outbound messages until they've managed to do so.
|
||||
MonitorUpdateFailed = (1 << 8),
|
||||
/// Flag which implies that we have sent a commitment_signed but are awaiting the responding
|
||||
/// revoke_and_ack message. During this time period, we can't generate new commitment_signed
|
||||
|
@ -248,6 +248,7 @@ pub(super) struct Channel {
|
|||
/// send it first.
|
||||
resend_order: RAACommitmentOrder,
|
||||
|
||||
monitor_pending_funding_locked: bool,
|
||||
monitor_pending_revoke_and_ack: bool,
|
||||
monitor_pending_commitment_signed: bool,
|
||||
monitor_pending_forwards: Vec<(PendingForwardHTLCInfo, u64)>,
|
||||
|
@ -457,6 +458,7 @@ impl Channel {
|
|||
|
||||
resend_order: RAACommitmentOrder::CommitmentFirst,
|
||||
|
||||
monitor_pending_funding_locked: false,
|
||||
monitor_pending_revoke_and_ack: false,
|
||||
monitor_pending_commitment_signed: false,
|
||||
monitor_pending_forwards: Vec::new(),
|
||||
|
@ -672,6 +674,7 @@ impl Channel {
|
|||
|
||||
resend_order: RAACommitmentOrder::CommitmentFirst,
|
||||
|
||||
monitor_pending_funding_locked: false,
|
||||
monitor_pending_revoke_and_ack: false,
|
||||
monitor_pending_commitment_signed: false,
|
||||
monitor_pending_forwards: Vec::new(),
|
||||
|
@ -1538,7 +1541,7 @@ impl Channel {
|
|||
if !self.channel_outbound {
|
||||
return Err(ChannelError::Close("Received funding_signed for an inbound channel?"));
|
||||
}
|
||||
if self.channel_state != ChannelState::FundingCreated as u32 {
|
||||
if self.channel_state & !(ChannelState::MonitorUpdateFailed as u32) != ChannelState::FundingCreated as u32 {
|
||||
return Err(ChannelError::Close("Received funding_signed in strange state!"));
|
||||
}
|
||||
if self.channel_monitor.get_min_seen_secret() != (1 << 48) ||
|
||||
|
@ -1559,10 +1562,14 @@ impl Channel {
|
|||
self.sign_commitment_transaction(&mut local_initial_commitment_tx, &msg.signature);
|
||||
self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx.clone(), local_keys, self.feerate_per_kw, Vec::new());
|
||||
self.last_local_commitment_txn = vec![local_initial_commitment_tx];
|
||||
self.channel_state = ChannelState::FundingSent as u32;
|
||||
self.channel_state = ChannelState::FundingSent as u32 | (self.channel_state & (ChannelState::MonitorUpdateFailed as u32));
|
||||
self.cur_local_commitment_transaction_number -= 1;
|
||||
|
||||
Ok(self.channel_monitor.clone())
|
||||
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
|
||||
Ok(self.channel_monitor.clone())
|
||||
} else {
|
||||
Err(ChannelError::Ignore("Previous monitor update failure prevented funding_signed from allowing funding broadcast"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn funding_locked(&mut self, msg: &msgs::FundingLocked) -> Result<(), ChannelError> {
|
||||
|
@ -1577,10 +1584,13 @@ impl Channel {
|
|||
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
|
||||
self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
|
||||
self.channel_update_count += 1;
|
||||
} else if self.channel_state & (ChannelState::ChannelFunded as u32) != 0 &&
|
||||
// Note that funding_signed/funding_created will have decremented both by 1!
|
||||
self.cur_local_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 &&
|
||||
self.cur_remote_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 {
|
||||
} else if (self.channel_state & (ChannelState::ChannelFunded as u32) != 0 &&
|
||||
// Note that funding_signed/funding_created will have decremented both by 1!
|
||||
self.cur_local_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 &&
|
||||
self.cur_remote_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1) ||
|
||||
// If we reconnected before sending our funding locked they may still resend theirs:
|
||||
(self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) ==
|
||||
(ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32)) {
|
||||
if self.their_cur_commitment_point != Some(msg.next_per_commitment_point) {
|
||||
return Err(ChannelError::Close("Peer sent a reconnect funding_locked with a different point"));
|
||||
}
|
||||
|
@ -2343,10 +2353,29 @@ impl Channel {
|
|||
/// Indicates that the latest ChannelMonitor update has been committed by the client
|
||||
/// successfully and we should restore normal operation. Returns messages which should be sent
|
||||
/// to the remote side.
|
||||
pub fn monitor_updating_restored(&mut self) -> (Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>) {
|
||||
pub fn monitor_updating_restored(&mut self) -> (Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, bool, Option<msgs::FundingLocked>) {
|
||||
assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, ChannelState::MonitorUpdateFailed as u32);
|
||||
self.channel_state &= !(ChannelState::MonitorUpdateFailed as u32);
|
||||
|
||||
let needs_broadcast_safe = self.channel_state & (ChannelState::FundingSent as u32) != 0 && self.channel_outbound;
|
||||
|
||||
// Because we will never generate a FundingBroadcastSafe event when we're in
|
||||
// MonitorUpdateFailed, if we assume the user only broadcast the funding transaction when
|
||||
// they received the FundingBroadcastSafe event, we can only ever hit
|
||||
// monitor_pending_funding_locked when we're an inbound channel which failed to persist the
|
||||
// monitor on funding_created, and we even got the funding transaction confirmed before the
|
||||
// monitor was persisted.
|
||||
let funding_locked = if self.monitor_pending_funding_locked {
|
||||
assert!(!self.channel_outbound, "Funding transaction broadcast without FundingBroadcastSafe!");
|
||||
self.monitor_pending_funding_locked = false;
|
||||
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
|
||||
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
|
||||
Some(msgs::FundingLocked {
|
||||
channel_id: self.channel_id(),
|
||||
next_per_commitment_point: next_per_commitment_point,
|
||||
})
|
||||
} else { None };
|
||||
|
||||
let mut forwards = Vec::new();
|
||||
mem::swap(&mut forwards, &mut self.monitor_pending_forwards);
|
||||
let mut failures = Vec::new();
|
||||
|
@ -2355,7 +2384,7 @@ impl Channel {
|
|||
if self.channel_state & (ChannelState::PeerDisconnected as u32) != 0 {
|
||||
self.monitor_pending_revoke_and_ack = false;
|
||||
self.monitor_pending_commitment_signed = false;
|
||||
return (None, None, RAACommitmentOrder::RevokeAndACKFirst, forwards, failures);
|
||||
return (None, None, RAACommitmentOrder::RevokeAndACKFirst, forwards, failures, needs_broadcast_safe, funding_locked);
|
||||
}
|
||||
|
||||
let raa = if self.monitor_pending_revoke_and_ack {
|
||||
|
@ -2368,11 +2397,12 @@ impl Channel {
|
|||
self.monitor_pending_revoke_and_ack = false;
|
||||
self.monitor_pending_commitment_signed = false;
|
||||
let order = self.resend_order.clone();
|
||||
log_trace!(self, "Restored monitor updating resulting in {} commitment update and {} RAA, with {} first",
|
||||
log_trace!(self, "Restored monitor updating resulting in {}{} commitment update and {} RAA, with {} first",
|
||||
if needs_broadcast_safe { "a funding broadcast safe, " } else { "" },
|
||||
if commitment_update.is_some() { "a" } else { "no" },
|
||||
if raa.is_some() { "an" } else { "no" },
|
||||
match order { RAACommitmentOrder::CommitmentFirst => "commitment", RAACommitmentOrder::RevokeAndACKFirst => "RAA"});
|
||||
(raa, commitment_update, order, forwards, failures)
|
||||
(raa, commitment_update, order, forwards, failures, needs_broadcast_safe, funding_locked)
|
||||
}
|
||||
|
||||
pub fn update_fee(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::UpdateFee) -> Result<(), ChannelError> {
|
||||
|
@ -2482,7 +2512,9 @@ impl Channel {
|
|||
} else { None };
|
||||
|
||||
if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
|
||||
if self.channel_state & ChannelState::OurFundingLocked as u32 == 0 {
|
||||
// If we're waiting on a monitor update, we shouldn't re-send any funding_locked's.
|
||||
if self.channel_state & (ChannelState::OurFundingLocked as u32) == 0 ||
|
||||
self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
|
||||
if msg.next_remote_commitment_number != 0 {
|
||||
return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet"));
|
||||
}
|
||||
|
@ -2972,12 +3004,17 @@ impl Channel {
|
|||
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
|
||||
//a protocol oversight, but I assume I'm just missing something.
|
||||
if need_commitment_update {
|
||||
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
|
||||
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
|
||||
return Ok(Some(msgs::FundingLocked {
|
||||
channel_id: self.channel_id,
|
||||
next_per_commitment_point: next_per_commitment_point,
|
||||
}));
|
||||
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
|
||||
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
|
||||
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
|
||||
return Ok(Some(msgs::FundingLocked {
|
||||
channel_id: self.channel_id,
|
||||
next_per_commitment_point: next_per_commitment_point,
|
||||
}));
|
||||
} else {
|
||||
self.monitor_pending_funding_locked = true;
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3696,6 +3733,7 @@ impl Writeable for Channel {
|
|||
RAACommitmentOrder::RevokeAndACKFirst => 1u8.write(writer)?,
|
||||
}
|
||||
|
||||
self.monitor_pending_funding_locked.write(writer)?;
|
||||
self.monitor_pending_revoke_and_ack.write(writer)?;
|
||||
self.monitor_pending_commitment_signed.write(writer)?;
|
||||
|
||||
|
@ -3863,6 +3901,7 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
|
|||
_ => return Err(DecodeError::InvalidValue),
|
||||
};
|
||||
|
||||
let monitor_pending_funding_locked = Readable::read(reader)?;
|
||||
let monitor_pending_revoke_and_ack = Readable::read(reader)?;
|
||||
let monitor_pending_commitment_signed = Readable::read(reader)?;
|
||||
|
||||
|
@ -3959,6 +3998,7 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
|
|||
|
||||
resend_order,
|
||||
|
||||
monitor_pending_funding_locked,
|
||||
monitor_pending_revoke_and_ack,
|
||||
monitor_pending_commitment_signed,
|
||||
monitor_pending_forwards,
|
||||
|
|
|
@ -1131,7 +1131,7 @@ impl ChannelManager {
|
|||
pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
|
||||
let _ = self.total_consistency_lock.read().unwrap();
|
||||
|
||||
let (chan, msg, chan_monitor) = {
|
||||
let (mut chan, msg, chan_monitor) = {
|
||||
let (res, chan) = {
|
||||
let mut channel_state = self.channel_state.lock().unwrap();
|
||||
match channel_state.by_id.remove(temporary_channel_id) {
|
||||
|
@ -1162,8 +1162,30 @@ impl ChannelManager {
|
|||
};
|
||||
// Because we have exclusive ownership of the channel here we can release the channel_state
|
||||
// lock before add_update_monitor
|
||||
if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
|
||||
unimplemented!();
|
||||
if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
|
||||
match e {
|
||||
ChannelMonitorUpdateErr::PermanentFailure => {
|
||||
match handle_error!(self, Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", *temporary_channel_id, chan.force_shutdown(), None))) {
|
||||
Err(e) => {
|
||||
log_error!(self, "Failed to store ChannelMonitor update for funding tx generation");
|
||||
let mut channel_state = self.channel_state.lock().unwrap();
|
||||
channel_state.pending_msg_events.push(events::MessageSendEvent::HandleError {
|
||||
node_id: chan.get_their_node_id(),
|
||||
action: e.action,
|
||||
});
|
||||
return;
|
||||
},
|
||||
Ok(()) => unreachable!(),
|
||||
}
|
||||
},
|
||||
ChannelMonitorUpdateErr::TemporaryFailure => {
|
||||
// Its completely fine to continue with a FundingCreated until the monitor
|
||||
// update is persisted, as long as we don't generate the FundingBroadcastSafe
|
||||
// until the monitor has been safely persisted (as funding broadcast is not,
|
||||
// in fact, safe).
|
||||
chan.monitor_update_failed(false, false, Vec::new(), Vec::new());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let mut channel_state = self.channel_state.lock().unwrap();
|
||||
|
@ -1627,6 +1649,7 @@ impl ChannelManager {
|
|||
let mut close_results = Vec::new();
|
||||
let mut htlc_forwards = Vec::new();
|
||||
let mut htlc_failures = Vec::new();
|
||||
let mut pending_events = Vec::new();
|
||||
let _ = self.total_consistency_lock.read().unwrap();
|
||||
|
||||
{
|
||||
|
@ -1661,7 +1684,7 @@ impl ChannelManager {
|
|||
ChannelMonitorUpdateErr::TemporaryFailure => true,
|
||||
}
|
||||
} else {
|
||||
let (raa, commitment_update, order, pending_forwards, mut pending_failures) = channel.monitor_updating_restored();
|
||||
let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel.monitor_updating_restored();
|
||||
if !pending_forwards.is_empty() {
|
||||
htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards));
|
||||
}
|
||||
|
@ -1693,12 +1716,33 @@ impl ChannelManager {
|
|||
handle_cs!();
|
||||
},
|
||||
}
|
||||
if needs_broadcast_safe {
|
||||
pending_events.push(events::Event::FundingBroadcastSafe {
|
||||
funding_txo: channel.get_funding_txo().unwrap(),
|
||||
user_channel_id: channel.get_user_id(),
|
||||
});
|
||||
}
|
||||
if let Some(msg) = funding_locked {
|
||||
pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
|
||||
node_id: channel.get_their_node_id(),
|
||||
msg,
|
||||
});
|
||||
if let Some(announcement_sigs) = self.get_announcement_sigs(channel) {
|
||||
pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
|
||||
node_id: channel.get_their_node_id(),
|
||||
msg: announcement_sigs,
|
||||
});
|
||||
}
|
||||
short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
|
||||
}
|
||||
true
|
||||
}
|
||||
} else { true }
|
||||
});
|
||||
}
|
||||
|
||||
self.pending_events.lock().unwrap().append(&mut pending_events);
|
||||
|
||||
for failure in htlc_failures.drain(..) {
|
||||
self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), failure.0, &failure.1, failure.2);
|
||||
}
|
||||
|
@ -1759,7 +1803,7 @@ impl ChannelManager {
|
|||
}
|
||||
|
||||
fn internal_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
|
||||
let ((funding_msg, monitor_update), chan) = {
|
||||
let ((funding_msg, monitor_update), mut chan) = {
|
||||
let mut channel_lock = self.channel_state.lock().unwrap();
|
||||
let channel_state = channel_lock.borrow_parts();
|
||||
match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
|
||||
|
@ -1775,8 +1819,23 @@ impl ChannelManager {
|
|||
};
|
||||
// Because we have exclusive ownership of the channel here we can release the channel_state
|
||||
// lock before add_update_monitor
|
||||
if let Err(_e) = self.monitor.add_update_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) {
|
||||
unimplemented!();
|
||||
if let Err(e) = self.monitor.add_update_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) {
|
||||
match e {
|
||||
ChannelMonitorUpdateErr::PermanentFailure => {
|
||||
// Note that we reply with the new channel_id in error messages if we gave up on the
|
||||
// channel, not the temporary_channel_id. This is compatible with ourselves, but the
|
||||
// spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
|
||||
// any messages referencing a previously-closed channel anyway.
|
||||
return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", funding_msg.channel_id, chan.force_shutdown(), None));
|
||||
},
|
||||
ChannelMonitorUpdateErr::TemporaryFailure => {
|
||||
// There's no problem signing a counterparty's funding transaction if our monitor
|
||||
// hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
|
||||
// accepted payment from yet. We do, however, need to wait to send our funding_locked
|
||||
// until we have persisted our monitor.
|
||||
chan.monitor_update_failed(false, false, Vec::new(), Vec::new());
|
||||
},
|
||||
}
|
||||
}
|
||||
let mut channel_state_lock = self.channel_state.lock().unwrap();
|
||||
let channel_state = channel_state_lock.borrow_parts();
|
||||
|
@ -1806,8 +1865,8 @@ impl ChannelManager {
|
|||
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
|
||||
}
|
||||
let chan_monitor = try_chan_entry!(self, chan.get_mut().funding_signed(&msg), channel_state, chan);
|
||||
if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
|
||||
unimplemented!();
|
||||
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, false, false);
|
||||
}
|
||||
(chan.get().get_funding_txo().unwrap(), chan.get().get_user_id())
|
||||
},
|
||||
|
|
|
@ -157,35 +157,39 @@ macro_rules! get_feerate {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_funding_transaction(node: &Node, expected_chan_value: u64, expected_user_chan_id: u64) -> ([u8; 32], Transaction, OutPoint) {
|
||||
let chan_id = *node.network_chan_count.borrow();
|
||||
|
||||
let events = node.node.get_and_clear_pending_events();
|
||||
assert_eq!(events.len(), 1);
|
||||
match events[0] {
|
||||
Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => {
|
||||
assert_eq!(*channel_value_satoshis, expected_chan_value);
|
||||
assert_eq!(user_channel_id, expected_user_chan_id);
|
||||
|
||||
let tx = Transaction { version: chan_id as u32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
|
||||
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
|
||||
}]};
|
||||
let funding_outpoint = OutPoint::new(tx.txid(), 0);
|
||||
(*temporary_channel_id, tx, funding_outpoint)
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_chan_between_nodes_with_value_init(node_a: &Node, node_b: &Node, channel_value: u64, push_msat: u64, a_flags: LocalFeatures, b_flags: LocalFeatures) -> Transaction {
|
||||
node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42).unwrap();
|
||||
node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id())).unwrap();
|
||||
node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id())).unwrap();
|
||||
|
||||
let chan_id = *node_a.network_chan_count.borrow();
|
||||
let tx;
|
||||
let funding_output;
|
||||
let (temporary_channel_id, tx, funding_output) = create_funding_transaction(node_a, channel_value, 42);
|
||||
|
||||
let events_2 = node_a.node.get_and_clear_pending_events();
|
||||
assert_eq!(events_2.len(), 1);
|
||||
match events_2[0] {
|
||||
Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => {
|
||||
assert_eq!(*channel_value_satoshis, channel_value);
|
||||
assert_eq!(user_channel_id, 42);
|
||||
|
||||
tx = Transaction { version: chan_id as u32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
|
||||
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
|
||||
}]};
|
||||
funding_output = OutPoint::new(tx.txid(), 0);
|
||||
|
||||
node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output);
|
||||
let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap();
|
||||
assert_eq!(added_monitors.len(), 1);
|
||||
assert_eq!(added_monitors[0].0, funding_output);
|
||||
added_monitors.clear();
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
{
|
||||
node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output);
|
||||
let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap();
|
||||
assert_eq!(added_monitors.len(), 1);
|
||||
assert_eq!(added_monitors[0].0, funding_output);
|
||||
added_monitors.clear();
|
||||
}
|
||||
|
||||
node_b.node.handle_funding_created(&node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendFundingCreated, node_b.node.get_our_node_id())).unwrap();
|
||||
|
@ -217,31 +221,37 @@ pub fn create_chan_between_nodes_with_value_init(node_a: &Node, node_b: &Node, c
|
|||
tx
|
||||
}
|
||||
|
||||
pub fn create_chan_between_nodes_with_value_confirm(node_a: &Node, node_b: &Node, tx: &Transaction) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32]) {
|
||||
confirm_transaction(&node_b.chain_monitor, &tx, tx.version);
|
||||
node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendFundingLocked, node_a.node.get_our_node_id())).unwrap();
|
||||
pub fn create_chan_between_nodes_with_value_confirm_first(node_recv: &Node, node_conf: &Node, tx: &Transaction) {
|
||||
confirm_transaction(&node_conf.chain_monitor, &tx, tx.version);
|
||||
node_recv.node.handle_funding_locked(&node_conf.node.get_our_node_id(), &get_event_msg!(node_conf, MessageSendEvent::SendFundingLocked, node_recv.node.get_our_node_id())).unwrap();
|
||||
}
|
||||
|
||||
pub fn create_chan_between_nodes_with_value_confirm_second(node_recv: &Node, node_conf: &Node) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32]) {
|
||||
let channel_id;
|
||||
|
||||
confirm_transaction(&node_a.chain_monitor, &tx, tx.version);
|
||||
let events_6 = node_a.node.get_and_clear_pending_msg_events();
|
||||
let events_6 = node_conf.node.get_and_clear_pending_msg_events();
|
||||
assert_eq!(events_6.len(), 2);
|
||||
((match events_6[0] {
|
||||
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
|
||||
channel_id = msg.channel_id.clone();
|
||||
assert_eq!(*node_id, node_b.node.get_our_node_id());
|
||||
assert_eq!(*node_id, node_recv.node.get_our_node_id());
|
||||
msg.clone()
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
}, match events_6[1] {
|
||||
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
|
||||
assert_eq!(*node_id, node_b.node.get_our_node_id());
|
||||
assert_eq!(*node_id, node_recv.node.get_our_node_id());
|
||||
msg.clone()
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
}), channel_id)
|
||||
}
|
||||
|
||||
pub fn create_chan_between_nodes_with_value_confirm(node_a: &Node, node_b: &Node, tx: &Transaction) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32]) {
|
||||
create_chan_between_nodes_with_value_confirm_first(node_a, node_b, tx);
|
||||
confirm_transaction(&node_a.chain_monitor, &tx, tx.version);
|
||||
create_chan_between_nodes_with_value_confirm_second(node_b, node_a)
|
||||
}
|
||||
|
||||
pub fn create_chan_between_nodes_with_value_a(node_a: &Node, node_b: &Node, channel_value: u64, push_msat: u64, a_flags: LocalFeatures, b_flags: LocalFeatures) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32], Transaction) {
|
||||
let tx = create_chan_between_nodes_with_value_init(node_a, node_b, channel_value, push_msat, a_flags, b_flags);
|
||||
let (msgs, chan_id) = create_chan_between_nodes_with_value_confirm(node_a, node_b, &tx);
|
||||
|
|
Loading…
Add table
Reference in a new issue