-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for sourcing chain data from Electrum #486
base: main
Are you sure you want to change the base?
Conversation
b386ee7
to
9352b2e
Compare
568d10d
to
678cf91
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm familiarizing myself with the codebase but I tried running a node locally with the changes here pointing to an electrum server and basic operations are working. I just have a couple of questions, if I may, to get a better understanding.
Not strictly related to the PR but maybe I can sneak it in, why is it that for bitcoin core rpc and electrum they are in their separate bitcoind_rpc.rs
and electrum.rs
files but for esplora it is all in the mod.rs
? I see that that the EsploraAsyncClient
is directly used without a wrapper but wanted to see what were the reasons for it (:
pub(crate) async fn broadcast(&self, tx: Transaction) { | ||
let electrum_client = Arc::clone(&self.electrum_client); | ||
|
||
let txid = tx.compute_txid(); | ||
let tx_bytes = tx.encode(); | ||
|
||
let spawn_fut = | ||
self.runtime.spawn_blocking(move || electrum_client.transaction_broadcast(&tx)); | ||
|
||
let timeout_fut = | ||
tokio::time::timeout(Duration::from_secs(TX_BROADCAST_TIMEOUT_SECS), spawn_fut); | ||
|
||
match timeout_fut.await { | ||
Ok(res) => match res { | ||
Ok(_) => { | ||
log_trace!(self.logger, "Successfully broadcast transaction {}", txid); | ||
}, | ||
Err(e) => { | ||
log_error!(self.logger, "Failed to broadcast transaction {}: {}", txid, e); | ||
log_trace!( | ||
self.logger, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the broadcast method in the BitcoindRpcClient
, it returns a Result
and then logs the errors when called in process_broadcast_queue
for ChainSource
. Should this do that as well and return a Result
and then log them in that method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, no, while I agree it's a bit inconsistent I decided to move the logging part also into the chain source-specific module this time around.
#[test] | ||
fn channel_full_cycle_electrum() { | ||
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); | ||
let chain_source = TestChainSource::Electrum(&electrsd); | ||
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, false); | ||
do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, false); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be good to also add tests in onchain_send_receive
for nodes using TestChainSource::Electrum
since that functionality depends on the ChainSource
used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, essentially every test/operation depends on sourcing chain data. I don't think we want to re-run our entire test suite for all chain sources. The full_cycle
test already should cover all fundamental parts of sourcing chain data (syncing onchain wallet, syncing lightning wallet, retrieving fee estimates, broadcasting transactions), so we should be good with just this test for now. That said, we considered making bitcoind
RPC the default for all tests (instead of Esplora) before, but that is orthogonal to this PR.
Hmm, for one it has historic reasons, but also
Right, that's essentially the main reason why it still lives in |
We upgrade our tests to use `electrum-client` v0.22 and `electrsd` v0.31 to ensure compatibility with `bdk_electrum` were about to start using.
By default, `rustls` uses `aws-lc-rs` which requires `bindgen` on some platforms. To allow building with `aws-lc-rs` on Android, we here install the `bindgen-cli` tool before running the bindings generation script in CI.
We here setup the basic API and structure for the `ChainSource::Electrum`. Currently, we won't have a `Runtime` available when initializing `ChainSource::Electrum` in `Builder::build`. We therefore isolate any runtime-specific behavior into an `ElectrumRuntimeClient`. This might change in the future, but for now we do need this workaround.
Currently, we won't have a `Runtime` available when initializing `ChainSource::Electrum`. We therefore isolate any runtime-specific behavior into an `ElectrumRuntimeClient`. Here, we implement `Filter` for `ElectrumRuntimeClient`, but we need to cache the registrations as they might happen prior to `ElectrumRuntimeClient` becoming available.
.. as we do with `BitcoindRpc`, we now test `Electrum` support by running the `full_cycle` test in CI.
42a499d
to
9608e66
Compare
9608e66
to
3142c41
Compare
Closes #196.
So far, we support Esplora and Bitcoind RPC chain sources. In this PR we add Electrum support based on the blocking
rust-electrum-client
, and it'sbdk_electrum
andlightning-transaction-sync
counterparts.Due to the blocking nature of
rust-electrum-client
and as it directly connects to the server uponClient::new
(see bitcoindevkit/rust-electrum-client#166), we ended up wrapping the runtime-specific behavior in anElectrumRuntimeClient
object that is initialized and dropped inNode::start
andstop
, respectively.One thing missing that we still need to consider is how we'd reestablish connections to the remote after they have been lost for one reason or another. IMO, that behavior should live in
rust-electrum-client
to avoid all users having to duplicate it, so it's pending resolution of bitcoindevkit/rust-electrum-client#165As we did with
bitcoind
-RPC, Electrum support is tested by adding anotherfull_cycle
integration test.