Skip to content
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 bitcoind RPC support #370

Merged
merged 13 commits into from
Oct 16, 2024

Conversation

tnull
Copy link
Collaborator

@tnull tnull commented Oct 10, 2024

Based on #365.

We add support for sourcing chain data from the bitcoind RPC interface. Ready for review.

TODO:

- [ ] Implement UtxoSource / GossipVerifier (via tokio feature of lightning-block-sync) (Bashing my head against the typechecker for a few hours is having me believe this is currently ~impossible with the upstream types, so moved to #377 / blocked on lightningdevkit/rust-lightning#3369)

@tnull tnull marked this pull request as draft October 10, 2024 15:37
@tnull tnull added this to the 0.4 milestone Oct 14, 2024
@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch 2 times, most recently from a2b10ef to d9cc69a Compare October 15, 2024 08:03
@tnull
Copy link
Collaborator Author

tnull commented Oct 15, 2024

Now rebased on #365 after we bumped to 0.0.125, i.e., also dropped the commit copy/pasting synchronize_listeners as the fix was part of the release.

@tnull tnull mentioned this pull request Oct 15, 2024
8 tasks
@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch from d9cc69a to 6e6e9b7 Compare October 15, 2024 15:13
@tnull tnull changed the title WIP Add bitcoind RPC support Add bitcoind RPC support Oct 15, 2024
@tnull tnull marked this pull request as ready for review October 15, 2024 15:14
@tnull
Copy link
Collaborator Author

tnull commented Oct 15, 2024

Alright, rebased on main after #365 landed. Also addressed (or postponed) the remaining TODOs, should be ready for review.

@tnull tnull requested a review from jkczyz October 15, 2024 15:15
@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch 3 times, most recently from f68adfc to 7c1ad82 Compare October 15, 2024 17:26
src/chain/bitcoind_rpc.rs Outdated Show resolved Hide resolved
src/chain/mod.rs Outdated Show resolved Hide resolved
src/chain/mod.rs Show resolved Hide resolved
src/chain/mod.rs Outdated Show resolved Hide resolved
src/chain/mod.rs Outdated Show resolved Hide resolved
Comment on lines 36 to 42
#[test]
fn channel_full_cycle_bitcoind() {
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
premine_dummy_blocks(&bitcoind.client, &electrsd.client);
let chain_source = TestChainSource::BitcoinRpc(&bitcoind);
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);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not expand the other tests for BitcoinRpc?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally sounds good, I mostly started off with this as I didn't simply want to double our test surface. Do you have any specific test cases in mind that would lend themselves to also be run on a BitcoindRpc backend?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... probably only tests where non-setup code depends on block (dis)connection notification (e.g., onchain_spend_receive). Though, I also wonder if we should use BitcoinRpc normally just to remove one moving part from the tests assuming that would lead to less flakiness.

Copy link
Collaborator Author

@tnull tnull Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though, I also wonder if we should use BitcoinRpc normally just to remove one moving part from the tests assuming that would lead to less flakiness.

I generally agree this would be preferable but thought we might be limited by the additional overhead of the premining required to populate estimatesmartfee. As we now added fallbacks for regtest anyways we can however drop that premining again.

I now added a fixup switching it around: we now default to bitcoind RPC and only have a single Esplora-specific full-cycle test. It seemed a bit flaky when run concurrently locally, but let's see how it works out in CI. If it turns out to be flaky we can take additional mitigation steps in a follow up (e.g., reduce the number of threads used in tests, etc).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, if the extra part is actually removing the underlying flakiness, maybe we should keep it. 😛 Though perhaps we need to make sure the (non-test) code is robust enough to retry appropriately.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, there we have the first CI failure due to flakiness. Mind if I revert and do the CI switch as a follow-up (possibly post-release)? I'd like to get main into a release-ready state ASAP.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now reverted, but still dropped the unnecessary premining.

@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch 3 times, most recently from 83b0a4f to c20359a Compare October 16, 2024 08:24
Copy link
Contributor

@jkczyz jkczyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo test changes

Comment on lines 36 to 42
#[test]
fn channel_full_cycle_bitcoind() {
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
premine_dummy_blocks(&bitcoind.client, &electrsd.client);
let chain_source = TestChainSource::BitcoinRpc(&bitcoind);
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);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... probably only tests where non-setup code depends on block (dis)connection notification (e.g., onchain_spend_receive). Though, I also wonder if we should use BitcoinRpc normally just to remove one moving part from the tests assuming that would lead to less flakiness.

tnull added 2 commits October 16, 2024 18:37
.. which we'll use to feed blocks to it in following commits.
@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch from c20359a to a45c7a7 Compare October 16, 2024 16:41
@tnull
Copy link
Collaborator Author

tnull commented Oct 16, 2024

LGTM modulo test changes

Cool, let me know if I can squash.

@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch 3 times, most recently from 4839e10 to f4538a3 Compare October 16, 2024 17:21
Copy link
Contributor

@jkczyz jkczyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, please squash

We first initialize by synchronizing all `Listen` implementations, and
then head into a loop continuously polling our RPC `BlockSource`.

We also implement a `BoundedHeaderCache` to limit in-memory footprint.
tnull added 10 commits October 16, 2024 19:55
.. to allow the on-chain wallet to detect what's inflight.
This behavior mirrors what we do in the Esplora case: we only enforce
successful fee rate updates on mainnet. On regtest/signet/testnet we
will just skip (i.e. return `Ok(())`) if we fail to retrieve the updates
(e.g., when bitcoind's `estimatesmartfee` isn't sufficiently populated)
and will either keep previously-retrieved values or worst case fallback
to the fallback defaults.
.. as it regularly makes CI fail and doesn't provide us anything really.
.. to account for slight differences in fee rate estmations between
chain sources.
@tnull tnull force-pushed the 2024-10-add-bitcoind-support branch from f4538a3 to 7c629f2 Compare October 16, 2024 17:55
@tnull
Copy link
Collaborator Author

tnull commented Oct 16, 2024

Squashed fixups without further changes.

@tnull tnull merged commit af5d85a into lightningdevkit:main Oct 16, 2024
6 of 13 checks passed
(sweeper_best_block_hash, &*output_sweeper as &(dyn Listen + Send + Sync)),
];

// TODO: Eventually we might want to see if we can synchronize `ChannelMonitor`s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the question post-merge but what would be the benefit of syncing the ChannelMonitors before passing them to the ChainMonitor? There would still be a need to sync them via the monitor even if it was possible to sync before, right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post-merge questions are great!

ChannelMonitors can by sync'd by just syncing the ChainMonitor and it'll multiplex the events across all the ChannelMonitors for us (cleaning up the logic here quite a bit). Sadly, doing so requires that the ChannelMonitors be in sync with each other before we pass them to ChainMonitor on load (or we'll end up connecting blocks on different ChannelMonitors even though they have different ideas of the current chain tip).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants