use bitcoin::{Sequence, Witness};
+use bitcoin::amount::Amount;
use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
use bitcoin::blockdata::locktime::absolute::LockTime;
use bitcoin::blockdata::transaction::{TxOut,TxIn, Transaction};
use bitcoin::hash_types::Txid;
use bitcoin::secp256k1::{SecretKey,PublicKey};
use bitcoin::sighash::EcdsaSighashType;
+use bitcoin::transaction::Version;
-use crate::ln::PaymentPreimage;
+use crate::ln::types::PaymentPreimage;
use crate::ln::chan_utils::{self, TxCreationKeys, HTLCOutputInCommitment};
use crate::ln::features::ChannelTypeFeatures;
use crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint};
use crate::ln::msgs::DecodeError;
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT, compute_feerate_sat_per_1000_weight, FEERATE_FLOOR_SATS_PER_KW};
-use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
+use crate::chain::transaction::MaybeSignedTransaction;
+use crate::sign::ecdsa::EcdsaChannelSigner;
use crate::chain::onchaintx::{FeerateStrategy, ExternalHTLCClaim, OnchainTxHandler};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, Writer, Writeable, RequiredWrapper};
use crate::io;
-use crate::prelude::*;
use core::cmp;
-use core::convert::TryInto;
use core::mem;
use core::ops::Deref;
+#[allow(unused_imports)]
+use crate::prelude::*;
+
use super::chaininterface::LowerBoundedFeeEstimator;
const MAX_ALLOC_SIZE: usize = 64*1024;
counterparty_htlc_base_key: HtlcBasepoint,
per_commitment_key: SecretKey,
weight: u64,
- amount: u64,
+ amount: Amount,
on_counterparty_tx_csv: u16,
is_counterparty_balance_on_anchors: Option<()>,
}
impl RevokedOutput {
- pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: DelayedPaymentBasepoint, counterparty_htlc_base_key: HtlcBasepoint, per_commitment_key: SecretKey, amount: u64, on_counterparty_tx_csv: u16, is_counterparty_balance_on_anchors: bool) -> Self {
+ pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: DelayedPaymentBasepoint, counterparty_htlc_base_key: HtlcBasepoint, per_commitment_key: SecretKey, amount: Amount, on_counterparty_tx_csv: u16, is_counterparty_balance_on_anchors: bool) -> Self {
RevokedOutput {
per_commitment_point,
counterparty_delayed_payment_base_key,
impl PackageSolvingData {
fn amount(&self) -> u64 {
let amt = match self {
- PackageSolvingData::RevokedOutput(ref outp) => outp.amount,
+ PackageSolvingData::RevokedOutput(ref outp) => outp.amount.to_sat(),
PackageSolvingData::RevokedHTLCOutput(ref outp) => outp.amount,
PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => outp.htlc.amount_msat / 1000,
PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => outp.htlc.amount_msat / 1000,
witness: Witness::new(),
}
}
- fn finalize_input<Signer: WriteableEcdsaChannelSigner>(&self, bumped_tx: &mut Transaction, i: usize, onchain_handler: &mut OnchainTxHandler<Signer>) -> bool {
+ fn finalize_input<Signer: EcdsaChannelSigner>(&self, bumped_tx: &mut Transaction, i: usize, onchain_handler: &mut OnchainTxHandler<Signer>) -> bool {
match self {
PackageSolvingData::RevokedOutput(ref outp) => {
let chan_keys = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint);
let witness_script = chan_utils::get_revokeable_redeemscript(&chan_keys.revocation_key, outp.on_counterparty_tx_csv, &chan_keys.broadcaster_delayed_payment_key);
//TODO: should we panic on signer failure ?
- if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_output(&bumped_tx, i, outp.amount, &outp.per_commitment_key, &onchain_handler.secp_ctx) {
+ if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_output(&bumped_tx, i, outp.amount.to_sat(), &outp.per_commitment_key, &onchain_handler.secp_ctx) {
let mut ser_sig = sig.serialize_der().to_vec();
ser_sig.push(EcdsaSighashType::All as u8);
bumped_tx.input[i].witness.push(ser_sig);
}
true
}
- fn get_finalized_tx<Signer: WriteableEcdsaChannelSigner>(&self, outpoint: &BitcoinOutPoint, onchain_handler: &mut OnchainTxHandler<Signer>) -> Option<Transaction> {
+ fn get_maybe_finalized_tx<Signer: EcdsaChannelSigner>(&self, outpoint: &BitcoinOutPoint, onchain_handler: &mut OnchainTxHandler<Signer>) -> Option<MaybeSignedTransaction> {
match self {
PackageSolvingData::HolderHTLCOutput(ref outp) => {
debug_assert!(!outp.channel_type_features.supports_anchors_zero_fee_htlc_tx());
- return onchain_handler.get_fully_signed_htlc_tx(outpoint, &outp.preimage);
+ onchain_handler.get_maybe_signed_htlc_tx(outpoint, &outp.preimage)
}
PackageSolvingData::HolderFundingOutput(ref outp) => {
- return Some(onchain_handler.get_fully_signed_holder_tx(&outp.funding_redeemscript));
+ Some(onchain_handler.get_maybe_signed_holder_tx(&outp.funding_redeemscript))
}
_ => { panic!("API Error!"); }
}
let output_weight = (8 + 1 + destination_script.len()) * WITNESS_SCALE_FACTOR;
(inputs_weight + witnesses_weight + transaction_weight + output_weight) as u64
}
- pub(crate) fn construct_malleable_package_with_external_funding<Signer: WriteableEcdsaChannelSigner>(
+ pub(crate) fn construct_malleable_package_with_external_funding<Signer: EcdsaChannelSigner>(
&self, onchain_handler: &mut OnchainTxHandler<Signer>,
) -> Option<Vec<ExternalHTLCClaim>> {
debug_assert!(self.requires_external_funding());
}
htlcs
}
- pub(crate) fn finalize_malleable_package<L: Logger, Signer: WriteableEcdsaChannelSigner>(
- &self, current_height: u32, onchain_handler: &mut OnchainTxHandler<Signer>, value: u64,
+ pub(crate) fn maybe_finalize_malleable_package<L: Logger, Signer: EcdsaChannelSigner>(
+ &self, current_height: u32, onchain_handler: &mut OnchainTxHandler<Signer>, value: Amount,
destination_script: ScriptBuf, logger: &L
- ) -> Option<Transaction> {
+ ) -> Option<MaybeSignedTransaction> {
debug_assert!(self.is_malleable());
let mut bumped_tx = Transaction {
- version: 2,
+ version: Version::TWO,
lock_time: LockTime::from_consensus(self.package_locktime(current_height)),
input: vec![],
output: vec![TxOut {
}
for (i, (outpoint, out)) in self.inputs.iter().enumerate() {
log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
- if !out.finalize_input(&mut bumped_tx, i, onchain_handler) { return None; }
+ if !out.finalize_input(&mut bumped_tx, i, onchain_handler) { continue; }
}
- log_debug!(logger, "Finalized transaction {} ready to broadcast", bumped_tx.txid());
- Some(bumped_tx)
+ Some(MaybeSignedTransaction(bumped_tx))
}
- pub(crate) fn finalize_untractable_package<L: Logger, Signer: WriteableEcdsaChannelSigner>(
+ pub(crate) fn maybe_finalize_untractable_package<L: Logger, Signer: EcdsaChannelSigner>(
&self, onchain_handler: &mut OnchainTxHandler<Signer>, logger: &L,
- ) -> Option<Transaction> {
+ ) -> Option<MaybeSignedTransaction> {
debug_assert!(!self.is_malleable());
if let Some((outpoint, outp)) = self.inputs.first() {
- if let Some(final_tx) = outp.get_finalized_tx(outpoint, onchain_handler) {
+ if let Some(final_tx) = outp.get_maybe_finalized_tx(outpoint, onchain_handler) {
log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
- log_debug!(logger, "Finalized transaction {} ready to broadcast", final_tx.txid());
return Some(final_tx);
}
return None;
if self.feerate_previous != 0 {
let previous_feerate = self.feerate_previous.try_into().unwrap_or(u32::max_value());
match feerate_strategy {
+ FeerateStrategy::RetryPrevious => previous_feerate,
FeerateStrategy::HighestOfPreviousOrNew => cmp::max(previous_feerate, feerate_estimate),
FeerateStrategy::ForceBump => if feerate_estimate > previous_feerate {
feerate_estimate
// If old feerate inferior to actual one given back by Fee Estimator, use it to compute new fee...
let (new_fee, new_feerate) = if let Some((new_fee, new_feerate)) = compute_fee_from_spent_amounts(input_amounts, predicted_weight, fee_estimator, logger) {
match feerate_strategy {
+ FeerateStrategy::RetryPrevious => {
+ let previous_fee = previous_feerate * predicted_weight / 1000;
+ (previous_fee, previous_feerate)
+ },
FeerateStrategy::HighestOfPreviousOrNew => if new_feerate > previous_feerate {
(new_fee, new_feerate)
} else {
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderHTLCOutput, PackageTemplate, PackageSolvingData, RevokedOutput, WEIGHT_REVOKED_OUTPUT, weight_offered_htlc, weight_received_htlc};
use crate::chain::Txid;
use crate::ln::chan_utils::HTLCOutputInCommitment;
- use crate::ln::{PaymentPreimage, PaymentHash};
+ use crate::ln::types::{PaymentPreimage, PaymentHash};
use crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint};
+ use bitcoin::amount::Amount;
use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
use bitcoin::blockdata::script::ScriptBuf;
use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
{
let dumb_scalar = SecretKey::from_slice(&<Vec<u8>>::from_hex("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
let dumb_point = PublicKey::from_secret_key(&$secp_ctx, &dumb_scalar);
- PackageSolvingData::RevokedOutput(RevokedOutput::build(dumb_point, DelayedPaymentBasepoint::from(dumb_point), HtlcBasepoint::from(dumb_point), dumb_scalar, 0, 0, $is_counterparty_balance_on_anchors))
+ PackageSolvingData::RevokedOutput(RevokedOutput::build(dumb_point, DelayedPaymentBasepoint::from(dumb_point), HtlcBasepoint::from(dumb_point), dumb_scalar, Amount::ZERO, 0, $is_counterparty_balance_on_anchors))
}
}
}