Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 145 additions & 60 deletions lightning/src/chain/chainmonitor.rs

Large diffs are not rendered by default.

312 changes: 232 additions & 80 deletions lightning/src/chain/channelmonitor.rs

Large diffs are not rendered by default.

71 changes: 42 additions & 29 deletions lightning/src/chain/onchaintx.rs
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
#![cfg_attr(rustfmt, rustfmt_skip)]

// This file is Copyright its original authors, visible in version control
// history.
//
Expand All@@ -15,37 +13,41 @@
//! building, tracking, bumping and notifications functions.

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::locktime::absolute::LockTime;
use bitcoin::transaction::Transaction;
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use bitcoin::secp256k1;
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::transaction::Transaction;

use crate::chain::chaininterface::{ConfirmationTarget, compute_feerate_sat_per_1000_weight};
use crate::sign::{EntropySource, HTLCDescriptor, SignerProvider, ecdsa::EcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::chain::transaction::MaybeSignedTransaction;
use crate::chain::ClaimId;
use crate::ln::chan_utils::{
self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::DecodeError;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, HTLCDescriptor, SignerProvider};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
use crate::util::ser::{
MaybeReadable, Readable, ReadableArgs, UpgradableRequired, Writeable, Writer,
};

use crate::io;
use crate::prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
use core::mem::swap;
use core::ops::Deref;

const MAX_ALLOC_SIZE: usize = 64*1024;
const MAX_ALLOC_SIZE: usize = 64 * 1024;

/// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
/// transaction causing it.
Expand DownExpand Up@@ -77,18 +79,14 @@ enum OnchainEvent {
/// as the request. This claim can either be ours or from the counterparty. Once the claiming
/// transaction has met [`ANTI_REORG_DELAY`] confirmations, we consider it final and remove the
/// pending request.
Claim {
claim_id: ClaimId,
},
Claim { claim_id: ClaimId },
/// The counterparty has claimed an outpoint from one of our pending requests through a
/// different transaction than ours. If our transaction was attempting to claim multiple
/// outputs, we need to drop the outpoint claimed by the counterparty and regenerate a new claim
/// transaction for ourselves. We keep tracking, separately, the outpoint claimed by the
/// counterparty up to [`ANTI_REORG_DELAY`] confirmations to ensure we attempt to re-claim it
/// if the counterparty's claim is reorged from the chain.
ContentiousOutpoint {
package: PackageTemplate,
}
ContentiousOutpoint { package: PackageTemplate },
}

impl Writeable for OnchainEventEntry {
Expand All@@ -104,6 +102,7 @@ impl Writeable for OnchainEventEntry {
}

impl MaybeReadable for OnchainEventEntry {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
let mut txid = Txid::all_zeros();
let mut height = 0;
Expand All@@ -129,6 +128,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
Expand DownExpand Up@@ -221,8 +221,8 @@ pub(crate) enum FeerateStrategy {
/// do RBF bumping if possible.
#[derive(Clone)]
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
channel_value_satoshis: u64, // Deprecated as of 0.2.
channel_keys_id: [u8; 32], // Deprecated as of 0.2.
destination_script: ScriptBuf, // Deprecated as of 0.2.
holder_commitment: HolderCommitmentTransaction,
prev_holder_commitment: Option<HolderCommitmentTransaction>,
Expand DownExpand Up@@ -277,6 +277,7 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
}

impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
fn eq(&self, other: &Self) -> bool {
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
self.channel_value_satoshis == other.channel_value_satoshis &&
Expand All@@ -296,6 +297,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
#[rustfmt::skip]
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

Expand DownExpand Up@@ -343,7 +345,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler<SP::EcdsaSigner> {
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])>
for OnchainTxHandler<SP::EcdsaSigner>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result<Self, DecodeError> {
let entropy_source = args.0;
let signer_provider = args.1;
Expand DownExpand Up@@ -438,7 +443,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
pub(crate) fn new(
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>,
) -> Self {
OnchainTxHandler {
channel_value_satoshis,
Expand DownExpand Up@@ -476,6 +481,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
/// invoking this every 30 seconds, or lower if running in an environment with spotty
/// connections, like on mobile.
#[rustfmt::skip]
pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
&mut self, current_height: u32, feerate_strategy: FeerateStrategy, broadcaster: &B,
conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -532,8 +538,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {

/// Returns true if we are currently tracking any pending claim requests that are not fully
/// confirmed yet.
pub(super) fn has_pending_claims(&self) -> bool
{
pub(super) fn has_pending_claims(&self) -> bool {
self.pending_claim_requests.len() != 0
}

Expand All@@ -545,6 +550,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
///
/// Panics if there are signing errors, because signing operations in reaction to on-chain
/// events are not expected to fail, and if they do, we may lose funds.
#[rustfmt::skip]
fn generate_claim<F: Deref, L: Logger>(
&mut self, cur_height: u32, cached_request: &PackageTemplate,
feerate_strategy: &FeerateStrategy, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -713,6 +719,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
None
}

#[rustfmt::skip]
pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
.or_else(|| {
Expand DownExpand Up@@ -741,6 +748,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the request was generated. This
/// does not need to equal the current blockchain tip height, which should be provided via
/// `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
&mut self, mut requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
broadcaster: &B, conf_target: ConfirmationTarget, destination_script: &Script,
Expand DownExpand Up@@ -895,6 +903,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
/// `conf_height` represents the height at which the transactions in `txn_matched` were
/// confirmed. This does not need to equal the current blockchain tip height, which should be
/// provided via `cur_height`, however it must never be higher than `cur_height`.
#[rustfmt::skip]
pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
&mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
cur_height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
Expand DownExpand Up@@ -1081,6 +1090,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
&mut self,
txid: &Txid,
Expand DownExpand Up@@ -1108,6 +1118,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
}
}

#[rustfmt::skip]
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
Expand DownExpand Up@@ -1190,6 +1201,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
self.claimable_outpoints.get(outpoint).is_some()
}

#[rustfmt::skip]
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
Expand DownExpand Up@@ -1243,6 +1255,7 @@ mod tests {
// immediately while claims with locktime greater than the current height are only broadcast
// once the locktime is reached.
#[test]
#[rustfmt::skip]
fn test_broadcast_height() {
let secp_ctx = Secp256k1::new();
let signer = InMemorySigner::new(
Expand Down
Loading