-
Notifications
You must be signed in to change notification settings - Fork 766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compress the state response to reduce the state sync data transfer #5312
Comments
It's odd this data is compressible, well maybe our underlying formats needs some redesign there. We've a few places where it'd be nice if we used libtorrent or some rust rewrite. |
I'm not surprised that the data is compressible as the state response is produced by reading the state sequentially, which means many entries share the same storage prefix. |
I think the idea is good, if it works like you say. Would be really nice if you can provide some numbers for Polkadot as well. This would require a RFC, because we need to change the networking messages. |
UPD:
diff --git a/substrate/client/network/sync/src/engine.rs b/substrate/client/network/sync/src/engine.rs
index ee7576c22f1..a7ab4a92385 100644
--- a/substrate/client/network/sync/src/engine.rs
+++ b/substrate/client/network/sync/src/engine.rs
@@ -1207,11 +1212,14 @@ where
Ok(request.encode_to_vec())
}
- fn decode_state_response(response: &[u8]) -> Result<OpaqueStateResponse, String> {
+ fn decode_state_response(response: &[u8]) -> Result<(usize, usize, OpaqueStateResponse), String> {
+ let compressed_data = zstd::stream::encode_all(response, 0).expect("Failed to compress state response");
+ let compressed_size = compressed_data.len();
+ let uncompressed_size = response.len();
let response = StateResponse::decode(response)
.map_err(|error| format!("Failed to decode state response: {error}"))?;
- Ok(OpaqueStateResponse(Box::new(response)))
+ Ok((compressed_size, uncompressed_size, OpaqueStateResponse(Box::new(response))))
} |
Opened RFC polkadot-fellows/RFCs#112 |
Is there an existing issue?
Experiencing problems? Have you tried our Stack Exchange first?
Motivation
The state syncing could download several GiB of data if the state size of the chain is huge, which is not uncommon nowadays.
This poses a significant challenge for nodes with slow network connections. Additionally, since state sync currently lacks a persistence feature (#4), any network disruption forces the node to re-download the entire state, which is annoying.
Request
Reduce the state syncing download size.
Solution
Compress the state response before sending it to the node and uncompress the state response on the receiver side.
This is a low-hanging fruit that can reduce the state sync data significantly as demonstrated by my local experiments. I conducted state sync tests at various block heights (before height 300000) using both the
fast
andfast-unsafe
modes for subcoin, the Uncompressed Total State Sync Data is calculated assum(data.len())
, the Compressed Total State Sync Data is calculated assum(compressed_data.len())
. The results are promising, indicating that several GiB of state sync data can be saved, especially when dealing with large chain states. The final state size of subcoin may be 12+GiB, this optimization will greatly help the state sync of subcoin.--sync
We can make this configurable if necessary.
Are you willing to help with this request?
Yes!
The text was updated successfully, but these errors were encountered: