|
7 | 7 | use bitcoin::blockdata::block::{Block, BlockHeader};
|
8 | 8 | use bitcoin::blockdata::transaction::Transaction;
|
9 | 9 | use bitcoin::blockdata::script::Script;
|
10 |
| -use bitcoin::blockdata::constants::genesis_block; |
11 |
| -use bitcoin::util::hash::BitcoinHash; |
12 |
| -use bitcoin::network::constants::Network; |
13 |
| -use bitcoin::hash_types::{Txid, BlockHash}; |
| 10 | +use bitcoin::hash_types::Txid; |
14 | 11 |
|
15 |
| -use std::sync::{Mutex, MutexGuard, Arc}; |
16 |
| -use std::sync::atomic::{AtomicUsize, Ordering}; |
| 12 | +use std::sync::{Mutex, Arc}; |
17 | 13 | use std::collections::HashSet;
|
18 | 14 | use std::ops::Deref;
|
19 | 15 | use std::marker::PhantomData;
|
20 | 16 | use std::ptr;
|
21 | 17 |
|
22 |
| -/// Used to give chain error details upstream |
23 |
| -#[derive(Clone)] |
24 |
| -pub enum ChainError { |
25 |
| - /// Client doesn't support UTXO lookup (but the chain hash matches our genesis block hash) |
26 |
| - NotSupported, |
27 |
| - /// Chain isn't the one watched |
28 |
| - NotWatched, |
29 |
| - /// Tx doesn't exist or is unconfirmed |
30 |
| - UnknownTx, |
31 |
| -} |
32 |
| - |
33 |
| -/// An interface to request notification of certain scripts as they appear the |
34 |
| -/// chain. |
35 |
| -/// |
36 |
| -/// Note that all of the functions implemented here *must* be reentrant-safe (obviously - they're |
37 |
| -/// called from inside the library in response to ChainListener events, P2P events, or timer |
38 |
| -/// events). |
39 |
| -pub trait ChainWatchInterface: Sync + Send { |
40 |
| - /// Provides a txid/random-scriptPubKey-in-the-tx which much be watched for. |
41 |
| - fn install_watch_tx(&self, txid: &Txid, script_pub_key: &Script); |
42 |
| - |
43 |
| - /// Provides an outpoint which must be watched for, providing any transactions which spend the |
44 |
| - /// given outpoint. |
45 |
| - fn install_watch_outpoint(&self, outpoint: (Txid, u32), out_script: &Script); |
46 |
| - |
47 |
| - /// Indicates that a listener needs to see all transactions. |
48 |
| - fn watch_all_txn(&self); |
49 |
| - |
50 |
| - /// Gets the script and value in satoshis for a given unspent transaction output given a |
51 |
| - /// short_channel_id (aka unspent_tx_output_identier). For BTC/tBTC channels the top three |
52 |
| - /// bytes are the block height, the next 3 the transaction index within the block, and the |
53 |
| - /// final two the output within the transaction. |
54 |
| - fn get_chain_utxo(&self, genesis_hash: BlockHash, unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError>; |
55 |
| - |
56 |
| - /// Gets the list of transaction indices within a given block that the ChainWatchInterface is |
57 |
| - /// watching for. |
58 |
| - fn filter_block(&self, header: &BlockHeader, txdata: &[(usize, &Transaction)]) -> Vec<usize>; |
59 |
| - |
60 |
| - /// Returns a usize that changes when the ChainWatchInterface's watched data is modified. |
61 |
| - /// Users of `filter_block` should pre-save a copy of `reentered`'s return value and use it to |
62 |
| - /// determine whether they need to re-filter a given block. |
63 |
| - fn reentered(&self) -> usize; |
64 |
| -} |
65 |
| - |
66 | 18 | /// An interface to send a transaction to the Bitcoin network.
|
67 | 19 | pub trait BroadcasterInterface: Sync + Send {
|
68 | 20 | /// Sends a transaction out to (hopefully) be mined.
|
@@ -273,95 +225,6 @@ impl<'a, CL: Deref<Target = ChainListener + 'a> + 'a> BlockNotifier<'a, CL> {
|
273 | 225 | }
|
274 | 226 | }
|
275 | 227 |
|
276 |
| -/// Utility to capture some common parts of ChainWatchInterface implementors. |
277 |
| -/// |
278 |
| -/// Keeping a local copy of this in a ChainWatchInterface implementor is likely useful. |
279 |
| -pub struct ChainWatchInterfaceUtil { |
280 |
| - network: Network, |
281 |
| - watched: Mutex<ChainWatchedUtil>, |
282 |
| - reentered: AtomicUsize, |
283 |
| -} |
284 |
| - |
285 |
| -// We only expose PartialEq in test since its somewhat unclear exactly what it should do and we're |
286 |
| -// only comparing a subset of fields (essentially just checking that the set of things we're |
287 |
| -// watching is the same). |
288 |
| -#[cfg(test)] |
289 |
| -impl PartialEq for ChainWatchInterfaceUtil { |
290 |
| - fn eq(&self, o: &Self) -> bool { |
291 |
| - self.network == o.network && |
292 |
| - *self.watched.lock().unwrap() == *o.watched.lock().unwrap() |
293 |
| - } |
294 |
| -} |
295 |
| - |
296 |
| -/// Register listener |
297 |
| -impl ChainWatchInterface for ChainWatchInterfaceUtil { |
298 |
| - fn install_watch_tx(&self, txid: &Txid, script_pub_key: &Script) { |
299 |
| - let mut watched = self.watched.lock().unwrap(); |
300 |
| - if watched.register_tx(txid, script_pub_key) { |
301 |
| - self.reentered.fetch_add(1, Ordering::Relaxed); |
302 |
| - } |
303 |
| - } |
304 |
| - |
305 |
| - fn install_watch_outpoint(&self, outpoint: (Txid, u32), out_script: &Script) { |
306 |
| - let mut watched = self.watched.lock().unwrap(); |
307 |
| - if watched.register_outpoint(outpoint, out_script) { |
308 |
| - self.reentered.fetch_add(1, Ordering::Relaxed); |
309 |
| - } |
310 |
| - } |
311 |
| - |
312 |
| - fn watch_all_txn(&self) { |
313 |
| - let mut watched = self.watched.lock().unwrap(); |
314 |
| - if watched.watch_all() { |
315 |
| - self.reentered.fetch_add(1, Ordering::Relaxed); |
316 |
| - } |
317 |
| - } |
318 |
| - |
319 |
| - fn get_chain_utxo(&self, genesis_hash: BlockHash, _unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError> { |
320 |
| - if genesis_hash != genesis_block(self.network).header.bitcoin_hash() { |
321 |
| - return Err(ChainError::NotWatched); |
322 |
| - } |
323 |
| - Err(ChainError::NotSupported) |
324 |
| - } |
325 |
| - |
326 |
| - fn filter_block(&self, _header: &BlockHeader, txdata: &[(usize, &Transaction)]) -> Vec<usize> { |
327 |
| - let mut matched_index = Vec::new(); |
328 |
| - { |
329 |
| - let watched = self.watched.lock().unwrap(); |
330 |
| - for (i, transaction) in txdata.iter().enumerate() { |
331 |
| - if self.does_match_tx_unguarded(transaction.1, &watched) { |
332 |
| - matched_index.push(i); |
333 |
| - } |
334 |
| - } |
335 |
| - } |
336 |
| - matched_index |
337 |
| - } |
338 |
| - |
339 |
| - fn reentered(&self) -> usize { |
340 |
| - self.reentered.load(Ordering::Relaxed) |
341 |
| - } |
342 |
| -} |
343 |
| - |
344 |
| -impl ChainWatchInterfaceUtil { |
345 |
| - /// Creates a new ChainWatchInterfaceUtil for the given network |
346 |
| - pub fn new(network: Network) -> ChainWatchInterfaceUtil { |
347 |
| - ChainWatchInterfaceUtil { |
348 |
| - network, |
349 |
| - watched: Mutex::new(ChainWatchedUtil::new()), |
350 |
| - reentered: AtomicUsize::new(1), |
351 |
| - } |
352 |
| - } |
353 |
| - |
354 |
| - /// Checks if a given transaction matches the current filter. |
355 |
| - pub fn does_match_tx(&self, tx: &Transaction) -> bool { |
356 |
| - let watched = self.watched.lock().unwrap(); |
357 |
| - self.does_match_tx_unguarded (tx, &watched) |
358 |
| - } |
359 |
| - |
360 |
| - fn does_match_tx_unguarded(&self, tx: &Transaction, watched: &MutexGuard<ChainWatchedUtil>) -> bool { |
361 |
| - watched.does_match_tx(tx) |
362 |
| - } |
363 |
| -} |
364 |
| - |
365 | 228 | #[cfg(test)]
|
366 | 229 | mod tests {
|
367 | 230 | use bitcoin::blockdata::block::BlockHeader;
|
|
0 commit comments