Merge pull request #71 from TheBlueMatt/2018-07-watch-funding

Ensure the funding transaction is registered to be monitored
This commit is contained in:
Matt Corallo 2018-07-22 17:54:50 -04:00 committed by GitHub
commit 456323886b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 17 deletions

View File

@ -12,7 +12,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
/// events). /// events).
pub trait ChainWatchInterface: Sync + Send { pub trait ChainWatchInterface: Sync + Send {
/// Provides a scriptPubKey which much be watched for. /// Provides a scriptPubKey which much be watched for.
fn install_watch_script(&self, script_pub_key: Script); fn install_watch_script(&self, script_pub_key: &Script);
/// Provides an outpoint which must be watched for, providing any transactions which spend the /// Provides an outpoint which must be watched for, providing any transactions which spend the
/// given outpoint. /// given outpoint.
@ -70,9 +70,9 @@ pub struct ChainWatchInterfaceUtil {
/// Register listener /// Register listener
impl ChainWatchInterface for ChainWatchInterfaceUtil { impl ChainWatchInterface for ChainWatchInterfaceUtil {
fn install_watch_script(&self, script_pub_key: Script) { fn install_watch_script(&self, script_pub_key: &Script) {
let mut watched = self.watched.lock().unwrap(); let mut watched = self.watched.lock().unwrap();
watched.0.push(Script::from(script_pub_key)); watched.0.push(script_pub_key.clone());
self.reentered.fetch_add(1, Ordering::Relaxed); self.reentered.fetch_add(1, Ordering::Relaxed);
} }
@ -103,7 +103,7 @@ impl ChainWatchInterfaceUtil {
} }
} }
/// Notify listeners that a block was connected. /// Notify listeners that a block was connected given a full, unfiltered block.
/// Handles re-scanning the block and calling block_connected again if listeners register new /// Handles re-scanning the block and calling block_connected again if listeners register new
/// watch data during the callbacks for you (see ChainListener::block_connected for more info). /// watch data during the callbacks for you (see ChainListener::block_connected for more info).
pub fn block_connected_with_filtering(&self, block: &Block, height: u32) { pub fn block_connected_with_filtering(&self, block: &Block, height: u32) {
@ -135,7 +135,8 @@ impl ChainWatchInterfaceUtil {
} }
} }
/// Notify listeners that a block was connected. /// Notify listeners that a block was connected, given pre-filtered list of transactions in the
/// block which matched the filter (probably using does_match_tx).
/// Returns true if notified listeners registered additional watch data (implying that the /// Returns true if notified listeners registered additional watch data (implying that the
/// block must be re-scanned and this function called again prior to further block_connected /// block must be re-scanned and this function called again prior to further block_connected
/// calls, see ChainListener::block_connected for more info). /// calls, see ChainListener::block_connected for more info).

View File

@ -1843,6 +1843,10 @@ impl Channel {
self.channel_update_count self.channel_update_count
} }
pub fn should_announce(&self) -> bool {
self.announce_publicly
}
/// Gets the fee we'd want to charge for adding an HTLC output to this Channel /// Gets the fee we'd want to charge for adding an HTLC output to this Channel
pub fn get_our_fee_base_msat(&self, fee_estimator: &FeeEstimator) -> u32 { pub fn get_our_fee_base_msat(&self, fee_estimator: &FeeEstimator) -> u32 {
// For lack of a better metric, we calculate what it would cost to consolidate the new HTLC // For lack of a better metric, we calculate what it would cost to consolidate the new HTLC

View File

@ -710,7 +710,7 @@ impl ChannelManager {
} }
fn get_announcement_sigs(&self, chan: &Channel) -> Result<Option<msgs::AnnouncementSignatures>, HandleError> { fn get_announcement_sigs(&self, chan: &Channel) -> Result<Option<msgs::AnnouncementSignatures>, HandleError> {
if !chan.is_usable() { return Ok(None) } if !chan.is_usable() || !chan.should_announce() { return Ok(None) }
let (announcement, our_bitcoin_sig) = chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone())?; let (announcement, our_bitcoin_sig) = chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone())?;
let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap(); let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap();
@ -1839,7 +1839,7 @@ mod tests {
use bitcoin::util::misc::hex_bytes; use bitcoin::util::misc::hex_bytes;
use bitcoin::util::hash::Sha256dHash; use bitcoin::util::hash::Sha256dHash;
use bitcoin::util::uint::Uint256; use bitcoin::util::uint::Uint256;
use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::block::{Block, BlockHeader};
use bitcoin::blockdata::transaction::{Transaction, TxOut}; use bitcoin::blockdata::transaction::{Transaction, TxOut};
use bitcoin::network::constants::Network; use bitcoin::network::constants::Network;
use bitcoin::network::serialize::serialize; use bitcoin::network::serialize::serialize;
@ -2010,6 +2010,7 @@ mod tests {
} }
fn confirm_transaction(chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) { fn confirm_transaction(chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) {
assert!(chain.does_match_tx(tx));
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
chain.block_connected_checked(&header, 1, &[tx; 1], &[chan_id; 1]); chain.block_connected_checked(&header, 1, &[tx; 1], &[chan_id; 1]);
for i in 2..100 { for i in 2..100 {
@ -2792,9 +2793,9 @@ mod tests {
// Simple case with no pending HTLCs: // Simple case with no pending HTLCs:
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
{ {
let node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE); let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]); nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0); assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
} }
get_announce_close_broadcast_events(&nodes, 0, 1); get_announce_close_broadcast_events(&nodes, 0, 1);
@ -2807,9 +2808,9 @@ mod tests {
// Simple case of one pending HTLC to HTLC-Timeout // Simple case of one pending HTLC to HTLC-Timeout
nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true); nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true);
{ {
let node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT); let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]); nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
assert_eq!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0); assert_eq!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
} }
get_announce_close_broadcast_events(&nodes, 1, 2); get_announce_close_broadcast_events(&nodes, 1, 2);
@ -2848,7 +2849,7 @@ mod tests {
claim_funds!(nodes[3], nodes[2], payment_preimage_1); claim_funds!(nodes[3], nodes[2], payment_preimage_1);
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[3].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]); nodes[3].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 1);
check_preimage_claim(&nodes[3], &node_txn); check_preimage_claim(&nodes[3], &node_txn);
} }
@ -2882,7 +2883,7 @@ mod tests {
test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS); test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[4].chain_monitor.block_connected_checked(&header, TEST_FINAL_CLTV - 5, &[&node_txn[0]; 1], &[4; 1]); nodes[4].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, TEST_FINAL_CLTV - 5);
check_preimage_claim(&nodes[4], &node_txn); check_preimage_claim(&nodes[4], &node_txn);
} }
@ -2902,7 +2903,7 @@ mod tests {
{ {
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[1].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 1]); nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
{ {
let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
assert_eq!(node_txn.len(), 1); assert_eq!(node_txn.len(), 1);
@ -2914,10 +2915,10 @@ mod tests {
node_txn.clear(); node_txn.clear();
} }
nodes[0].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 0]); nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT); let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT);
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[1]; 1], &[4; 1]); nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[1].clone()] }, 1);
//TODO: At this point nodes[1] should claim the revoked HTLC-Timeout output, but that's //TODO: At this point nodes[1] should claim the revoked HTLC-Timeout output, but that's
//not yet implemented in ChannelMonitor //not yet implemented in ChannelMonitor

View File

@ -94,7 +94,10 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key>
}; };
match &monitor.funding_txo { match &monitor.funding_txo {
&None => self.chain_monitor.watch_all_txn(), &None => self.chain_monitor.watch_all_txn(),
&Some((ref outpoint, ref script)) => self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script), &Some((ref outpoint, ref script)) => {
self.chain_monitor.install_watch_script(script);
self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script);
},
} }
monitors.insert(key, monitor); monitors.insert(key, monitor);
Ok(()) Ok(())