Skip to content

feat: chain source rest sync #526

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

enigbe
Copy link
Contributor

@enigbe enigbe commented Apr 18, 2025

What this PR does

This PR introduces chain source synchronization with Bitcoin Core's REST API. To do so, it explicitly distinguishes between the bitcoind_rpc_client and the newly introduced bitcoind_sync_client that can sync either via the RPC or REST APIs.

BitcoindRpcClient is maintained and the distinction created because the REST interface exposed by Bitcoin Core is not as robust as the RPC interface. This makes it impossible to send POST request to broadcast a transaction for example.

Related Issues

Fixes #496

cc @tnull @joostjager

enigbe added 2 commits April 17, 2025 22:50
Adds:
- Sync client configuration with RPC (default) and REST variants
- Extend the ChainSource::Bitcoind configuration options
- Preliminary implementation for BitcoindSyncClient in RPC mode
Additionally adds the BlockSource implementation for BitcoindSyncClient
@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Apr 18, 2025

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@enigbe enigbe changed the title feat: chain source rest sync with bitcoind feat: chain source rest sync Apr 18, 2025
@tnull tnull requested review from tnull and removed request for joostjager April 18, 2025 10:47
Copy link
Collaborator

@tnull tnull left a comment

Choose a reason for hiding this comment

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

Thanks for looking into this! Before I get into more detailed review, I want to note two things on the chosen approach that stood out to me from a first look:

  1. I'm not quite convinced we should rename the BitcoindRpc client. Wouldn't it be cleaner to just add a (granted, rather duplicative) BitcoindRest variant side-by-side, and then in a second step maybe see how we can DRY up the code. Mushing both variants together seems to result in a rather confusing API and code structure.
  2. I'm a bit confused why we'd now still have RPC credentials on set_chain_source_bitcoind (and elsewhere in downstream from that), even if we want to use the REST backend? Is there any operation that still requires RPC access? Can't we just rely on REST alone?

@enigbe
Copy link
Contributor Author

enigbe commented Apr 19, 2025

Thanks for the early feedback.

  1. I'm not quite convinced we should rename the BitcoindRpc client. Wouldn't it be cleaner to just add a (granted, rather duplicative) BitcoindRest variant side-by-side, and then in a second step maybe see how we can DRY up the code. Mushing both variants together seems to result in a rather confusing API and code structure.
  2. I'm a bit confused why we'd now still have RPC credentials on set_chain_source_bitcoind (and elsewhere in downstream from that), even if we want to use the REST backend? Is there any operation that still requires RPC access? Can't we just rely on REST alone?

I understand your concerns about the name and API changes I have introduced but here is a bit of context.

Adding a ChainSource::BitcondRest variant was my initial approach too because I had erroneously thought Bitcoin Core's REST interface exposed (more or less) the same APIs as the RPC interface. However, the REST interface exposes a handful of APIs only for GET requests. It is not possible to broadcast transactions with a pure REST variant as we do with the BitcoindRpcClient, There is no REST API to sendrawtransaction.
For that particular use case, given that we'd need a handle on an RPC client regardless, I thought it best to:

  • Keep the BitcoindRpcClient as is.
  • Introduce a configurable REST/RPC sync client. With this, users can decide if syncing should happen either via the REST or RPC APIs.
  • Rename ChainSource::BitcoindRpc to ChainSource::Bitcoind as the latter leaves no ambiguity about the possibility of a REST variant.

@tnull
Copy link
Collaborator

tnull commented Apr 22, 2025

I understand your concerns about the name and API changes I have introduced but here is a bit of context.

Adding a ChainSource::BitcondRest variant was my initial approach too because I had erroneously thought Bitcoin Core's REST interface exposed (more or less) the same APIs as the RPC interface. However, the REST interface exposes a handful of APIs only for GET requests. It is not possible to broadcast transactions with a pure REST variant as we do with the BitcoindRpcClient, There is no REST API to sendrawtransaction. For that particular use case, given that we'd need a handle on an RPC client regardless, I thought it best to:

* Keep the `BitcoindRpcClient` as is.

* Introduce a configurable REST/RPC sync client. With this, users can decide if syncing should happen either via the REST or RPC APIs.

* Rename `ChainSource::BitcoindRpc` to `ChainSource::Bitcoind` as the latter leaves no ambiguity about the possibility of a REST variant.

Aaah, okay, then the proposed approach makes more sense. I think it's still a bit awkward to have the mandatory RPC credentials on the set_chain_source_bitcoind method and addtionally have the BitcoindSyncConfig::Rpc variant.

While it then makes sense to reuse the client internally, it might be simpler to just keep the original set_chain_source_bitcoind_rpc method and just add a set_chain_source_bitcoind_rest variant, that also features the mandatory RPC credentials?

@Camillarhi
Copy link
Contributor

Hi @enigbe,

I noticed your CI is failing. I had a similar issue, but it was resolved after rebasing onto the latest dev branch (which includes changes from #524).

Could you try rebasing and see if that fixes the problem?

Thanks

- Adds set_chain_source_bitcoind_rest to configure REST synchronization.
- Update docs to reflect the configuration order if REST sync is preferred.
- Simplify the configuration object to capture only REST-related fields.
Copy link

@chuksys chuksys left a comment

Choose a reason for hiding this comment

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

Looking into this PR has helped me gain a good understanding of how chain sourcing works. I think introducing BitcoindSyncClient is a good idea as the user can still carry out syncing operations using the REST API while the RPC Client is still maintained to carry out operations not supported by the REST API. I have just a few suggestions with regards to error handling.

@enigbe enigbe force-pushed the 2025-04-bitcoind-rest-sync-v2 branch from 9b07570 to a28d28f Compare May 7, 2025 08:28
@tnull
Copy link
Collaborator

tnull commented May 12, 2025

@enigbe Please let me know when this is ready for a second look.

@enigbe
Copy link
Contributor Author

enigbe commented May 12, 2025

Thanks for the feedback @tnull. I revisited this last week and addressed concerns raised here.

Aaah, okay, then the proposed approach makes more sense. I think it's still a bit awkward to have the mandatory RPC credentials on the set_chain_source_bitcoind method and addtionally have the BitcoindSyncConfig::Rpc variant.

This has been removed and we just keep a config for REST sync.

While it then makes sense to reuse the client internally, it might be simpler to just keep the original set_chain_source_bitcoind_rpc method and just add a set_chain_source_bitcoind_rest variant, that also features the mandatory RPC credentials?

Agreed! This seems like a cleaner split. I've added a set_chain_source_bitcoind_rest variant accordingly. However, I think it'd be potentially confusing/awkward for callers to still pass RPC parameters to the REST function. I opted for set_chain_source_bitcoind_rest to take only REST parameters and clarified comments on usage and dependency on the RPC variant.

If you'd still prefer we pass RPC parameters as a required input for the REST variant, happy to adjust.

@enigbe
Copy link
Contributor Author

enigbe commented May 12, 2025

Hi @enigbe,

I noticed your CI is failing. I had a similar issue, but it was resolved after rebasing onto the latest dev branch (which includes changes from #524).

Could you try rebasing and see if that fixes the problem?

Thanks

Thanks for looking at this. I've rebased and have just the CLN integration tests failing. I tried reproducing the failing test locally but couldn't. I should give it another go today.

@tnull
Copy link
Collaborator

tnull commented May 12, 2025

Thanks for looking at this. I've rebased and have just the CLN integration tests failing. I tried reproducing the failing test locally but couldn't. I should give it another go today.

Yes, I think this is unrelated, so feel free to ignore the flaky CI in this PR. Fixing it is really an unrelated task.

@enigbe
Copy link
Contributor Author

enigbe commented May 12, 2025

Looking into this PR has helped me gain a good understanding of how chain sourcing works. I think introducing BitcoindSyncClient is a good idea as the user can still carry out syncing operations using the REST API while the RPC Client is still maintained to carry out operations not supported by the REST API. I have just a few suggestions with regards to error handling.

Thanks for the review. Added the suggestions recommended for error handling.

@enigbe
Copy link
Contributor Author

enigbe commented May 12, 2025

@enigbe Please let me know when this is ready for a second look.

This is ready @tnull.

Copy link
Collaborator

@tnull tnull left a comment

Choose a reason for hiding this comment

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

Hmm, tbh. I still dislike the current refactorings as they make the codepaths unnecessarily confusing and duplicative. Why keep a BitcoindRpcClient around side-by-side with the new BitcoindSyncClient that could also be an RPC client? If you maintain that merging in the REST codepaths with the RPC client is the way to go, why not extend the enum BitcoindSyncClient variants so that one would only hold the RPC client and the other the RPC and REST clients, which would allow us to add an fn rpc_client accessor that we can use everywhere, i.e., hence would allow us to drop the bitcoind_rpc_client field?

///
/// ## Parameters:
/// * `rest_host`, `rest_port` - Required parameters for the Bitcoin Core REST connection.
pub fn set_chain_source_bitcoind_rest(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, I really dislike this API design introducing a separate chain source setter here. Basically, the fact that you had to introduce two new error variants to handle the cases where users misuse this API call already tells you that there is room for improvement here. Why not just have an entirely separate set_chain_source_bitcoind_rest call that take all the necessary fields, including the RPC configs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll refactor to include the recommended changes . I thought having to pass RPC config for REST would be confusing but I now agree that it would be clearer and less likely to misuse.

rpc_port: u16,
rpc_user: String,
rpc_password: String,
sync_client_config: Option<BitcoindRestSyncClientConfig>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mhh, let's name this rest_client_config then.

@@ -186,6 +190,52 @@ impl ElectrumRuntimeStatus {
}
}

pub(crate) enum BitcoindSyncClient {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure why this was added here vs bitcoind_rpc.rs.

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.

Bitcoind REST sync
5 participants