Skip to content

Commit 98d626c

Browse files
committed
Move chain::Access to routing and rename it ChainAccess
The `chain::Access` trait (and the `chain::AccessError` enum) is a bit strange - it only really makes sense if users import it via the `chain` module, otherwise they're left with a trait just called `Access`. Worse, for bindings users its always just called `Access`, in part because many downstream languages don't have a mechanism to import a module and then refer to it. Further, its stuck dangling in the `chain` top-level mod.rs file, sitting in a module that doesn't use it at all (it's only used in `routing::gossip`). Instead, we give it its full name - `ChainAccess` (and rename the error enum `ChainAccessError`) and put it in the a new `routing::gossip_checking` module, next to `routing::gossip`.
1 parent 153b048 commit 98d626c

File tree

9 files changed

+67
-57
lines changed

9 files changed

+67
-57
lines changed

fuzz/src/full_stack.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor,Ig
4141
use lightning::ln::msgs::{self, DecodeError};
4242
use lightning::ln::script::ShutdownScript;
4343
use lightning::routing::gossip::{P2PGossipSync, NetworkGraph};
44+
use lightning::routing::gossip_checking::ChainAccess;
4445
use lightning::routing::router::{find_route, InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, Router};
4546
use lightning::routing::scoring::FixedPenaltyScorer;
4647
use lightning::util::config::UserConfig;
@@ -183,7 +184,7 @@ impl<'a> std::hash::Hash for Peer<'a> {
183184
type ChannelMan<'a> = ChannelManager<
184185
Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
185186
Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
186-
type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler, Arc<KeyProvider>>;
187+
type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn ChainAccess>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler, Arc<KeyProvider>>;
187188

188189
struct MoneyLossDetector<'a> {
189190
manager: Arc<ChannelMan<'a>>,

fuzz/src/router.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ use bitcoin::blockdata::script::Builder;
1111
use bitcoin::blockdata::transaction::TxOut;
1212
use bitcoin::hash_types::BlockHash;
1313

14-
use lightning::chain;
1514
use lightning::chain::transaction::OutPoint;
1615
use lightning::ln::channelmanager::{self, ChannelDetails, ChannelCounterparty};
1716
use lightning::ln::msgs;
1817
use lightning::routing::gossip::{NetworkGraph, RoutingFees};
18+
use lightning::routing::gossip_checking::{ChainAccess, ChainAccessError};
1919
use lightning::routing::router::{find_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters};
2020
use lightning::routing::scoring::FixedPenaltyScorer;
2121
use lightning::util::config::UserConfig;
@@ -84,13 +84,13 @@ impl InputData {
8484
struct FuzzChainSource {
8585
input: Arc<InputData>,
8686
}
87-
impl chain::Access for FuzzChainSource {
88-
fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, chain::AccessError> {
87+
impl ChainAccess for FuzzChainSource {
88+
fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, ChainAccessError> {
8989
match self.input.get_slice(2) {
90-
Some(&[0, _]) => Err(chain::AccessError::UnknownChain),
91-
Some(&[1, _]) => Err(chain::AccessError::UnknownTx),
90+
Some(&[0, _]) => Err(ChainAccessError::UnknownChain),
91+
Some(&[1, _]) => Err(ChainAccessError::UnknownTx),
9292
Some(&[_, x]) => Ok(TxOut { value: 0, script_pubkey: Builder::new().push_int(x as i64).into_script().to_v0_p2wsh() }),
93-
None => Err(chain::AccessError::UnknownTx),
93+
None => Err(ChainAccessError::UnknownTx),
9494
_ => unreachable!(),
9595
}
9696
}

lightning-background-processor/src/lib.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use lightning::ln::channelmanager::ChannelManager;
2727
use lightning::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler};
2828
use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor};
2929
use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
30+
use lightning::routing::gossip_checking::ChainAccess;
3031
use lightning::routing::router::Router;
3132
use lightning::routing::scoring::WriteableScore;
3233
use lightning::util::events::{Event, EventHandler, EventsProvider};
@@ -117,7 +118,7 @@ pub enum GossipSync<
117118
A: Deref,
118119
L: Deref,
119120
>
120-
where A::Target: chain::Access, L::Target: Logger {
121+
where A::Target: ChainAccess, L::Target: Logger {
121122
/// Gossip sync via the lightning peer-to-peer network as defined by BOLT 7.
122123
P2P(P),
123124
/// Rapid gossip sync from a trusted server.
@@ -133,7 +134,7 @@ impl<
133134
A: Deref,
134135
L: Deref,
135136
> GossipSync<P, R, G, A, L>
136-
where A::Target: chain::Access, L::Target: Logger {
137+
where A::Target: ChainAccess, L::Target: Logger {
137138
fn network_graph(&self) -> Option<&G> {
138139
match self {
139140
GossipSync::P2P(gossip_sync) => Some(gossip_sync.network_graph()),
@@ -161,7 +162,7 @@ where A::Target: chain::Access, L::Target: Logger {
161162
impl<P: Deref<Target = P2PGossipSync<G, A, L>>, G: Deref<Target = NetworkGraph<L>>, A: Deref, L: Deref>
162163
GossipSync<P, &RapidGossipSync<G, L>, G, A, L>
163164
where
164-
A::Target: chain::Access,
165+
A::Target: ChainAccess,
165166
L::Target: Logger,
166167
{
167168
/// Initializes a new [`GossipSync::P2P`] variant.
@@ -173,10 +174,10 @@ where
173174
/// (C-not exported) as the bindings concretize everything and have constructors for us
174175
impl<'a, R: Deref<Target = RapidGossipSync<G, L>>, G: Deref<Target = NetworkGraph<L>>, L: Deref>
175176
GossipSync<
176-
&P2PGossipSync<G, &'a (dyn chain::Access + Send + Sync), L>,
177+
&P2PGossipSync<G, &'a (dyn ChainAccess + Send + Sync), L>,
177178
R,
178179
G,
179-
&'a (dyn chain::Access + Send + Sync),
180+
&'a (dyn ChainAccess + Send + Sync),
180181
L,
181182
>
182183
where
@@ -191,10 +192,10 @@ where
191192
/// (C-not exported) as the bindings concretize everything and have constructors for us
192193
impl<'a, L: Deref>
193194
GossipSync<
194-
&P2PGossipSync<&'a NetworkGraph<L>, &'a (dyn chain::Access + Send + Sync), L>,
195+
&P2PGossipSync<&'a NetworkGraph<L>, &'a (dyn ChainAccess + Send + Sync), L>,
195196
&RapidGossipSync<&'a NetworkGraph<L>, L>,
196197
&'a NetworkGraph<L>,
197-
&'a (dyn chain::Access + Send + Sync),
198+
&'a (dyn ChainAccess + Send + Sync),
198199
L,
199200
>
200201
where
@@ -396,7 +397,7 @@ pub async fn process_events_async<
396397
sleeper: Sleeper,
397398
) -> Result<(), io::Error>
398399
where
399-
CA::Target: 'static + chain::Access,
400+
CA::Target: 'static + ChainAccess,
400401
CF::Target: 'static + chain::Filter,
401402
CW::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::Signer>,
402403
T::Target: 'static + BroadcasterInterface,
@@ -522,7 +523,7 @@ impl BackgroundProcessor {
522523
gossip_sync: GossipSync<PGS, RGS, G, CA, L>, peer_manager: PM, logger: L, scorer: Option<S>,
523524
) -> Self
524525
where
525-
CA::Target: 'static + chain::Access,
526+
CA::Target: 'static + ChainAccess,
526527
CF::Target: 'static + chain::Filter,
527528
CW::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::Signer>,
528529
T::Target: 'static + BroadcasterInterface,

lightning-net-tokio/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
//! type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator + Send + Sync;
3434
//! type Logger = dyn lightning::util::logger::Logger + Send + Sync;
3535
//! type NodeSigner = dyn lightning::chain::keysinterface::NodeSigner + Send + Sync;
36-
//! type ChainAccess = dyn lightning::chain::Access + Send + Sync;
36+
//! type ChainAccess = dyn lightning::routing::gossip_checking::ChainAccess + Send + Sync;
3737
//! type ChainFilter = dyn lightning::chain::Filter + Send + Sync;
3838
//! type DataPersister = dyn lightning::chain::chainmonitor::Persist<lightning::chain::keysinterface::InMemorySigner> + Send + Sync;
3939
//! type ChainMonitor = lightning::chain::chainmonitor::ChainMonitor<lightning::chain::keysinterface::InMemorySigner, Arc<ChainFilter>, Arc<TxBroadcaster>, Arc<FeeEstimator>, Arc<Logger>, Arc<DataPersister>>;

lightning/src/chain/mod.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use bitcoin::blockdata::block::{Block, BlockHeader};
1313
use bitcoin::blockdata::constants::genesis_block;
1414
use bitcoin::blockdata::script::Script;
15-
use bitcoin::blockdata::transaction::TxOut;
1615
use bitcoin::hash_types::{BlockHash, Txid};
1716
use bitcoin::network::constants::Network;
1817
use bitcoin::secp256k1::PublicKey;
@@ -60,26 +59,6 @@ impl BestBlock {
6059
pub fn height(&self) -> u32 { self.height }
6160
}
6261

63-
/// An error when accessing the chain via [`Access`].
64-
#[derive(Clone, Debug)]
65-
pub enum AccessError {
66-
/// The requested chain is unknown.
67-
UnknownChain,
68-
69-
/// The requested transaction doesn't exist or hasn't confirmed.
70-
UnknownTx,
71-
}
72-
73-
/// The `Access` trait defines behavior for accessing chain data and state, such as blocks and
74-
/// UTXOs.
75-
pub trait Access {
76-
/// Returns the transaction output of a funding transaction encoded by [`short_channel_id`].
77-
/// Returns an error if `genesis_hash` is for a different chain or if such a transaction output
78-
/// is unknown.
79-
///
80-
/// [`short_channel_id`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#definition-of-short_channel_id
81-
fn get_utxo(&self, genesis_hash: &BlockHash, short_channel_id: u64) -> Result<TxOut, AccessError>;
82-
}
8362

8463
/// The `Listen` trait is used to notify when blocks have been connected or disconnected from the
8564
/// chain.

lightning/src/routing/gossip.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@ use bitcoin::hashes::Hash;
1919
use bitcoin::blockdata::transaction::TxOut;
2020
use bitcoin::hash_types::BlockHash;
2121

22-
use crate::chain;
23-
use crate::chain::Access;
2422
use crate::ln::chan_utils::make_funding_redeemscript;
2523
use crate::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures};
2624
use crate::ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, NetAddress, MAX_VALUE_MSAT};
2725
use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, GossipTimestampFilter};
2826
use crate::ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd};
2927
use crate::ln::msgs;
28+
use crate::routing::gossip_checking::{ChainAccess, ChainAccessError};
3029
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, MaybeReadable};
3130
use crate::util::logger::{Logger, Level};
3231
use crate::util::events::{MessageSendEvent, MessageSendEventsProvider};
@@ -214,7 +213,7 @@ impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate,
214213
/// Provides interface to help with initial routing sync by
215214
/// serving historical announcements.
216215
pub struct P2PGossipSync<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref>
217-
where C::Target: chain::Access, L::Target: Logger
216+
where C::Target: ChainAccess, L::Target: Logger
218217
{
219218
network_graph: G,
220219
chain_access: Option<C>,
@@ -225,7 +224,7 @@ where C::Target: chain::Access, L::Target: Logger
225224
}
226225

227226
impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> P2PGossipSync<G, C, L>
228-
where C::Target: chain::Access, L::Target: Logger
227+
where C::Target: ChainAccess, L::Target: Logger
229228
{
230229
/// Creates a new tracker of the actual state of the network of channels and nodes,
231230
/// assuming an existing Network Graph.
@@ -322,7 +321,7 @@ macro_rules! secp_verify_sig {
322321
}
323322

324323
impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync<G, C, L>
325-
where C::Target: chain::Access, L::Target: Logger
324+
where C::Target: ChainAccess, L::Target: Logger
326325
{
327326
fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> {
328327
self.network_graph.update_node_from_announcement(msg)?;
@@ -613,7 +612,7 @@ where C::Target: chain::Access, L::Target: Logger
613612

614613
impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync<G, C, L>
615614
where
616-
C::Target: chain::Access,
615+
C::Target: ChainAccess,
617616
L::Target: Logger,
618617
{
619618
fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent> {
@@ -1316,13 +1315,13 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
13161315
/// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
13171316
/// routing messages from a source using a protocol other than the lightning P2P protocol.
13181317
///
1319-
/// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
1318+
/// If a [`ChainAccess`] object is provided via `chain_access`, it will be called to verify
13201319
/// the corresponding UTXO exists on chain and is correctly-formatted.
13211320
pub fn update_channel_from_announcement<C: Deref>(
13221321
&self, msg: &msgs::ChannelAnnouncement, chain_access: &Option<C>,
13231322
) -> Result<(), LightningError>
13241323
where
1325-
C::Target: chain::Access,
1324+
C::Target: ChainAccess,
13261325
{
13271326
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
13281327
secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1, "channel_announcement");
@@ -1336,13 +1335,13 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
13361335
/// signatures. Because we aren't given the associated signatures here we cannot relay the
13371336
/// channel announcement to any of our peers.
13381337
///
1339-
/// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
1338+
/// If a [`ChainAccess`] object is provided via `chain_access`, it will be called to verify
13401339
/// the corresponding UTXO exists on chain and is correctly-formatted.
13411340
pub fn update_channel_from_unsigned_announcement<C: Deref>(
13421341
&self, msg: &msgs::UnsignedChannelAnnouncement, chain_access: &Option<C>
13431342
) -> Result<(), LightningError>
13441343
where
1345-
C::Target: chain::Access,
1344+
C::Target: ChainAccess,
13461345
{
13471346
self.update_channel_from_unsigned_announcement_intern(msg, None, chain_access)
13481347
}
@@ -1428,7 +1427,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
14281427
&self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, chain_access: &Option<C>
14291428
) -> Result<(), LightningError>
14301429
where
1431-
C::Target: chain::Access,
1430+
C::Target: ChainAccess,
14321431
{
14331432
if msg.node_id_1 == msg.node_id_2 || msg.bitcoin_key_1 == msg.bitcoin_key_2 {
14341433
return Err(LightningError{err: "Channel announcement node had a channel with itself".to_owned(), action: ErrorAction::IgnoreError});
@@ -1499,10 +1498,10 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
14991498
//to the new HTLC max field in channel_update
15001499
Some(value)
15011500
},
1502-
Err(chain::AccessError::UnknownChain) => {
1501+
Err(ChainAccessError::UnknownChain) => {
15031502
return Err(LightningError{err: format!("Channel announced on an unknown chain ({})", msg.chain_hash.encode().to_hex()), action: ErrorAction::IgnoreError});
15041503
},
1505-
Err(chain::AccessError::UnknownTx) => {
1504+
Err(ChainAccessError::UnknownTx) => {
15061505
return Err(LightningError{err: "Channel announced without corresponding UTXO entry".to_owned(), action: ErrorAction::IgnoreError});
15071506
},
15081507
}
@@ -1932,11 +1931,11 @@ impl ReadOnlyNetworkGraph<'_> {
19321931

19331932
#[cfg(test)]
19341933
mod tests {
1935-
use crate::chain;
19361934
use crate::ln::channelmanager;
19371935
use crate::ln::chan_utils::make_funding_redeemscript;
19381936
use crate::ln::features::InitFeatures;
19391937
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo, NodeAnnouncementInfo, NodeInfo};
1938+
use crate::routing::gossip_checking::ChainAccessError;
19401939
use crate::ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
19411940
UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate,
19421941
ReplyChannelRange, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT};
@@ -2168,7 +2167,7 @@ mod tests {
21682167

21692168
// Test if an associated transaction were not on-chain (or not confirmed).
21702169
let chain_source = test_utils::TestChainSource::new(Network::Testnet);
2171-
*chain_source.utxo_ret.lock().unwrap() = Err(chain::AccessError::UnknownTx);
2170+
*chain_source.utxo_ret.lock().unwrap() = Err(ChainAccessError::UnknownTx);
21722171
let network_graph = NetworkGraph::new(genesis_hash, &logger);
21732172
gossip_sync = P2PGossipSync::new(&network_graph, Some(&chain_source), &logger);
21742173

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! When lightning nodes gossip channel information, they resist DoS attacks by checking that each
2+
//! channel matches a UTXO on-chain, requireing at least some marginal on-chain transacting in
3+
//! order to announce a channel.
4+
//!
5+
//! This module contains traits for LDK to access these UTXOs to check gossip data is correct.
6+
7+
use bitcoin::{BlockHash, TxOut};
8+
9+
/// An error when accessing the chain via [`ChainAccess`].
10+
#[derive(Clone, Debug)]
11+
pub enum ChainAccessError {
12+
/// The requested chain is unknown.
13+
UnknownChain,
14+
15+
/// The requested transaction doesn't exist or hasn't confirmed.
16+
UnknownTx,
17+
}
18+
19+
/// The `ChainAccess` trait defines behavior for accessing chain data and state, such as blocks and
20+
/// UTXOs.
21+
pub trait ChainAccess {
22+
/// Returns the transaction output of a funding transaction encoded by [`short_channel_id`].
23+
/// Returns an error if `genesis_hash` is for a different chain or if such a transaction output
24+
/// is unknown.
25+
///
26+
/// [`short_channel_id`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#definition-of-short_channel_id
27+
fn get_utxo(&self, genesis_hash: &BlockHash, short_channel_id: u64) -> Result<TxOut, ChainAccessError>;
28+
}

lightning/src/routing/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
//! Structs and impls for receiving messages about the network and storing the topology live here.
1111
12+
pub mod gossip_checking;
1213
pub mod gossip;
1314
pub mod router;
1415
pub mod scoring;

lightning/src/util/test_utils.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
2222
use crate::ln::{msgs, wire};
2323
use crate::ln::script::ShutdownScript;
2424
use crate::routing::gossip::NetworkGraph;
25+
use crate::routing::gossip_checking::{ChainAccess, ChainAccessError};
2526
use crate::routing::router::{find_route, InFlightHtlcs, Route, RouteHop, RouteParameters, Router, ScorerAccountingForInFlightHtlcs};
2627
use crate::routing::scoring::FixedPenaltyScorer;
2728
use crate::util::config::UserConfig;
@@ -817,7 +818,7 @@ impl core::fmt::Debug for OnGetShutdownScriptpubkey {
817818

818819
pub struct TestChainSource {
819820
pub genesis_hash: BlockHash,
820-
pub utxo_ret: Mutex<Result<TxOut, chain::AccessError>>,
821+
pub utxo_ret: Mutex<Result<TxOut, ChainAccessError>>,
821822
pub watched_txn: Mutex<HashSet<(Txid, Script)>>,
822823
pub watched_outputs: Mutex<HashSet<(OutPoint, Script)>>,
823824
}
@@ -834,10 +835,10 @@ impl TestChainSource {
834835
}
835836
}
836837

837-
impl chain::Access for TestChainSource {
838-
fn get_utxo(&self, genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, chain::AccessError> {
838+
impl ChainAccess for TestChainSource {
839+
fn get_utxo(&self, genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, ChainAccessError> {
839840
if self.genesis_hash != *genesis_hash {
840-
return Err(chain::AccessError::UnknownChain);
841+
return Err(ChainAccessError::UnknownChain);
841842
}
842843

843844
self.utxo_ret.lock().unwrap().clone()

0 commit comments

Comments
 (0)