X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannel.rs;h=906d1ffff0e36f09caccd5009966cc19000c1620;hb=832fc4fd4435fa236f15d3e737bebf64619ff60e;hp=614c13b442d76d9826875178879da20c6ef0d226;hpb=cfc3fe3148b6d4bcf5b8b8eb974376a939e2edbb;p=rust-lightning diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 614c13b4..1e5c38b4 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -2,103 +2,93 @@ use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::script::{Script,Builder}; use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType}; use bitcoin::blockdata::opcodes; -use bitcoin::util::hash::{Sha256dHash, Hash160}; +use bitcoin::util::hash::{BitcoinHash, Sha256dHash, Hash160}; use bitcoin::util::bip143; -use bitcoin::network::serialize::BitcoinHash; +use bitcoin::consensus::encode::{self, Encodable, Decodable}; use secp256k1::key::{PublicKey,SecretKey}; use secp256k1::{Secp256k1,Message,Signature}; use secp256k1; use crypto::digest::Digest; -use crypto::hkdf::{hkdf_extract,hkdf_expand}; use ln::msgs; -use ln::msgs::{ErrorAction, HandleError, MsgEncodable}; +use ln::msgs::DecodeError; use ln::channelmonitor::ChannelMonitor; -use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason}; +use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash}; 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 chain::keysinterface::{ChannelKeys, KeysInterface}; use util::{transaction_utils,rng}; +use util::ser::{Readable, ReadableArgs, Writeable, Writer, WriterWriteAdaptor}; use util::sha2::Sha256; +use util::logger::Logger; +use util::errors::APIError; +use util::config::{UserConfig,ChannelConfig}; 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, - pub revocation_base_key: SecretKey, - pub payment_base_key: SecretKey, - pub delayed_payment_base_key: SecretKey, - pub htlc_base_key: SecretKey, - pub channel_close_key: SecretKey, - pub channel_monitor_claim_key: SecretKey, - pub commitment_seed: [u8; 32], +#[cfg(test)] +pub struct ChannelValueStat { + pub value_to_self_msat: u64, + pub channel_value_msat: u64, + pub channel_reserve_msat: u64, + pub pending_outbound_htlcs_amount_msat: u64, + pub pending_inbound_htlcs_amount_msat: u64, + pub holding_cell_outbound_amount_msat: u64, + pub their_max_htlc_value_in_flight_msat: u64, // outgoing } -impl ChannelKeys { - pub fn new_from_seed(seed: &[u8; 32]) -> Result { - let mut prk = [0; 32]; - hkdf_extract(Sha256::new(), b"rust-lightning key gen salt", seed, &mut prk); - let secp_ctx = Secp256k1::without_caps(); - - let mut okm = [0; 32]; - hkdf_expand(Sha256::new(), &prk, b"rust-lightning funding key info", &mut okm); - let funding_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning revocation base key info", &mut okm); - let revocation_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning payment base key info", &mut okm); - let payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning delayed payment base key info", &mut okm); - let delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); - let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm); - let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); - let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm); - - Ok(ChannelKeys { - funding_key: funding_key, - revocation_base_key: revocation_base_key, - payment_base_key: payment_base_key, - delayed_payment_base_key: delayed_payment_base_key, - htlc_base_key: htlc_base_key, - channel_close_key: channel_close_key, - channel_monitor_claim_key: channel_monitor_claim_key, - commitment_seed: okm - }) - } +enum InboundHTLCRemovalReason { + FailRelay(msgs::OnionErrorPacket), + FailMalformed(([u8; 32], u16)), + Fulfill(PaymentPreimage), } -#[derive(PartialEq)] -enum HTLCState { +enum InboundHTLCState { /// Added by remote, to be included in next local commitment tx. - RemoteAnnounced, + RemoteAnnounced(PendingHTLCStatus), /// Included in a received commitment_signed message (implying we've revoke_and_ack'ed it), but /// the remote side hasn't yet revoked their previous state, which we need them to do before we /// accept this HTLC. Implies AwaitingRemoteRevoke. /// We also have not yet included this HTLC in a commitment_signed message, and are waiting on /// a remote revoke_and_ack on a previous state before we can do so. - AwaitingRemoteRevokeToAnnounce, + AwaitingRemoteRevokeToAnnounce(PendingHTLCStatus), /// Included in a received commitment_signed message (implying we've revoke_and_ack'ed it), but /// the remote side hasn't yet revoked their previous state, which we need them to do before we /// accept this HTLC. Implies AwaitingRemoteRevoke. /// We have included this HTLC in our latest commitment_signed and are now just waiting on a /// revoke_and_ack. - AwaitingAnnouncedRemoteRevoke, + AwaitingAnnouncedRemoteRevoke(PendingHTLCStatus), + 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(InboundHTLCRemovalReason), +} + +struct InboundHTLCOutput { + htlc_id: u64, + amount_msat: u64, + cltv_expiry: u32, + payment_hash: PaymentHash, + state: InboundHTLCState, +} + +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 @@ -109,7 +99,9 @@ enum HTLCState { /// allowed to remove it, the "can only be removed once committed on both sides" requirement /// doesn't matter to us and its up to them to enforce it, worst-case they jump ahead but /// we'll never get out of sync). - LocalAnnounced, + /// Note that we Box the OnionPacket as its rather large and we don't want to blow up + /// OutboundHTLCOutput's size just for a temporary bit + LocalAnnounced(Box), Committed, /// Remote removed this (outbound) HTLC. We're waiting on their commitment_signed to finalize /// the change (though they'll need to revoke before we fail the payment). @@ -126,42 +118,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. Implies local_removed_fulfilled. - 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 + payment_hash: PaymentHash, + 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 } } @@ -173,20 +149,28 @@ enum HTLCUpdateAwaitingACK { // always outbound amount_msat: u64, cltv_expiry: u32, - payment_hash: [u8; 32], + payment_hash: PaymentHash, + 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 + payment_preimage: PaymentPreimage, + htlc_id: u64, }, FailHTLC { - payment_hash: [u8; 32], + htlc_id: u64, err_packet: msgs::OnionErrorPacket, }, } +/// There are a few "states" and then a number of flags which can be applied: +/// We first move through init with OurInitSent -> TheirInitSent -> FundingCreated -> FundingSent. +/// TheirFundingLocked and OurFundingLocked then get set on FundingSent, and when both are set we +/// move on to ChannelFunded. +/// Note that PeerDisconnected can be set on both ChannelFunded and FundingSent. +/// ChannelFunded can then get all remaining flags set on it, until we finish shutdown, then we +/// move on to ShutdownComplete, at which point most calls into this channel are disallowed. enum ChannelState { /// Implies we have (or are prepared to) send our open_channel/accept_channel message OurInitSent = (1 << 0), @@ -207,43 +191,56 @@ enum ChannelState { /// Once both TheirFundingLocked and OurFundingLocked are set, state moves on to ChannelFunded. OurFundingLocked = (1 << 5), ChannelFunded = 64, + /// Flag which is set on ChannelFunded and FundingSent indicating remote side is considered + /// "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. + 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 /// messages as then we will be unable to determine which HTLCs they included in their /// revoke_and_ack implicit ACK, so instead we have to hold them away temporarily to be sent /// later. /// Flag is set on ChannelFunded. - AwaitingRemoteRevoke = (1 << 7), + AwaitingRemoteRevoke = (1 << 9), /// Flag which is set on ChannelFunded or FundingSent after receiving a shutdown message from /// the remote end. If set, they may not add any new HTLCs to the channel, and we are expected /// to respond with our own shutdown message when possible. - RemoteShutdownSent = (1 << 8), + RemoteShutdownSent = (1 << 10), /// Flag which is set on ChannelFunded or FundingSent after sending a shutdown message. At this /// point, we may not add any new HTLCs to the channel. /// TODO: Investigate some kind of timeout mechanism by which point the remote end must provide /// us their shutdown. - LocalShutdownSent = (1 << 9), + LocalShutdownSent = (1 << 11), /// We've successfully negotiated a closing_signed dance. At this point ChannelManager is about /// to drop us, but we store this anyway. - ShutdownComplete = (1 << 10), + ShutdownComplete = 4096, } const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32); +const MULTI_STATE_FLAGS: u32 = (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32); + +const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; // TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking // has been completed, and then turn into a Channel to get compiler-time enforcement of things like // calling channel_id() before we're set up or things like get_outbound_funding_signed on an // inbound channel. -pub struct Channel { +pub(super) struct Channel { + config: ChannelConfig, + user_id: u64, channel_id: [u8; 32], channel_state: u32, channel_outbound: bool, - secp_ctx: Secp256k1, - announce_publicly: bool, + secp_ctx: Secp256k1, channel_value_satoshis: u64, local_keys: ChannelKeys, + shutdown_pubkey: PublicKey, // Our commitment numbers start at 2^48-1 and count down, whereas the ones used in transaction // generation start at 0 and count up...this simplifies some parts of implementation at the @@ -252,13 +249,51 @@ 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, + /// Upon receipt of a channel_reestablish we have to figure out whether to send a + /// revoke_and_ack first or a commitment update first. Generally, we prefer to send + /// revoke_and_ack first, but if we had a pending commitment update of our own waiting on a + /// remote revoke when we received the latest commitment update from the remote we have to make + /// sure that commitment update gets resent first. + received_commitment_while_awaiting_raa: bool, + pending_inbound_htlcs: Vec, + pending_outbound_htlcs: Vec, holding_cell_htlc_updates: Vec, + + monitor_pending_revoke_and_ack: bool, + monitor_pending_commitment_signed: bool, + monitor_pending_order: Option, + monitor_pending_forwards: Vec<(PendingForwardHTLCInfo, u64)>, + monitor_pending_failures: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, + + // pending_update_fee is filled when sending and receiving update_fee + // For outbound channel, feerate_per_kw is updated with the value from + // pending_update_fee when revoke_and_ack is received + // + // For inbound channel, feerate_per_kw is updated when it receives + // commitment_signed and revoke_and_ack is generated + // The pending value is kept when another pair of update_fee and commitment_signed + // is received during AwaitingRemoteRevoke and relieved when the expected + // revoke_and_ack is received and new commitment_signed is generated to be + // sent to the funder. Otherwise, the pending value is removed when receiving + // commitment_signed. + pending_update_fee: Option, + // update_fee() during ChannelState::AwaitingRemoteRevoke is hold in + // holdina_cell_update_fee then moved to pending_udpate_fee when revoke_and_ack + // is received. holding_cell_update_fee is updated when there are additional + // update_fee() during ChannelState::AwaitingRemoteRevoke. + holding_cell_update_fee: Option, next_local_htlc_id: u64, next_remote_htlc_id: u64, channel_update_count: u32, feerate_per_kw: u64, + #[cfg(debug_assertions)] + /// Max to_local and to_remote outputs in a locally-generated commitment transaction + max_commitment_tx_output_local: ::std::sync::Mutex<(u64, u64)>, + #[cfg(debug_assertions)] + /// Max to_local and to_remote outputs in a remote-generated commitment transaction + max_commitment_tx_output_remote: ::std::sync::Mutex<(u64, u64)>, + #[cfg(test)] // Used in ChannelManager's tests to send a revoked transaction pub last_local_commitment_txn: Vec, @@ -271,16 +306,18 @@ 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, + /// Used to deduplicate block_connected callbacks, also used to verify consistency during + /// ChannelManager deserialization (hence pub(super)) + pub(super) last_block_connected: Sha256dHash, funding_tx_confirmations: u64, their_dust_limit_satoshis: u64, our_dust_limit_satoshis: u64, their_max_htlc_value_in_flight_msat: u64, //get_our_max_htlc_value_in_flight_msat(): u64, + /// minimum channel reserve for **self** to maintain - set by them. their_channel_reserve_satoshis: u64, //get_our_channel_reserve_satoshis(): u64, their_htlc_minimum_msat: u64, @@ -289,13 +326,14 @@ pub struct Channel { //implied by BREAKDOWN_TIMEOUT: our_to_self_delay: u16, their_max_accepted_htlcs: u16, //implied by OUR_MAX_HTLCS: our_max_accepted_htlcs: u16, + minimum_depth: u32, - 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 +341,11 @@ pub struct Channel { their_shutdown_scriptpubkey: Option