X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=c34fc6a38c28e5ae89a5cd98e094ee7a5348781a;hb=c7e198e6fca8fc31e004b51368978b109c1caff6;hp=b4a24833919b96fa26b9037ecea1844d253d0e0e;hpb=43eed8dd8b9ab54af444c5d19a8d25431da4e18d;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index b4a24833..b940b45f 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1,12 +1,19 @@ -use bitcoin::blockdata::block::BlockHeader; +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + use bitcoin::blockdata::script::{Script,Builder}; use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType}; use bitcoin::blockdata::opcodes; -use bitcoin::util::hash::BitcoinHash; use bitcoin::util::bip143; use bitcoin::consensus::encode; -use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash}; @@ -14,26 +21,30 @@ use bitcoin::secp256k1::key::{PublicKey,SecretKey}; use bitcoin::secp256k1::{Secp256k1,Signature}; use bitcoin::secp256k1; +use ln::{PaymentPreimage, PaymentHash}; use ln::features::{ChannelFeatures, InitFeatures}; use ln::msgs; use ln::msgs::{DecodeError, OptionalField, DataLossProtect}; -use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER}; -use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT}; -use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys}; +use ln::channelmanager::{BestBlock, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT}; +use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor}; use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; -use chain::transaction::OutPoint; -use chain::keysinterface::{ChannelKeys, KeysInterface}; +use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER}; +use chain::transaction::{OutPoint, TransactionData}; +use chain::keysinterface::{Sign, KeysInterface}; use util::transaction_utils; -use util::ser::{Readable, Writeable, Writer}; +use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use util::logger::Logger; use util::errors::APIError; use util::config::{UserConfig,ChannelConfig}; +use util::scid_utils::scid_from_parts; -use std; -use std::default::Default; -use std::{cmp,mem,fmt}; -use std::ops::Deref; +use core::{cmp,mem,fmt}; +use core::ops::Deref; +#[cfg(any(test, feature = "fuzztarget"))] +use std::sync::Mutex; +use bitcoin::hashes::hex::ToHex; +use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0; #[cfg(test)] pub struct ChannelValueStat { @@ -43,8 +54,8 @@ pub struct ChannelValueStat { 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 - pub their_dust_limit_msat: u64, + pub counterparty_max_htlc_value_in_flight_msat: u64, // outgoing + pub counterparty_dust_limit_msat: u64, } enum InboundHTLCRemovalReason { @@ -84,6 +95,7 @@ enum InboundHTLCState { /// is used to derive commitment keys, which are used to construct the /// signatures in a commitment_signed message. /// Implies AwaitingRemoteRevoke. + /// /// [BOLT #2]: https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md AwaitingRemoteRevokeToAnnounce(PendingHTLCStatus), /// Included in a received commitment_signed message (implying we've revoke_and_ack'd it). @@ -102,7 +114,7 @@ enum InboundHTLCState { /// 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. + /// ChannelMonitor::provide_latest_local_commitment_tx will not include this HTLC. LocalRemoved(InboundHTLCRemovalReason), } @@ -184,9 +196,9 @@ enum HTLCUpdateAwaitingACK { /// 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), + OurInitSent = 1 << 0, /// Implies we have received their open_channel/accept_channel message - TheirInitSent = (1 << 1), + 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. @@ -197,35 +209,35 @@ enum ChannelState { 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), + 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), + 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), + PeerDisconnected = 1 << 7, /// Flag which is set on ChannelFunded, FundingCreated, 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), + 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 << 9), + 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 << 10), + 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 << 11), + 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 = 4096, @@ -233,43 +245,79 @@ enum ChannelState { 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; - -/// Liveness is called to fluctuate given peer disconnecton/monitor failures/closing. -/// If channel is public, network should have a liveness view announced by us on a -/// best-effort, which means we may filter out some status transitions to avoid spam. -/// See further timer_chan_freshness_every_min. -#[derive(PartialEq)] -enum UpdateStatus { - /// Status has been gossiped. - Fresh, - /// Status has been changed. - DisabledMarked, - /// Status has been marked to be gossiped at next flush +pub const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; + +/// The "channel disabled" bit in channel_update must be set based on whether we are connected to +/// our counterparty or not. However, we don't want to announce updates right away to avoid +/// spamming the network with updates if the connection is flapping. Instead, we "stage" updates to +/// our channel_update message and track the current state here. +/// See implementation at [`super::channelmanager::ChannelManager::timer_tick_occurred`]. +#[derive(Clone, Copy, PartialEq)] +pub(super) enum ChannelUpdateStatus { + /// We've announced the channel as enabled and are connected to our peer. + Enabled, + /// Our channel is no longer live, but we haven't announced the channel as disabled yet. DisabledStaged, + /// Our channel is live again, but we haven't announced the channel as enabled yet. + EnabledStaged, + /// We've announced the channel as disabled. + Disabled, +} + +/// An enum indicating whether the local or remote side offered a given HTLC. +enum HTLCInitiator { + LocalOffered, + RemoteOffered, +} + +/// Used when calculating whether we or the remote can afford an additional HTLC. +struct HTLCCandidate { + amount_msat: u64, + origin: HTLCInitiator, +} + +impl HTLCCandidate { + fn new(amount_msat: u64, origin: HTLCInitiator) -> Self { + Self { + amount_msat, + origin, + } + } +} + +/// Information needed for constructing an invoice route hint for this channel. +#[derive(Clone)] +pub struct CounterpartyForwardingInfo { + /// Base routing fee in millisatoshis. + pub fee_base_msat: u32, + /// Amount in millionths of a satoshi the channel will charge per transferred satoshi. + pub fee_proportional_millionths: u32, + /// The minimum difference in cltv_expiry between an ingoing HTLC and its outgoing counterpart, + /// such that the outgoing HTLC is forwardable to this counterparty. See `msgs::ChannelUpdate`'s + /// `cltv_expiry_delta` for more details. + pub cltv_expiry_delta: u16, } // 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(super) struct Channel { +// +// Holder designates channel data owned for the benefice of the user client. +// Counterparty designates channel data owned by the another channel participant entity. +pub(super) struct Channel { config: ChannelConfig, user_id: u64, channel_id: [u8; 32], channel_state: u32, - channel_outbound: bool, secp_ctx: Secp256k1, channel_value_satoshis: u64, latest_monitor_update_id: u64, - #[cfg(not(test))] - local_keys: ChanSigner, - #[cfg(test)] - pub(super) local_keys: ChanSigner, + holder_signer: Signer, shutdown_pubkey: PublicKey, destination_script: Script, @@ -277,8 +325,8 @@ pub(super) struct Channel { // 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, + cur_holder_commitment_transaction_number: u64, + cur_counterparty_commitment_transaction_number: u64, value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees pending_inbound_htlcs: Vec, pending_outbound_htlcs: Vec, @@ -316,81 +364,83 @@ pub(super) struct Channel { // 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, + next_holder_htlc_id: u64, + next_counterparty_htlc_id: u64, update_time_counter: u32, feerate_per_kw: u32, #[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)>, + holder_max_commitment_tx_output: ::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)>, + counterparty_max_commitment_tx_output: ::std::sync::Mutex<(u64, u64)>, - last_sent_closing_fee: Option<(u32, u64, Signature)>, // (feerate, fee, our_sig) + last_sent_closing_fee: Option<(u32, u64, Signature)>, // (feerate, fee, holder_sig) - funding_txo: Option, - - /// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this - /// to detect unconfirmation after a serialize-unserialize roundtrip 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. + /// The hash of the block in which the funding transaction was included. funding_tx_confirmed_in: Option, + funding_tx_confirmation_height: u32, short_channel_id: Option, - /// Used to deduplicate block_connected callbacks, also used to verify consistency during - /// ChannelManager deserialization (hence pub(super)) - pub(super) last_block_connected: BlockHash, - funding_tx_confirmations: u64, - their_dust_limit_satoshis: u64, + counterparty_dust_limit_satoshis: u64, #[cfg(test)] - pub(super) our_dust_limit_satoshis: u64, + pub(super) holder_dust_limit_satoshis: u64, #[cfg(not(test))] - our_dust_limit_satoshis: u64, + holder_dust_limit_satoshis: u64, #[cfg(test)] - pub(super) their_max_htlc_value_in_flight_msat: u64, + pub(super) counterparty_max_htlc_value_in_flight_msat: u64, #[cfg(not(test))] - their_max_htlc_value_in_flight_msat: u64, - //get_our_max_htlc_value_in_flight_msat(): u64, + counterparty_max_htlc_value_in_flight_msat: u64, + //get_holder_max_htlc_value_in_flight_msat(): u64, /// minimum channel reserve for self to maintain - set by them. - local_channel_reserve_satoshis: u64, - // get_remote_channel_reserve_satoshis(channel_value_sats: u64): u64 - their_htlc_minimum_msat: u64, - our_htlc_minimum_msat: u64, - their_to_self_delay: u16, - our_to_self_delay: u16, + counterparty_selected_channel_reserve_satoshis: u64, + // get_holder_selected_channel_reserve_satoshis(channel_value_sats: u64): u64 + counterparty_htlc_minimum_msat: u64, + holder_htlc_minimum_msat: u64, #[cfg(test)] - pub their_max_accepted_htlcs: u16, + pub counterparty_max_accepted_htlcs: u16, #[cfg(not(test))] - their_max_accepted_htlcs: u16, - //implied by OUR_MAX_HTLCS: our_max_accepted_htlcs: u16, + counterparty_max_accepted_htlcs: u16, + //implied by OUR_MAX_HTLCS: max_accepted_htlcs: u16, minimum_depth: u32, - their_pubkeys: Option, + counterparty_forwarding_info: Option, - their_cur_commitment_point: Option, + pub(crate) channel_transaction_parameters: ChannelTransactionParameters, + funding_transaction: Option, - their_prev_commitment_point: Option, - their_node_id: PublicKey, + counterparty_cur_commitment_point: Option, + counterparty_prev_commitment_point: Option, + counterparty_node_id: PublicKey, - their_shutdown_scriptpubkey: Option