Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Add submitpackage support #23

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

tnull
Copy link
Contributor

@tnull tnull commented Aug 30, 2024

Based on #22.

Rebased after #22 landed. Should be good for review.

@tnull tnull marked this pull request as draft August 30, 2024 12:22
Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

Looks good so far.

/// whose fees and vsizes are included in effective-feerate.
#[serde(rename = "effective-includes")]
pub effective_includes: Vec<Wtxid>,
}
Copy link
Member

Choose a reason for hiding this comment

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

These structs look good, we will need to also add similar structs in json/src/model and also into_model() functions on each of them here in this module.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I think on the first attempt I didn't quite get when code would fully live in one of the vXX modules and when it would go in model. IIUC, Is the idea that everthing should be duplicated in model and the model is fed with the respective implementations based on the features?

Copy link
Member

Choose a reason for hiding this comment

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

In model the structs are fully typed i.e., in the respective json version module we use standard language types (String, u32) and in model we use bitcoin types (BlockHash, Version). The into_model function is to do the conversion. The hope is that then the model structs will be somewhat universal across all the Core versions without having a bunch of conditional logic in them. We will only know if this works after writing a bunch more code though. I did iterate quite a few times already to get to this design, so I am hopeful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I think I still don't fully get why the model is necessary. Why can't we just use serde's with attribute for the fields that need to be de/serialized differently from their Rust type?
It would allow to avoid a lot of redundant boilerplate, at least if I understand the problem at hand correctly?

For example, see these definitions: https://github.com/lightningdevkit/lightning-liquidity/blob/8dd8a1cdf52d5913ff18d9677c152c521b22c4cc/src/lsps0/ser.rs#L603-L678 which are used here: https://github.com/lightningdevkit/lightning-liquidity/blob/8dd8a1cdf52d5913ff18d9677c152c521b22c4cc/src/lsps2/msgs.rs#L85-L105

Copy link
Member

Choose a reason for hiding this comment

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

The problem the model module is trying to solve is multiple versions of Core returning different things for the same JSONRPC method. This led, in rust-bitcoincore-rpc, to loads of logic inside the types crate to handle the differences, this was scattered all over the place making it hard to know exactly what was supported and what was not. The idea in this repo is to make the version specific types dumb as possible, then the model types are, if possible, some representation of the data returned by all supported Core versions. Each version specific type then implements into_model (if possible). Users are free to not use the model types at all if they only want standard typed fields and not the rust-bitcoin typed fields in model. Does that make sense?

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 don't think there is a good solution to Core's JSONRPC API returning different data for different versions

Mhh, I see the issue for the raw JSON types, but want to note we could somewhat mitigate the issue in the client implementation by checking the version after connection (e.g., through getnetworkinfo), and switch to the matching types accordingly? In any case, I'll just proceed for now.

Copy link
Member

Choose a reason for hiding this comment

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

Yes in theory, but someone somewhere said that some ops guys disable that RPC method for some security reason that I don't remember so their is no reliable way to get the version. The fella shortly afterwards did a PR to Core to add a new method to get just the version. I can dig it out if you want but since we want to support old versions it doesn't help us much.

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 can dig it out if you want but since we want to support old versions it doesn't help us much.

Since it came up once or twice since you wrote this, I'd actually be interested to hear how and why they do this. Do you think you can still find it?

Copy link
Member

Choose a reason for hiding this comment

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

Right now I have no clue, but I can keep you in mind and message you if/when I stumble upon it.

Copy link
Member

Choose a reason for hiding this comment

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

These structs look good

Bother, sorry I did not notice the rust-bitcoin types here last month when I reviewed. I bet I caused you to be confused about the purpose into_model this last week when you implemented it.

@tcharding
Copy link
Member

Woops, no need to run CI we know its going to fail because there is no binary to pull down.

@tcharding
Copy link
Member

How hard was it to work out how to patch this repo @tnull? I realise its a bit unusual, from your experience do you think I'm correct in thinking that there is no point asking more junior devs to work on this repo because its a little too strange?

@tnull
Copy link
Contributor Author

tnull commented Sep 2, 2024

How hard was it to work out how to patch this repo @tnull? I realise its a bit unusual, from your experience do you think I'm correct in thinking that there is no point asking more junior devs to work on this repo because its a little too strange?

Given there are no docs describing the ideas behind the project layout (w.r.t. features etc) it took a while to get the hang of it. I think if it would be clearly documented how everything's supposed to work it shouldn't be too hard to contribute though, even for more junior devs.

@tcharding
Copy link
Member

No sweat, I actually added a wiki doc yesterday before reading your comment above but we can do even better. Thanks man.

@tnull tnull force-pushed the 2024-08-add-submitpackage branch 2 times, most recently from 7e61405 to 4230085 Compare November 7, 2024 13:11
@tnull tnull changed the title WIP: Add submitpackage support Add submitpackage support Nov 7, 2024
@tnull tnull marked this pull request as ready for review November 7, 2024 13:11
@tnull tnull requested a review from tcharding November 7, 2024 13:11
@tnull
Copy link
Contributor Author

tnull commented Nov 7, 2024

I now rebased this after #22 landed, fixed some minor things and added a really basic test for most of the introduced API types (we don't actually test package submission, but submission of two already-known transactions).

Should be good for review (cc @tcharding)

@tcharding
Copy link
Member

Thanks for the work man, I didn't review closely but a few quick comments:

  • Can you do this as a single patch please since its a discreet change
  • Can you remove the commented out docs from Bitocin Core in json/src/v28/raw_transactions.rs
  • We either need an issue saying "Implement into_model for SubmitPackage" or we should implement it in this PR

@tnull
Copy link
Contributor Author

tnull commented Nov 11, 2024

Thanks for the work man, I didn't review closely but a few quick comments:

* Can you do this as a single patch please since its a discreet change

If you prefer, now squashed the commits and added further fixups.

* Can you remove the commented out docs from Bitocin Core in `json/src/v28/raw_transactions.rs`

Hmm, I intentionally didn't include the bitcoind output as a doc-comment since a) it's slightly wrong/misleading in the Rust context and b) is redundant to the actual field docs.

* We either need an issue saying "Implement `into_model` for `SubmitPackage`" or we should implement it in this PR

Done

@tcharding
Copy link
Member

Hmm, I intentionally didn't include the bitcoind output as a doc-comment since a) it's slightly wrong/misleading in the Rust context and b) is redundant to the actual field docs.

Yeah I agree with this, I mean we don't want it as a code comment either simply because if we do this everywhere there will be too much noise IMO, or is this specific method special on some way I'm missing that means the comment is needed?

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

Holla if the concept between model vs v28/raw_transaction is not clear man, I can try explain it a different way if so.

json/src/model/raw_transactions.rs Outdated Show resolved Hide resolved
json/src/v28/raw_transactions.rs Show resolved Hide resolved
json/src/v28/raw_transactions.rs Outdated Show resolved Hide resolved
/// whose fees and vsizes are included in effective-feerate.
#[serde(rename = "effective-includes")]
pub effective_includes: Vec<Wtxid>,
}
Copy link
Member

Choose a reason for hiding this comment

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

These structs look good

Bother, sorry I did not notice the rust-bitcoin types here last month when I reviewed. I bet I caused you to be confused about the purpose into_model this last week when you implemented it.

@tnull
Copy link
Contributor Author

tnull commented Nov 12, 2024

Holla if the concept between model vs v28/raw_transaction is not clear man, I can try explain it a different way if so.

No, I think I get it overall. I have to say though that it makes for a pretty unergonomic API, since it requires doing call().unwrap().into_model().unwrap() everywhere and users might not expect that they are required to manually initiate the actual parsing in the API essentially.

@tnull
Copy link
Contributor Author

tnull commented Nov 12, 2024

Now made the requested changes.

@tcharding
Copy link
Member

I have to say though that it makes for a pretty unergonomic API

I tend to agree with you. Its the best API I could come up with that solves the problem. I'm open to suggestions but the idea to split the model types from the actual types returned by the JSONRPC methods is core to the design of the crate and I still believe that it is the correct decision.

@tcharding
Copy link
Member

tcharding commented Nov 12, 2024

If you grep for cl. in this file https://github.com/rust-bitcoin/rust-miniscript/blob/master/bitcoind-tests/tests/test_cpp.rs you can see that how I used the Client. I updated these tests while designing the API and this was the best that I could come up with.

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

Thanks man, I realize that this crate is a bit odd and probably annoying to work on so thanks for doing so. I had a few more nits but I didn't want to be too anal about it, I can come back and do a follow up if that doesn't annoy you or I can post all the nits if you like. Because the crate is basically all boilerplate I'm trying to be really uniform.

Thanks again


/// Error when converting a `SubmitPackageTxResultFees` type into the model type.
#[derive(Debug)]
pub enum SubmitPackageError {
Copy link
Member

Choose a reason for hiding this comment

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

This error type needs to go over in v28/raw_transactions.rs (the conversion is coupled with the into_model function). Also the error needs a few more things implementing, see v17/blockchain.rs for an example. FTR the v17 stuff is in the best state because its the part of the crate I've been working on lately, if something is non-uniform favour the stuff in v17.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh, well that's surprising to me. In fact I started the error type in v28 but then realized it is / needs to be part of the stable model conversion API, and hence shouldn't / can't be version-specific, no?

Comment on lines +79 to +80
let vsize = if let Some(vsize) = self.vsize {
Some(vsize.try_into().map_err(|_| SubmitPackageError::Vsize)?)
Copy link
Member

Choose a reason for hiding this comment

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

Does this definitely need to be a usize, a u32 would be ok, right? Then we can use the to_u32 function and put a NumericError variant in the SubmitPackageError (again see the v17 blockchain stuff for an example)
Here is an example

        let stripped_size =
            self.stripped_size.map(|size| crate::to_u32(size, "stripped_size")).transpose()?;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this definitely need to be a usize, a u32 would be ok, right?

No, as it's a usize in bitcoin::Transaction? https://docs.rs/bitcoin/latest/bitcoin/blockdata/transaction/struct.Transaction.html#method.vsize

Doesn't make a lot of sense to me to first convert from i32 to u32 to then eventually convert it to usize (or have the user convert it) anyways?

@tnull
Copy link
Contributor Author

tnull commented Nov 14, 2024

If you grep for cl. in this file https://github.com/rust-bitcoin/rust-miniscript/blob/master/bitcoind-tests/tests/test_cpp.rs you can see that how I used the Client. I updated these tests while designing the API and this was the best that I could come up with.

Mhh, seems this 'always call into_model' logic should live in the client crate eventually? And possibly it could adhere to some more standard Rust patterns, e.g., impl TryFrom<X> for Y?

I had a few more nits but I didn't want to be too anal about it, I can come back and do a follow up if that doesn't annoy you or I can post all the nits if you like.

Please go ahead!

@tcharding
Copy link
Member

Hey @tnull sorry to be a pain in the arse but I've moved this repo to a new name. Its now called corepc. See #48 and #51 for context.

Are you willing to re-do this? If not I'll get to it eventually. I'm focused on the earlier versions still though ATM. Thanks man.

(I moved all issues to the new repo but one cannot move PRs its seems.)

@tnull
Copy link
Contributor Author

tnull commented Nov 26, 2024

Are you willing to re-do this?

I mean, sure. Is there anything else I should include besides just reopening the PR over there?

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

Successfully merging this pull request may close these issues.

2 participants