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::bip143; use bitcoin::network::serialize::BitcoinHash; 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::channelmonitor::ChannelMonitor; use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason}; 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 std; use std::default::Default; use std::{cmp,mem}; use std::time::Instant; 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], } 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 }) } } #[derive(PartialEq)] enum HTLCState { /// 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 /// 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, /// 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, /// 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 /// revoke, but we dont really care about that: /// * they've revoked, so worst case we can announce an old state and get our (option on) /// money back (though we wont), and, /// * we'll send them a revoke when they send a commitment_signed, and since only they're /// 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, 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). RemoteRemoved, /// Remote removed this and sent a commitment_signed (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 /// can do any backwards failing. Implies AwaitingRemoteRevoke. /// We also have not yet removed 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. AwaitingRemoteRevokeToRemove, /// Remote removed this and sent a commitment_signed (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 /// can do any backwards failing. Implies AwaitingRemoteRevoke. /// 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 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 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 { HTLCOutputInCommitment { offered: offered, amount_msat: self.amount_msat, cltv_expiry: self.cltv_expiry, payment_hash: self.payment_hash, transaction_output_index: 0 } } } /// See AwaitingRemoteRevoke ChannelState for more info enum HTLCUpdateAwaitingACK { AddHTLC { // always outbound amount_msat: u64, cltv_expiry: u32, payment_hash: [u8; 32], 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 }, FailHTLC { payment_hash: [u8; 32], err_packet: msgs::OnionErrorPacket, }, } enum ChannelState { /// Implies we have (or are prepared to) send our open_channel/accept_channel message OurInitSent = (1 << 0), /// Implies we have received their open_channel/accept_channel message TheirInitSent = (1 << 1), /// We have sent funding_created and are awaiting a funding_signed to advance to FundingSent. /// Note that this is nonsense for an inbound channel as we immediately generate funding_signed /// upon receipt of funding_created, so simply skip this state. FundingCreated = 4, /// Set when we have received/sent funding_created and funding_signed and are thus now waiting /// on the funding transaction to confirm. The FundingLocked flags are set to indicate when we /// and our counterparty consider the funding transaction confirmed. FundingSent = 8, /// Flag which can be set on FundingSent to indicate they sent us a funding_locked message. /// Once both TheirFundingLocked and OurFundingLocked are set, state moves on to ChannelFunded. TheirFundingLocked = (1 << 4), /// Flag which can be set on FundingSent to indicate we sent them a funding_locked message. /// Once both TheirFundingLocked and OurFundingLocked are set, state moves on to ChannelFunded. OurFundingLocked = (1 << 5), ChannelFunded = 64, /// 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), /// 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), /// 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), /// 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), } const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32); // 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 { user_id: u64, channel_id: [u8; 32], channel_state: u32, channel_outbound: bool, secp_ctx: Secp256k1, announce_publicly: bool, channel_value_satoshis: u64, local_keys: ChannelKeys, // 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 // cost of others, but should really just be changed. 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, holding_cell_htlc_updates: Vec, next_local_htlc_id: u64, next_remote_htlc_id: u64, channel_update_count: u32, feerate_per_kw: u64, #[cfg(test)] // Used in ChannelManager's tests to send a revoked transaction pub last_local_commitment_txn: Vec, #[cfg(not(test))] last_local_commitment_txn: Vec, last_sent_closing_fee: Option<(u64, u64)>, // (feerate, fee) /// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this /// 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: Option, short_channel_id: Option, /// Used to deduplicate block_connected callbacks 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, their_channel_reserve_satoshis: u64, //get_our_channel_reserve_satoshis(): u64, their_htlc_minimum_msat: u64, our_htlc_minimum_msat: u64, their_to_self_delay: u16, //implied by BREAKDOWN_TIMEOUT: our_to_self_delay: u16, 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_prev_commitment_point: Option, their_node_id: PublicKey, their_shutdown_scriptpubkey: Option