1 // This file is Copyright its original authors, visible in version control
2 // history and in the source files from which this was generated.
4 // This file is licensed under the license available in the LICENSE or LICENSE.md
5 // file in the root of this repository or, if no such file exists, the same
6 // license as that which applies to the original source files from which this
7 // source was automatically generated.
9 //! Chain sync using the Esplora API
11 use alloc::str::FromStr;
12 use alloc::string::String;
13 use core::ffi::c_void;
14 use core::convert::Infallible;
15 use bitcoin::hashes::Hash;
16 use crate::c_types::*;
17 #[cfg(feature="no-std")]
18 use alloc::{vec::Vec, boxed::Box};
21 use lightning_transaction_sync::esplora::EsploraSyncClient as nativeEsploraSyncClientImport;
22 pub(crate) type nativeEsploraSyncClient = nativeEsploraSyncClientImport<crate::lightning::util::logger::Logger, >;
24 /// Synchronizes LDK with a given [`Esplora`] server.
26 /// Needs to be registered with a [`ChainMonitor`] via the [`Filter`] interface to be informed of
27 /// transactions and outputs to monitor for on-chain confirmation, unconfirmation, and
30 /// Note that registration via [`Filter`] needs to happen before any calls to
31 /// [`Watch::watch_channel`] to ensure we get notified of the items to monitor.
33 /// This uses and exposes either a blocking or async client variant dependent on whether the
34 /// `esplora-blocking` or the `esplora-async` feature is enabled.
36 /// [`Esplora`]: https://github.com/Blockstream/electrs
37 /// [`ChainMonitor`]: lightning::chain::chainmonitor::ChainMonitor
38 /// [`Watch::watch_channel`]: lightning::chain::Watch::watch_channel
39 /// [`Filter`]: lightning::chain::Filter
42 pub struct EsploraSyncClient {
43 /// A pointer to the opaque Rust object.
45 /// Nearly everywhere, inner must be non-null, however in places where
46 /// the Rust equivalent takes an Option, it may be set to null to indicate None.
47 pub inner: *mut nativeEsploraSyncClient,
48 /// Indicates that this is the only struct which contains the same pointer.
50 /// Rust functions which take ownership of an object provided via an argument require
51 /// this to be true and invalidate the object pointed to by inner.
55 impl Drop for EsploraSyncClient {
57 if self.is_owned && !<*mut nativeEsploraSyncClient>::is_null(self.inner) {
58 let _ = unsafe { Box::from_raw(ObjOps::untweak_ptr(self.inner)) };
62 /// Frees any resources used by the EsploraSyncClient, if is_owned is set and inner is non-NULL.
64 pub extern "C" fn EsploraSyncClient_free(this_obj: EsploraSyncClient) { }
66 /// Used only if an object of this type is returned as a trait impl by a method
67 pub(crate) extern "C" fn EsploraSyncClient_free_void(this_ptr: *mut c_void) {
68 let _ = unsafe { Box::from_raw(this_ptr as *mut nativeEsploraSyncClient) };
71 impl EsploraSyncClient {
72 pub(crate) fn get_native_ref(&self) -> &'static nativeEsploraSyncClient {
73 unsafe { &*ObjOps::untweak_ptr(self.inner) }
75 pub(crate) fn get_native_mut_ref(&self) -> &'static mut nativeEsploraSyncClient {
76 unsafe { &mut *ObjOps::untweak_ptr(self.inner) }
78 /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
79 pub(crate) fn take_inner(mut self) -> *mut nativeEsploraSyncClient {
80 assert!(self.is_owned);
81 let ret = ObjOps::untweak_ptr(self.inner);
82 self.inner = core::ptr::null_mut();
86 /// Returns a new [`EsploraSyncClient`] object.
89 pub extern "C" fn EsploraSyncClient_new(mut server_url: crate::c_types::Str, mut logger: crate::lightning::util::logger::Logger) -> crate::lightning_transaction_sync::esplora::EsploraSyncClient {
90 let mut ret = lightning_transaction_sync::esplora::EsploraSyncClient::new(server_url.into_string(), logger);
91 crate::lightning_transaction_sync::esplora::EsploraSyncClient { inner: ObjOps::heap_alloc(ret), is_owned: true }
94 /// Synchronizes the given `confirmables` via their [`Confirm`] interface implementations. This
95 /// method should be called regularly to keep LDK up-to-date with current chain data.
97 /// For example, instances of [`ChannelManager`] and [`ChainMonitor`] can be informed about the
98 /// newest on-chain activity related to the items previously registered via the [`Filter`]
101 /// [`Confirm`]: lightning::chain::Confirm
102 /// [`ChainMonitor`]: lightning::chain::chainmonitor::ChainMonitor
103 /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
104 /// [`Filter`]: lightning::chain::Filter
107 pub extern "C" fn EsploraSyncClient_sync(this_arg: &crate::lightning_transaction_sync::esplora::EsploraSyncClient, mut confirmables: crate::c_types::derived::CVec_ConfirmZ) -> crate::c_types::derived::CResult_NoneTxSyncErrorZ {
108 let mut local_confirmables = Vec::new(); for mut item in confirmables.into_rust().drain(..) { local_confirmables.push( { item }); };
109 let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.sync(local_confirmables);
110 let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning_transaction_sync::error::TxSyncError::native_into(e) }).into() };
114 impl From<nativeEsploraSyncClient> for crate::lightning::chain::Filter {
115 fn from(obj: nativeEsploraSyncClient) -> Self {
116 let rust_obj = crate::lightning_transaction_sync::esplora::EsploraSyncClient { inner: ObjOps::heap_alloc(obj), is_owned: true };
117 let mut ret = EsploraSyncClient_as_Filter(&rust_obj);
118 // We want to free rust_obj when ret gets drop()'d, not rust_obj, so forget it and set ret's free() fn
119 core::mem::forget(rust_obj);
120 ret.free = Some(EsploraSyncClient_free_void);
124 /// Constructs a new Filter which calls the relevant methods on this_arg.
125 /// This copies the `inner` pointer in this_arg and thus the returned Filter must be freed before this_arg is
127 pub extern "C" fn EsploraSyncClient_as_Filter(this_arg: &EsploraSyncClient) -> crate::lightning::chain::Filter {
128 crate::lightning::chain::Filter {
129 this_arg: unsafe { ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void },
131 register_tx: EsploraSyncClient_Filter_register_tx,
132 register_output: EsploraSyncClient_Filter_register_output,
136 extern "C" fn EsploraSyncClient_Filter_register_tx(this_arg: *const c_void, txid: *const [u8; 32], mut script_pubkey: crate::c_types::u8slice) {
137 <nativeEsploraSyncClient as lightning::chain::Filter>::register_tx(unsafe { &mut *(this_arg as *mut nativeEsploraSyncClient) }, &::bitcoin::hash_types::Txid::from_slice(&unsafe { &*txid }[..]).unwrap(), ::bitcoin::blockdata::script::Script::from_bytes(script_pubkey.to_slice()))
139 extern "C" fn EsploraSyncClient_Filter_register_output(this_arg: *const c_void, mut output: crate::lightning::chain::WatchedOutput) {
140 <nativeEsploraSyncClient as lightning::chain::Filter>::register_output(unsafe { &mut *(this_arg as *mut nativeEsploraSyncClient) }, *unsafe { Box::from_raw(output.take_inner()) })