Create an async corepc-client#505
Conversation
d5524e1 to
9a77aa2
Compare
6981d8f to
6cd8bb2
Compare
|
@apoelstra whats your take man? Would you be willing to have |
6cd8bb2 to
87dfe15
Compare
|
Holla at me if/when you would like some review mate. |
1c174a6 to
7a79b87
Compare
|
Rewrote the async client:
@tcharding thoughts? in particular the error handling of converting to the modelled type. Returning a modelled type vs the inner field e.g. |
After writing a massive post I realised this solution is not going to work (see bottom for explanation). I think we should inline the How about throwing this at the top: //! Async JSON-RPC client designed explicitly to support BDK.
//!
//! ## Project decisions
//!
//! * Support Core versions 25 to 30.
Troublesome, commented already on the code.
Another solution is to have an error type for each function. Then it can have a variant (assuming its an enum) for the exact error returned by
Agreed that a wrapper type is not useful to returen (eg
Nice.
I don't think separation by project module is not going to work because the modules will conflict with each other. And if we feature gate the features will not be additive. We could try some macro stuff but I think it defeats the purpose which is to write a simple clean client that others can fork if they need to. |
7a79b87 to
2f2ca44
Compare
Would this then tie all users of the crate to tokio? Why can't it be executor-agnostic? |
fd21983 to
8448aab
Compare
The changes to |
0aa7803 Add async support to jsonrpc (Jamil Lambert, PhD) 7302ebd Change Debug impl to local Client (Jamil Lambert, PhD) 7d556f9 Remove fuzz related sections (Jamil Lambert, PhD) e62b044 Copy jsonrpc client and bitreq_http for async. (Jamil Lambert, PhD) c16f4b5 Round timeouts to whole seconds (Jamil Lambert, PhD) Pull request description: Pulled out of #505 and polished. The aim is to add async support without breaking existing sync downstream. This includes keeping the reexports of the current sync `Client` at the crate root. ACKs for top commit: apoelstra: utACK 0aa7803 Tree-SHA512: d0a096181668f7656ed3ba8f7d3cf77560a39c6eec2c6ff410627e35ae7d798ef6abe6cd0a467317383a6091c403aded977d095a43f2090a5e359f305e0bf12a
84d501b to
b27af91
Compare
|
Reviving this PR. I rebased on master now that jsonrpc has async support. The commit sequence is recreated to be simpler. Still a work in progress. |
b27af91 to
021baf0
Compare
1674e53 to
035940d
Compare
035940d to
854ac31
Compare
There is a lint error: this expression creates a reference which is immediately dereferenced by the compiler. Fix it as suggested by the compiler.
854ac31 to
aa1e80d
Compare
|
@tcharding I think this is ready for preliminary review. The last patch is a new idea to make the async client universal by not having any inherent RPC methods. Users instead add an extension trait to implement the RPCs that they need in their own codebase. The RPCs for BDK have already been done in this crate and can be used as a template for others. Users don't need to fork the client and can instead depend on the published version which is better for any fixes or security updates. It can also stay in this repo. The docs will need to be improved, I'm leaving it for now due to this possible change in structure. The CI failure for v31 needs the related PR and then I'll see if any of the async client tests need to be updated. |
| GetBlockVerboseOneError as GetBlockVerboseOneErrorV29, | ||
| }; | ||
|
|
||
| pub use crate::error::{Error, UnexpectedServerVersionError}; |
There was a problem hiding this comment.
For a production client all this error stuff could be better I rekon.
There was a problem hiding this comment.
I made the errors simpler and better.
| /// This trait exposes the Bitcoin Core RPC methods available on [`Client`]. Downstream users | ||
| /// can define their own extension traits with additional methods without risk of | ||
| /// name collision with the methods defined here. | ||
| // `async fn` in traits produces non-`Send` futures by default; we suppress this lint because | ||
| // `BitcoinRpcs` is intended only for use with concrete types (never `dyn BitcoinRpcs`). |
There was a problem hiding this comment.
We can just put the subset of RPC methods we want directly on the Client type. Downstream can still define extension traits and name collisions can still be avoided by calling their trait methods using trait syntax or whatever its called.
Does BDK use the verbose methods? At first blush I don't like them, bit ugly for a 'bare bones client'.
There was a problem hiding this comment.
I rekon we add an example that adds an extension trait and a single method, then that can be used as documentation and to link LLMs too.
There was a problem hiding this comment.
The reason for this change was to separate Client from the BDK RPCs. Otherwise we have a BDK client which can be modified for other projects, rather than the way it is here where it is a universal client with a trait premade for BDK.
So I still prefer to have no RPCs at all in the Client, and keep the full set of BDK RPCs in the prewritten trait.
I also think that having extra RPCs in this trait is a good idea rather than just one example and force everyone to write their own. If we put in all that BDK need it works out of the box for them, and if a few can be added to fill the needs of LDK and possibly there is only a few changes needed to this set to support multiple users. I understand the concern that supporting multiple projects will cause conflicts in the RPC methods if they are all together. But if we can support multiple projects without conflicts why not? i.e. The policy is we don't support adding downstream RPC requirements to the Client you need to add the trait to your own codebase, but on an individual basis we can consider if only a small change is required to support whole project then why not.
EDIT: AI says LDK only need getblockchaininfo and gettxout added to the trait so that is supports them too.
There was a problem hiding this comment.
I agree with all that about supporting bdk and ldk. I rekon we should do so as methods on the client still though not a trait. We can chat about it on the phone tomorrow though.
In preparation for adding bitreq_http_async feature to jsonrpc move the sync version to the client-sync feature so it is not always on with jsonrpc.
These will both be used by the async client. Move them out of sync client in preparation. Edit the logging function so it doesn't panic.
Create a new folder for the upcoming async client and copy in the existing client_sync code. Code copy only to make the next patch easier to review.
Edit the copy of the sync client created in the previous commit to be async. Update the readme and cargo.toml files. Replace macros with functions. There is only one async client so the macros are not needed anymore. Create a new module for the bdk client that has the required RPCs in it that return either the rust-bitcoin type or non-version specific model types.
Use trait methods instead of inherent methods to define the RPCs to better allow downstream clients that define their own RPCs. This helps when different implementations of the ones defined in the client are required. Move the error module to the crate root. Create a new `IntoModelError` error type that carries the RPC method name as context and the original conversion error as a boxed `source`. Use this error type in both sync and async clients. Assisted-by: GPT-5.4
aa1e80d to
436d488
Compare
Add these two RPCs to the async client Trait and tests. Assisted-by: GPT-5.4
436d488 to
2750000
Compare
This PR adds an async corepc-client with the RPCs used by BDK.
The patches are structured to make it easier to see what was changed from sync to async. First the sync version is copied and renamed, then in a separate patch it is changed to async.