Skip to content

Commit

Permalink
Implement chain::Access trait
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull committed Oct 20, 2022
1 parent 623116a commit c384381
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 7 deletions.
69 changes: 62 additions & 7 deletions src/access.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use crate::logger::{
log_error, log_given_level, log_internal, log_trace, FilesystemLogger, Logger,
};
use crate::{Config, Error};
use crate::{scid_utils, Config, Error};

use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
use lightning::chain::WatchedOutput;
use lightning::chain::{Confirm, Filter};
use lightning::chain::{Access, AccessError, Confirm, Filter};

use bdk::blockchain::{Blockchain, EsploraBlockchain};
use bdk::database::BatchDatabase;
use bdk::esplora_client;
use bdk::wallet::AddressIndex;
use bdk::{SignOptions, SyncOptions};

use bitcoin::{Script, Transaction, Txid};
use bitcoin::{BlockHash, Script, Transaction, TxOut, Txid};

use std::collections::HashSet;
use std::sync::{Arc, Mutex, RwLock};
Expand All @@ -33,15 +33,15 @@ where
D: BatchDatabase,
{
blockchain: EsploraBlockchain,
_client: Arc<esplora_client::AsyncClient>,
client: Arc<esplora_client::AsyncClient>,
wallet: Mutex<bdk::Wallet<D>>,
queued_transactions: Mutex<Vec<Txid>>,
watched_transactions: Mutex<Vec<Txid>>,
queued_outputs: Mutex<Vec<WatchedOutput>>,
watched_outputs: Mutex<Vec<WatchedOutput>>,
last_sync_height: tokio::sync::Mutex<Option<u32>>,
tokio_runtime: RwLock<Option<Arc<tokio::runtime::Runtime>>>,
_config: Arc<Config>,
config: Arc<Config>,
logger: Arc<FilesystemLogger>,
}

Expand All @@ -68,15 +68,15 @@ where
let client = Arc::new(client_builder.build_async().unwrap());
Self {
blockchain,
_client: client,
client,
wallet,
queued_transactions,
watched_transactions,
queued_outputs,
watched_outputs,
last_sync_height,
tokio_runtime,
_config: config,
config,
logger,
}
}
Expand Down Expand Up @@ -361,6 +361,61 @@ where
}
}

impl<D> Access for ChainAccess<D>
where
D: BatchDatabase,
{
fn get_utxo(
&self, genesis_hash: &BlockHash, short_channel_id: u64,
) -> Result<TxOut, AccessError> {
if genesis_hash
!= &bitcoin::blockdata::constants::genesis_block(self.config.network)
.header
.block_hash()
{
return Err(AccessError::UnknownChain);
}

let locked_runtime = self.tokio_runtime.read().unwrap();
if locked_runtime.as_ref().is_none() {
return Err(AccessError::UnknownTx);
}

let block_height = scid_utils::block_from_scid(&short_channel_id);
let tx_index = scid_utils::tx_index_from_scid(&short_channel_id);
let vout = scid_utils::vout_from_scid(&short_channel_id);

let client_tokio = Arc::clone(&self.client);
locked_runtime.as_ref().unwrap().block_on(async move {
// TODO: migrate to https://github.com/bitcoindevkit/rust-esplora-client/pull/13 with
// next release.
let block_hash = client_tokio
.get_header(block_height.into())
.await
.map_err(|_| AccessError::UnknownTx)?
.block_hash();

let txid = client_tokio
.get_txid_at_block_index(&block_hash, tx_index as usize)
.await
.map_err(|_| AccessError::UnknownTx)?
.ok_or(AccessError::UnknownTx)?;

let tx = client_tokio
.get_tx(&txid)
.await
.map_err(|_| AccessError::UnknownTx)?
.ok_or(AccessError::UnknownTx)?;

if let Some(tx_out) = tx.output.get(vout as usize) {
return Ok(tx_out.clone());
} else {
Err(AccessError::UnknownTx)
}
})
}
}

fn num_blocks_from_conf_target(confirmation_target: ConfirmationTarget) -> usize {
match confirmation_target {
ConfirmationTarget::Background => 12,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod hex_utils;
mod io_utils;
mod logger;
mod peer_store;
mod scid_utils;

use access::ChainAccess;
pub use error::Error;
Expand Down
33 changes: 33 additions & 0 deletions src/scid_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copied from `rust-lightning`
//
// This file is Copyright its original authors, visible in version control
// history.
//
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
// You may not use this file except in accordance with one or both of these
// licenses.

/// Maximum transaction index that can be used in a `short_channel_id`.
/// This value is based on the 3-bytes available for tx index.
pub const MAX_SCID_TX_INDEX: u64 = 0x00ffffff;

/// Maximum vout index that can be used in a `short_channel_id`. This
/// value is based on the 2-bytes available for the vout index.
pub const MAX_SCID_VOUT_INDEX: u64 = 0xffff;

/// Extracts the block height (most significant 3-bytes) from the `short_channel_id`
pub fn block_from_scid(short_channel_id: &u64) -> u32 {
return (short_channel_id >> 40) as u32;
}

/// Extracts the tx index (bytes [2..4]) from the `short_channel_id`
pub fn tx_index_from_scid(short_channel_id: &u64) -> u32 {
return ((short_channel_id >> 16) & MAX_SCID_TX_INDEX) as u32;
}

/// Extracts the vout (bytes [0..2]) from the `short_channel_id`
pub fn vout_from_scid(short_channel_id: &u64) -> u16 {
return ((short_channel_id) & MAX_SCID_VOUT_INDEX) as u16;
}

0 comments on commit c384381

Please sign in to comment.