Skip to content

Commit 82687b6

Browse files
author
Antoine Riard
committed
Add FeeEstimator in ChannelMonitor
Use it to substract fee in claim txn build thanks to added method get_claim_tx_weight
1 parent f5a5729 commit 82687b6

File tree

4 files changed

+63
-15
lines changed

4 files changed

+63
-15
lines changed

src/ln/channelmonitor.rs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use ln::chan_utils;
3434
use ln::chan_utils::HTLCOutputInCommitment;
3535
use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
3636
use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT};
37-
use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface};
37+
use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface, FeeEstimator, ConfirmationTarget};
3838
use chain::transaction::OutPoint;
3939
use chain::keysinterface::SpendableOutputDescriptor;
4040
use util::logger::Logger;
@@ -143,6 +143,7 @@ pub struct SimpleManyChannelMonitor<Key> {
143143
pending_events: Mutex<Vec<events::Event>>,
144144
pending_htlc_updated: Mutex<HashMap<PaymentHash, Vec<(HTLCSource, Option<PaymentPreimage>)>>>,
145145
logger: Arc<Logger>,
146+
fee_estimator: Arc<FeeEstimator>
146147
}
147148

148149
impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonitor<Key> {
@@ -153,7 +154,7 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
153154
{
154155
let mut monitors = self.monitors.lock().unwrap();
155156
for monitor in monitors.values_mut() {
156-
let (txn_outputs, spendable_outputs, mut htlc_updated) = monitor.block_connected(txn_matched, height, &block_hash, &*self.broadcaster);
157+
let (txn_outputs, spendable_outputs, mut htlc_updated) = monitor.block_connected(txn_matched, height, &block_hash, &*self.broadcaster, &*self.fee_estimator);
157158
if spendable_outputs.len() > 0 {
158159
new_events.push(events::Event::SpendableOutputs {
159160
outputs: spendable_outputs,
@@ -210,14 +211,15 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
210211
impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key> {
211212
/// Creates a new object which can be used to monitor several channels given the chain
212213
/// interface with which to register to receive notifications.
213-
pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>) -> Arc<SimpleManyChannelMonitor<Key>> {
214+
pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>, feeest: Arc<FeeEstimator>) -> Arc<SimpleManyChannelMonitor<Key>> {
214215
let res = Arc::new(SimpleManyChannelMonitor {
215216
monitors: Mutex::new(HashMap::new()),
216217
chain_monitor,
217218
broadcaster,
218219
pending_events: Mutex::new(Vec::new()),
219220
pending_htlc_updated: Mutex::new(HashMap::new()),
220221
logger,
222+
fee_estimator: feeest,
221223
});
222224
let weak_res = Arc::downgrade(&res);
223225
res.chain_monitor.register_listener(weak_res);
@@ -306,6 +308,11 @@ pub(crate) const HTLC_FAIL_TIMEOUT_BLOCKS: u32 = 3;
306308
/// and then getting a reorg resulting in us losing money.
307309
//TODO: We currently don't actually use this...we should
308310
pub(crate) const HTLC_FAIL_ANTI_REORG_DELAY: u32 = 6;
311+
/// A claim tx is either a justice tx on remote revoked outputs or a HTLC-solving tx on remote valid HTLC outputs.
312+
/// Its construction is free to us, i.e we may choose to batch in one single claim tx all outpoints for which
313+
/// we have solving witness programs modulo HTLC expiration requirements.
314+
/// Base weight is at least : 4 (version) + 2 (segwit flag) + 1 (out-counter) + 8 (single-ouput value) + 4 (locktime)
315+
const CLAIM_TX_BASE_WEIGHT: u64 = 4 + 2 + 1 + 8 + 4;
309316

310317
#[derive(Clone, PartialEq)]
311318
enum Storage {
@@ -340,6 +347,14 @@ struct LocalSignedTx {
340347
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<(Signature, Signature)>, Option<HTLCSource>)>,
341348
}
342349

350+
enum InputDescriptors {
351+
RevokedOfferedHTLC,
352+
RevokedReceivedHTLC,
353+
OfferedHTLC,
354+
ReceivedHTLC,
355+
RevokedOutput, // either a revoked to_local output on commitment tx, a revoked HTLC-Timeout output or a revoked HTLC-Success output
356+
}
357+
343358
const SERIALIZATION_VERSION: u8 = 1;
344359
const MIN_SERIALIZATION_VERSION: u8 = 1;
345360

@@ -475,6 +490,32 @@ impl ChannelMonitor {
475490
}
476491
}
477492

493+
fn get_claim_tx_weight(inputs: Vec<InputDescriptors>, output_scriptpubkey: &Script) -> u64 {
494+
let mut tx_weight = CLAIM_TX_BASE_WEIGHT;
495+
tx_weight += if inputs.len() > 255 { 2 } else { 1 };
496+
for inp in inputs {
497+
tx_weight += match inp {
498+
InputDescriptors::RevokedOfferedHTLC => {
499+
41 + 1 + 1 + 73 + 1 + 33 + 1 + 133
500+
},
501+
InputDescriptors::RevokedReceivedHTLC => {
502+
41 + 1 + 1 + 73 + 1 + 33 + 1 + 139
503+
},
504+
InputDescriptors::OfferedHTLC => {
505+
41 + 1 + 1 + 73 + 1 + 32 + 1 + 133
506+
},
507+
InputDescriptors::ReceivedHTLC => {
508+
41 + 1 + 1 + 73 + 1 + 1 + 139
509+
},
510+
InputDescriptors::RevokedOutput => {
511+
41 + 1 + 1 + 73 + 1 + 1 + 1 + 82
512+
},
513+
};
514+
}
515+
tx_weight += output_scriptpubkey.len() as u64;
516+
tx_weight
517+
}
518+
478519
#[inline]
479520
fn place_secret(idx: u64) -> u8 {
480521
for i in 0..48 {
@@ -1019,7 +1060,7 @@ impl ChannelMonitor {
10191060
/// HTLC-Success/HTLC-Timeout transactions.
10201061
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
10211062
/// revoked remote commitment tx
1022-
fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec<Transaction>, (Sha256dHash, Vec<TxOut>), Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)>) {
1063+
fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32, fee_estimator: &FeeEstimator) -> (Vec<Transaction>, (Sha256dHash, Vec<TxOut>), Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)>) {
10231064
// Most secp and related errors trying to create keys means we have no hope of constructing
10241065
// a spend transaction...so we return no transactions to broadcast
10251066
let mut txn_to_broadcast = Vec::new();
@@ -1077,6 +1118,7 @@ impl ChannelMonitor {
10771118
let mut values = Vec::new();
10781119
let mut inputs = Vec::new();
10791120
let mut htlc_idxs = Vec::new();
1121+
let mut input_descriptors = Vec::new();
10801122

10811123
for (idx, outp) in tx.output.iter().enumerate() {
10821124
if outp.script_pubkey == revokeable_p2wsh {
@@ -1092,6 +1134,7 @@ impl ChannelMonitor {
10921134
htlc_idxs.push(None);
10931135
values.push(outp.value);
10941136
total_value += outp.value;
1137+
input_descriptors.push(InputDescriptors::RevokedOutput);
10951138
} else if Some(&outp.script_pubkey) == local_payment_p2wpkh.as_ref() {
10961139
spendable_outputs.push(SpendableOutputDescriptor::DynamicOutputP2WPKH {
10971140
outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 },
@@ -1155,6 +1198,7 @@ impl ChannelMonitor {
11551198
htlc_idxs.push(Some(idx));
11561199
values.push(tx.output[transaction_output_index as usize].value);
11571200
total_value += htlc.amount_msat / 1000;
1201+
input_descriptors.push(if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC });
11581202
} else {
11591203
let mut single_htlc_tx = Transaction {
11601204
version: 2,
@@ -1165,6 +1209,7 @@ impl ChannelMonitor {
11651209
value: htlc.amount_msat / 1000, //TODO: - fee
11661210
}),
11671211
};
1212+
single_htlc_tx.output[0].value -= fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * Self::get_claim_tx_weight(vec![if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }], &single_htlc_tx.output[0].script_pubkey) / 1000;
11681213
let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
11691214
sign_input!(sighash_parts, single_htlc_tx.input[0], Some(idx), htlc.amount_msat / 1000);
11701215
txn_to_broadcast.push(single_htlc_tx);
@@ -1208,7 +1253,7 @@ impl ChannelMonitor {
12081253

12091254
let outputs = vec!(TxOut {
12101255
script_pubkey: self.destination_script.clone(),
1211-
value: total_value, //TODO: - fee
1256+
value: total_value - fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * Self::get_claim_tx_weight(input_descriptors, &self.destination_script) / 1000,
12121257
});
12131258
let mut spend_tx = Transaction {
12141259
version: 2,
@@ -1324,6 +1369,7 @@ impl ChannelMonitor {
13241369
let mut total_value = 0;
13251370
let mut values = Vec::new();
13261371
let mut inputs = Vec::new();
1372+
let mut input_descriptors = Vec::new();
13271373

13281374
macro_rules! sign_input {
13291375
($sighash_parts: expr, $input: expr, $amount: expr, $preimage: expr) => {
@@ -1370,16 +1416,18 @@ impl ChannelMonitor {
13701416
inputs.push(input);
13711417
values.push((tx.output[transaction_output_index as usize].value, payment_preimage));
13721418
total_value += htlc.amount_msat / 1000;
1419+
input_descriptors.push(if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC });
13731420
} else {
13741421
let mut single_htlc_tx = Transaction {
13751422
version: 2,
13761423
lock_time: 0,
13771424
input: vec![input],
13781425
output: vec!(TxOut {
13791426
script_pubkey: self.destination_script.clone(),
1380-
value: htlc.amount_msat / 1000, //TODO: - fee
1427+
value: htlc.amount_msat / 1000,
13811428
}),
13821429
};
1430+
single_htlc_tx.output[0].value -= fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * Self::get_claim_tx_weight(vec![if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC }], &single_htlc_tx.output[0].script_pubkey) / 1000;
13831431
let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
13841432
sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec());
13851433
spendable_outputs.push(SpendableOutputDescriptor::StaticOutput {
@@ -1421,7 +1469,7 @@ impl ChannelMonitor {
14211469

14221470
let outputs = vec!(TxOut {
14231471
script_pubkey: self.destination_script.clone(),
1424-
value: total_value, //TODO: - fee
1472+
value: total_value - fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * Self::get_claim_tx_weight(input_descriptors, &self.destination_script) / 1000,
14251473
});
14261474
let mut spend_tx = Transaction {
14271475
version: 2,
@@ -1698,7 +1746,7 @@ impl ChannelMonitor {
16981746
}
16991747
}
17001748

1701-
fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec<TxOut>)>, Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)>) {
1749+
fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface, fee_estimator: &FeeEstimator)-> (Vec<(Sha256dHash, Vec<TxOut>)>, Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)>) {
17021750
let mut watch_outputs = Vec::new();
17031751
let mut spendable_outputs = Vec::new();
17041752
let mut htlc_updated = Vec::new();
@@ -1719,7 +1767,7 @@ impl ChannelMonitor {
17191767
}
17201768
};
17211769
if funding_txo.is_none() || (prevout.txid == funding_txo.as_ref().unwrap().0.txid && prevout.vout == funding_txo.as_ref().unwrap().0.index as u32) {
1722-
let (remote_txn, new_outputs, mut spendable_output, mut updated) = self.check_spend_remote_transaction(tx, height);
1770+
let (remote_txn, new_outputs, mut spendable_output, mut updated) = self.check_spend_remote_transaction(tx, height, fee_estimator);
17231771
txn = remote_txn;
17241772
spendable_outputs.append(&mut spendable_output);
17251773
if !new_outputs.1.is_empty() {

src/ln/functional_test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ pub fn create_network(node_count: usize) -> Vec<Node> {
821821
let mut seed = [0; 32];
822822
rng.fill_bytes(&mut seed);
823823
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet, Arc::clone(&logger)));
824-
let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone()));
824+
let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone(), feeest.clone()));
825825
let mut config = UserConfig::new();
826826
config.channel_options.announced_channel = true;
827827
config.channel_limits.force_announced_channel_preference = false;

src/ln/functional_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,7 +3210,7 @@ fn test_no_txn_manager_serialize_deserialize() {
32103210
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
32113211
nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap();
32123212

3213-
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new())));
3213+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 })));
32143214
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
32153215
let (_, chan_0_monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut chan_0_monitor_read, Arc::new(test_utils::TestLogger::new())).unwrap();
32163216
assert!(chan_0_monitor_read.is_empty());
@@ -3276,7 +3276,7 @@ fn test_simple_manager_serialize_deserialize() {
32763276
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
32773277
nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap();
32783278

3279-
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new())));
3279+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 })));
32803280
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
32813281
let (_, chan_0_monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut chan_0_monitor_read, Arc::new(test_utils::TestLogger::new())).unwrap();
32823282
assert!(chan_0_monitor_read.is_empty());
@@ -3336,7 +3336,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
33363336
node_0_monitors_serialized.push(writer.0);
33373337
}
33383338

3339-
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new())));
3339+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 })));
33403340
let mut node_0_monitors = Vec::new();
33413341
for serialized in node_0_monitors_serialized.iter() {
33423342
let mut read = &serialized[..];

src/util/test_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ pub struct TestChannelMonitor {
4646
pub update_ret: Mutex<Result<(), channelmonitor::ChannelMonitorUpdateErr>>,
4747
}
4848
impl TestChannelMonitor {
49-
pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>) -> Self {
49+
pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>, fee_estimator: Arc<chaininterface::FeeEstimator>) -> Self {
5050
Self {
5151
added_monitors: Mutex::new(Vec::new()),
52-
simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger),
52+
simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger, fee_estimator),
5353
update_ret: Mutex::new(Ok(())),
5454
}
5555
}

0 commit comments

Comments
 (0)