Skip to content

Commit

Permalink
feat(jstzd): spawn rollup in jstzd server
Browse files Browse the repository at this point in the history
  • Loading branch information
ryutamago committed Dec 4, 2024
1 parent fcc31a2 commit cff28d2
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 57 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ fmt-check: fmt-nix-check fmt-rust-check fmt-js-check

.PHONY: lint
lint:
@touch $(CLI_KERNEL_PATH) $(JSTZD_KERNEL_PATH)
@touch $(CLI_KERNEL_PATH)
# Jstzd has to processes a non-empty kernel in its build script
@echo "ignore" > $(JSTZD_KERNEL_PATH)
@cargo clippy --all-targets -- --deny warnings
@rm -f $(CLI_KERNEL_PATH) $(JSTZD_KERNEL_PATH)
3 changes: 2 additions & 1 deletion crates/jstzd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ reqwest.workspace = true
serde.workspace = true
serde_json.workspace = true
tempfile.workspace = true
tezos_crypto_rs.workspace = true
tokio.workspace = true

[build-dependencies]
anyhow.workspace = true
bincode.workspace = true
hex.workspace = true
tempfile.workspace = true
tezos_crypto_rs.workspace = true
tezos_crypto_rs.workspace = true
tezos-smart-rollup-host.workspace = true
tezos-smart-rollup-installer.workspace = true
tezos-smart-rollup-installer-config.workspace = true
Expand Down
20 changes: 19 additions & 1 deletion crates/jstzd/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::path::{Path, PathBuf};

use crate::task::jstzd::JstzdConfig;
use crate::{EXCHANGER_ADDRESS, JSTZ_NATIVE_BRIDGE_ADDRESS};
use crate::{EXCHANGER_ADDRESS, JSTZ_NATIVE_BRIDGE_ADDRESS, JSTZ_ROLLUP_ADDRESS};
use anyhow::{Context, Result};
use octez::r#async::endpoint::Endpoint;
use octez::r#async::protocol::{BootstrapContract, ProtocolParameter};
use octez::r#async::rollup::{OctezRollupConfigBuilder, RollupDataDir};
use octez::{
r#async::{
baker::{BakerBinaryPath, OctezBakerConfig, OctezBakerConfigBuilder},
Expand All @@ -14,6 +16,7 @@ use octez::{
unused_port,
};
use serde::Deserialize;
use tezos_crypto_rs::hash::SmartRollupHash;
use tokio::io::AsyncReadExt;

const ACTIVATOR_PUBLIC_KEY: &str =
Expand Down Expand Up @@ -65,6 +68,20 @@ pub(crate) async fn build_config(
&octez_client_config,
)?;

// dummy rollup config for now
let octez_node_endpoint = octez_node_config.rpc_endpoint.clone();
let octez_rollup_config = OctezRollupConfigBuilder::new(
octez_node_endpoint,
octez_client_config.base_dir().into(),
SmartRollupHash::from_base58_check(JSTZ_ROLLUP_ADDRESS).unwrap(),
"bootstrap1".to_string(),
"dummy-kernel".into(),
)
.set_data_dir(RollupDataDir::Temp)
.set_rpc_endpoint(&Endpoint::localhost(8000))
.build()
.expect("aaa");

let protocol_params = build_protocol_params(config.protocol).await?;
let server_port = config.server_port.unwrap_or(unused_port());
Ok((
Expand All @@ -73,6 +90,7 @@ pub(crate) async fn build_config(
octez_node_config,
baker_config,
octez_client_config,
octez_rollup_config,
protocol_params,
),
))
Expand Down
64 changes: 58 additions & 6 deletions crates/jstzd/src/task/jstzd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use super::{octez_baker::OctezBaker, octez_node::OctezNode, utils::retry, Task};
use anyhow::Result;
use super::{
octez_baker::OctezBaker,
octez_node::OctezNode,
octez_rollup::OctezRollup,
utils::{get_block_level, retry},
Task,
};
use anyhow::{bail, Context, Result};
use async_dropper_simple::{AsyncDrop, AsyncDropper};
use async_trait::async_trait;
use axum::{
Expand All @@ -11,8 +17,10 @@ use axum::{
use octez::r#async::{
baker::OctezBakerConfig,
client::{OctezClient, OctezClientConfig},
endpoint::Endpoint,
node_config::OctezNodeConfig,
protocol::ProtocolParameter,
rollup::OctezRollupConfig,
};
use serde::Serialize;
use std::sync::Arc;
Expand All @@ -25,6 +33,7 @@ use tokio::{
struct Jstzd {
octez_node: Arc<RwLock<OctezNode>>,
baker: Arc<RwLock<OctezBaker>>,
rollup: Arc<RwLock<OctezRollup>>,
}

#[derive(Clone, Serialize)]
Expand All @@ -36,6 +45,8 @@ pub struct JstzdConfig {
#[serde(rename(serialize = "octez-client"))]
octez_client_config: OctezClientConfig,
#[serde(skip_serializing)]
octez_rollup_config: OctezRollupConfig,
#[serde(skip_serializing)]
protocol_params: ProtocolParameter,
}

Expand All @@ -44,12 +55,14 @@ impl JstzdConfig {
octez_node_config: OctezNodeConfig,
baker_config: OctezBakerConfig,
octez_client_config: OctezClientConfig,
octez_rollup_config: OctezRollupConfig,
protocol_params: ProtocolParameter,
) -> Self {
Self {
octez_node_config,
baker_config,
octez_client_config,
octez_rollup_config,
protocol_params,
}
}
Expand Down Expand Up @@ -80,20 +93,24 @@ impl Task for Jstzd {
let octez_client = OctezClient::new(config.octez_client_config.clone());
Self::wait_for_node(&octez_node).await?;

Self::import_activator(&octez_client).await;
Self::import_activator(&octez_client).await?;
Self::import_rollup_operator(&octez_client).await?;
Self::activate_protocol(&octez_client, &config.protocol_params).await?;

let baker = OctezBaker::spawn(config.baker_config.clone()).await?;
Self::wait_for_block_level(&config.octez_node_config.rpc_endpoint, 3).await?;
let rollup = OctezRollup::spawn(config.octez_rollup_config.clone()).await?;
Ok(Self {
octez_node: Arc::new(RwLock::new(octez_node)),
baker: Arc::new(RwLock::new(baker)),
rollup: Arc::new(RwLock::new(rollup)),
})
}

async fn kill(&mut self) -> Result<()> {
let results = futures::future::join_all([
self.octez_node.write().await.kill(),
self.baker.write().await.kill(),
self.rollup.write().await.kill(),
])
.await;

Expand All @@ -115,6 +132,7 @@ impl Task for Jstzd {
let check_results = futures::future::join_all([
self.octez_node.read().await.health_check(),
self.baker.read().await.health_check(),
self.rollup.read().await.health_check(),
])
.await;

Expand All @@ -139,12 +157,25 @@ impl Jstzd {
const ACTIVATOR_ACCOUNT_SK: &'static str =
"unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6";
const ACTIVATOR_ACCOUNT_ALIAS: &'static str = "activator";
const ROLLUP_OPERATOR_ACCOUNT_SK: &'static str =
"unencrypted:edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh";
const ROLLUP_OPERATOR_ACCOUNT_ALIAS: &'static str = "bootstrap1";

async fn import_activator(octez_client: &OctezClient) {
async fn import_activator(octez_client: &OctezClient) -> Result<()> {
octez_client
.import_secret_key(Self::ACTIVATOR_ACCOUNT_ALIAS, Self::ACTIVATOR_ACCOUNT_SK)
.await
.expect("Failed to import account 'activator'");
.context("Failed to import account 'activator'")
}

async fn import_rollup_operator(octez_client: &OctezClient) -> Result<()> {
octez_client
.import_secret_key(
Self::ROLLUP_OPERATOR_ACCOUNT_ALIAS,
Self::ROLLUP_OPERATOR_ACCOUNT_SK,
)
.await
.context("Failed to import account 'rollup_operator'")
}

async fn activate_protocol(
Expand Down Expand Up @@ -173,6 +204,20 @@ impl Jstzd {
}
Ok(())
}

/// Wait for the baker to bake at least `level` blocks.
async fn wait_for_block_level(node_endpoint: &Endpoint, level: i64) -> Result<()> {
let ready = retry(10, 1000, || async {
get_block_level(&node_endpoint.to_string())
.await
.map(|l| l >= level)
})
.await;
if !ready {
bail!("baker is not ready after retries");
}
Ok(())
}
}

#[derive(Clone, Default)]
Expand Down Expand Up @@ -283,6 +328,13 @@ impl JstzdServer {
false
}
}

pub async fn rollup_healthy(&self) -> bool {
match &self.inner.state.read().await.jstzd {
Some(v) => v.rollup.read().await.health_check().await.unwrap_or(false),
None => false,
}
}
}

async fn health_check(state: &ServerState) -> bool {
Expand Down
16 changes: 16 additions & 0 deletions crates/jstzd/src/task/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use anyhow::{anyhow, Result};
use serde_json::Value;

pub async fn retry<'a, F>(
retries: u16,
interval_ms: u64,
Expand Down Expand Up @@ -105,3 +108,16 @@ mod tests {
);
}
}

pub async fn get_block_level(rpc_endpoint: &str) -> Result<i64> {
let blocks_head_endpoint = format!("{}/chains/main/blocks/head", rpc_endpoint);
let response: Value = reqwest::get(&blocks_head_endpoint).await?.json().await?;

let level = response
.get("header")
.and_then(|header| header.get("level"))
.ok_or_else(|| anyhow!("Failed to extract level from head block"))?;
level
.as_i64()
.ok_or_else(|| anyhow!("Level is not a valid i64"))
}
Loading

0 comments on commit cff28d2

Please sign in to comment.