Skip to content

Commit 0bfa602

Browse files
committed
changes: switch to bitreq from chunked_transfer
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.
1 parent 0b45bfd commit 0bfa602

File tree

5 files changed

+345
-762
lines changed

5 files changed

+345
-762
lines changed

lightning-block-sync/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ all-features = true
1616
rustdoc-args = ["--cfg", "docsrs"]
1717

1818
[features]
19-
rest-client = [ "serde_json", "chunked_transfer" ]
20-
rpc-client = [ "serde_json", "chunked_transfer" ]
19+
rest-client = [ "serde_json", "dep:bitreq" ]
20+
rpc-client = [ "serde_json", "dep:bitreq" ]
21+
tokio = [ "dep:tokio", "bitreq?/async" ]
2122

2223
[dependencies]
2324
bitcoin = "0.32.2"
2425
lightning = { version = "0.3.0", path = "../lightning" }
2526
tokio = { version = "1.35", features = [ "io-util", "net", "time", "rt" ], optional = true }
2627
serde_json = { version = "1.0", optional = true }
27-
chunked_transfer = { version = "1.4", optional = true }
28+
bitreq = { version = "0.3", default-features = false, features = ["std"], optional = true }
2829

2930
[dev-dependencies]
3031
lightning = { version = "0.3.0", path = "../lightning", features = ["_test_utils"] }

lightning-block-sync/src/convert.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::http::{BinaryResponse, JsonResponse};
1+
use crate::http::{BinaryResponse, HttpClientError, JsonResponse};
2+
#[cfg(feature = "rpc-client")]
3+
use crate::rpc::RpcClientError;
24
use crate::utils::hex_to_work;
35
use crate::{BlockHeaderData, BlockSourceError};
46

@@ -35,6 +37,64 @@ impl From<io::Error> for BlockSourceError {
3537
}
3638
}
3739

40+
/// Conversion from `HttpClientError` into `BlockSourceError`.
41+
impl From<HttpClientError> for BlockSourceError {
42+
fn from(e: HttpClientError) -> BlockSourceError {
43+
match e {
44+
// Transport errors (connection, timeout, etc.) are transient
45+
HttpClientError::Transport(err) => {
46+
BlockSourceError::transient(HttpClientError::Transport(err))
47+
},
48+
// 5xx errors are transient (server issues), others are persistent (client errors)
49+
HttpClientError::Http(http_err) => {
50+
if (500..600).contains(&http_err.status_code) {
51+
BlockSourceError::transient(HttpClientError::Http(http_err))
52+
} else {
53+
BlockSourceError::persistent(HttpClientError::Http(http_err))
54+
}
55+
},
56+
// Delegate to existing From<io::Error> implementation
57+
HttpClientError::Io(io_err) => BlockSourceError::from(io_err),
58+
}
59+
}
60+
}
61+
62+
/// Conversion from `RpcClientError` into `BlockSourceError`.
63+
#[cfg(feature = "rpc-client")]
64+
impl From<RpcClientError> for BlockSourceError {
65+
fn from(e: RpcClientError) -> BlockSourceError {
66+
match e {
67+
RpcClientError::Http(http_err) => match http_err {
68+
// Transport errors (connection, timeout, etc.) are transient
69+
HttpClientError::Transport(err) => BlockSourceError::transient(
70+
RpcClientError::Http(HttpClientError::Transport(err)),
71+
),
72+
// 5xx errors are transient (server issues), others are persistent (client errors)
73+
HttpClientError::Http(http) => {
74+
if (500..600).contains(&http.status_code) {
75+
BlockSourceError::transient(RpcClientError::Http(HttpClientError::Http(
76+
http,
77+
)))
78+
} else {
79+
BlockSourceError::persistent(RpcClientError::Http(HttpClientError::Http(
80+
http,
81+
)))
82+
}
83+
},
84+
HttpClientError::Io(io_err) => BlockSourceError::from(io_err),
85+
},
86+
// RPC errors (e.g. "block not found") are transient
87+
RpcClientError::Rpc(rpc_err) => {
88+
BlockSourceError::transient(RpcClientError::Rpc(rpc_err))
89+
},
90+
// Malformed response data is persistent
91+
RpcClientError::InvalidData(msg) => {
92+
BlockSourceError::persistent(RpcClientError::InvalidData(msg))
93+
},
94+
}
95+
}
96+
}
97+
3898
/// Parses binary data as a block.
3999
impl TryInto<Block> for BinaryResponse {
40100
type Error = io::Error;

0 commit comments

Comments
 (0)