Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
lightning-block-sync: switch to bitreq, drop chunked_transfer by Apostlex0 · Pull Request #4350 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' lightning-block-sync: switch to bitreq, drop chunked_transfer by Apostlex0 · Pull Request #4350 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' lightning-block-sync: switch to bitreq, drop chunked_transfer by Apostlex0 · Pull Request #4350 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' lightning-block-sync: switch to bitreq, drop chunked_transfer by Apostlex0 · Pull Request #4350 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' lightning-block-sync: switch to bitreq, drop chunked_transfer by Apostlex0 · Pull Request #4350 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); lightning-block-sync: switch to bitreq, drop chunked_transfer by Apostlex0 · Pull Request #4350 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-block-sync: switch to bitreq, drop chunked_transfer - #4350

Merged
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq
Feb 19, 2026
Merged

lightning-block-sync: switch to bitreq, drop chunked_transfer#4350
TheBlueMatt merged 2 commits into
lightningdevkit:mainfrom
Apostlex0:feat/blocks-sync-bitreq

Conversation

@Apostlex0

@Apostlex0Apostlex0 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

fixes#4325
the ldk-node tests doesn't seem to need any changes as the changes here preserve the public api, hence what happens internally doesn't really matter as all the existing tests pass without any problems.
Though changes to payment/bolt11.rs were needed to compile and run the tests.

@ldk-reviews-bot

ldk-reviews-bot commented Jan 27, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt 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.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt the ci fails due to the problem in payment/bolt11.rs in ldk-node, which is unrelated to this task, should i open a pr to fix this in ldk-node as i have made the changes locally while testing.

@tnull
tnull self-requested a review January 27, 2026 09:24

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look, had a quick first look, here are some initial remarks.

Comment threadlightning-block-sync/src/http.rs
Comment threadlightning-block-sync/Cargo.toml Outdated
rpc-client = [ "serde_json", "chunked_transfer" ]
rest-client = [ "serde_json", "bitreq" ]
rpc-client = [ "serde_json", "bitreq" ]
tokio = [ "dep:tokio", "bitreq/async" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm confused: why does tokio depend on bitreq?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

changing this to bitreq?/async this is because the rest and rpc client enables the sync mode of bitreq by default so this would enable the async mode of bitreq which uses send_async_with_client() if bitreq exists.

Comment threadlightning-block-sync/src/http.rs Outdated
/// Server for handling HTTP client requests with a stock response.
pub struct HttpServer {
address: std::net::SocketAddr,
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to allow dead code here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

it was causing a warning so i kept that before, though now I've Implemented Drop for HttpServer that will use all the fields.

@codecov

codecovBot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.73171% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.86%. Comparing base (153e57e) to head (16ea4c7).
⚠️ Report is 3 commits behind head on main.

Files with missing linesPatch %Lines
lightning-block-sync/src/convert.rs53.33%39 Missing and 3 partials ⚠️
lightning-block-sync/src/http.rs83.72%16 Missing and 5 partials ⚠️
lightning-block-sync/src/rpc.rs65.38%13 Missing and 5 partials ⚠️
lightning-block-sync/src/rest.rs81.25%0 Missing and 3 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4350 +/- ##
==========================================
- Coverage 85.90% 85.86% -0.05% 
==========================================
Files 156 156 Lines 103965 103731 -234 Branches 103965 103731 -234 ==========================================
- Hits 89316 89071 -245 - Misses 12128 12160 +32 + Partials 2521 2500 -21 
FlagCoverage Δ
tests85.86% <70.73%> (-0.05%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not convinced that any of the remaining tests in this file test anything useful now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'm unsure on what else can be tested in this, there isn't any heavy stuff that we can test here, so if you can suggest any then i'll add those.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If there's tests that aren't testing anything useful, we should remove them.

@Apostlex0
Apostlex0 requested a review from tnullJanuary 27, 2026 13:40
@joostjager
joostjager removed their request for review January 28, 2026 09:23
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@TheBlueMatt
TheBlueMatt removed the request for review from tnullJanuary 29, 2026 15:44
Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +134 to +135
.with_header("Host", host)
.with_header("Connection", "keep-alive")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Comment on lines +137 to +138
.with_max_headers_size(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))
.with_max_status_line_length(Some(MAX_HTTP_MESSAGE_HEADER_SIZE))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please let bitreq handle this

Comment threadlightning-block-sync/src/http.rs Outdated
Some(address) => address,
};

// Verify reachability by attempting a connection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you're gonna verify, please make a request

Comment threadlightning-block-sync/src/http.rs Outdated
}

/// Converts a bitreq error to an std::io::Error.
fn bitreq_to_io_error(err: bitreq::Error) -> std::io::Error {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please just change the API?

@Apostlex0Apostlex0Jan 29, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

doing that would mean that we will have to make changes in the ldk-node as well, so should i do that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, that would be much appreciated.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Got it👍

@@ -572,27 +334,54 @@ mod endpoint_tests {
#[cfg(test)]
pub(crate) mod client_tests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't addressed. Do you agree? Are there some tests you think are useful here?

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch 2 times, most recently from 83f1e7b to d274f6fCompareJanuary 31, 2026 17:01
@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

@TheBlueMatt I've removed some of the tests, if this seems ok then i can move to the ldk-node side changes.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This still has some random "make it compile"-kinda stuff. Mind going through it more carefully and making sure the API that's being exposed is consistent and makes sense?

Comment threadlightning-block-sync/src/convert.rs Outdated
match &e {
// Transport errors (connection, timeout, etc.) are transient
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Presumably a 404 or 403, for example, would, in fact, indicate a persistent issue (though a 503 might not)? Maybe 5XX should be a transient issue and anything else persistent?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

yeah that makes sense, will do that👍

Comment threadlightning-block-sync/src/convert.rs Outdated
HttpClientError::Transport(_) => BlockSourceError::transient(e),
// HTTP non-2xx errors are transient - e.g. "not found" must not stop polling
HttpClientError::Http(_) => BlockSourceError::transient(e),
// I/O errors follow the same logic as std::io::Error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then just call it?

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems this is only used for conversion errors, never io errors...

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is basically for parsing/conversion errors, so now I've changed the comments describing it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's still more here that we really shouldn't do - let bitreq handle the HTTP logic. All of it :)

Comment threadlightning-block-sync/src/http.rs Outdated
impl HttpClient {
/// Opens a connection to an HTTP endpoint.
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> std::io::Result<Self> {
pub fn connect<E: ToSocketAddrs>(endpoint: E) -> Result<Self, HttpClientError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that we no longer need to do socket resolution immediately, let's defer it and let bitreq handle it? IOW let's just accept a domain name here and use it.

Comment threadlightning-block-sync/src/http.rs Outdated
Err(HttpClientError::Io(e))
},
Err(HttpClientError::Transport(_)) => {
// Reconnect and retry on transport failures. This can happen if the connection

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

bitreq does this.

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 2de6b7b to ffa084eCompareFebruary 9, 2026 06:21

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

HttpEndpoint can be dropped too. We're converting it into a string to pass to bitreq anyway.

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

should be clean now

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM, two small comments. Please go ahead and squash down all the fixup commits, breaking the total work up logically (if possible, may not be, one commit is fine if you can't) and write a description of what changed and what decisions were made (don't use an LLM for this, they really suck at decent commit messages!), wrapping lines at ~70 chars.

Comment threadlightning-block-sync/src/http.rs Outdated
///
/// The base URL should include the scheme, host, and port (e.g., "http://127.0.0.1:8332").
/// DNS resolution is deferred until the first request is made.
pub fn new(base_url: &str) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do not take an &str only to convert it to a string, take the string.

let url = format!("{}{}", self.base_url, uri);
let request = bitreq::get(url)
.with_timeout(TCP_STREAM_RESPONSE_TIMEOUT)
.with_max_body_size(Some(MAX_HTTP_MESSAGE_BODY_SIZE));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for both this and post requests below please enable pipelining.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done👍

@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from 6f427ea to 0bfa602CompareFebruary 13, 2026 15:28
@Apostlex0

Apostlex0 commented Feb 13, 2026

Copy link
Copy Markdown
ContributorAuthor

squashed everything into one commit since separating them by files/upgrades wasn't possible since the changes were mixed up in the 10 or so commits, but the commit message should explain every change made pretty clearly.
please tell me if you feel something's off.

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oops one more, this wasn't really resolved.

Comment threadlightning-block-sync/src/http.rs Outdated
/// HTTP error response
Http(HttpError),
/// I/O error (DNS resolution, etc.)
Io(std::io::Error),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Then let's avoid wrapping the errors in std::io::Error and instead just put the error here directly? Even a &'static str probably makes more sense.

@Apostlex0

Apostlex0 commented Feb 16, 2026

Copy link
Copy Markdown
ContributorAuthor

oops one more, this wasn't really resolved.

I changed the comment regarding the io error field but kept the field itself as it is since the internal tryfroms in the convert.rs for binary and json response used io:errors everywhere, so should i just changes the error api field from io to simple `static str and keep the internal as it is, or should i change all the tryfroms as well( there are around 15 tryfroms)?

@TheBlueMatt

TheBlueMatt commented Feb 16, 2026

Copy link
Copy Markdown
Collaborator

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

@Apostlex0

Copy link
Copy Markdown
ContributorAuthor

In general we want to and up with as little code as possible, so it might be nice to change the TryFroms as well. Most of them only ever return one specific error anyway, so in those cases we could even make the error type ()

cool i'll change it to &`static str and string

we changed the http layer from the manual tcpstream client
implementation to bitreq, this change lets us rely on bitreq for
http request formatting, sockets, HTTP parsing, chunked bodies,
pooling, and async support instead of having to manually implement
them.
cargo.toml: we added bitreq 0.3 and updates the rest-client and
rpc-client feature wiring to depend on bitreq. A tokio feature is
also enabled to allow bitreq async support and pipelining.
http.rs: The old HttpEndpoint builder and all manual TCP/socket
timeout logic are dropped along with the manual GET/POST
construction and response parsing. The client API now uses base_url
and get/post return Result with a typed HttpClientError instead of
std::io::Result. HttpClientError splits transport failures
(bitreq::Error), non-2xx HTTP responses (HttpError), and response
decoding issues (std::io::Error).
rest.rs and rpc.rs: HttpEndpoint and the Mutex<Option<HttpClient>>
caching pattern are removed and both clients now own an HttpClient
directly using base_url. rpc.rs also adds RpcClientError so we can
represent HTTP failures, JSON-RPC errors from the server, and
malformed responses instead of just giving out std::io::Error.
convert.rs: it maps HttpClientError and RpcClientError into
BlockSourceError with this retry classification: transport errors
and HTTP 5xx are transient, HTTP 4xx and invalid data are
persistent, and RPC errors are treated as transient.
@Apostlex0
Apostlex0force-pushed the feat/blocks-sync-bitreq branch from fb244d2 to 16ea4c7CompareFebruary 19, 2026 14:06

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's quite a maze of error types and still quite a few tests in http.rs that are testing bitreq, rather than our own code. Still, there's no reason to keep going back and forth on this, so just gonna land it.

As a followup, if you're interested, can you clean up the error types that we've ended up with? Maybe just drop all of them in favor of always using BlockSourceError everywhere and dropping the internal Box'd std::error::Error in favor of a simple string?

}

/// Conversion from `HttpClientError` into `BlockSourceError`.
impl From<HttpClientError> for BlockSourceError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be behind a cfg(feature = rest-client)

},
None => Err(e)?,
Err(HttpClientError::Http(http_error)) => {
// Try to parse the error body as JSON-RPC response

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this fallback? I don't think it adds anything.

/// Sends a `GET` request for a resource identified by `uri`.
///
/// Returns the response body in `F` format.
#[allow(dead_code)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove this.

assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(e.get_ref().unwrap().to_string(), "unsupported transfer coding");
},
async fn connect_with_invalid_host() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a useful test?

@TheBlueMatt
TheBlueMatt merged commit 94b1c72 into lightningdevkit:mainFeb 19, 2026
20 of 21 checks passed
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Also, please do take a look at updating ldk node to use the new API!

@jkczyz

Copy link
Copy Markdown
Contributor

Also, please do take a look at updating ldk node to use the new API!

My two merged PRs sandwich this one, so I'll handle all three PRs in lightningdevkit/ldk-node#794.

Sign up for freeto 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.

Switch lightning-block-sync to bitreq

5 participants

@Apostlex0@ldk-reviews-bot@TheBlueMatt@jkczyz@tnull