use bitcoin::blockdata::transaction::{TxIn,TxOut,SigHashType,Transaction};
use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::blockdata::script::Script;
-use bitcoin::network::serialize;
-use bitcoin::network::serialize::BitcoinHash;
-use bitcoin::network::encodable::{ConsensusDecodable, ConsensusEncodable};
-use bitcoin::util::hash::Sha256dHash;
+use bitcoin::consensus::encode::{self, Decodable, Encodable};
+use bitcoin::util::hash::{BitcoinHash,Sha256dHash};
use bitcoin::util::bip143;
use crypto::digest::Digest;
chain_monitor: Arc<ChainWatchInterface>,
broadcaster: Arc<BroadcasterInterface>,
pending_events: Mutex<Vec<events::Event>>,
+ logger: Arc<Logger>,
}
impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonitor<Key> {
impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key> {
/// Creates a new object which can be used to monitor several channels given the chain
/// interface with which to register to receive notifications.
- pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>) -> Arc<SimpleManyChannelMonitor<Key>> {
+ pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>) -> Arc<SimpleManyChannelMonitor<Key>> {
let res = Arc::new(SimpleManyChannelMonitor {
monitors: Mutex::new(HashMap::new()),
chain_monitor,
broadcaster,
pending_events: Mutex::new(Vec::new()),
+ logger,
});
let weak_res = Arc::downgrade(&res);
res.chain_monitor.register_listener(weak_res);
pub fn add_update_monitor_by_key(&self, key: Key, monitor: ChannelMonitor) -> Result<(), HandleError> {
let mut monitors = self.monitors.lock().unwrap();
match monitors.get_mut(&key) {
- Some(orig_monitor) => return orig_monitor.insert_combine(monitor),
+ Some(orig_monitor) => {
+ log_trace!(self, "Updating Channel Monitor for channel {}", log_funding_option!(monitor.funding_txo));
+ return orig_monitor.insert_combine(monitor);
+ },
None => {}
};
match &monitor.funding_txo {
- &None => self.chain_monitor.watch_all_txn(),
+ &None => {
+ log_trace!(self, "Got new Channel Monitor for no-funding-set channel (monitoring all txn!)");
+ self.chain_monitor.watch_all_txn()
+ },
&Some((ref outpoint, ref script)) => {
+ log_trace!(self, "Got new Channel Monitor for channel {}", log_bytes!(outpoint.to_channel_id()[..]));
self.chain_monitor.install_watch_tx(&outpoint.txid, script);
self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script);
},
}
writer.write_all(&byte_utils::be64_to_array(self.remote_claimable_outpoints.len() as u64))?;
- for (txid, htlc_outputs) in self.remote_claimable_outpoints.iter() {
+ for (ref txid, ref htlc_outputs) in self.remote_claimable_outpoints.iter() {
writer.write_all(&txid[..])?;
writer.write_all(&byte_utils::be64_to_array(htlc_outputs.len() as u64))?;
for htlc_output in htlc_outputs.iter() {
}
writer.write_all(&byte_utils::be64_to_array(self.remote_commitment_txn_on_chain.len() as u64))?;
- for (txid, (commitment_number, txouts)) in self.remote_commitment_txn_on_chain.iter() {
+ for (ref txid, &(commitment_number, ref txouts)) in self.remote_commitment_txn_on_chain.iter() {
writer.write_all(&txid[..])?;
- writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
+ writer.write_all(&byte_utils::be48_to_array(commitment_number))?;
(txouts.len() as u64).write(writer)?;
for script in txouts.iter() {
script.write(writer)?;
if for_local_storage {
writer.write_all(&byte_utils::be64_to_array(self.remote_hash_commitment_number.len() as u64))?;
- for (payment_hash, commitment_number) in self.remote_hash_commitment_number.iter() {
- writer.write_all(payment_hash)?;
+ for (ref payment_hash, commitment_number) in self.remote_hash_commitment_number.iter() {
+ writer.write_all(*payment_hash)?;
writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
}
} else {
macro_rules! serialize_local_tx {
($local_tx: expr) => {
- if let Err(e) = $local_tx.tx.consensus_encode(&mut serialize::RawEncoder::new(WriterWriteAdaptor(writer))) {
+ if let Err(e) = $local_tx.tx.consensus_encode(&mut WriterWriteAdaptor(writer)) {
match e {
- serialize::Error::Io(e) => return Err(e),
+ encode::Error::Io(e) => return Err(e),
_ => panic!("local tx must have been well-formed!"),
}
}
let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
let mut spendable_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
+ macro_rules! add_dynamic_output {
+ ($father_tx: expr, $vout: expr) => {
+ if let Some(ref per_commitment_point) = *per_commitment_point {
+ if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key {
+ if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) {
+ spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput {
+ outpoint: BitcoinOutPoint { txid: $father_tx.txid(), vout: $vout },
+ local_delayedkey,
+ witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key),
+ to_self_delay: self.our_to_self_delay
+ });
+ }
+ }
+ }
+ }
+ }
+
+
+ let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.their_to_self_delay.unwrap(), &local_tx.delayed_payment_key);
+ let revokeable_p2wsh = redeemscript.to_v0_p2wsh();
+ for (idx, output) in local_tx.tx.output.iter().enumerate() {
+ if output.script_pubkey == revokeable_p2wsh {
+ add_dynamic_output!(local_tx.tx, idx as u32);
+ break;
+ }
+ }
+
for &(ref htlc, ref their_sig, ref our_sig) in local_tx.htlc_outputs.iter() {
if htlc.offered {
let mut htlc_timeout_tx = chan_utils::build_htlc_transaction(&local_tx.txid, local_tx.feerate_per_kw, self.their_to_self_delay.unwrap(), htlc, &local_tx.delayed_payment_key, &local_tx.revocation_key);
htlc_timeout_tx.input[0].witness.push(Vec::new());
htlc_timeout_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes());
- if let Some(ref per_commitment_point) = *per_commitment_point {
- if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key {
- if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) {
- spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput {
- outpoint: BitcoinOutPoint { txid: htlc_timeout_tx.txid(), vout: 0 },
- local_delayedkey,
- witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key),
- to_self_delay: self.our_to_self_delay
- });
- }
- }
- }
+ add_dynamic_output!(htlc_timeout_tx, 0);
res.push(htlc_timeout_tx);
} else {
if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
htlc_success_tx.input[0].witness.push(payment_preimage.to_vec());
htlc_success_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes());
- if let Some(ref per_commitment_point) = *per_commitment_point {
- if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key {
- if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) {
- spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput {
- outpoint: BitcoinOutPoint { txid: htlc_success_tx.txid(), vout: 0 },
- local_delayedkey,
- witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key),
- to_self_delay: self.our_to_self_delay
- });
- }
- }
- }
+ add_dynamic_output!(htlc_success_tx, 0);
res.push(htlc_success_tx);
}
}
macro_rules! read_local_tx {
() => {
{
- let tx = match Transaction::consensus_decode(&mut serialize::RawDecoder::new(reader.by_ref())) {
+ let tx = match Transaction::consensus_decode(reader.by_ref()) {
Ok(tx) => tx,
Err(e) => match e {
- serialize::Error::Io(ioe) => return Err(DecodeError::Io(ioe)),
+ encode::Error::Io(ioe) => return Err(DecodeError::Io(ioe)),
_ => return Err(DecodeError::InvalidValue),
},
};