Skip to content

[bitreq] Bitreq client builder#502

Open
APonce911 wants to merge 32 commits intorust-bitcoin:masterfrom
APonce911:bitreq-client-builder
Open

[bitreq] Bitreq client builder#502
APonce911 wants to merge 32 commits intorust-bitcoin:masterfrom
APonce911:bitreq-client-builder

Conversation

@APonce911
Copy link

@APonce911 APonce911 commented Feb 11, 2026

Summary

This PR addresses issue #473 by creating a Client Builder able to receive custom root certificates at runtime.
The ClientBuilder requires the same features as Client (async-https-rustls).

Changes

  • Add Client Builder pattern.
  • Creates Certificates wrapper module
  • Append certificate using with_root_certificate builder method.
  • Include example.

@APonce911 APonce911 changed the title [Bitreq] Bitreq client builder [bitreq] Bitreq client builder Feb 11, 2026
@tcharding
Copy link
Member

Holla if you want/need any review mate. Otherwise, for me at least, while there are WIP commits I'll assume you are happily working on it still.

@tcharding
Copy link
Member

Holla at me also if you want me to kick CI into action for you. Once you have a patch merged CI will run automatically. You could just do a basic fix somewhere else in the repo if this is going to be long running work.

@APonce911
Copy link
Author

Thanks @tcharding. My idea with this draft was to give a bit of visibility of where we're at and to guarantee that the solution is in the right path. No formal code review is needed yet.

Thanks for the tip about the CI, so far it's ok not to run.

}

#[cfg(all(feature = "rustls", feature = "tokio-rustls"))]
pub(super) async fn wrap_async_stream_with_configs(
Copy link
Author

Choose a reason for hiding this comment

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

same as wrap_async_stream but with additional parameter custom_client_config

@APonce911 APonce911 marked this pull request as ready for review February 12, 2026 22:52
@APonce911
Copy link
Author

@tcharding hey mate, can you please run the CI once? It's ready for review.

Copy link
Member

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

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

Obv needs docs, but at a high level looks good to me.

Self { capacity: 1, client_config: None }
}

pub fn with_root_certificate<T: Into<Vec<u8>>>(mut self, certificate: T) -> Self {
Copy link
Member

Choose a reason for hiding this comment

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

Its pretty awkward that we don't error here but then just ignore certs silently. IMO we kinda need to actually make this fallible, store a root cert store in ClientConfig, and pass that around instead. We'll have to have an abstract root cert store in rustls_stream (or somewhere), but that should be pretty straightforward.

Copy link
Author

Choose a reason for hiding this comment

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

@TheBlueMatt makes sense. Will work on that tomorrow! Thanks

Copy link
Author

Choose a reason for hiding this comment

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

@TheBlueMatt updated the PR with your suggestion. I moved the new certificates logic to a new module. We still have lots of stuff in the rustls_stream module, but I thought refactoring that would make this PR too large.

Copy link
Member

Choose a reason for hiding this comment

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

This still looks like its currently infallible and not parsing the cert? We should validate the cert here.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @TheBlueMatt. Currently the method is fallible, it panics on expect() if certificate appending fails. However, I intentionally kept the return type as Self (not Result<Self, Error>) to maintain fluent builder chaining without requiring callers to handle Result at every step. Would you prefer that I return Result<Self, Error> here?

About parsing, I don't know if I understand you're question well, I'm sorry. But we're currently parsing it on the new Certificates module. I tried to keep this Client interface simple and more details about certificate management inside this module.

https://github.com/rust-bitcoin/corepc/pull/502/changes#diff-4501e006f554583aacf6f0039d2c12e149a90447ec1af22f3c68d74820932c5fR28

@tcharding
Copy link
Member

Just an FYI, you can use just to run build commands in this repo mate.

https://github.com/casey/just

Copy link

@DanGould DanGould left a comment

Choose a reason for hiding this comment

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

Great start here that's gonna solve a real problem for me. Saw something that's nice to have when we're dealing with loose types. Use cert_der: Vec<u8> if the type signature expects DER encoding please

}

impl Certificates {
pub(crate) fn new(certificate: Option<&Vec<u8>>) -> Result<Self, Error> {

Choose a reason for hiding this comment

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

Since this is just a Vec<u8> tell me what format you're expecting input both in the param name and docstring

Suggested change
pub(crate) fn new(certificate: Option<&Vec<u8>>) -> Result<Self, Error> {
/// Pass a new certificate in DER [?] format
pub(crate) fn new(certificate_der: Option<&Vec<u8>>) -> Result<Self, Error> {

Copy link
Author

@APonce911 APonce911 Feb 16, 2026

Choose a reason for hiding this comment

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

@DanGould Great catch. Yes, you're correct. We must receive a DER encoded certificate.
I've updated the variable to cert_der to give more clarity. About the doc, I've written on the Client class since it's public.

https://github.com/rust-bitcoin/corepc/pull/502/changes#diff-21f18a8053f4d7bce98cbe0c84adc7e943caf49c0a245be26096be8ce461ae64R100-R127

What do you think?

}
}

#[cfg(feature = "rustls")]
Copy link
Member

Choose a reason for hiding this comment

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

We need support for native-tls, too.

Self { capacity: 1, client_config: None }
}

pub fn with_root_certificate<T: Into<Vec<u8>>>(mut self, certificate: T) -> Self {
Copy link
Member

Choose a reason for hiding this comment

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

This still looks like its currently infallible and not parsing the cert? We should validate the cert here.

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