X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannel.rs;h=3a627f35baa9548881e8e52f8b1f888abff791a6;hb=refs%2Fheads%2F2018-09-163-cleanups;hp=3a442091cb0919436d605d661ad8aae68810de44;hpb=cf6532e3e6a52154e4d09f64c17a46b34e441da0;p=rust-lightning diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 3a442091..3a627f35 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -14,20 +14,23 @@ use crypto::digest::Digest; use crypto::hkdf::{hkdf_extract,hkdf_expand}; use ln::msgs; -use ln::msgs::{HandleError, MsgEncodable}; +use ln::msgs::{ErrorAction, HandleError, MsgEncodable}; use ln::channelmonitor::ChannelMonitor; -use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason}; +use ln::channelmanager::{PendingHTLCStatus, HTLCSource, PendingForwardHTLCInfo, HTLCFailReason, HTLCFailureMsg}; use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT}; use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; use chain::transaction::OutPoint; use util::{transaction_utils,rng}; use util::sha2::Sha256; +use util::logger::Logger; +use util::errors::APIError; use std; use std::default::Default; use std::{cmp,mem}; use std::time::Instant; +use std::sync::{Arc}; pub struct ChannelKeys { pub funding_key: SecretKey, @@ -84,7 +87,7 @@ impl ChannelKeys { } #[derive(PartialEq)] -enum HTLCState { +enum InboundHTLCState { /// Added by remote, to be included in next local commitment tx. RemoteAnnounced, /// Included in a received commitment_signed message (implying we've revoke_and_ack'ed it), but @@ -99,6 +102,34 @@ enum HTLCState { /// We have included this HTLC in our latest commitment_signed and are now just waiting on a /// revoke_and_ack. AwaitingAnnouncedRemoteRevoke, + Committed, + /// Removed by us and a new commitment_signed was sent (if we were AwaitingRemoteRevoke when we + /// created it we would have put it in the holding cell instead). When they next revoke_and_ack + /// we'll drop it. + /// Note that we have to keep an eye on the HTLC until we've received a broadcastable + /// commitment transaction without it as otherwise we'll have to force-close the channel to + /// claim it before the timeout (obviously doesn't apply to revoked HTLCs that we can't claim + /// anyway). That said, ChannelMonitor does this for us (see + /// ChannelMonitor::would_broadcast_at_height) so we actually remove the HTLC from our own + /// local state before then, once we're sure that the next commitment_signed and + /// ChannelMonitor::provide_latest_local_commitment_tx_info will not include this HTLC. + LocalRemoved, +} + +struct InboundHTLCOutput { + htlc_id: u64, + amount_msat: u64, + cltv_expiry: u32, + payment_hash: [u8; 32], + state: InboundHTLCState, + /// If we're in LocalRemoved, set to true if we fulfilled the HTLC, and can claim money + local_removed_fulfilled: bool, + /// state pre-Committed implies pending_forward_state, otherwise it must be None + pending_forward_state: Option, +} + +#[derive(PartialEq)] +enum OutboundHTLCState { /// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we /// created it we would have put it in the holding cell instead). When they next revoke_and_ack /// we will promote to Committed (note that they may not accept it until the next time we @@ -126,42 +157,26 @@ enum HTLCState { /// We have removed this HTLC in our latest commitment_signed and are now just waiting on a /// revoke_and_ack to drop completely. AwaitingRemovedRemoteRevoke, - /// Removed by us and a new commitment_signed was sent (if we were AwaitingRemoteRevoke when we - /// created it we would have put it in the holding cell instead). When they next revoke_and_ack - /// we'll promote to LocalRemovedAwaitingCommitment if we fulfilled, otherwise we'll drop at - /// that point. - /// Note that we have to keep an eye on the HTLC until we've received a broadcastable - /// commitment transaction without it as otherwise we'll have to force-close the channel to - /// claim it before the timeout (obviously doesn't apply to revoked HTLCs that we can't claim - /// anyway). - LocalRemoved, - /// Removed by us, sent a new commitment_signed and got a revoke_and_ack. Just waiting on an - /// updated local commitment transaction. - LocalRemovedAwaitingCommitment, } -struct HTLCOutput { //TODO: Refactor into Outbound/InboundHTLCOutput (will save memory and fewer panics) - outbound: bool, // ie to an HTLC-Timeout transaction +struct OutboundHTLCOutput { htlc_id: u64, amount_msat: u64, cltv_expiry: u32, payment_hash: [u8; 32], - state: HTLCState, - /// If we're in a Remote* removed state, set if they failed, otherwise None + state: OutboundHTLCState, + source: HTLCSource, + /// If we're in a removed state, set if they failed, otherwise None fail_reason: Option, - /// If we're in LocalRemoved*, set to true if we fulfilled the HTLC, and can claim money - local_removed_fulfilled: bool, - /// state pre-committed Remote* implies pending_forward_state, otherwise it must be None - pending_forward_state: Option, } -impl HTLCOutput { - fn get_in_commitment(&self, offered: bool) -> HTLCOutputInCommitment { +macro_rules! get_htlc_in_commitment { + ($htlc: expr, $offered: expr) => { HTLCOutputInCommitment { - offered: offered, - amount_msat: self.amount_msat, - cltv_expiry: self.cltv_expiry, - payment_hash: self.payment_hash, + offered: $offered, + amount_msat: $htlc.amount_msat, + cltv_expiry: $htlc.cltv_expiry, + payment_hash: $htlc.payment_hash, transaction_output_index: 0 } } @@ -174,15 +189,16 @@ enum HTLCUpdateAwaitingACK { amount_msat: u64, cltv_expiry: u32, payment_hash: [u8; 32], + source: HTLCSource, onion_routing_packet: msgs::OnionPacket, time_created: Instant, //TODO: Some kind of timeout thing-a-majig }, ClaimHTLC { payment_preimage: [u8; 32], - payment_hash: [u8; 32], // Only here for effecient duplicate detection + htlc_id: u64, }, FailHTLC { - payment_hash: [u8; 32], + htlc_id: u64, err_packet: msgs::OnionErrorPacket, }, } @@ -239,7 +255,7 @@ pub struct Channel { channel_id: [u8; 32], channel_state: u32, channel_outbound: bool, - secp_ctx: Secp256k1, + secp_ctx: Secp256k1, announce_publicly: bool, channel_value_satoshis: u64, @@ -252,7 +268,8 @@ pub struct Channel { cur_local_commitment_transaction_number: u64, cur_remote_commitment_transaction_number: u64, value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees - pending_htlcs: Vec, + pending_inbound_htlcs: Vec, + pending_outbound_htlcs: Vec, holding_cell_htlc_updates: Vec, next_local_htlc_id: u64, next_remote_htlc_id: u64, @@ -271,7 +288,7 @@ pub struct Channel { /// to detect unconfirmation after a serialize-unserialize roudtrip where we may not see a full /// series of block_connected/block_disconnected calls. Obviously this is not a guarantee as we /// could miss the funding_tx_confirmed_in block as well, but it serves as a useful fallback. - funding_tx_confirmed_in: Sha256dHash, + funding_tx_confirmed_in: Option, short_channel_id: Option, /// Used to deduplicate block_connected callbacks last_block_connected: Sha256dHash, @@ -290,12 +307,12 @@ pub struct Channel { their_max_accepted_htlcs: u16, //implied by OUR_MAX_HTLCS: our_max_accepted_htlcs: u16, - their_funding_pubkey: PublicKey, - their_revocation_basepoint: PublicKey, - their_payment_basepoint: PublicKey, - their_delayed_payment_basepoint: PublicKey, - their_htlc_basepoint: PublicKey, - their_cur_commitment_point: PublicKey, + their_funding_pubkey: Option, + their_revocation_basepoint: Option, + their_payment_basepoint: Option, + their_delayed_payment_basepoint: Option, + their_htlc_basepoint: Option, + their_cur_commitment_point: Option, their_prev_commitment_point: Option, their_node_id: PublicKey, @@ -303,10 +320,11 @@ pub struct Channel { their_shutdown_scriptpubkey: Option