Skip to content

Commit c384381

Browse files
committed
Implement chain::Access trait
1 parent 623116a commit c384381

File tree

3 files changed

+96
-7
lines changed

3 files changed

+96
-7
lines changed

src/access.rs

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
use crate::logger::{
22
log_error, log_given_level, log_internal, log_trace, FilesystemLogger, Logger,
33
};
4-
use crate::{Config, Error};
4+
use crate::{scid_utils, Config, Error};
55

66
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
77
use lightning::chain::WatchedOutput;
8-
use lightning::chain::{Confirm, Filter};
8+
use lightning::chain::{Access, AccessError, Confirm, Filter};
99

1010
use bdk::blockchain::{Blockchain, EsploraBlockchain};
1111
use bdk::database::BatchDatabase;
1212
use bdk::esplora_client;
1313
use bdk::wallet::AddressIndex;
1414
use bdk::{SignOptions, SyncOptions};
1515

16-
use bitcoin::{Script, Transaction, Txid};
16+
use bitcoin::{BlockHash, Script, Transaction, TxOut, Txid};
1717

1818
use std::collections::HashSet;
1919
use std::sync::{Arc, Mutex, RwLock};
@@ -33,15 +33,15 @@ where
3333
D: BatchDatabase,
3434
{
3535
blockchain: EsploraBlockchain,
36-
_client: Arc<esplora_client::AsyncClient>,
36+
client: Arc<esplora_client::AsyncClient>,
3737
wallet: Mutex<bdk::Wallet<D>>,
3838
queued_transactions: Mutex<Vec<Txid>>,
3939
watched_transactions: Mutex<Vec<Txid>>,
4040
queued_outputs: Mutex<Vec<WatchedOutput>>,
4141
watched_outputs: Mutex<Vec<WatchedOutput>>,
4242
last_sync_height: tokio::sync::Mutex<Option<u32>>,
4343
tokio_runtime: RwLock<Option<Arc<tokio::runtime::Runtime>>>,
44-
_config: Arc<Config>,
44+
config: Arc<Config>,
4545
logger: Arc<FilesystemLogger>,
4646
}
4747

@@ -68,15 +68,15 @@ where
6868
let client = Arc::new(client_builder.build_async().unwrap());
6969
Self {
7070
blockchain,
71-
_client: client,
71+
client,
7272
wallet,
7373
queued_transactions,
7474
watched_transactions,
7575
queued_outputs,
7676
watched_outputs,
7777
last_sync_height,
7878
tokio_runtime,
79-
_config: config,
79+
config,
8080
logger,
8181
}
8282
}
@@ -361,6 +361,61 @@ where
361361
}
362362
}
363363

364+
impl<D> Access for ChainAccess<D>
365+
where
366+
D: BatchDatabase,
367+
{
368+
fn get_utxo(
369+
&self, genesis_hash: &BlockHash, short_channel_id: u64,
370+
) -> Result<TxOut, AccessError> {
371+
if genesis_hash
372+
!= &bitcoin::blockdata::constants::genesis_block(self.config.network)
373+
.header
374+
.block_hash()
375+
{
376+
return Err(AccessError::UnknownChain);
377+
}
378+
379+
let locked_runtime = self.tokio_runtime.read().unwrap();
380+
if locked_runtime.as_ref().is_none() {
381+
return Err(AccessError::UnknownTx);
382+
}
383+
384+
let block_height = scid_utils::block_from_scid(&short_channel_id);
385+
let tx_index = scid_utils::tx_index_from_scid(&short_channel_id);
386+
let vout = scid_utils::vout_from_scid(&short_channel_id);
387+
388+
let client_tokio = Arc::clone(&self.client);
389+
locked_runtime.as_ref().unwrap().block_on(async move {
390+
// TODO: migrate to https://github.com/bitcoindevkit/rust-esplora-client/pull/13 with
391+
// next release.
392+
let block_hash = client_tokio
393+
.get_header(block_height.into())
394+
.await
395+
.map_err(|_| AccessError::UnknownTx)?
396+
.block_hash();
397+
398+
let txid = client_tokio
399+
.get_txid_at_block_index(&block_hash, tx_index as usize)
400+
.await
401+
.map_err(|_| AccessError::UnknownTx)?
402+
.ok_or(AccessError::UnknownTx)?;
403+
404+
let tx = client_tokio
405+
.get_tx(&txid)
406+
.await
407+
.map_err(|_| AccessError::UnknownTx)?
408+
.ok_or(AccessError::UnknownTx)?;
409+
410+
if let Some(tx_out) = tx.output.get(vout as usize) {
411+
return Ok(tx_out.clone());
412+
} else {
413+
Err(AccessError::UnknownTx)
414+
}
415+
})
416+
}
417+
}
418+
364419
fn num_blocks_from_conf_target(confirmation_target: ConfirmationTarget) -> usize {
365420
match confirmation_target {
366421
ConfirmationTarget::Background => 12,

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mod hex_utils;
3131
mod io_utils;
3232
mod logger;
3333
mod peer_store;
34+
mod scid_utils;
3435

3536
use access::ChainAccess;
3637
pub use error::Error;

src/scid_utils.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copied from `rust-lightning`
2+
//
3+
// This file is Copyright its original authors, visible in version control
4+
// history.
5+
//
6+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
7+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
9+
// You may not use this file except in accordance with one or both of these
10+
// licenses.
11+
12+
/// Maximum transaction index that can be used in a `short_channel_id`.
13+
/// This value is based on the 3-bytes available for tx index.
14+
pub const MAX_SCID_TX_INDEX: u64 = 0x00ffffff;
15+
16+
/// Maximum vout index that can be used in a `short_channel_id`. This
17+
/// value is based on the 2-bytes available for the vout index.
18+
pub const MAX_SCID_VOUT_INDEX: u64 = 0xffff;
19+
20+
/// Extracts the block height (most significant 3-bytes) from the `short_channel_id`
21+
pub fn block_from_scid(short_channel_id: &u64) -> u32 {
22+
return (short_channel_id >> 40) as u32;
23+
}
24+
25+
/// Extracts the tx index (bytes [2..4]) from the `short_channel_id`
26+
pub fn tx_index_from_scid(short_channel_id: &u64) -> u32 {
27+
return ((short_channel_id >> 16) & MAX_SCID_TX_INDEX) as u32;
28+
}
29+
30+
/// Extracts the vout (bytes [0..2]) from the `short_channel_id`
31+
pub fn vout_from_scid(short_channel_id: &u64) -> u16 {
32+
return ((short_channel_id) & MAX_SCID_VOUT_INDEX) as u16;
33+
}

0 commit comments

Comments
 (0)