Skip to content

Commit 72ae308

Browse files
committed
Track block height in ChannelMonitor
1 parent 1a80b7a commit 72ae308

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use bitcoin::secp256k1;
3737
use ln::msgs::DecodeError;
3838
use ln::chan_utils;
3939
use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCType, ChannelTransactionParameters, HolderCommitmentTransaction};
40-
use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
40+
use ln::channelmanager::{BestBlock, HTLCSource, PaymentPreimage, PaymentHash};
4141
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
4242
use chain;
4343
use chain::WatchedOutput;
@@ -735,12 +735,13 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
735735
// remote monitor out-of-order with regards to the block view.
736736
holder_tx_signed: bool,
737737

738-
// We simply modify last_block_hash in Channel's block_connected so that serialization is
738+
// We simply modify best_block in Channel's block_connected so that serialization is
739739
// consistent but hopefully the users' copy handles block_connected in a consistent way.
740740
// (we do *not*, however, update them in update_monitor to ensure any local user copies keep
741-
// their last_block_hash from its state and not based on updated copies that didn't run through
741+
// their best_block from its state and not based on updated copies that didn't run through
742742
// the full block_connected).
743-
last_block_hash: BlockHash,
743+
best_block: BestBlock,
744+
744745
secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
745746
}
746747

@@ -952,7 +953,8 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
952953
event.write(writer)?;
953954
}
954955

955-
self.last_block_hash.write(writer)?;
956+
self.best_block.block_hash().write(writer)?;
957+
writer.write_all(&byte_utils::be32_to_array(self.best_block.height()))?;
956958

957959
writer.write_all(&byte_utils::be64_to_array(self.onchain_events_waiting_threshold_conf.len() as u64))?;
958960
for ref entry in self.onchain_events_waiting_threshold_conf.iter() {
@@ -996,7 +998,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
996998
funding_redeemscript: Script, channel_value_satoshis: u64,
997999
commitment_transaction_number_obscure_factor: u64,
9981000
initial_holder_commitment_tx: HolderCommitmentTransaction,
999-
last_block_hash: BlockHash) -> ChannelMonitor<Signer> {
1001+
best_block: BestBlock) -> ChannelMonitor<Signer> {
10001002

10011003
assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
10021004
let our_channel_close_key_hash = WPubkeyHash::hash(&shutdown_pubkey.serialize());
@@ -1083,7 +1085,8 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
10831085
lockdown_from_offchain: false,
10841086
holder_tx_signed: false,
10851087

1086-
last_block_hash,
1088+
best_block,
1089+
10871090
secp_ctx,
10881091
}),
10891092
}
@@ -2128,7 +2131,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21282131
}
21292132

21302133
self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, Some(height), &&*broadcaster, &&*fee_estimator, &&*logger);
2131-
self.last_block_hash = block_hash;
2134+
self.best_block = BestBlock::new(block_hash, height);
21322135

21332136
// Determine new outputs to watch by comparing against previously known outputs to watch,
21342137
// updating the latter in the process.
@@ -2167,7 +2170,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21672170

21682171
self.onchain_tx_handler.block_disconnected(height, broadcaster, fee_estimator, logger);
21692172

2170-
self.last_block_hash = header.prev_blockhash;
2173+
self.best_block = BestBlock::new(header.prev_blockhash, height - 1);
21712174
}
21722175

21732176
/// Filters a block's `txdata` for transactions spending watched outputs or for any child
@@ -2738,7 +2741,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
27382741
}
27392742
}
27402743

2741-
let last_block_hash: BlockHash = Readable::read(reader)?;
2744+
let best_block = BestBlock::new(Readable::read(reader)?, Readable::read(reader)?);
27422745

27432746
let waiting_threshold_conf_len: u64 = Readable::read(reader)?;
27442747
let mut onchain_events_waiting_threshold_conf = Vec::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128));
@@ -2785,7 +2788,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
27852788
let mut secp_ctx = Secp256k1::new();
27862789
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
27872790

2788-
Ok((last_block_hash.clone(), ChannelMonitor {
2791+
Ok((best_block.block_hash(), ChannelMonitor {
27892792
inner: Mutex::new(ChannelMonitorImpl {
27902793
latest_update_id,
27912794
commitment_transaction_number_obscure_factor,
@@ -2830,7 +2833,8 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
28302833
lockdown_from_offchain,
28312834
holder_tx_signed,
28322835

2833-
last_block_hash,
2836+
best_block,
2837+
28342838
secp_ctx,
28352839
}),
28362840
}))
@@ -2839,7 +2843,6 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
28392843

28402844
#[cfg(test)]
28412845
mod tests {
2842-
use bitcoin::blockdata::constants::genesis_block;
28432846
use bitcoin::blockdata::script::{Script, Builder};
28442847
use bitcoin::blockdata::opcodes;
28452848
use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType};
@@ -2853,7 +2856,7 @@ mod tests {
28532856
use hex;
28542857
use chain::channelmonitor::ChannelMonitor;
28552858
use chain::transaction::OutPoint;
2856-
use ln::channelmanager::{PaymentPreimage, PaymentHash};
2859+
use ln::channelmanager::{BestBlock, PaymentPreimage, PaymentHash};
28572860
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
28582861
use ln::chan_utils;
28592862
use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
@@ -2949,13 +2952,13 @@ mod tests {
29492952
};
29502953
// Prune with one old state and a holder commitment tx holding a few overlaps with the
29512954
// old state.
2952-
let last_block_hash = genesis_block(Network::Testnet).block_hash();
2955+
let best_block = BestBlock::from_genesis(Network::Testnet);
29532956
let monitor = ChannelMonitor::new(Secp256k1::new(), keys,
29542957
&PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0, &Script::new(),
29552958
(OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
29562959
&channel_parameters,
29572960
Script::new(), 46, 0,
2958-
HolderCommitmentTransaction::dummy(), last_block_hash);
2961+
HolderCommitmentTransaction::dummy(), best_block);
29592962

29602963
monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
29612964
let dummy_txid = dummy_tx.txid();

lightning/src/ln/channel.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use bitcoin::secp256k1;
2424
use ln::features::{ChannelFeatures, InitFeatures};
2525
use ln::msgs;
2626
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
27-
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
27+
use ln::channelmanager::{BestBlock, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
2828
use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor};
2929
use ln::chan_utils;
3030
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
@@ -1531,7 +1531,7 @@ impl<Signer: Sign> Channel<Signer> {
15311531
&self.get_counterparty_pubkeys().funding_pubkey
15321532
}
15331533

1534-
pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, last_block_hash: BlockHash, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
1534+
pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
15351535
if self.is_outbound() {
15361536
return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned()));
15371537
}
@@ -1585,7 +1585,7 @@ impl<Signer: Sign> Channel<Signer> {
15851585
&self.channel_transaction_parameters,
15861586
funding_redeemscript.clone(), self.channel_value_satoshis,
15871587
obscure_factor,
1588-
holder_commitment_tx, last_block_hash);
1588+
holder_commitment_tx, best_block);
15891589

15901590
channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_commitment_txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
15911591

@@ -1602,7 +1602,7 @@ impl<Signer: Sign> Channel<Signer> {
16021602

16031603
/// Handles a funding_signed message from the remote end.
16041604
/// If this call is successful, broadcast the funding transaction (and not before!)
1605-
pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, last_block_hash: BlockHash, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction), ChannelError> where L::Target: Logger {
1605+
pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction), ChannelError> where L::Target: Logger {
16061606
if !self.is_outbound() {
16071607
return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
16081608
}
@@ -1655,7 +1655,7 @@ impl<Signer: Sign> Channel<Signer> {
16551655
&self.channel_transaction_parameters,
16561656
funding_redeemscript.clone(), self.channel_value_satoshis,
16571657
obscure_factor,
1658-
holder_commitment_tx, last_block_hash);
1658+
holder_commitment_tx, best_block);
16591659

16601660
channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_bitcoin_tx.txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
16611661

@@ -4799,7 +4799,7 @@ mod tests {
47994799
use bitcoin::network::constants::Network;
48004800
use bitcoin::hashes::hex::FromHex;
48014801
use hex;
4802-
use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
4802+
use ln::channelmanager::{BestBlock, HTLCSource, PaymentPreimage, PaymentHash};
48034803
use ln::channel::{Channel,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,HTLCCandidate,HTLCInitiator,TxCreationKeys};
48044804
use ln::channel::MAX_FUNDING_SATOSHIS;
48054805
use ln::features::InitFeatures;
@@ -5012,8 +5012,8 @@ mod tests {
50125012
let secp_ctx = Secp256k1::new();
50135013
let seed = [42; 32];
50145014
let network = Network::Testnet;
5015-
let chain_hash = genesis_block(network).header.block_hash();
5016-
let last_block_hash = chain_hash;
5015+
let best_block = BestBlock::from_genesis(network);
5016+
let chain_hash = best_block.block_hash();
50175017
let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
50185018

50195019
// Go through the flow of opening a channel between two nodes.
@@ -5039,10 +5039,10 @@ mod tests {
50395039
}]};
50405040
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
50415041
let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap();
5042-
let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, last_block_hash, &&logger).unwrap();
5042+
let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&logger).unwrap();
50435043

50445044
// Node B --> Node A: funding signed
5045-
let _ = node_a_chan.funding_signed(&funding_signed_msg, last_block_hash, &&logger);
5045+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&logger);
50465046

50475047
// Now disconnect the two nodes and check that the commitment point in
50485048
// Node B's channel_reestablish message is sane.

lightning/src/ln/channelmanager.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ pub struct ChainParameters {
478478
}
479479

480480
/// The best known block as identified by its hash and height.
481+
#[derive(Clone, Copy)]
481482
pub struct BestBlock {
482483
block_hash: BlockHash,
483484
height: u32,
@@ -2543,15 +2544,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
25432544

25442545
fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
25452546
let ((funding_msg, monitor), mut chan) = {
2546-
let last_block_hash = self.best_block.read().unwrap().block_hash();
2547+
let best_block = *self.best_block.read().unwrap();
25472548
let mut channel_lock = self.channel_state.lock().unwrap();
25482549
let channel_state = &mut *channel_lock;
25492550
match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
25502551
hash_map::Entry::Occupied(mut chan) => {
25512552
if chan.get().get_counterparty_node_id() != *counterparty_node_id {
25522553
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.temporary_channel_id));
25532554
}
2554-
(try_chan_entry!(self, chan.get_mut().funding_created(msg, last_block_hash, &self.logger), channel_state, chan), chan.remove())
2555+
(try_chan_entry!(self, chan.get_mut().funding_created(msg, best_block, &self.logger), channel_state, chan), chan.remove())
25552556
},
25562557
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.temporary_channel_id))
25572558
}
@@ -2600,15 +2601,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
26002601

26012602
fn internal_funding_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> {
26022603
let funding_tx = {
2603-
let last_block_hash = self.best_block.read().unwrap().block_hash();
2604+
let best_block = *self.best_block.read().unwrap();
26042605
let mut channel_lock = self.channel_state.lock().unwrap();
26052606
let channel_state = &mut *channel_lock;
26062607
match channel_state.by_id.entry(msg.channel_id) {
26072608
hash_map::Entry::Occupied(mut chan) => {
26082609
if chan.get().get_counterparty_node_id() != *counterparty_node_id {
26092610
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
26102611
}
2611-
let (monitor, funding_tx) = match chan.get_mut().funding_signed(&msg, last_block_hash, &self.logger) {
2612+
let (monitor, funding_tx) = match chan.get_mut().funding_signed(&msg, best_block, &self.logger) {
26122613
Ok(update) => update,
26132614
Err(e) => try_chan_entry!(self, Err(e), channel_state, chan),
26142615
};

0 commit comments

Comments
 (0)