Skip to content

Commit b388ee1

Browse files
authored
Merge pull request #428 from tnull/2025-01-start-verifying-gossip
Start verifying gossip data via bitcoind RPC
2 parents 9953d2b + b774b33 commit b388ee1

File tree

5 files changed

+83
-9
lines changed

5 files changed

+83
-9
lines changed

src/builder.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,12 @@ fn build_with_store_internal(
11261126

11271127
liquidity_source.as_ref().map(|l| l.set_peer_manager(Arc::clone(&peer_manager)));
11281128

1129+
gossip_source.set_gossip_verifier(
1130+
Arc::clone(&chain_source),
1131+
Arc::clone(&peer_manager),
1132+
Arc::clone(&runtime),
1133+
);
1134+
11291135
let connection_manager =
11301136
Arc::new(ConnectionManager::new(Arc::clone(&peer_manager), Arc::clone(&logger)));
11311137

src/chain/bitcoind_rpc.rs

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ impl BitcoindRpcClient {
4545
Self { rpc_client, latest_mempool_timestamp }
4646
}
4747

48+
pub(crate) fn rpc_client(&self) -> Arc<RpcClient> {
49+
Arc::clone(&self.rpc_client)
50+
}
51+
4852
pub(crate) async fn broadcast_transaction(&self, tx: &Transaction) -> std::io::Result<Txid> {
4953
let tx_serialized = bitcoin::consensus::encode::serialize_hex(tx);
5054
let tx_json = serde_json::json!(tx_serialized);

src/chain/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use lightning::util::ser::Writeable;
3131

3232
use lightning_transaction_sync::EsploraSyncClient;
3333

34+
use lightning_block_sync::gossip::UtxoSource;
3435
use lightning_block_sync::init::{synchronize_listeners, validate_best_block_header};
3536
use lightning_block_sync::poll::{ChainPoller, ChainTip, ValidatedBlockHeader};
3637
use lightning_block_sync::SpvClient;
@@ -192,6 +193,13 @@ impl ChainSource {
192193
}
193194
}
194195

196+
pub(crate) fn as_utxo_source(&self) -> Option<Arc<dyn UtxoSource>> {
197+
match self {
198+
Self::BitcoindRpc { bitcoind_rpc_client, .. } => Some(bitcoind_rpc_client.rpc_client()),
199+
_ => None,
200+
}
201+
}
202+
195203
pub(crate) async fn continuously_sync_wallets(
196204
&self, mut stop_sync_receiver: tokio::sync::watch::Receiver<()>,
197205
channel_manager: Arc<ChannelManager>, chain_monitor: Arc<ChainMonitor>,

src/gossip.rs

+59-8
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@
55
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66
// accordance with one or both of these licenses.
77

8+
use crate::chain::ChainSource;
89
use crate::config::RGS_SYNC_TIMEOUT_SECS;
9-
use crate::logger::{log_trace, FilesystemLogger, Logger};
10-
use crate::types::{GossipSync, Graph, P2PGossipSync, RapidGossipSync};
10+
use crate::logger::{log_error, log_trace, FilesystemLogger, Logger};
11+
use crate::types::{GossipSync, Graph, P2PGossipSync, PeerManager, RapidGossipSync, UtxoLookup};
1112
use crate::Error;
1213

13-
use lightning::routing::utxo::UtxoLookup;
14+
use lightning_block_sync::gossip::{FutureSpawner, GossipVerifier};
1415

16+
use std::future::Future;
1517
use std::sync::atomic::{AtomicU32, Ordering};
16-
use std::sync::Arc;
18+
use std::sync::{Arc, RwLock};
1719
use std::time::Duration;
1820

1921
pub(crate) enum GossipSource {
2022
P2PNetwork {
2123
gossip_sync: Arc<P2PGossipSync>,
24+
logger: Arc<FilesystemLogger>,
2225
},
2326
RapidGossipSync {
2427
gossip_sync: Arc<RapidGossipSync>,
@@ -32,10 +35,10 @@ impl GossipSource {
3235
pub fn new_p2p(network_graph: Arc<Graph>, logger: Arc<FilesystemLogger>) -> Self {
3336
let gossip_sync = Arc::new(P2PGossipSync::new(
3437
network_graph,
35-
None::<Arc<dyn UtxoLookup + Send + Sync>>,
36-
logger,
38+
None::<Arc<UtxoLookup>>,
39+
Arc::clone(&logger),
3740
));
38-
Self::P2PNetwork { gossip_sync }
41+
Self::P2PNetwork { gossip_sync, logger }
3942
}
4043

4144
pub fn new_rgs(
@@ -58,9 +61,30 @@ impl GossipSource {
5861
}
5962
}
6063

64+
pub(crate) fn set_gossip_verifier(
65+
&self, chain_source: Arc<ChainSource>, peer_manager: Arc<PeerManager>,
66+
runtime: Arc<RwLock<Option<Arc<tokio::runtime::Runtime>>>>,
67+
) {
68+
match self {
69+
Self::P2PNetwork { gossip_sync, logger } => {
70+
if let Some(utxo_source) = chain_source.as_utxo_source() {
71+
let spawner = RuntimeSpawner::new(Arc::clone(&runtime), Arc::clone(&logger));
72+
let gossip_verifier = Arc::new(GossipVerifier::new(
73+
utxo_source,
74+
spawner,
75+
Arc::clone(gossip_sync),
76+
peer_manager,
77+
));
78+
gossip_sync.add_utxo_lookup(Some(gossip_verifier));
79+
}
80+
},
81+
_ => (),
82+
}
83+
}
84+
6185
pub async fn update_rgs_snapshot(&self) -> Result<u32, Error> {
6286
match self {
63-
Self::P2PNetwork { gossip_sync: _ } => Ok(0),
87+
Self::P2PNetwork { gossip_sync: _, .. } => Ok(0),
6488
Self::RapidGossipSync { gossip_sync, server_url, latest_sync_timestamp, logger } => {
6589
let query_timestamp = latest_sync_timestamp.load(Ordering::Acquire);
6690
let query_url = format!("{}/{}", server_url, query_timestamp);
@@ -101,3 +125,30 @@ impl GossipSource {
101125
}
102126
}
103127
}
128+
129+
pub(crate) struct RuntimeSpawner {
130+
runtime: Arc<RwLock<Option<Arc<tokio::runtime::Runtime>>>>,
131+
logger: Arc<FilesystemLogger>,
132+
}
133+
134+
impl RuntimeSpawner {
135+
pub(crate) fn new(
136+
runtime: Arc<RwLock<Option<Arc<tokio::runtime::Runtime>>>>, logger: Arc<FilesystemLogger>,
137+
) -> Self {
138+
Self { runtime, logger }
139+
}
140+
}
141+
142+
impl FutureSpawner for RuntimeSpawner {
143+
fn spawn<T: Future<Output = ()> + Send + 'static>(&self, future: T) {
144+
let rt_lock = self.runtime.read().unwrap();
145+
if rt_lock.is_none() {
146+
log_error!(self.logger, "Tried spawing a future while the runtime wasn't available. This should never happen.");
147+
debug_assert!(false, "Tried spawing a future while the runtime wasn't available. This should never happen.");
148+
return;
149+
}
150+
151+
let runtime = rt_lock.as_ref().unwrap();
152+
runtime.spawn(future);
153+
}
154+
}

src/types.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use crate::chain::ChainSource;
99
use crate::config::ChannelConfig;
1010
use crate::fee_estimator::OnchainFeeEstimator;
11+
use crate::gossip::RuntimeSpawner;
1112
use crate::logger::FilesystemLogger;
1213
use crate::message_handler::NodeCustomMessageHandler;
1314

@@ -25,6 +26,9 @@ use lightning::sign::InMemorySigner;
2526
use lightning::util::persist::KVStore;
2627
use lightning::util::ser::{Readable, Writeable, Writer};
2728
use lightning::util::sweep::OutputSweeper;
29+
30+
use lightning_block_sync::gossip::{GossipVerifier, UtxoSource};
31+
2832
use lightning_net_tokio::SocketDescriptor;
2933

3034
use bitcoin::secp256k1::PublicKey;
@@ -91,7 +95,8 @@ pub(crate) type Scorer = ProbabilisticScorer<Arc<Graph>, Arc<FilesystemLogger>>;
9195

9296
pub(crate) type Graph = gossip::NetworkGraph<Arc<FilesystemLogger>>;
9397

94-
pub(crate) type UtxoLookup = dyn lightning::routing::utxo::UtxoLookup + Send + Sync;
98+
pub(crate) type UtxoLookup =
99+
GossipVerifier<RuntimeSpawner, Arc<dyn UtxoSource>, Arc<FilesystemLogger>>;
95100

96101
pub(crate) type P2PGossipSync =
97102
lightning::routing::gossip::P2PGossipSync<Arc<Graph>, Arc<UtxoLookup>, Arc<FilesystemLogger>>;

0 commit comments

Comments
 (0)