From d4983ba58a654c16e63ffc91b9e0cccd97cd2682 Mon Sep 17 00:00:00 2001 From: Hugo CAILLARD <911307+hugocaillard@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:28:25 +0200 Subject: [PATCH] fix: iter an epoch to build stacks-node config --- Cargo.lock | 7 +++ Cargo.toml | 1 + src/lib.rs | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e50a27f..a93c385 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1843,6 +1843,12 @@ dependencies = [ "serde", ] +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + [[package]] name = "instant" version = "0.1.13" @@ -3515,6 +3521,7 @@ dependencies = [ "futures", "hiro-system-kit 0.1.0", "hyper 0.14.31", + "indoc", "k8s-openapi", "kube", "pretty_assertions", diff --git a/Cargo.toml b/Cargo.toml index d7923b2..a62da7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ tower = "0.5.2" strum_macros = "0.24.3" strum = "0.24.1" toml = "0.5.9" +indoc = "2.0.6" hiro-system-kit = { version = "0.1.0", features = ["log"] } clarinet-files = "3" diff --git a/src/lib.rs b/src/lib.rs index f89a7bd..06b1e83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,14 @@ -use clarinet_files::{compute_addresses, StacksNetwork}; +use std::{collections::BTreeMap, str::FromStr, time::Duration}; +use std::{env, thread::sleep}; + +use clarinet_files::{compute_addresses, DevnetConfig, StacksNetwork}; use futures::future::try_join3; use hiro_system_kit::{slog, Logger}; use hyper::{ body::{Bytes, HttpBody}, Body, Client as HttpClient, Request, Response, Uri, }; +use indoc::formatdoc; use k8s_openapi::{ api::{ apps::v1::{Deployment, StatefulSet}, @@ -25,9 +29,8 @@ use resources::{ StacksDevnetResource, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::{collections::BTreeMap, str::FromStr, time::Duration}; -use std::{env, thread::sleep}; use strum::IntoEnumIterator; +use strum_macros::EnumIter; use tower::BoxError; pub mod config; @@ -44,6 +47,28 @@ use crate::resources::configmap::StacksDevnetConfigmap; use crate::resources::pod::StacksDevnetPod; use crate::resources::service::{get_service_url, StacksDevnetService}; +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Copy, Eq, PartialOrd, Ord, EnumIter)] +pub enum EpochSpec { + #[serde(rename = "2.0")] + Epoch2_0, + #[serde(rename = "2.05")] + Epoch2_05, + #[serde(rename = "2.1")] + Epoch2_1, + #[serde(rename = "2.2")] + Epoch2_2, + #[serde(rename = "2.3")] + Epoch2_3, + #[serde(rename = "2.4")] + Epoch2_4, + #[serde(rename = "2.5")] + Epoch2_5, + #[serde(rename = "3.0")] + Epoch3_0, + #[serde(rename = "3.1")] + Epoch3_1, +} + const COMPONENT_SELECTOR: &str = "app.kubernetes.io/component"; const USER_SELECTOR: &str = "app.kubernetes.io/instance"; const NAME_SELECTOR: &str = "app.kubernetes.io/name"; @@ -103,6 +128,7 @@ struct StacksV2InfoResponse { burn_block_height: u64, stacks_tip_height: u64, } + #[derive(Clone)] pub struct StacksDevnetApiK8sManager { client: Client, @@ -1358,6 +1384,9 @@ impl StacksDevnetApiK8sManager { get_service_port(StacksDevnetService::BitcoindNode, ServicePort::P2P).unwrap() )); + let epoch_conf = build_stacks_epoch_config(devnet_config); + stacks_conf.push_str(&epoch_conf); + stacks_conf.push_str(&format!( r#" [[burnchain.epochs]] @@ -1395,6 +1424,10 @@ impl StacksDevnetApiK8sManager { [[burnchain.epochs]] epoch_name = "3.0" start_height = {} + + [[burnchain.epochs]] + epoch_name = "3.1" + start_height = {} "#, devnet_config.epoch_2_0, devnet_config.epoch_2_05, @@ -1404,6 +1437,7 @@ impl StacksDevnetApiK8sManager { devnet_config.epoch_2_4, devnet_config.epoch_2_5, devnet_config.epoch_3_0, + devnet_config.epoch_3_1, )); stacks_conf }; @@ -1713,3 +1747,97 @@ impl StacksDevnetApiK8sManager { } } } + +fn build_stacks_epoch_config(config: &DevnetConfig) -> String { + EpochSpec::iter() + .map(|epoch| { + let start_height = match epoch { + EpochSpec::Epoch2_0 => config.epoch_2_0, + EpochSpec::Epoch2_05 => config.epoch_2_05, + EpochSpec::Epoch2_1 => config.epoch_2_1, + EpochSpec::Epoch2_2 => config.epoch_2_2, + EpochSpec::Epoch2_3 => config.epoch_2_3, + EpochSpec::Epoch2_4 => config.epoch_2_4, + EpochSpec::Epoch2_5 => config.epoch_2_5, + EpochSpec::Epoch3_0 => config.epoch_3_0, + EpochSpec::Epoch3_1 => config.epoch_3_1, + }; + let epoch_toml = toml::to_string(&epoch).unwrap(); + formatdoc!( + r#" + [[burnchain.epochs]] + epoch_name = {epoch_toml} + start_height = {start_height} + "#, + ) + }) + .collect::>() + .join("\n") +} + +#[cfg(test)] +mod tests { + use indoc::indoc; + use pretty_assertions::assert_eq; + + use super::*; + + #[test] + fn test_epoch_conf() { + let devnet_config = DevnetConfig { + epoch_2_0: 0, + epoch_2_05: 1, + epoch_2_1: 2, + epoch_2_2: 3, + epoch_2_3: 4, + epoch_2_4: 5, + epoch_2_5: 6, + epoch_3_0: 7, + epoch_3_1: 8, + ..Default::default() + }; + + let epoch_config = build_stacks_epoch_config(&devnet_config); + + assert_eq!( + epoch_config.trim_end(), + indoc! { r#" + [[burnchain.epochs]] + epoch_name = "2.0" + start_height = 0 + + [[burnchain.epochs]] + epoch_name = "2.05" + start_height = 1 + + [[burnchain.epochs]] + epoch_name = "2.1" + start_height = 2 + + [[burnchain.epochs]] + epoch_name = "2.2" + start_height = 3 + + [[burnchain.epochs]] + epoch_name = "2.3" + start_height = 4 + + [[burnchain.epochs]] + epoch_name = "2.4" + start_height = 5 + + [[burnchain.epochs]] + epoch_name = "2.5" + start_height = 6 + + [[burnchain.epochs]] + epoch_name = "3.0" + start_height = 7 + + [[burnchain.epochs]] + epoch_name = "3.1" + start_height = 8"# + } + ); + } +}