REGISTRY_PATH='path/to/registry.proto'
OUTPUT_PATH='path/to/init.bin'
cargo run -- \
--registry ${REGISTRY_PATH} \
--out ${OUTPUT_PATH}
cat init.bin | xxd -p | tr -d '\n'
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 | |
} |