Skip to content

Commit 521564d

Browse files
committed
Implement chain::Access trait
1 parent a6174dc commit 521564d

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

src/access.rs

Lines changed: 60 additions & 5 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::EsploraBlockchain;
1111
use bdk::database::BatchDatabase;
1212
use bdk::esplora_client;
1313
use bdk::wallet::AddressIndex;
1414
use bdk::{FeeRate, 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::{mpsc, Arc, Mutex, RwLock};
@@ -41,7 +41,7 @@ where
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

@@ -78,7 +78,7 @@ where
7878
watched_outputs,
7979
last_sync_height,
8080
tokio_runtime,
81-
_config: config,
81+
config,
8282
logger,
8383
}
8484
}
@@ -387,6 +387,61 @@ where
387387
}
388388
}
389389

390+
impl<D> Access for ChainAccess<D>
391+
where
392+
D: BatchDatabase,
393+
{
394+
fn get_utxo(
395+
&self, genesis_hash: &BlockHash, short_channel_id: u64,
396+
) -> Result<TxOut, AccessError> {
397+
if genesis_hash
398+
!= &bitcoin::blockdata::constants::genesis_block(self.config.network)
399+
.header
400+
.block_hash()
401+
{
402+
return Err(AccessError::UnknownChain);
403+
}
404+
405+
let locked_runtime = self.tokio_runtime.read().unwrap();
406+
if locked_runtime.as_ref().is_none() {
407+
return Err(AccessError::UnknownTx);
408+
}
409+
410+
let block_height = scid_utils::block_from_scid(&short_channel_id);
411+
let tx_index = scid_utils::tx_index_from_scid(&short_channel_id);
412+
let vout = scid_utils::vout_from_scid(&short_channel_id);
413+
414+
let client_tokio = Arc::clone(&self.client);
415+
locked_runtime.as_ref().unwrap().block_on(async move {
416+
// TODO: migrate to https://github.com/bitcoindevkit/rust-esplora-client/pull/13 with
417+
// next release.
418+
let block_hash = client_tokio
419+
.get_header(block_height.into())
420+
.await
421+
.map_err(|_| AccessError::UnknownTx)?
422+
.block_hash();
423+
424+
let txid = client_tokio
425+
.get_txid_at_block_index(&block_hash, tx_index as usize)
426+
.await
427+
.map_err(|_| AccessError::UnknownTx)?
428+
.ok_or(AccessError::UnknownTx)?;
429+
430+
let tx = client_tokio
431+
.get_tx(&txid)
432+
.await
433+
.map_err(|_| AccessError::UnknownTx)?
434+
.ok_or(AccessError::UnknownTx)?;
435+
436+
if let Some(tx_out) = tx.output.get(vout as usize) {
437+
return Ok(tx_out.clone());
438+
} else {
439+
Err(AccessError::UnknownTx)
440+
}
441+
})
442+
}
443+
}
444+
390445
fn num_blocks_from_conf_target(confirmation_target: ConfirmationTarget) -> usize {
391446
match confirmation_target {
392447
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)