Skip to content

Instantly share code, notes, and snippets.

@rikonor
Created May 30, 2024 16:05
Show Gist options
  • Save rikonor/fb72c7318260b5b4c473464fa59ed1ad to your computer and use it in GitHub Desktop.
Save rikonor/fb72c7318260b5b4c473464fa59ed1ad to your computer and use it in GitHub Desktop.
Convert registry snapshot to registry init payload

Usage

REGISTRY_PATH='path/to/registry.proto'
OUTPUT_PATH='path/to/init.bin'

cargo run -- \
    --registry ${REGISTRY_PATH} \
    --out ${OUTPUT_PATH}

Convert to base64 (for dfx)

cat init.bin | xxd -p | tr -d '\n'

Inspect with didc

cat init.bin | xxd -p | tr -d '\n' | didc decode
[package]
name = "tmp"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.86"
clap = { version = "4.5.4", features = ["derive"] }
tokio = { version = "1.37.0", features = ["full"] }
ic-registry-transport = { git = "https://github.com/dfinity/ic.git", rev = "88f5d225b7e02ae46315e416cb87d853f7e75a14" }
ic-registry-proto-data-provider = { git = "https://github.com/dfinity/ic.git", rev = "88f5d225b7e02ae46315e416cb87d853f7e75a14" }
ic-interfaces-registry = { git = "https://github.com/dfinity/ic.git", rev = "88f5d225b7e02ae46315e416cb87d853f7e75a14" }
candid = "0.10.8"
serde = { version = "1.0.203", features = ["derive"] }
use std::{
fs,
io::{stdout, Write},
path::PathBuf,
};
use anyhow::{Context, Error};
use candid::{CandidType, Deserialize, Encode};
use clap::Parser;
use ic_interfaces_registry::{
RegistryDataProvider, RegistryValue, RegistryVersionedRecord, ZERO_REGISTRY_VERSION,
};
use ic_registry_proto_data_provider::ProtoRegistryDataProvider;
use ic_registry_transport::pb::v1::{
registry_mutation::Type, RegistryAtomicMutateRequest, RegistryMutation,
};
#[derive(Debug, Parser)]
struct Cli {
/// Path to Protobuf registry file (e.g registry.proto)
#[clap(long)]
registry: PathBuf,
/// Optional path to output init arg blob
#[clap(long)]
out: Option<PathBuf>,
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let cli = Cli::parse();
let r = ProtoRegistryDataProvider::load_from_file(cli.registry);
let us = r
.get_updates_since(ZERO_REGISTRY_VERSION)
.context("failed to obtain registry updates")?;
let ms = us
.into_iter()
.filter(|u| u.is_some())
.map(record_to_mutation)
.collect::<Vec<RegistryMutation>>();
if ms.is_empty() {
panic!("empty registry");
}
let mreq = RegistryAtomicMutateRequest {
mutations: ms,
..Default::default()
};
let p = Payload {
mutations: vec![mreq],
};
let out = Encode!(&p).context("failed to encode payload")?;
if let Some(path) = cli.out {
fs::write(path, out).context("failed to write output to file")?;
return Ok(());
}
stdout()
.write_all(&out)
.context("failed to write output to stdout")?;
Ok(())
}
#[derive(CandidType, Deserialize)]
struct Payload {
mutations: Vec<RegistryAtomicMutateRequest>,
}
fn record_to_mutation(r: RegistryVersionedRecord<Vec<u8>>) -> RegistryMutation {
let mut m = RegistryMutation::default();
m.set_mutation_type(Type::Insert);
m.key = r.key.encode_to_vec();
m.value = r.value.expect("missing value");
m
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment