X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fverifier.rs;h=c44cb663158e19d7e1c850b22bd57f6f952665c1;hb=81c27c87b10f2e097eef99e0766d1bcef2ebef60;hp=872a5010c8955b17a1f6114ab9c63ea57f8ad079;hpb=cf326fd7a9f42c58a24788943745f066ecb5f641;p=rapid-gossip-sync-server diff --git a/src/verifier.rs b/src/verifier.rs index 872a501..c44cb66 100644 --- a/src/verifier.rs +++ b/src/verifier.rs @@ -1,11 +1,13 @@ -use std::convert::TryInto; +use std::io::ErrorKind; use std::ops::Deref; use std::sync::Arc; use std::sync::Mutex; +use bitcoin::blockdata::constants::ChainHash; use bitcoin::{BlockHash, TxOut}; use bitcoin::blockdata::block::Block; use bitcoin::hashes::Hash; +use lightning::log_error; use lightning::routing::gossip::{NetworkGraph, P2PGossipSync}; use lightning::routing::utxo::{UtxoFuture, UtxoLookup, UtxoResult, UtxoLookupError}; use lightning::util::logger::Logger; @@ -21,41 +23,57 @@ pub(crate) struct ChainVerifier where graph: Arc>, outbound_gossiper: Arc>, Arc, L>>, peer_handler: Mutex>>, + logger: L } struct RestBinaryResponse(Vec); impl ChainVerifier where L::Target: Logger { - pub(crate) fn new(graph: Arc>, outbound_gossiper: Arc>, Arc, L>>) -> Self { + pub(crate) fn new(graph: Arc>, outbound_gossiper: Arc>, Arc, L>>, logger: L) -> Self { ChainVerifier { rest_client: Arc::new(RestClient::new(config::bitcoin_rest_endpoint()).unwrap()), outbound_gossiper, graph, peer_handler: Mutex::new(None), + logger } } pub(crate) fn set_ph(&self, peer_handler: GossipPeerManager) { *self.peer_handler.lock().unwrap() = Some(peer_handler); } - async fn retrieve_utxo(client: Arc, short_channel_id: u64) -> Result { + async fn retrieve_utxo(client: Arc, short_channel_id: u64, logger: L) -> Result { let block_height = (short_channel_id >> 5 * 8) as u32; // block height is most significant three bytes let transaction_index = ((short_channel_id >> 2 * 8) & 0xffffff) as u32; let output_index = (short_channel_id & 0xffff) as u16; - let mut block = Self::retrieve_block(client, block_height).await?; - if transaction_index as usize >= block.txdata.len() { return Err(UtxoLookupError::UnknownTx); } + let mut block = Self::retrieve_block(client, block_height, logger.clone()).await?; + if transaction_index as usize >= block.txdata.len() { + log_error!(logger, "Could't find transaction {} in block {}", transaction_index, block_height); + return Err(UtxoLookupError::UnknownTx); + } let mut transaction = block.txdata.swap_remove(transaction_index as usize); - if output_index as usize >= transaction.output.len() { return Err(UtxoLookupError::UnknownTx); } + if output_index as usize >= transaction.output.len() { + log_error!(logger, "Could't find output {} in transaction {}", output_index, transaction.txid()); + return Err(UtxoLookupError::UnknownTx); + } Ok(transaction.output.swap_remove(output_index as usize)) } - async fn retrieve_block(client: Arc, block_height: u32) -> Result { + async fn retrieve_block(client: Arc, block_height: u32, logger: L) -> Result { let uri = format!("blockhashbyheight/{}.bin", block_height); let block_hash_result = client.request_resource::(&uri).await; let block_hash: Vec = block_hash_result.map_err(|error| { - eprintln!("Could't find block hash at height {}: {}", block_height, error.to_string()); + match error.kind() { + ErrorKind::InvalidData => { + // the response length was likely 0 + log_error!(logger, "Could't find block hash at height {}: Invalid response! Please make sure the `-rest=1` flag is set.", block_height); + } + _ => { + log_error!(logger, "Could't find block hash at height {}: {}", block_height, error.to_string()); + } + } UtxoLookupError::UnknownChain })?.0; let block_hash = BlockHash::from_slice(&block_hash).unwrap(); @@ -67,7 +85,7 @@ impl ChainVerifier where L::Target: }, Ok(_) => unreachable!(), Err(error) => { - eprintln!("Couldn't retrieve block {}: {:?} ({})", block_height, error, block_hash); + log_error!(logger, "Couldn't retrieve block {}: {:?} ({})", block_height, error, block_hash); Err(UtxoLookupError::UnknownChain) } } @@ -75,15 +93,16 @@ impl ChainVerifier where L::Target: } impl UtxoLookup for ChainVerifier where L::Target: Logger { - fn get_utxo(&self, _genesis_hash: &BlockHash, short_channel_id: u64) -> UtxoResult { + fn get_utxo(&self, _genesis_hash: &ChainHash, short_channel_id: u64) -> UtxoResult { let res = UtxoFuture::new(); let fut = res.clone(); let graph_ref = Arc::clone(&self.graph); let client_ref = Arc::clone(&self.rest_client); let gossip_ref = Arc::clone(&self.outbound_gossiper); let pm_ref = self.peer_handler.lock().unwrap().clone(); + let logger_ref = self.logger.clone(); tokio::spawn(async move { - let res = Self::retrieve_utxo(client_ref, short_channel_id).await; + let res = Self::retrieve_utxo(client_ref, short_channel_id, logger_ref).await; fut.resolve(&*graph_ref, &*gossip_ref, res); if let Some(pm) = pm_ref { pm.process_events(); } });