pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
let _ = self.total_consistency_lock.read().unwrap();
- let (mut chan, msg, chan_monitor) = {
+ let (chan, msg) = {
let (res, chan) = match self.channel_state.lock().unwrap().by_id.remove(temporary_channel_id) {
Some(mut chan) => {
(chan.get_outbound_funding_created(funding_txo)
};
match handle_error!(self, res, chan.get_their_node_id()) {
Ok(funding_msg) => {
- (chan, funding_msg.0, funding_msg.1)
+ (chan, funding_msg)
},
Err(_) => { return; }
}
};
- // Because we have exclusive ownership of the channel here we can release the channel_state
- // lock before add_monitor
- if let Err(e) = self.monitor.add_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(true), None)), chan.get_their_node_id()) {
- Err(_) => { 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();
channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
}
if total_value >= msgs::MAX_VALUE_MSAT || total_value > data.total_msat {
for htlc in htlcs.iter() {
+ let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
+ htlc_msat_height_data.extend_from_slice(
+ &byte_utils::be32_to_array(
+ self.latest_block_height.load(Ordering::Acquire)
+ as u32,
+ ),
+ );
failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
short_channel_id: htlc.prev_hop.short_channel_id,
htlc_id: htlc.prev_hop.htlc_id,
incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret,
}), payment_hash,
- HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(htlc.value).to_vec() }
+ HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }
));
}
} else if total_value == data.total_msat {
if let Some(mut sources) = removed_source {
for htlc in sources.drain(..) {
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
+ let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
+ htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
+ self.latest_block_height.load(Ordering::Acquire) as u32,
+ ));
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash,
- HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(htlc.value).to_vec() });
+ HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data });
}
true
} else { false }
match &onion_error {
&HTLCFailReason::LightningError { ref err } => {
#[cfg(test)]
- let (channel_update, payment_retryable, onion_error_code) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
+ let (channel_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
#[cfg(not(test))]
- let (channel_update, payment_retryable, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
+ let (channel_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
// TODO: If we decided to blame ourselves (or one of our channels) in
// process_onion_failure we should close that channel as it implies our
// next-hop is needlessly blaming us!
payment_hash: payment_hash.clone(),
rejected_by_dest: !payment_retryable,
#[cfg(test)]
- error_code: onion_error_code
+ error_code: onion_error_code,
+#[cfg(test)]
+ error_data: onion_error_data
}
);
},
&HTLCFailReason::Reason {
#[cfg(test)]
ref failure_code,
+#[cfg(test)]
+ ref data,
.. } => {
// we get a fail_malformed_htlc from the first hop
// TODO: We'd like to generate a PaymentFailureNetworkUpdate for temporary
rejected_by_dest: path.len() == 1,
#[cfg(test)]
error_code: Some(*failure_code),
+#[cfg(test)]
+ error_data: Some(data.clone()),
}
);
}
for htlc in sources.drain(..) {
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) {
- let mut htlc_msat_data = byte_utils::be64_to_array(htlc.value).to_vec();
- let mut height_data = byte_utils::be32_to_array(self.latest_block_height.load(Ordering::Acquire) as u32).to_vec();
- htlc_msat_data.append(&mut height_data);
+ let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
+ htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
+ self.latest_block_height.load(Ordering::Acquire) as u32,
+ ));
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
- HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_data });
+ HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data });
} else {
match self.claim_funds_from_hop(channel_state.as_mut().unwrap(), htlc.prev_hop, payment_preimage) {
Err(Some(e)) => {
};
// Because we have exclusive ownership of the channel here we can release the channel_state
// lock before add_monitor
- if let Err(e) = self.monitor.add_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) {
+ if let Err(e) = self.monitor.add_monitor(monitor_update.get_funding_txo(), monitor_update) {
match e {
ChannelMonitorUpdateErr::PermanentFailure => {
// Note that we reply with the new channel_id in error messages if we gave up on the
if chan.get().get_their_node_id() != *their_node_id {
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
- let monitor_update = match chan.get_mut().funding_signed(&msg) {
- Err((None, e)) => try_chan_entry!(self, Err(e), channel_state, chan),
- Err((Some(monitor_update), e)) => {
- assert!(chan.get().is_awaiting_monitor_update());
- let _ = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update);
- try_chan_entry!(self, Err(e), channel_state, chan);
- unreachable!();
- },
+ let monitor = match chan.get_mut().funding_signed(&msg) {
Ok(update) => update,
+ Err(e) => try_chan_entry!(self, Err(e), channel_state, chan),
};
- if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
+ if let Err(e) = self.monitor.add_monitor(chan.get().get_funding_txo().unwrap(), monitor) {
return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, false, false);
}
(chan.get().get_funding_txo().unwrap(), chan.get().get_user_id())