-
Notifications
You must be signed in to change notification settings - Fork 4
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
Consider using code generation to produce Rust code from structured RPC information exported from Bitcoin Core #4
Comments
Thanks for the write up man, I didn't totally grok it but I had an immediate question, will your idea achieve what I want to achieve with less work now and less work to maintain it? If so I'm in favour of it. To assist you in possibly answering this perhaps I can outline what it is this repo is trying to achieve and why I think it should be low maintenance going forward. FTR if I never have to look at JSON RPC code again I will be a happy camper, I am working on this crate because I think it needs to exist not because I find it interesting in any way. Wants and don't wants
This project is pretty new so I don't know if it will achieve these aims but in regards to each one:
It is bleedingly obvious while working on this repo that a trained monkey could do it because it is so repetative. It is also boring, hence why it is taking me so long. |
A big problem with the codegen approach is that I wrote the code for Bitcoin Core 28. I don't know how much change there's been in the RPC API code, but if there's been a lot, rebasing the the code onto earlier and earlier versions, back to v17, might be very hard. I do wonder if it's worth supporting versions of core which are that old. Is there demand for it? If not, then you could just decided to support v28 going forward, and anyone who wants support for an older version should use the deprecated library. |
I posted the API description PR to Twitter, and someone mentioned it in an issue in Core, so linking here for posterity. |
Gawd damn, if I knew that before I started this repo I might not have started. |
😭 |
I wasn't aware of this repo. I only looked at https://github.com/rust-bitcoin/rust-bitcoincore-rpc, which looked a bit incomplete and stale, according to its own readme: https://github.com/rust-bitcoin/rust-bitcoincore-rpc?tab=readme-ov-file#supported-bitcoin-core-versions This repo looks a lot more what I think should be the goal. That is, this repo properly versions RPCs for each release and every field has the correct type (only did some spot checking). Short of auto-generation (which no one has implemented yet) this is probably the best approach that I've seen so far. |
Mad, that inspires me. Thanks. |
The names are a mess now, below I'm going to use the new names because they are shorter but for anyone not following the rename I list them here
We test using features on the
I think you are right, as long as we don't manually go in and touch the generated code. All "fixes" would have to go into the code generator.
This one I'm more confident you are correct.
I'm hopeful that you are correct here, I don't know exactly how hard it is to go from a fully fleshed out version to the next in this crate yet because v17 is not fully fleshed out. All other versions are just minimal (basically just what was needed by
One idea would be to only codegen Rust std types and leave the
Yeah I asked myself this question also, I started at v17 because that is where |
I started working on a new branch which exports a description of the RPC API as JSON Schema. I don't have a lot of experience with JSON Schema, but it seems pretty widely adopted, and there is at least some amount of tooling for it. At the very worst, it doesn't seem a whole lot more difficult to work with than an ad-hoc JSON description of the API For each command, there is an |
Does that mean that client code has to statically select which version of bitcoind it wants to talk to with a feature? |
I don't quite understand the question. By 'client code' you mean code in the |
Ah yeah, sorry it's confusing. Yeah, I mean a user of |
I'll try to clarify. The
A user uses A user of If other projects ( Now, my opinion, and background on design assumptions: For production code, people should write their own client and only use the
And all of these depend on what subset of RPC methods the app calls. Hence my view that its app specific and not right to have a single production client library that everyone can use. The final piece of the puzzle is the
One can convert from an I have a good reason for the split between |
I've been considering an alternative approach to writing a Bitcoin Core JSON RPC client, namely, exporting the structured API information available within Bitcoin Core as JSON, and using that to auto-generate the API.
I created a branch of Core here which implements a new JSON RPC command,
api
, which dumps structured API information as JSON.You can see the output here. It contains types and documentation for all RPC commands.
These could be used to automatically generate Rust code, instead of writing them manually and keeping them up to date between versions of Core. Types are not ideal, for example, addresses have type "string". However, you could write a complementary JSON "patch" file which described what the user facing types should be.
For example,
getaddressinfo
takes a single argument which is of typestring
. The patch file could contain instructions for the code generator to expose this as abitcoin::Address
:The code generator would then load the JSON file dumped by
bitcoin-cli api
, as well as the patch file, and use them to generate user-facing Rust code which exposed the appropriate types, and performed the appropriate conversions when calling Bitcoin Core.There are a bunch of advantages to this approach. You would be guaranteed to be up-to-date with Core, and could automatically expose documentation from Core as Rust doc comments, without needing to copy them manually. Since everything is auto-generated, you would likely only need a minimum of tests to be confident that things were working.
Some types would require special considerations, like addresses, fee rates, and amounts (which are exposed by the Core RPC with different units in different places). So, it might be wise to consider the patchfile to be a kind of whitelist, and require entries in the patch file for all commands before allowing to code generator to expose them, to ensure that a human had manually confirmed that no types require special handling.
I don't know if I'm going to keep working on this myself. Since
rust-bitcoincore-rpc
has been deprecated, I went down a bit of a rabbit hole thinking about how the whole RPC situation could be improved, and this is what I came up with. However, in reality, we'll probably keep usingrust-bitcoincore-rpc
for the time being, and just hack around the limitations until they become intolerable.If this approach is fruitful, it would be nice to get the branch which adds the
api
command merged into Core, so it doesn't require continual rebasing. I've been away from Core development for a while, and have been spoiled rotten by Rust, so I might not be the right person to do that.The text was updated successfully, but these errors were encountered: