From 5aed2a22c0ac3936cf6726c42c04ac4f6537b4c9 Mon Sep 17 00:00:00 2001 From: umr1352 Date: Thu, 7 Aug 2025 15:44:33 +0200 Subject: [PATCH] automatic package history with build.rs --- identity_iota_core/Cargo.toml | 7 +- identity_iota_core/build.rs | 129 ++++++++++++++++++ identity_iota_core/src/rebased/iota/mod.rs | 1 + .../src/rebased/iota/package.rs | 38 +----- .../src/rebased/iota/package_registry.rs | 66 +++++++++ 5 files changed, 203 insertions(+), 38 deletions(-) create mode 100644 identity_iota_core/build.rs create mode 100644 identity_iota_core/src/rebased/iota/package_registry.rs diff --git a/identity_iota_core/Cargo.toml b/identity_iota_core/Cargo.toml index 3eb9c4044..b79e3ef80 100644 --- a/identity_iota_core/Cargo.toml +++ b/identity_iota_core/Cargo.toml @@ -43,7 +43,6 @@ phf = { version = "0.11.2", features = ["macros"] } rand = { version = "0.8.5", optional = true } secret-storage = { git = "https://github.com/iotaledger/secret-storage.git", tag = "v0.3.0", default-features = false, optional = true } serde-aux = { version = "4.5.0", optional = true } -toml = "0.8.22" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] iota-config = { git = "https://github.com/iotaledger/iota.git", package = "iota-config", tag = "v1.2.3", optional = true } @@ -128,3 +127,9 @@ keytool = [ [lints] workspace = true + +[build-dependencies] +anyhow = "1.0.75" +serde.workspace = true +serde_json = { workspace = true, features = ["std"] } +toml = "0.8.22" diff --git a/identity_iota_core/build.rs b/identity_iota_core/build.rs new file mode 100644 index 000000000..cd97f4446 --- /dev/null +++ b/identity_iota_core/build.rs @@ -0,0 +1,129 @@ +use anyhow::Context; +use serde::Deserialize; +use serde::Serialize; + +const PACKAGE_REGISTRY_FILE: &str = "src/rebased/iota/package_registry.rs"; +const MOVE_LOCK_PATH: &str = "packages/iota_identity/Move.lock"; + +#[derive(Debug, Serialize, Deserialize)] +struct Env { + id: String, + alias: String, + packages: Vec, +} + +fn read_history() -> anyhow::Result<[Env; 3]> { + let registy_src_content = std::fs::read_to_string(PACKAGE_REGISTRY_FILE)?; + let registry_json_str = { + let start_of_comment = registy_src_content + .find("/*") + .context("cannot find start of comment containing JSON history")?; + let end_of_comment = registy_src_content + .find("*/") + .context("cannot find end of coment containing JSON history")?; + // The part of the source file inside /* */ + let comment_section = ®isty_src_content[start_of_comment + 2..end_of_comment]; + comment_section.trim_ascii() + }; + + serde_json::from_str(registry_json_str).context("failed to parse JSON history") +} + +fn read_lock_file() -> anyhow::Result<[String; 3]> { + let lock_table = { + let lock_file_content = std::fs::read_to_string(MOVE_LOCK_PATH)?; + lock_file_content.parse::()? + }; + + let env_table = lock_table + .get("env") + .and_then(toml::Value::as_table) + .context("malformed Move.lock: missing or malformed `env` table")?; + + let mut latest_packages: [String; 3] = Default::default(); + for (i, network) in ["mainnet", "testnet", "devnet"].into_iter().enumerate() { + latest_packages[i] = env_table + .get(network) + .and_then(toml::Value::as_table) + .and_then(|table| table.get("latest-published-id")) + .and_then(toml::Value::as_str) + .context(format!( + "malformed Move.lock: failed to read property `latest-published-id` of table `env.{network}`" + ))? + .to_owned(); + } + + Ok(latest_packages) +} + +fn write_history(history: [Env; 3]) -> anyhow::Result<()> { + use std::io::Write as _; + + let mut history_file = std::fs::File::create(PACKAGE_REGISTRY_FILE)?; + writeln!(&mut history_file, "// Copyright 2020-2025 IOTA Stiftung")?; + writeln!(&mut history_file, "// SPDX-License-Identifier: Apache-2.0\n")?; + + writeln!(&mut history_file, "/*\n{}\n*/", serde_json::to_string_pretty(&history)?)?; + + writeln!( + &mut history_file, + " +use iota_interaction::types::base_types::ObjectID; +use std::sync::LazyLock; +use tokio::sync::RwLock; + +use super::package::Env; +use super::package::PackageRegistry; + +#[rustfmt::skip] +pub(crate) static IOTA_IDENTITY_PACKAGE_REGISTRY: LazyLock> = LazyLock::new(|| {{ + RwLock::new({{ + let mut registry = PackageRegistry::default();" + )?; + for env in history { + writeln!( + &mut history_file, + " + registry.insert_env( + Env::new_with_alias(\"{}\", \"{}\"), + vec![", + env.id, env.alias + )?; + for pkg in env.packages { + writeln!( + &mut history_file, + " ObjectID::from_hex_literal(\"{}\").unwrap(),", + pkg + )?; + } + write!(&mut history_file, " ],\n );")?; + } + writeln!( + &mut history_file, + " + registry + }}) +}});" + )?; + + Ok(()) +} + +fn main() -> anyhow::Result<()> { + let mut history = read_history()?; + let latest = read_lock_file()?; + + for (latest_id, history) in latest.iter().zip(history.iter_mut()) { + if history.packages.last().unwrap() == latest_id { + continue; + } + + history.packages.push(latest_id.clone()); + } + + write_history(history)?; + + println!("cargo::rerun-if-changed=packages/iota_identity/Move.lock"); + + Ok(()) +} diff --git a/identity_iota_core/src/rebased/iota/mod.rs b/identity_iota_core/src/rebased/iota/mod.rs index 6a471c9b4..82a5249f7 100644 --- a/identity_iota_core/src/rebased/iota/mod.rs +++ b/identity_iota_core/src/rebased/iota/mod.rs @@ -3,4 +3,5 @@ pub(crate) mod move_calls; pub(crate) mod package; +mod package_registry; pub(crate) mod types; diff --git a/identity_iota_core/src/rebased/iota/package.rs b/identity_iota_core/src/rebased/iota/package.rs index f0828e9ea..4e70ae5cf 100644 --- a/identity_iota_core/src/rebased/iota/package.rs +++ b/identity_iota_core/src/rebased/iota/package.rs @@ -4,54 +4,18 @@ #![allow(dead_code)] use std::collections::HashMap; -use std::sync::LazyLock; use iota_interaction::types::base_types::ObjectID; use product_common::core_client::CoreClientReadOnly; use serde::Deserialize; use serde::Serialize; -use tokio::sync::RwLock; use tokio::sync::RwLockReadGuard; use tokio::sync::RwLockWriteGuard; use crate::rebased::Error; -macro_rules! object_id { - ($id:literal) => { - ObjectID::from_hex_literal($id).unwrap() - }; -} +pub(crate) use super::package_registry::IOTA_IDENTITY_PACKAGE_REGISTRY; -static IOTA_IDENTITY_PACKAGE_REGISTRY: LazyLock> = LazyLock::new(|| { - RwLock::new({ - let mut registry = PackageRegistry::default(); - // Add well-known networks. - registry.insert_env( - Env::new_with_alias("6364aad5", "iota"), - vec![object_id!( - "0x84cf5d12de2f9731a89bb519bc0c982a941b319a33abefdd5ed2054ad931de08" - )], - ); - registry.insert_env( - Env::new_with_alias("2304aa97", "testnet"), - vec![ - object_id!("0x222741bbdff74b42df48a7b4733185e9b24becb8ccfbafe8eac864ab4e4cc555"), - object_id!("0x3403da7ec4cd2ff9bdf6f34c0b8df5a2bd62c798089feb0d2ebf1c2e953296dc"), - ], - ); - registry.insert_env( - Env::new_with_alias("e678123a", "devnet"), - vec![ - object_id!("0xe6fa03d273131066036f1d2d4c3d919b9abbca93910769f26a924c7a01811103"), - object_id!("0x6a976d3da90db5d27f8a0c13b3268a37e582b455cfc7bf72d6461f6e8f668823"), - ], - ); - - registry - }) -}); - -/// Network / Chain information. #[derive(Debug, Clone, Deserialize, Serialize)] pub(crate) struct Env { pub chain_id: String, diff --git a/identity_iota_core/src/rebased/iota/package_registry.rs b/identity_iota_core/src/rebased/iota/package_registry.rs new file mode 100644 index 000000000..db3b4bb44 --- /dev/null +++ b/identity_iota_core/src/rebased/iota/package_registry.rs @@ -0,0 +1,66 @@ +// Copyright 2020-2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/* +[ + { + "id": "6364aad5", + "alias": "iota", + "packages": [ + "0x84cf5d12de2f9731a89bb519bc0c982a941b319a33abefdd5ed2054ad931de08" + ] + }, + { + "id": "2304aa97", + "alias": "testnet", + "packages": [ + "0x222741bbdff74b42df48a7b4733185e9b24becb8ccfbafe8eac864ab4e4cc555", + "0x3403da7ec4cd2ff9bdf6f34c0b8df5a2bd62c798089feb0d2ebf1c2e953296dc" + ] + }, + { + "id": "e678123a", + "alias": "devnet", + "packages": [ + "0xe6fa03d273131066036f1d2d4c3d919b9abbca93910769f26a924c7a01811103", + "0x6a976d3da90db5d27f8a0c13b3268a37e582b455cfc7bf72d6461f6e8f668823" + ] + } +] +*/ + +use iota_interaction::types::base_types::ObjectID; +use std::sync::LazyLock; +use tokio::sync::RwLock; + +use super::package::Env; +use super::package::PackageRegistry; + +#[rustfmt::skip] +pub(crate) static IOTA_IDENTITY_PACKAGE_REGISTRY: LazyLock> = LazyLock::new(|| { + RwLock::new({ + let mut registry = PackageRegistry::default(); + + registry.insert_env( + Env::new_with_alias("6364aad5", "iota"), + vec![ + ObjectID::from_hex_literal("0x84cf5d12de2f9731a89bb519bc0c982a941b319a33abefdd5ed2054ad931de08").unwrap(), + ], + ); + registry.insert_env( + Env::new_with_alias("2304aa97", "testnet"), + vec![ + ObjectID::from_hex_literal("0x222741bbdff74b42df48a7b4733185e9b24becb8ccfbafe8eac864ab4e4cc555").unwrap(), + ObjectID::from_hex_literal("0x3403da7ec4cd2ff9bdf6f34c0b8df5a2bd62c798089feb0d2ebf1c2e953296dc").unwrap(), + ], + ); + registry.insert_env( + Env::new_with_alias("e678123a", "devnet"), + vec![ + ObjectID::from_hex_literal("0xe6fa03d273131066036f1d2d4c3d919b9abbca93910769f26a924c7a01811103").unwrap(), + ObjectID::from_hex_literal("0x6a976d3da90db5d27f8a0c13b3268a37e582b455cfc7bf72d6461f6e8f668823").unwrap(), + ], + ); + registry + }) +});