snapshot api added#545
Conversation
| &self, | ||
| out_path: impl AsRef<Path>, | ||
| ) -> Result<NodeSnapshot, anyhow::Error> { | ||
| let out_path = out_path.as_ref().to_path_buf(); |
There was a problem hiding this comment.
This logic should be in the native provider and use inner from here to call it. We can let k8s/docker as unimplemented for now (but is also possible to implement).
Thx!
| } | ||
| } | ||
|
|
||
| fn build_bundle( |
There was a problem hiding this comment.
Just nit, since we provide a nice way to generate the bundle maybe we can also include the untar_bundle fn here to not allow users to use it directly and not need to re-implement.
wdyt?
|
Awesome job @michalkucharczyk !! I added a couple of comments, if you are agree I can make those changes and also wire your test to run in CI. Thx! |
Yes, feel free to take it from here. But I can also implement your requests. Whatever works for you :) |
| )); | ||
| } | ||
|
|
||
| let bytes = tokio::fs::read(&out_path) |
There was a problem hiding this comment.
We should not read t he entire file here and hash it, but do this iteratively to save some memory.
|
ping @michalkucharczyk, I applied the changes and wire the test to run in ci. If you are ok, I will merge it and draft a new release. |
| )); | ||
| } | ||
|
|
||
| let mut file = File::open(&out_path).unwrap(); |
There was a problem hiding this comment.
| let mut file = File::open(&out_path).unwrap(); | |
| let mut file = File::open(&out_path).map_err(|err| ProviderError::SnapshotDb(self.name().into(), anyhow!(err)))?; |
There was a problem hiding this comment.
ahh, let me remove the unwrap 🤦♂️
| let bytes = std::fs::read(&out_path) | ||
| .with_context(|| format!("reading produced bundle {}", out_path.display()))?; | ||
| let size = bytes.len() as u64; | ||
| let sha256 = hex::encode(sha2::Sha256::digest(&bytes)); |
There was a problem hiding this comment.
stream could be used here too (not reading entire file to memory).
There was a problem hiding this comment.
yes, I will apply the same logic that in the node
| Ok(()) | ||
| } | ||
|
|
||
| fn untar_bundle(bundle_path: &Path, out_dir: &Path) -> anyhow::Result<()> { |
There was a problem hiding this comment.
nit: maybe this could be used in tests?
There was a problem hiding this comment.
You mean moving to the snapshot module?
|
Nit: maybe we could keep |
| size, | ||
| } = self.inner.snapshot_db(is_cumulus_based).await?; | ||
|
|
||
| // now we need to _move_ the inner file to the out_path |
There was a problem hiding this comment.
nit: It acutally copies the file. Maybe this could be avoided by tzg'ing the file to the destination location? Or moving instead copying?
There was a problem hiding this comment.
Yes, could be an optimization for native but the idea here is that this method can be used in all the supported providers, so in docker/k8s we need to get the file from the pod.
Thx!
Implementation of proposal from #541 (also #542).
Tests that build DB snapshot artifacts (cumulus
full_node_warp_sync, smoldotsmoke/bulletin) each hand-roll the same pause → tar → checksum → bundle dance. This moves it into the SDK.What's new
NetworkNode::snapshot_db(out_path)— tars a node's DB into a.tgz(data/, plusrelay-data/for cumulus collators). Dropskeystore/andnetwork/so the archive can be loaded on several sibling nodes without key/peer-id clashes.Network::pause()/resume()— SIGSTOP/SIGCONT all nodes in parallel, so the DB on disk is consistent while you snapshot.snapshot::BundleBuilder— packs per-node archives + a JSONuser_datablob into onebundle.tar.gzwith amanifest.json(sha256 + size per archive).build()won't compile until you've added at least one archive.with_optional_default_db_snapshot(Option<…>)on the relay/parachain builders (andwith_optional_db_snapshotper node) — so one network builder works for both the fresh and the from-snapshot case without branching.Example
Tests
crates/sdk/src/snapshot.rs: bundle build → unpack → manifest round-trip (no network, runs in CI).crates/configuration: tests for the threewith_optional_*db_snapshotmethods.crates/sdk/tests/snapshot_roundtrip.rs(#[ignore], needs polkadot binaries): snapshot a live network, bundle it, re-spawn from the snapshot, and check both chains advance and finalize past the snapshot height.Notes
snapshot_dbreads the node's local base dir, so it's native-provider only.terminate()(instead ofpause) before snapshotting is left for a follow-up.SIGSTOPallows for safe db copy. So far it worked well.