use bitcoin::blockdata::script::{Script, Builder};
use bitcoin::blockdata::opcodes;
use bitcoin::consensus::encode;
-use bitcoin::util::hash::BitcoinHash;
use bitcoin::hashes::Hash;
use bitcoin::hashes::sha256::Hash as Sha256;
use util::logger::Logger;
use util::ser::{Readable, MaybeReadable, Writer, Writeable, U48};
use util::{byte_utils, events};
+use util::events::Event;
use std::collections::{HashMap, hash_map};
use std::sync::Mutex;
use std::{hash,cmp, mem};
use std::ops::Deref;
+use std::io::Error;
/// An update generated by the underlying Channel itself which contains some new information the
/// ChannelMonitor should be made aware of.
C::Target: ChainWatchInterface,
{
fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], _indexes_of_txn_matched: &[usize]) {
- let block_hash = header.bitcoin_hash();
+ let block_hash = header.block_hash();
{
let mut monitors = self.monitors.lock().unwrap();
for monitor in monitors.values_mut() {
}
fn block_disconnected(&self, header: &BlockHeader, disconnected_height: u32) {
- let block_hash = header.bitcoin_hash();
+ let block_hash = header.block_hash();
let mut monitors = self.monitors.lock().unwrap();
for monitor in monitors.values_mut() {
monitor.block_disconnected(disconnected_height, &block_hash, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
L::Target: Logger,
C::Target: ChainWatchInterface,
{
- fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
+ fn get_and_clear_pending_events(&self) -> Vec<Event> {
let mut pending_events = Vec::new();
for chan in self.monitors.lock().unwrap().values_mut() {
pending_events.append(&mut chan.get_and_clear_pending_events());
payment_preimages: HashMap<PaymentHash, PaymentPreimage>,
pending_monitor_events: Vec<MonitorEvent>,
- pending_events: Vec<events::Event>,
+ pending_events: Vec<Event>,
// Used to track onchain events, i.e transactions parts of channels confirmed on chain, on which
// we have to take actions once they reach enough confs. Key is a block height timer, i.e we enforce
/// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
/// returned block hash and the the current chain and then reconnecting blocks to get to the
/// best chain) upon deserializing the object!
- pub fn write_for_disk<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+ pub fn write_for_disk<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
//TODO: We still write out all the serialization here manually instead of using the fancy
//serialization framework we have, we should migrate things over to it.
writer.write_all(&[SERIALIZATION_VERSION; 1])?;
/// This is called by ManyChannelMonitor::get_and_clear_pending_events() and is equivalent to
/// EventsProvider::get_and_clear_pending_events() except that it requires &mut self as we do
/// no internal locking in ChannelMonitors.
- pub fn get_and_clear_pending_events(&mut self) -> Vec<events::Event> {
+ pub fn get_and_clear_pending_events(&mut self) -> Vec<Event> {
let mut ret = Vec::new();
mem::swap(&mut ret, &mut self.pending_events);
ret
},
OnchainEvent::MaturingOutput { descriptor } => {
log_trace!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor));
- self.pending_events.push(events::Event::SpendableOutputs {
+ self.pending_events.push(Event::SpendableOutputs {
outputs: vec![descriptor]
});
}
fn is_paying_spendable_output<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger {
let mut spendable_output = None;
for (i, outp) in tx.output.iter().enumerate() { // There is max one spendable output for any channel tx, including ones generated by us
+ if i > ::std::u16::MAX as usize {
+ // While it is possible that an output exists on chain which is greater than the
+ // 2^16th output in a given transaction, this is only possible if the output is not
+ // in a lightning transaction and was instead placed there by some third party who
+ // wishes to give us money for no reason.
+ // Namely, any lightning transactions which we pre-sign will never have anywhere
+ // near 2^16 outputs both because such transactions must have ~2^16 outputs who's
+ // scripts are not longer than one byte in length and because they are inherently
+ // non-standard due to their size.
+ // Thus, it is completely safe to ignore such outputs, and while it may result in
+ // us ignoring non-lightning fund to us, that is only possible if someone fills
+ // nearly a full block with garbage just to hit this case.
+ continue;
+ }
if outp.script_pubkey == self.destination_script {
spendable_output = Some(SpendableOutputDescriptor::StaticOutput {
- outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 },
+ outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
output: outp.clone(),
});
break;
} else if let Some(ref broadcasted_local_revokable_script) = self.broadcasted_local_revokable_script {
if broadcasted_local_revokable_script.0 == outp.script_pubkey {
spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WSH {
- outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 },
+ outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
per_commitment_point: broadcasted_local_revokable_script.1,
to_self_delay: self.on_local_tx_csv,
output: outp.clone(),
}
} else if self.remote_payment_script == outp.script_pubkey {
spendable_output = Some(SpendableOutputDescriptor::StaticOutputRemotePayment {
- outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 },
+ outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
output: outp.clone(),
key_derivation_params: self.keys.key_derivation_params(),
});
break;
} else if outp.script_pubkey == self.shutdown_script {
spendable_output = Some(SpendableOutputDescriptor::StaticOutput {
- outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 },
+ outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
output: outp.clone(),
});
}
}
let pending_events_len: u64 = Readable::read(reader)?;
- let mut pending_events = Vec::with_capacity(cmp::min(pending_events_len as usize, MAX_ALLOC_SIZE / mem::size_of::<events::Event>()));
+ let mut pending_events = Vec::with_capacity(cmp::min(pending_events_len as usize, MAX_ALLOC_SIZE / mem::size_of::<Event>()));
for _ in 0..pending_events_len {
if let Some(event) = MaybeReadable::read(reader)? {
pending_events.push(event);