Skip to content

Commit dd97b78

Browse files
committed
Implement chain::Access trait
1 parent 393bf55 commit dd97b78

File tree

3 files changed

+94
-11
lines changed

3 files changed

+94
-11
lines changed

src/access.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ use crate::logger::{
44
log_error, log_given_level, log_info, log_internal, log_trace, log_warn, FilesystemLogger,
55
Logger,
66
};
7+
use crate::{scid_utils, LdkLiteConfig};
78

89
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
910
use lightning::chain::WatchedOutput;
10-
use lightning::chain::{Confirm, Filter};
11+
use lightning::chain::{Access, AccessError, Confirm, Filter};
1112

1213
use bdk::blockchain::{Blockchain, EsploraBlockchain, GetBlockHash, GetHeight, GetTx};
1314
use bdk::database::BatchDatabase;
1415
use bdk::wallet::AddressIndex;
1516
use bdk::{SignOptions, SyncOptions};
1617

17-
use bitcoin::{BlockHash, Script, Transaction, Txid};
18+
use bitcoin::{BlockHash, Script, Transaction, TxOut, Txid};
1819

1920
use std::sync::{Arc, Mutex};
2021

@@ -29,6 +30,7 @@ where
2930
queued_outputs: Mutex<Vec<WatchedOutput>>,
3031
watched_outputs: Mutex<Vec<WatchedOutput>>,
3132
last_sync_height: Mutex<Option<u32>>,
33+
config: Arc<LdkLiteConfig>,
3234
logger: Arc<FilesystemLogger>,
3335
}
3436

@@ -37,7 +39,8 @@ where
3739
D: BatchDatabase,
3840
{
3941
pub(crate) fn new(
40-
blockchain: EsploraBlockchain, wallet: bdk::Wallet<D>, logger: Arc<FilesystemLogger>,
42+
blockchain: EsploraBlockchain, wallet: bdk::Wallet<D>, config: Arc<LdkLiteConfig>,
43+
logger: Arc<FilesystemLogger>,
4144
) -> Self {
4245
let wallet = Mutex::new(wallet);
4346
let watched_transactions = Mutex::new(Vec::new());
@@ -53,6 +56,7 @@ where
5356
queued_outputs,
5457
watched_outputs,
5558
last_sync_height,
59+
config,
5660
logger,
5761
}
5862
}
@@ -275,6 +279,44 @@ where
275279
}
276280
}
277281

282+
impl<D> Access for LdkLiteChainAccess<D>
283+
where
284+
D: BatchDatabase,
285+
{
286+
fn get_utxo(
287+
&self, genesis_hash: &BlockHash, short_channel_id: u64,
288+
) -> Result<TxOut, AccessError> {
289+
if genesis_hash
290+
!= &bitcoin::blockdata::constants::genesis_block(self.config.network)
291+
.header
292+
.block_hash()
293+
{
294+
return Err(AccessError::UnknownChain);
295+
}
296+
297+
let block_height = scid_utils::block_from_scid(&short_channel_id);
298+
let tx_index = scid_utils::tx_index_from_scid(&short_channel_id);
299+
let vout = scid_utils::vout_from_scid(&short_channel_id);
300+
301+
let client = &*self.blockchain;
302+
let block_hash = self
303+
.blockchain
304+
.get_block_hash(block_height.into())
305+
.map_err(|_| AccessError::UnknownTx)?;
306+
let txid = client
307+
.get_txid_at_block_index(&block_hash, tx_index as usize)
308+
.map_err(|_| AccessError::UnknownTx)?
309+
.ok_or(AccessError::UnknownTx)?;
310+
let tx = client
311+
.get_tx(&txid)
312+
.map_err(|_| AccessError::UnknownTx)?
313+
.ok_or(AccessError::UnknownTx)?;
314+
let tx_out = tx.output.get(vout as usize).ok_or(AccessError::UnknownTx)?;
315+
316+
Ok(tx_out.clone())
317+
}
318+
}
319+
278320
impl<D> Filter for LdkLiteChainAccess<D>
279321
where
280322
D: BatchDatabase,

src/lib.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@
2727
mod access;
2828
mod error;
2929
mod event;
30-
mod peer_store;
3130
mod hex_utils;
3231
mod io_utils;
32+
mod scid_utils;
3333
mod logger;
34+
mod peer_store;
3435

3536
use access::LdkLiteChainAccess;
3637
pub use error::LdkLiteError as Error;
@@ -45,7 +46,7 @@ use logger::{
4546
};
4647

4748
use lightning::chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager, Recipient};
48-
use lightning::chain::{chainmonitor, Access, BestBlock, Confirm, Filter, Watch};
49+
use lightning::chain::{chainmonitor, BestBlock, Confirm, Filter, Watch};
4950
use lightning::ln::channelmanager;
5051
use lightning::ln::channelmanager::{
5152
ChainParameters, ChannelManagerReadArgs, SimpleArcChannelManager,
@@ -227,8 +228,12 @@ impl LdkLiteBuilder {
227228
let blockchain = EsploraBlockchain::new(&config.esplora_server_url, BDK_CLIENT_STOP_GAP)
228229
.with_concurrency(BDK_CLIENT_CONCURRENCY);
229230

230-
let chain_access =
231-
Arc::new(LdkLiteChainAccess::new(blockchain, bdk_wallet, Arc::clone(&logger)));
231+
let chain_access = Arc::new(LdkLiteChainAccess::new(
232+
blockchain,
233+
bdk_wallet,
234+
Arc::clone(&config),
235+
Arc::clone(&logger),
236+
));
232237

233238
// Step 3: Initialize Persist
234239
let persister = Arc::new(FilesystemPersister::new(ldk_data_dir.clone()));
@@ -303,7 +308,7 @@ impl LdkLiteBuilder {
303308
Arc::new(io_utils::read_network_graph(Arc::clone(&config), Arc::clone(&logger))?);
304309
let gossip_sync = Arc::new(P2PGossipSync::new(
305310
Arc::clone(&network_graph),
306-
None::<Arc<dyn Access + Send + Sync>>,
311+
Some(Arc::clone(&chain_access)),
307312
Arc::clone(&logger),
308313
));
309314

@@ -963,7 +968,7 @@ type PeerManager = SimpleArcPeerManager<
963968
ChainMonitor,
964969
LdkLiteChainAccess<bdk::sled::Tree>,
965970
LdkLiteChainAccess<bdk::sled::Tree>,
966-
dyn Access + Send + Sync,
971+
LdkLiteChainAccess<bdk::sled::Tree>,
967972
FilesystemLogger,
968973
>;
969974

@@ -985,8 +990,11 @@ type InvoicePayer<F> = payment::InvoicePayer<
985990
type Router = DefaultRouter<Arc<NetworkGraph>, Arc<FilesystemLogger>>;
986991
type Scorer = ProbabilisticScorer<Arc<NetworkGraph>, Arc<FilesystemLogger>>;
987992

988-
type GossipSync =
989-
P2PGossipSync<Arc<NetworkGraph>, Arc<dyn Access + Send + Sync>, Arc<FilesystemLogger>>;
993+
type GossipSync = P2PGossipSync<
994+
Arc<NetworkGraph>,
995+
Arc<LdkLiteChainAccess<bdk::sled::Tree>>,
996+
Arc<FilesystemLogger>,
997+
>;
990998

991999
pub(crate) type NetworkGraph = gossip::NetworkGraph<Arc<FilesystemLogger>>;
9921000

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)