use lightning::routing::scoring::ProbabilisticScoringFeeParameters;
use lightning::sign::{EntropySource, InMemorySigner, KeysManager, SpendableOutputDescriptor};
use lightning::util::config::UserConfig;
-use lightning::util::persist::{self, read_channel_monitors, KVStore};
+use lightning::util::persist::{self, KVStore, MonitorUpdatingPersister};
use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
use lightning::{chain, impl_writeable_tlv_based, impl_writeable_tlv_based_enum};
use lightning_background_processor::{process_events_async, GossipSync};
Arc<BitcoindClient>,
Arc<BitcoindClient>,
Arc<FilesystemLogger>,
- Arc<FilesystemStore>,
+ Arc<
+ MonitorUpdatingPersister<
+ Arc<FilesystemStore>,
+ Arc<FilesystemLogger>,
+ Arc<KeysManager>,
+ Arc<KeysManager>,
+ >,
+ >,
+>;
+
+pub(crate) type GossipVerifier = lightning_block_sync::gossip::GossipVerifier<
+ lightning_block_sync::gossip::TokioSpawner,
+ Arc<lightning_block_sync::rpc::RpcClient>,
+ Arc<FilesystemLogger>,
+ SocketDescriptor,
+ Arc<ChannelManager>,
+ Arc<OnionMessenger>,
+ IgnoringMessageHandler,
+ Arc<KeysManager>,
>;
pub(crate) type PeerManager = SimpleArcPeerManager<
ChainMonitor,
BitcoindClient,
BitcoindClient,
- Arc<BitcoindClient>,
+ GossipVerifier,
FilesystemLogger,
>;
pub(crate) type NetworkGraph = gossip::NetworkGraph<Arc<FilesystemLogger>>;
-type OnionMessenger = SimpleArcOnionMessenger<FilesystemLogger>;
+type OnionMessenger =
+ SimpleArcOnionMessenger<ChainMonitor, BitcoindClient, BitcoindClient, FilesystemLogger>;
pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler<
Arc<BitcoindClient>,
channel_manager: &Arc<ChannelManager>, bitcoind_client: &BitcoindClient,
network_graph: &NetworkGraph, keys_manager: &KeysManager,
bump_tx_event_handler: &BumpTxEventHandler, inbound_payments: Arc<Mutex<PaymentInfoStorage>>,
- outbound_payments: Arc<Mutex<PaymentInfoStorage>>, persister: &Arc<FilesystemStore>,
+ outbound_payments: Arc<Mutex<PaymentInfoStorage>>, fs_store: &Arc<FilesystemStore>,
network: Network, event: Event,
) {
match event {
} => {
println!(
"\nEVENT: received payment from payment hash {} of {} millisatoshis",
- hex_utils::hex_str(&payment_hash.0),
- amount_msat,
+ payment_hash, amount_msat,
);
print!("> ");
io::stdout().flush().unwrap();
} => {
println!(
"\nEVENT: claimed payment from payment hash {} of {} millisatoshis",
- hex_utils::hex_str(&payment_hash.0),
- amount_msat,
+ payment_hash, amount_msat,
);
print!("> ");
io::stdout().flush().unwrap();
});
}
}
- persister.write("", "", INBOUND_PAYMENTS_FNAME, &inbound.encode()).unwrap();
+ fs_store.write("", "", INBOUND_PAYMENTS_FNAME, &inbound.encode()).unwrap();
}
Event::PaymentSent { payment_preimage, payment_hash, fee_paid_msat, .. } => {
let mut outbound = outbound_payments.lock().unwrap();
payment.status = HTLCStatus::Succeeded;
println!(
"\nEVENT: successfully sent payment of {} millisatoshis{} from \
- payment hash {:?} with preimage {:?}",
+ payment hash {} with preimage {}",
payment.amt_msat,
if let Some(fee) = fee_paid_msat {
format!(" (fee {} msat)", fee)
} else {
"".to_string()
},
- hex_utils::hex_str(&payment_hash.0),
- hex_utils::hex_str(&payment_preimage.0)
+ payment_hash,
+ payment_preimage
);
print!("> ");
io::stdout().flush().unwrap();
}
}
- persister.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
+ fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
}
Event::OpenChannelRequest {
ref temporary_channel_id, ref counterparty_node_id, ..
Event::ProbeFailed { .. } => {}
Event::PaymentFailed { payment_hash, reason, .. } => {
print!(
- "\nEVENT: Failed to send payment to payment hash {:?}: {:?}",
- hex_utils::hex_str(&payment_hash.0),
+ "\nEVENT: Failed to send payment to payment hash {}: {:?}",
+ payment_hash,
if let Some(r) = reason { r } else { PaymentFailureReason::RetriesExhausted }
);
print!("> ");
let payment = outbound.payments.get_mut(&payment_hash).unwrap();
payment.status = HTLCStatus::Failed;
}
- persister.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
+ fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
+ }
+ Event::InvoiceRequestFailed { payment_id } => {
+ print!("\nEVENT: Failed to request invoice to send payment with id {}", payment_id);
+ print!("> ");
+ io::stdout().flush().unwrap();
+
+ // TODO: mark the payment as failed
}
Event::PaymentForwarded {
prev_channel_id,
let key = hex_utils::hex_str(&keys_manager.get_secure_random_bytes());
// Note that if the type here changes our read code needs to change as well.
let output: SpendableOutputDescriptor = output;
- persister.write(PENDING_SPENDABLE_OUTPUT_DIR, "", &key, &output.encode()).unwrap();
+ fs_store.write(PENDING_SPENDABLE_OUTPUT_DIR, "", &key, &output.encode()).unwrap();
}
}
Event::ChannelPending { channel_id, counterparty_node_id, .. } => {
// broadcaster.
let broadcaster = bitcoind_client.clone();
- // Step 4: Initialize Persist
- let persister = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
-
- // Step 5: Initialize the ChainMonitor
- let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
- None,
- broadcaster.clone(),
- logger.clone(),
- fee_estimator.clone(),
- persister.clone(),
- ));
-
- // Step 6: Initialize the KeysManager
+ // Step 4: Initialize the KeysManager
// The key seed that we use to derive the node privkey (that corresponds to the node pubkey) and
// other secret key material.
Arc::clone(&logger),
));
+ // Step 5: Initialize Persistence
+ let fs_store = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
+ let persister = Arc::new(MonitorUpdatingPersister::new(
+ Arc::clone(&fs_store),
+ Arc::clone(&logger),
+ 1000,
+ Arc::clone(&keys_manager),
+ Arc::clone(&keys_manager),
+ ));
+ // Alternatively, you can use the `FilesystemStore` as a `Persist` directly, at the cost of
+ // larger `ChannelMonitor` update writes (but no deletion or cleanup):
+ //let persister = Arc::clone(&fs_store);
+
+ // Step 6: Initialize the ChainMonitor
+ let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
+ None,
+ Arc::clone(&broadcaster),
+ Arc::clone(&logger),
+ Arc::clone(&fee_estimator),
+ Arc::clone(&persister),
+ ));
+
// Step 7: Read ChannelMonitor state from disk
- let mut channelmonitors =
- read_channel_monitors(Arc::clone(&persister), keys_manager.clone(), keys_manager.clone())
- .unwrap();
+ let mut channelmonitors = persister
+ .read_all_channel_monitors_with_updates(&bitcoind_client, &bitcoind_client)
+ .unwrap();
+ // If you are using the `FilesystemStore` as a `Persist` directly, use
+ // `lightning::util::persist::read_channel_monitors` like this:
+ //read_channel_monitors(Arc::clone(&persister), Arc::clone(&keys_manager), Arc::clone(&keys_manager)).unwrap();
// Step 8: Poll for the best chain tip, which may be used by the channel manager & spv client
let polled_chain_tip = init::validate_best_block_header(bitcoind_client.as_ref())
}
// Step 14: Optional: Initialize the P2PGossipSync
- let gossip_sync = Arc::new(P2PGossipSync::new(
- Arc::clone(&network_graph),
- None::<Arc<BitcoindClient>>,
- logger.clone(),
- ));
+ let gossip_sync =
+ Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
// Step 15: Initialize the PeerManager
let channel_manager: Arc<ChannelManager> = Arc::new(channel_manager);
Arc::clone(&keys_manager),
Arc::clone(&logger),
Arc::new(DefaultMessageRouter {}),
- IgnoringMessageHandler {},
+ Arc::clone(&channel_manager),
IgnoringMessageHandler {},
));
let mut ephemeral_bytes = [0; 32];
Arc::clone(&keys_manager),
));
+ // Install a GossipVerifier in in the P2PGossipSync
+ let utxo_lookup = GossipVerifier::new(
+ Arc::clone(&bitcoind_client.bitcoind_rpc_client),
+ lightning_block_sync::gossip::TokioSpawner,
+ Arc::clone(&gossip_sync),
+ Arc::clone(&peer_manager),
+ );
+ gossip_sync.add_utxo_lookup(Some(utxo_lookup));
+
// ## Running LDK
// Step 16: Initialize networking
payment_info.status = HTLCStatus::Failed;
}
}
- persister
+ fs_store
.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound_payments.lock().unwrap().encode())
.unwrap();
let keys_manager_event_listener = Arc::clone(&keys_manager);
let inbound_payments_event_listener = Arc::clone(&inbound_payments);
let outbound_payments_event_listener = Arc::clone(&outbound_payments);
- let persister_event_listener = Arc::clone(&persister);
+ let fs_store_event_listener = Arc::clone(&fs_store);
let network = args.network;
let event_handler = move |event: Event| {
let channel_manager_event_listener = Arc::clone(&channel_manager_event_listener);
let bump_tx_event_handler = Arc::clone(&bump_tx_event_handler);
let inbound_payments_event_listener = Arc::clone(&inbound_payments_event_listener);
let outbound_payments_event_listener = Arc::clone(&outbound_payments_event_listener);
- let persister_event_listener = Arc::clone(&persister_event_listener);
+ let fs_store_event_listener = Arc::clone(&fs_store_event_listener);
async move {
handle_ldk_events(
&channel_manager_event_listener,
&bump_tx_event_handler,
inbound_payments_event_listener,
outbound_payments_event_listener,
- &persister_event_listener,
+ &fs_store_event_listener,
network,
event,
)