Skip to content

Commit 30ed951

Browse files
committed
Implement chain::Access trait
1 parent 4c62cd8 commit 30ed951

File tree

3 files changed

+93
-10
lines changed

3 files changed

+93
-10
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::collections::HashSet;
2021
use std::sync::{Arc, Mutex};
@@ -33,6 +34,7 @@ where
3334
queued_outputs: Mutex<Vec<WatchedOutput>>,
3435
watched_outputs: Mutex<Vec<WatchedOutput>>,
3536
last_sync_height: Mutex<Option<u32>>,
37+
config: Arc<LdkLiteConfig>,
3638
logger: Arc<FilesystemLogger>,
3739
}
3840

@@ -41,7 +43,8 @@ where
4143
D: BatchDatabase,
4244
{
4345
pub(crate) fn new(
44-
blockchain: EsploraBlockchain, wallet: bdk::Wallet<D>, logger: Arc<FilesystemLogger>,
46+
blockchain: EsploraBlockchain, wallet: bdk::Wallet<D>, config: Arc<LdkLiteConfig>,
47+
logger: Arc<FilesystemLogger>,
4548
) -> Self {
4649
let wallet = Mutex::new(wallet);
4750
let watched_transactions = Mutex::new(Vec::new());
@@ -57,6 +60,7 @@ where
5760
queued_outputs,
5861
watched_outputs,
5962
last_sync_height,
63+
config,
6064
logger,
6165
}
6266
}
@@ -281,6 +285,44 @@ where
281285
}
282286
}
283287

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

src/lib.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod error;
2929
mod event;
3030
mod hex_utils;
3131
mod io_utils;
32+
mod scid_utils;
3233
mod logger;
3334
mod peer_store;
3435

@@ -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)