Skip to content

Commit b014242

Browse files
committed
Bump retries and timeouts considerably
As LDK currently will still panic and crash if we'd ever fail a `write` operation, we here considerably bump the defaults set in `VssClient` to at least make this less likely. Longer term, we still hope to mitigate the issue by moving to the async-persist flow.
1 parent 2a7b980 commit b014242

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ serde_json = { version = "1.0.128", default-features = false, features = ["std"]
6666
log = { version = "0.4.22", default-features = false, features = ["std"]}
6767

6868
#vss-client-ng = "0.3"
69-
vss-client-ng = { git = "https://github.com/tnull/vss-client", rev = "e6d8e57a949bff3cf511aef258b7aa2c681e35c9" }
69+
vss-client-ng = { git = "https://github.com/tnull/vss-client", rev = "7cf661b4ba45983ecad0f59e6d74050e2c84212f" }
7070
prost = { version = "0.11.6", default-features = false}
7171

7272
[target.'cfg(windows)'.dependencies]

src/io/vss_store.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ use crate::io::utils::check_namespace_key_validity;
3535
// would hit a blocking case
3636
const INTERNAL_RUNTIME_WORKERS: usize = 2;
3737

38+
const HTTP_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
39+
const HTTP_RETRIES: u32 = 10;
40+
3841
/// A [`KVStoreSync`] implementation that writes to and reads from a [VSS](https://github.com/lightningdevkit/vss-server/blob/main/README.md) backend.
3942
pub struct VssStore {
4043
inner: Arc<VssStoreInner>,
@@ -284,10 +287,11 @@ impl VssStoreInner {
284287
let (data_encryption_key, obfuscation_master_key) =
285288
derive_data_encryption_and_obfuscation_keys(&vss_seed);
286289
let key_obfuscator = KeyObfuscator::new(obfuscation_master_key);
287-
let client = VssClient::new_with_headers(base_url, header_provider).map_err(|e| {
288-
let msg = format!("Failed to setup VssClient: {}", e);
290+
let reqwest_client = build_client(&base_url).map_err(|_| {
291+
let msg = format!("Failed to setup HTTP client: invalid URL");
289292
Error::new(ErrorKind::Other, msg)
290293
})?;
294+
let client = VssClient::from_client_and_headers(base_url, reqwest_client, header_provider);
291295
let locks = Mutex::new(HashMap::new());
292296
Ok(Self { client, store_id, data_encryption_key, key_obfuscator, locks })
293297
}
@@ -524,6 +528,32 @@ impl VssStoreInner {
524528
}
525529
}
526530

531+
fn build_client(base_url: &str) -> Result<reqwest::Client, ()> {
532+
let url = reqwest::Url::parse(base_url).map_err(|_| ())?;
533+
let host_str = url.host_str().ok_or(())?.to_string();
534+
let retry = reqwest::retry::for_host(host_str)
535+
.max_retries_per_request(HTTP_RETRIES)
536+
.classify_fn(|req_rep| match req_rep.status() {
537+
// VSS uses INTERNAL_SERVER_ERROR when sending back error repsonses. These are
538+
// currently still covered by our `RetryPolicy`, so we tell `reqwest` not to retry them.
539+
Some(reqwest::StatusCode::INTERNAL_SERVER_ERROR) => req_rep.success(),
540+
Some(reqwest::StatusCode::BAD_REQUEST) => req_rep.success(),
541+
Some(reqwest::StatusCode::UNAUTHORIZED) => req_rep.success(),
542+
Some(reqwest::StatusCode::NOT_FOUND) => req_rep.success(),
543+
Some(reqwest::StatusCode::CONFLICT) => req_rep.success(),
544+
Some(reqwest::StatusCode::OK) => req_rep.success(),
545+
_ => req_rep.retryable(),
546+
});
547+
let client = reqwest::Client::builder()
548+
.timeout(HTTP_TIMEOUT)
549+
.connect_timeout(HTTP_TIMEOUT)
550+
.read_timeout(HTTP_TIMEOUT)
551+
.retry(retry)
552+
.build()
553+
.unwrap();
554+
Ok(client)
555+
}
556+
527557
fn derive_data_encryption_and_obfuscation_keys(vss_seed: &[u8; 32]) -> ([u8; 32], [u8; 32]) {
528558
let hkdf = |initial_key_material: &[u8], salt: &[u8]| -> [u8; 32] {
529559
let mut engine = HmacEngine::<sha256::Hash>::new(salt);

0 commit comments

Comments
 (0)