diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..69878d9 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,89 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "generate-readme" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..6c7a40f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "generate-readme" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +serde_json = { version = "1.0.106", default-features = false, features = ["alloc"] } + +[[bin]] +name = "generate-readme" +path = "generate_readme.rs" diff --git a/TEMPLATE.md b/TEMPLATE.md new file mode 100644 index 0000000..041aea7 --- /dev/null +++ b/TEMPLATE.md @@ -0,0 +1,45 @@ +

+

starknet-snapshots

+

+ +**Starknet full node snapshots maintained by the [zkLend](https://zklend.com) team** + +## Downloading the snapshots + +There are several ways to download the snapshots. You're recommended to use S3-compatible clients (e.g. `rclone`). It's also possible to just use a plain `curl` command, but it seems to be prone to failures based on reports from users. + +### Rclone + +Download and install [Rclone](https://rclone.org/). Then, add this section to your config file, typically located at `$HOME/.config/rclone/rclone.conf` (you may need to create the file on a fresh install): + +```conf +[zklend-pathfinder-backup] +type = s3 +provider = Cloudflare +region = auto +endpoint = https://pathfinder-backup.zklend.com/ +``` + +Then, download a snapshot to the current directory with: + +```console +rclone copy -P zklend-pathfinder-backup:EXAMPLE_NETWORK/EXAMPLE_FILE_NAME . +``` + +### `curl` + +Downloading with `curl` is not recommended but possible: + +```console +curl -OL "https://pathfinder-backup.zklend.com/EXAMPLE_NETWORK/EXAMPLE_FILE_NAME" +``` + +## Using the snapshots + +Simply decompress and extract the file downloaded with `tar`: + +```console +tar Jxvf ./EXAMPLE_FILE_NAME +``` + +LIST_OF_SNAPSHOTS diff --git a/generate_readme.rs b/generate_readme.rs new file mode 100644 index 0000000..f2677b0 --- /dev/null +++ b/generate_readme.rs @@ -0,0 +1,138 @@ +use std::{ + fmt::{Display, Formatter, Write as FmtWrite}, + io::Write, +}; + +use serde::Deserialize; + +const JSON: &str = include_str!("./snapshots.json"); +const TEMPLATE: &str = include_str!("./TEMPLATE.md"); + +#[derive(Deserialize)] +struct Node { + node: NodeType, + networks: Vec, +} + +#[derive(Deserialize)] +#[serde(rename_all = "snake_case")] +enum NodeType { + Pathfinder, +} + +#[derive(Deserialize)] +struct Network { + network: NetworkType, + snapshots: Vec, +} + +#[derive(Deserialize)] +enum NetworkType { + #[serde(rename = "mainnet")] + Mainnet, + #[serde(rename = "goerli-1")] + Goerli1, + #[serde(rename = "goerli-2")] + Goerli2, +} + +#[derive(Deserialize)] +struct Snapshot { + block: u64, + version: String, +} + +impl NodeType { + fn downloand_link_base(&self) -> &str { + match self { + Self::Pathfinder => "https://pathfinder-backup.zklend.com/", + } + } +} + +impl Snapshot { + fn file_name(&self, network: &NetworkType) -> String { + format!("{}-v{}-{}.tar.xz", network, self.version, self.block) + } +} + +impl Display for NodeType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Pathfinder => write!(f, "pathfinder"), + } + } +} + +impl Display for NetworkType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Mainnet => write!(f, "mainnet"), + Self::Goerli1 => write!(f, "goerli-1"), + Self::Goerli2 => write!(f, "goerli-2"), + } + } +} + +fn main() { + let nodes: Vec = serde_json::from_str(JSON).expect("unable to deserialize JSON"); + + let mut snapshot_list = String::new(); + + let mut example_network: Option = None; + let mut example_file_name: Option = None; + + for node in nodes.iter() { + writeln!(snapshot_list, "## `{}`", node.node).unwrap(); + + for network in node.networks.iter() { + writeln!(snapshot_list).unwrap(); + writeln!(snapshot_list, "### `{}`", network.network).unwrap(); + writeln!(snapshot_list).unwrap(); + + writeln!( + snapshot_list, + "| Network | Version | Block | Download Link |" + ) + .unwrap(); + writeln!(snapshot_list, "| - | - | - | - |").unwrap(); + + for snapshot in network.snapshots.iter() { + let network_name = format!("{}", network.network); + let file_name = snapshot.file_name(&network.network); + + if example_network.is_none() { + example_network = Some(network_name.clone()); + } + if example_file_name.is_none() { + example_file_name = Some(file_name.clone()); + } + + writeln!( + snapshot_list, + "| `{}` | `v{}` | `{}` | {}{}/{} |", + network_name, + snapshot.version, + snapshot.block, + node.node.downloand_link_base(), + network_name, + file_name + ) + .unwrap(); + } + } + } + + let example_network = example_network.expect("no example network generated"); + let example_file_name = example_file_name.expect("no example file name generated"); + + let full_readme = TEMPLATE + .replace("EXAMPLE_NETWORK", &example_network) + .replace("EXAMPLE_FILE_NAME", &example_file_name) + .replace("LIST_OF_SNAPSHOTS", &snapshot_list); + + let mut file = std::fs::File::create("./README.md").expect("unable to create file"); + + file.write_all(full_readme.as_bytes()) + .expect("unable to write to file"); +} diff --git a/snapshots.json b/snapshots.json new file mode 100644 index 0000000..a3741c8 --- /dev/null +++ b/snapshots.json @@ -0,0 +1,46 @@ +[ + { + "node": "pathfinder", + "networks": [ + { + "network": "mainnet", + "snapshots": [ + { + "block": 213169, + "version": "0.8.1" + }, + { + "block": 141083, + "version": "0.7.0" + } + ] + }, + { + "network": "goerli-1", + "snapshots": [ + { + "block": 860674, + "version": "0.8.1" + }, + { + "block": 841817, + "version": "0.7.0" + } + ] + }, + { + "network": "goerli-2", + "snapshots": [ + { + "block": 141801, + "version": "0.8.1" + }, + { + "block": 136651, + "version": "0.7.0" + } + ] + } + ] + } +]