X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=374d74f6c18b578b8123e4f2344375164abff704;hb=3512d6626d24a16337bfb92b470b928bb880ad23;hp=2e4f49ce8371991630e8e5c470b6a625ee821a1a;hpb=ce4de5fb52246f91d37127594f8fd7d304ab86ad;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 2e4f49ce..374d74f6 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -295,7 +295,7 @@ pub(super) struct Channel { holding_cell_update_fee: Option, next_local_htlc_id: u64, next_remote_htlc_id: u64, - channel_update_count: u32, + update_time_counter: u32, feerate_per_kw: u64, #[cfg(debug_assertions)] @@ -433,10 +433,6 @@ impl Channel { cmp::max(at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000, 546) //TODO } - fn derive_our_htlc_minimum_msat(_at_open_channel_feerate_per_kw: u64) -> u64 { - 1000 // TODO - } - // Constructors: pub fn new_outbound(fee_estimator: &F, keys_provider: &K, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc, config: &UserConfig) -> Result, APIError> where K::Target: KeysInterface, @@ -490,7 +486,7 @@ impl Channel { holding_cell_update_fee: None, next_local_htlc_id: 0, next_remote_htlc_id: 0, - channel_update_count: 1, + update_time_counter: 1, resend_order: RAACommitmentOrder::CommitmentFirst, @@ -519,7 +515,7 @@ impl Channel { their_max_htlc_value_in_flight_msat: 0, their_channel_reserve_satoshis: 0, their_htlc_minimum_msat: 0, - our_htlc_minimum_msat: Channel::::derive_our_htlc_minimum_msat(feerate), + our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat }, their_to_self_delay: 0, our_to_self_delay: config.own_channel_config.our_to_self_delay, their_max_accepted_htlcs: 0, @@ -714,7 +710,7 @@ impl Channel { holding_cell_update_fee: None, next_local_htlc_id: 0, next_remote_htlc_id: 0, - channel_update_count: 1, + update_time_counter: 1, resend_order: RAACommitmentOrder::CommitmentFirst, @@ -744,7 +740,7 @@ impl Channel { their_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000), their_channel_reserve_satoshis: msg.channel_reserve_satoshis, their_htlc_minimum_msat: msg.htlc_minimum_msat, - our_htlc_minimum_msat: Channel::::derive_our_htlc_minimum_msat(msg.feerate_per_kw as u64), + our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat }, their_to_self_delay: msg.to_self_delay, our_to_self_delay: config.own_channel_config.our_to_self_delay, their_max_accepted_htlcs: msg.max_accepted_htlcs, @@ -1142,8 +1138,11 @@ impl Channel { } /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made. - /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return - /// Ok(_) if debug assertions are turned on and preconditions are met. + /// In such cases we debug_assert!(false) and return a ChannelError::Ignore. Thus, will always + /// return Ok(_) if debug assertions are turned on or preconditions are met. + /// + /// Note that it is still possible to hit these assertions in case we find a preimage on-chain + /// but then have a reorg which settles on an HTLC-failure on chain. fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage) -> Result<(Option, Option), ChannelError> { // Either ChannelFunded got set (which means it won't be unset) or there is no way any // caller thought we could have something claimed (cause we wouldn't have accepted in an @@ -1171,6 +1170,7 @@ impl Channel { } else { log_warn!(self, "Have preimage and want to fulfill HTLC with payment hash {} we already failed against channel {}", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id())); } + debug_assert!(false, "Tried to fulfill an HTLC that was already fail/fulfilled"); return Ok((None, None)); }, _ => { @@ -1204,6 +1204,9 @@ impl Channel { match pending_update { &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => { if htlc_id_arg == htlc_id { + // Make sure we don't leave latest_monitor_update_id incremented here: + self.latest_monitor_update_id -= 1; + debug_assert!(false, "Tried to fulfill an HTLC that was already fulfilled"); return Ok((None, None)); } }, @@ -1212,6 +1215,7 @@ impl Channel { log_warn!(self, "Have preimage and want to fulfill HTLC with pending failure against channel {}", log_bytes!(self.channel_id())); // TODO: We may actually be able to switch to a fulfill here, though its // rare enough it may not be worth the complexity burden. + debug_assert!(false, "Tried to fulfill an HTLC that was already failed"); return Ok((None, Some(monitor_update))); } }, @@ -1263,8 +1267,11 @@ impl Channel { } /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made. - /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return - /// Ok(_) if debug assertions are turned on and preconditions are met. + /// In such cases we debug_assert!(false) and return a ChannelError::Ignore. Thus, will always + /// return Ok(_) if debug assertions are turned on or preconditions are met. + /// + /// Note that it is still possible to hit these assertions in case we find a preimage on-chain + /// but then have a reorg which settles on an HTLC-failure on chain. pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket) -> Result, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { panic!("Was asked to fail an HTLC when channel was not in an operational state"); @@ -1281,6 +1288,7 @@ impl Channel { match htlc.state { InboundHTLCState::Committed => {}, InboundHTLCState::LocalRemoved(_) => { + debug_assert!(false, "Tried to fail an HTLC that was already fail/fulfilled"); return Ok(None); }, _ => { @@ -1301,11 +1309,13 @@ impl Channel { match pending_update { &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => { if htlc_id_arg == htlc_id { + debug_assert!(false, "Tried to fail an HTLC that was already fulfilled"); return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID")); } }, &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, .. } => { if htlc_id_arg == htlc_id { + debug_assert!(false, "Tried to fail an HTLC that was already failed"); return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID")); } }, @@ -1586,7 +1596,7 @@ impl Channel { self.channel_state |= ChannelState::TheirFundingLocked as u32; } 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; + self.update_time_counter += 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 && @@ -1656,6 +1666,9 @@ impl Channel { if msg.amount_msat > self.channel_value_satoshis * 1000 { return Err(ChannelError::Close("Remote side tried to send more than the total value of the channel")); } + if msg.amount_msat == 0 { + return Err(ChannelError::Close("Remote side tried to send a 0-msat HTLC")); + } if msg.amount_msat < self.our_htlc_minimum_msat { return Err(ChannelError::Close("Remote side tried to send less than our minimum HTLC value")); } @@ -2480,7 +2493,7 @@ impl Channel { } Channel::::check_remote_fee(fee_estimator, msg.feerate_per_kw)?; self.pending_update_fee = Some(msg.feerate_per_kw as u64); - self.channel_update_count += 1; + self.update_time_counter += 1; Ok(()) } @@ -2763,7 +2776,7 @@ impl Channel { // From here on out, we may not fail! self.channel_state |= ChannelState::RemoteShutdownSent as u32; - self.channel_update_count += 1; + self.update_time_counter += 1; // We can't send our shutdown until we've committed all of our pending HTLCs, but the // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding @@ -2793,7 +2806,7 @@ impl Channel { }; self.channel_state |= ChannelState::LocalShutdownSent as u32; - self.channel_update_count += 1; + self.update_time_counter += 1; Ok((our_shutdown, self.maybe_propose_first_closing_signed(fee_estimator), dropped_outbound_htlcs)) } @@ -2860,7 +2873,7 @@ impl Channel { if last_fee == msg.fee_satoshis { self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig); self.channel_state = ChannelState::ShutdownComplete as u32; - self.channel_update_count += 1; + self.update_time_counter += 1; return Ok((None, Some(closing_tx))); } } @@ -2910,7 +2923,7 @@ impl Channel { self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig); self.channel_state = ChannelState::ShutdownComplete as u32; - self.channel_update_count += 1; + self.update_time_counter += 1; Ok((Some(msgs::ClosingSigned { channel_id: self.channel_id, @@ -3022,8 +3035,8 @@ impl Channel { } /// Allowed in any state (including after shutdown) - pub fn get_channel_update_count(&self) -> u32 { - self.channel_update_count + pub fn get_update_time_counter(&self) -> u32 { + self.update_time_counter } pub fn get_latest_monitor_update_id(&self) -> u64 { @@ -3149,7 +3162,7 @@ impl Channel { panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!"); } self.channel_state = ChannelState::ShutdownComplete as u32; - self.channel_update_count += 1; + self.update_time_counter += 1; return Err(msgs::ErrorMessage { channel_id: self.channel_id(), data: "funding tx had wrong script/value".to_owned() @@ -3175,6 +3188,7 @@ impl Channel { } if header.bitcoin_hash() != self.last_block_connected { self.last_block_connected = header.bitcoin_hash(); + self.update_time_counter = cmp::max(self.update_time_counter, header.time); if let Some(channel_monitor) = self.channel_monitor.as_mut() { channel_monitor.last_block_hash = self.last_block_connected; } @@ -3185,7 +3199,7 @@ impl Channel { true } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) { self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS); - self.channel_update_count += 1; + self.update_time_counter += 1; true } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) { // We got a reorg but not enough to trigger a force close, just update @@ -3444,10 +3458,10 @@ impl Channel { my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1)) }) } else { - log_debug!(self, "We don't seen yet any revoked secret, if this channnel has already been updated it means we are fallen-behind, you should wait for other peer closing"); + log_info!(self, "Sending a data_loss_protect with no previous remote per_commitment_secret"); OptionalField::Present(DataLossProtect { your_last_per_commitment_secret: [0;32], - my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number)) + my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1)) }) }; msgs::ChannelReestablish { @@ -3492,6 +3506,11 @@ impl Channel { if amount_msat > self.channel_value_satoshis * 1000 { return Err(ChannelError::Ignore("Cannot send more than the total value of the channel")); } + + if amount_msat == 0 { + return Err(ChannelError::Ignore("Cannot send 0-msat HTLC")); + } + if amount_msat < self.their_htlc_minimum_msat { return Err(ChannelError::Ignore("Cannot send less than their minimum HTLC value")); } @@ -3728,7 +3747,7 @@ impl Channel { } else { self.channel_state |= ChannelState::LocalShutdownSent as u32; } - self.channel_update_count += 1; + self.update_time_counter += 1; // Go ahead and drop holding cell updates as we'd rather fail payments than wait to send // our shutdown until we've committed all of the pending changes. @@ -3755,7 +3774,7 @@ impl Channel { /// those explicitly stated to be allowed after shutdown completes, eg some simple getters). /// Also returns the list of payment_hashes for channels which we can safely fail backwards /// immediately (others we will have to allow to time out). - pub fn force_shutdown(&mut self) -> (Vec, Vec<(HTLCSource, PaymentHash)>) { + pub fn force_shutdown(&mut self, should_broadcast: bool) -> (Option, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>) { assert!(self.channel_state != ChannelState::ShutdownComplete as u32); // We go ahead and "free" any holding cell HTLCs or HTLCs we haven't yet committed to and @@ -3777,13 +3796,12 @@ impl Channel { } self.channel_state = ChannelState::ShutdownComplete as u32; - self.channel_update_count += 1; - if self.channel_monitor.is_some() { - (self.channel_monitor.as_mut().unwrap().get_latest_local_commitment_txn(), dropped_outbound_htlcs) - } else { - // We aren't even signed funding yet, so can't broadcast anything - (Vec::new(), dropped_outbound_htlcs) - } + self.update_time_counter += 1; + self.latest_monitor_update_id += 1; + (self.funding_txo.clone(), ChannelMonitorUpdate { + update_id: self.latest_monitor_update_id, + updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }], + }, dropped_outbound_htlcs) } } @@ -3811,9 +3829,9 @@ impl Writeable for InboundHTLCRemovalReason { } } -impl Readable for InboundHTLCRemovalReason { - fn read(reader: &mut R) -> Result { - Ok(match >::read(reader)? { +impl Readable for InboundHTLCRemovalReason { + fn read(reader: &mut R) -> Result { + Ok(match ::read(reader)? { 0 => InboundHTLCRemovalReason::FailRelay(Readable::read(reader)?), 1 => InboundHTLCRemovalReason::FailMalformed((Readable::read(reader)?, Readable::read(reader)?)), 2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?), @@ -3883,18 +3901,6 @@ impl Writeable for Channel { } } - macro_rules! write_option { - ($thing: expr) => { - match &$thing { - &None => 0u8.write(writer)?, - &Some(ref v) => { - 1u8.write(writer)?; - v.write(writer)?; - }, - } - } - } - (self.pending_outbound_htlcs.len() as u64).write(writer)?; for htlc in self.pending_outbound_htlcs.iter() { htlc.htlc_id.write(writer)?; @@ -3912,15 +3918,15 @@ impl Writeable for Channel { }, &OutboundHTLCState::RemoteRemoved(ref fail_reason) => { 2u8.write(writer)?; - write_option!(*fail_reason); + fail_reason.write(writer)?; }, &OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref fail_reason) => { 3u8.write(writer)?; - write_option!(*fail_reason); + fail_reason.write(writer)?; }, &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref fail_reason) => { 4u8.write(writer)?; - write_option!(*fail_reason); + fail_reason.write(writer)?; }, } } @@ -3971,12 +3977,12 @@ impl Writeable for Channel { fail_reason.write(writer)?; } - write_option!(self.pending_update_fee); - write_option!(self.holding_cell_update_fee); + self.pending_update_fee.write(writer)?; + self.holding_cell_update_fee.write(writer)?; self.next_local_htlc_id.write(writer)?; (self.next_remote_htlc_id - dropped_inbound_htlcs).write(writer)?; - self.channel_update_count.write(writer)?; + self.update_time_counter.write(writer)?; self.feerate_per_kw.write(writer)?; match self.last_sent_closing_fee { @@ -3989,9 +3995,9 @@ impl Writeable for Channel { None => 0u8.write(writer)?, } - write_option!(self.funding_txo); - write_option!(self.funding_tx_confirmed_in); - write_option!(self.short_channel_id); + self.funding_txo.write(writer)?; + self.funding_tx_confirmed_in.write(writer)?; + self.short_channel_id.write(writer)?; self.last_block_connected.write(writer)?; self.funding_tx_confirmations.write(writer)?; @@ -4007,13 +4013,13 @@ impl Writeable for Channel { self.their_max_accepted_htlcs.write(writer)?; self.minimum_depth.write(writer)?; - write_option!(self.their_pubkeys); - write_option!(self.their_cur_commitment_point); + self.their_pubkeys.write(writer)?; + self.their_cur_commitment_point.write(writer)?; - write_option!(self.their_prev_commitment_point); + self.their_prev_commitment_point.write(writer)?; self.their_node_id.write(writer)?; - write_option!(self.their_shutdown_scriptpubkey); + self.their_shutdown_scriptpubkey.write(writer)?; self.commitment_secrets.write(writer)?; @@ -4022,8 +4028,8 @@ impl Writeable for Channel { } } -impl> ReadableArgs> for Channel { - fn read(reader: &mut R, logger: Arc) -> Result { +impl ReadableArgs> for Channel { + fn read(reader: &mut R, logger: Arc) -> Result { let _ver: u8 = Readable::read(reader)?; let min_ver: u8 = Readable::read(reader)?; if min_ver > SERIALIZATION_VERSION { @@ -4056,7 +4062,7 @@ impl> ReadableArgs>::read(reader)? { + state: match ::read(reader)? { 1 => InboundHTLCState::AwaitingRemoteRevokeToAnnounce(Readable::read(reader)?), 2 => InboundHTLCState::AwaitingAnnouncedRemoteRevoke(Readable::read(reader)?), 3 => InboundHTLCState::Committed, @@ -4075,7 +4081,7 @@ impl> ReadableArgs>::read(reader)? { + state: match ::read(reader)? { 0 => OutboundHTLCState::LocalAnnounced(Box::new(Readable::read(reader)?)), 1 => OutboundHTLCState::Committed, 2 => OutboundHTLCState::RemoteRemoved(Readable::read(reader)?), @@ -4089,7 +4095,7 @@ impl> ReadableArgs>::read(reader)? { + holding_cell_htlc_updates.push(match ::read(reader)? { 0 => HTLCUpdateAwaitingACK::AddHTLC { amount_msat: Readable::read(reader)?, cltv_expiry: Readable::read(reader)?, @@ -4109,7 +4115,7 @@ impl> ReadableArgs>::read(reader)? { + let resend_order = match ::read(reader)? { 0 => RAACommitmentOrder::CommitmentFirst, 1 => RAACommitmentOrder::RevokeAndACKFirst, _ => return Err(DecodeError::InvalidValue), @@ -4136,10 +4142,10 @@ impl> ReadableArgs>::read(reader)? { + let last_sent_closing_fee = match ::read(reader)? { 0 => None, 1 => Some((Readable::read(reader)?, Readable::read(reader)?, Readable::read(reader)?)), _ => return Err(DecodeError::InvalidValue), @@ -4215,7 +4221,7 @@ impl> ReadableArgs> ReadableArgs = Arc::new(test_utils::TestLogger::new()); + let secp_ctx = Secp256k1::new(); + let mut seed = [0; 32]; + let mut rng = thread_rng(); + rng.fill_bytes(&mut seed); + let network = Network::Testnet; + let keys_provider = test_utils::TestKeysInterface::new(&seed, network, logger.clone() as Arc); + + // Go through the flow of opening a channel between two nodes. + + // Create Node A's channel + let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); + let config = UserConfig::default(); + let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_a_node_id, 10000000, 100000, 42, Arc::clone(&logger), &config).unwrap(); + + // Create Node B's channel by receiving Node A's open_channel message + let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.bitcoin_hash(), &&feeest); + let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); + let mut node_b_chan = Channel::::new_from_req(&&feeest, &&keys_provider, node_b_node_id, InitFeatures::supported(), &open_channel_msg, 7, logger, &config).unwrap(); + + // Node B --> Node A: accept channel + let accept_channel_msg = node_b_chan.get_accept_channel(); + node_a_chan.accept_channel(&accept_channel_msg, &config, InitFeatures::supported()).unwrap(); + + // Node A --> Node B: funding created + let output_script = node_a_chan.get_funding_redeemscript(); + let tx = Transaction { version: 1, lock_time: 0, input: Vec::new(), output: vec![TxOut { + value: 10000000, script_pubkey: output_script.clone(), + }]}; + let funding_outpoint = OutPoint::new(tx.txid(), 0); + let (funding_created_msg, _) = node_a_chan.get_outbound_funding_created(funding_outpoint).unwrap(); + let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg).unwrap(); + + // Node B --> Node A: funding signed + let _ = node_a_chan.funding_signed(&funding_signed_msg); + + // Now disconnect the two nodes and check that the commitment point in + // Node B's channel_reestablish message is sane. + node_b_chan.remove_uncommitted_htlcs_and_mark_paused(); + let expected_commitment_point = PublicKey::from_secret_key(&secp_ctx, &node_b_chan.build_local_commitment_secret(node_b_chan.cur_local_commitment_transaction_number + 1)); + let msg = node_b_chan.get_channel_reestablish(); + match msg.data_loss_protect { + OptionalField::Present(DataLossProtect { my_current_per_commitment_point, .. }) => { + assert_eq!(expected_commitment_point, my_current_per_commitment_point); + }, + _ => panic!() + } + + // Check that the commitment point in Node A's channel_reestablish message + // is sane. + node_a_chan.remove_uncommitted_htlcs_and_mark_paused(); + let expected_commitment_point = PublicKey::from_secret_key(&secp_ctx, &node_a_chan.build_local_commitment_secret(node_a_chan.cur_local_commitment_transaction_number + 1)); + let msg = node_a_chan.get_channel_reestablish(); + match msg.data_loss_protect { + OptionalField::Present(DataLossProtect { my_current_per_commitment_point, .. }) => { + assert_eq!(expected_commitment_point, my_current_per_commitment_point); + }, + _ => panic!() + } + } + #[test] fn outbound_commitment_test() { // Test vectors from BOLT 3 Appendix C: