X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=9a586254beaad85cce559fa898846db5135b2ffe;hb=HEAD;hp=e539490951d9b2e9cd780c2189c1e76775ae7586;hpb=28794931b72d7de3f79a554321fb3892c66f9e80;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index e5394909..9a586254 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -366,19 +366,21 @@ pub const OUR_MAX_HTLCS: u16 = 50; //TODO /// Confirmation count threshold at which we close a channel. Ideally we'd keep the channel around /// on ice until the funding transaction gets more confirmations, but the LN protocol doesn't /// really allow for this, so instead we're stuck closing it out at that point. -const UNCONF_THRESHOLD: u32 = 6; +const UNCONF_THRESHOLD: u32 = 1; const SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT: u64 = 79; // prevout: 36, nSequence: 4, script len: 1, witness lengths: (3+1)/4, sig: 73/4, if-selector: 1, redeemScript: (6 ops + 2*33 pubkeys + 1*2 delay)/4 const B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT: u64 = 104; // prevout: 40, nSequence: 4, script len: 1, witness lengths: 3/4, sig: 73/4, pubkey: 33/4, output: 31 (TODO: Wrong? Useless?) #[cfg(not(test))] -const COMMITMENT_TX_BASE_WEIGHT: u64 = 724; +const COMMITMENT_TX_BASE_WEIGHT: u64 = 896; #[cfg(test)] -pub const COMMITMENT_TX_BASE_WEIGHT: u64 = 724; +pub const COMMITMENT_TX_BASE_WEIGHT: u64 = 896; #[cfg(not(test))] const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172; #[cfg(test)] pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172; +const ANCHOR_VALUE_SATOSHIS: u64 = 330; + /// Maximmum `funding_satoshis` value, according to the BOLT #2 specification /// it's 2^24. pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24; @@ -539,7 +541,7 @@ impl Channel { if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) { return Err(ChannelError::Close("Peer's feerate much too low")); } - if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * 2 { + if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * 200 { return Err(ChannelError::Close("Peer's feerate much too high")); } Ok(()) @@ -648,13 +650,14 @@ impl Channel { // check if the funder's amount for the initial commitment tx is sufficient // for full fee payment let funders_amount_msat = msg.funding_satoshis * 1000 - msg.push_msat; - if funders_amount_msat < background_feerate * COMMITMENT_TX_BASE_WEIGHT { + if funders_amount_msat < background_feerate * COMMITMENT_TX_BASE_WEIGHT + ANCHOR_VALUE_SATOSHIS * 1000 { return Err(ChannelError::Close("Insufficient funding amount for initial commitment")); } - let to_local_msat = msg.push_msat; - let to_remote_msat = funders_amount_msat - background_feerate * COMMITMENT_TX_BASE_WEIGHT; - if to_local_msat <= msg.channel_reserve_satoshis * 1000 && to_remote_msat <= remote_channel_reserve_satoshis * 1000 { + let to_remote_msat = funders_amount_msat - background_feerate * COMMITMENT_TX_BASE_WEIGHT - ANCHOR_VALUE_SATOSHIS * 1000; + // While its reasonable for us to not meet the channel reserve initially (if they don't + // want to push much to us), our counterparty should always have more than the reserve. + if to_remote_msat <= remote_channel_reserve_satoshis * 1000 { return Err(ChannelError::Close("Insufficient funding amount for initial commitment")); } @@ -954,14 +957,24 @@ impl Channel { let total_fee: u64 = feerate_per_kw * (COMMITMENT_TX_BASE_WEIGHT + (txouts.len() as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000; let (value_to_self, value_to_remote) = if self.channel_outbound { - (value_to_self_msat / 1000 - total_fee as i64, value_to_remote_msat / 1000) + (value_to_self_msat / 1000 - total_fee as i64 - ANCHOR_VALUE_SATOSHIS as i64, value_to_remote_msat / 1000) } else { - (value_to_self_msat / 1000, value_to_remote_msat / 1000 - total_fee as i64) + (value_to_self_msat / 1000, value_to_remote_msat / 1000 - total_fee as i64 - ANCHOR_VALUE_SATOSHIS as i64) }; + debug_assert!(value_to_self >= 0); + debug_assert!(value_to_remote >= 0); let value_to_a = if local { value_to_self } else { value_to_remote }; let value_to_b = if local { value_to_remote } else { value_to_self }; + if value_to_a >= (dust_limit_satoshis as i64) || !txouts.is_empty() { + // Always push the anchor output so that local can get the transaction confirmed. + txouts.push((TxOut { + script_pubkey: Script::new(), //XXX + value: ANCHOR_VALUE_SATOSHIS + }, None)); + } + if value_to_a >= (dust_limit_satoshis as i64) { log_trace!(logger, " ...including {} output with value {}", if local { "to_local" } else { "to_remote" }, value_to_a); txouts.push((TxOut { @@ -987,6 +1000,7 @@ impl Channel { }, None)); } + transaction_utils::sort_outputs(&mut txouts, |a, b| { if let &Some(ref a_htlc) = a { if let &Some(ref b_htlc) = b { @@ -1751,6 +1765,7 @@ debug_assert!(false, "This should be triggerable, and we should add a test case None => {}, Some(payment_hash) => if payment_hash != htlc.payment_hash { + println!("FAIL: {:?}, {:?}", htlc.payment_hash, payment_hash); return Err(ChannelError::Close("Remote tried to fulfill HTLC with an incorrect preimage")); } }; @@ -1846,7 +1861,7 @@ debug_assert!(false, "This should be triggerable, and we should add a test case //If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction if update_fee { let num_htlcs = local_commitment_tx.1; - let total_fee: u64 = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000; + let total_fee: u64 = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000 + ANCHOR_VALUE_SATOSHIS; let remote_reserve_we_require = Channel::::get_remote_channel_reserve_satoshis(self.channel_value_satoshis); if self.channel_value_satoshis - self.value_to_self_msat / 1000 < total_fee + remote_reserve_we_require { @@ -2492,6 +2507,7 @@ debug_assert!(false, "This should be triggerable, and we should add a test case let commitment_update = if self.monitor_pending_commitment_signed { Some(self.get_last_commitment_update(logger)) } else { None }; +//XXX: Should we free_holding_cell_htlcs() here if we dont need a cs normally? self.monitor_pending_revoke_and_ack = false; self.monitor_pending_commitment_signed = false;