X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=c34fc6a38c28e5ae89a5cd98e094ee7a5348781a;hb=c7e198e6fca8fc31e004b51368978b109c1caff6;hp=3d3fecbdfca12133ecd95dd1b08d4d2defadd3d1;hpb=8058202c4c6ee218ce99fc97f87f4f1aa65c76f3;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 3d3fecbd..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,27 +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, PreCalculatedTxCreationKeys}; +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 { @@ -44,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 { @@ -85,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). @@ -103,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), } @@ -234,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, @@ -278,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, @@ -317,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