Skip to content

Commit

Permalink
Citrea docker support
Browse files Browse the repository at this point in the history
  • Loading branch information
jfldde committed Oct 14, 2024
1 parent d3b6daf commit 40501fb
Show file tree
Hide file tree
Showing 16 changed files with 841 additions and 513 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/code_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,11 @@ jobs:
with:
version: "latest"
args: "--workspace --all-features --all-targets"

test:
name: Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Cargo test
run: cargo test
55 changes: 27 additions & 28 deletions src/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct BitcoinNode {

impl BitcoinNode {
pub async fn new(config: &BitcoinConfig, docker: Arc<Option<DockerEnv>>) -> Result<Self> {
let spawn_output = Self::spawn(config, &docker).await?;
let spawn_output = <Self as NodeT>::spawn(config, &docker).await?;

let rpc_url = format!(
"http://127.0.0.1:{}/wallet/{}",
Expand Down Expand Up @@ -136,12 +136,26 @@ impl BitcoinNode {
.await;
}

// Switch this over to Node signature once we add support for docker to citrea nodes
async fn spawn(config: &BitcoinConfig, docker: &Arc<Option<DockerEnv>>) -> Result<SpawnOutput> {
match docker.as_ref() {
Some(docker) => docker.spawn(config.into()).await,
None => <Self as NodeT>::spawn(config),
}
fn spawn(config: &BitcoinConfig) -> Result<SpawnOutput> {
let args = config.args();
debug!("Running bitcoind with args : {args:?}");

info!(
"Bitcoin debug.log available at : {}",
config.log_path().display()
);

let stderr_path = config.stderr_path();
let stderr_file = File::create(stderr_path).context("Failed to create stderr file")?;

Command::new("bitcoind")
.args(&args)
.kill_on_drop(true)
.envs(config.env.clone())
.stderr(Stdio::from(stderr_file))
.spawn()
.context("Failed to spawn bitcoind process")
.map(SpawnOutput::Child)
}
}

Expand Down Expand Up @@ -182,26 +196,11 @@ impl NodeT for BitcoinNode {
type Config = BitcoinConfig;
type Client = Client;

fn spawn(config: &Self::Config) -> Result<SpawnOutput> {
let args = config.args();
debug!("Running bitcoind with args : {args:?}");

info!(
"Bitcoin debug.log available at : {}",
config.log_path().display()
);

let stderr_path = config.stderr_path();
let stderr_file = File::create(stderr_path).context("Failed to create stderr file")?;

Command::new("bitcoind")
.args(&args)
.kill_on_drop(true)
.envs(config.env.clone())
.stderr(Stdio::from(stderr_file))
.spawn()
.context("Failed to spawn bitcoind process")
.map(SpawnOutput::Child)
async fn spawn(config: &Self::Config, docker: &Arc<Option<DockerEnv>>) -> Result<SpawnOutput> {
match docker.as_ref() {
Some(docker) => docker.spawn(config.into()).await,
None => Self::spawn(config),
}
}

fn spawn_output(&mut self) -> &mut SpawnOutput {
Expand Down Expand Up @@ -270,7 +269,7 @@ impl Restart for BitcoinNode {
if let Some(config) = config {
self.config = config;
}
self.spawn_output = Self::spawn(&self.config, &self.docker_env).await?;
self.spawn_output = <Self as NodeT>::spawn(&self.config, &self.docker_env).await?;

self.wait_for_ready(None).await?;

Expand Down
71 changes: 71 additions & 0 deletions src/citrea_config/rollup.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::path::PathBuf;

use serde::{Deserialize, Serialize};
use tempfile::TempDir;

use crate::config::{BitcoinConfig, BitcoinServiceConfig};

/// Runner configuration.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
Expand Down Expand Up @@ -121,6 +124,74 @@ pub struct FullNodeConfig<BitcoinServiceConfig> {
pub public_keys: RollupPublicKeys,
}

impl Default for FullNodeConfig<BitcoinServiceConfig> {
fn default() -> Self {
Self {
rpc: RpcConfig {
bind_host: "127.0.0.1".into(),
bind_port: 0,
max_connections: 100,
max_request_body_size: 10 * 1024 * 1024,
max_response_body_size: 10 * 1024 * 1024,
batch_requests_limit: 50,
enable_subscriptions: true,
max_subscriptions_per_connection: 100,
},
storage: StorageConfig {
path: TempDir::new()
.expect("Failed to create temporary directory")
.into_path(),
db_max_open_files: None,
},
runner: None,
da: BitcoinServiceConfig {
node_url: String::new(),
node_username: String::from("user"),
node_password: String::from("password"),
network: bitcoin::Network::Regtest,
da_private_key: None,
tx_backup_dir: TempDir::new()
.expect("Failed to create temporary directory")
.into_path()
.display()
.to_string(),
},
public_keys: RollupPublicKeys {
sequencer_public_key: vec![
32, 64, 64, 227, 100, 193, 15, 43, 236, 156, 31, 229, 0, 161, 205, 76, 36, 124,
137, 214, 80, 160, 30, 215, 232, 44, 171, 168, 103, 135, 124, 33,
],
// private key [4, 95, 252, 129, 163, 193, 253, 179, 175, 19, 89, 219, 242, 209, 20, 176, 179, 239, 191, 127, 41, 204, 156, 93, 160, 18, 103, 170, 57, 210, 199, 141]
// Private Key (WIF): KwNDSCvKqZqFWLWN1cUzvMiJQ7ck6ZKqR6XBqVKyftPZtvmbE6YD
sequencer_da_pub_key: vec![
3, 136, 195, 18, 11, 187, 25, 37, 38, 109, 184, 237, 247, 208, 131, 219, 162,
70, 35, 174, 234, 47, 239, 247, 60, 51, 174, 242, 247, 112, 186, 222, 30,
],
// private key [117, 186, 249, 100, 208, 116, 89, 70, 0, 54, 110, 91, 17, 26, 29, 168, 248, 107, 46, 254, 45, 34, 218, 81, 200, 216, 33, 38, 160, 252, 172, 114]
// Private Key (WIF): L1AZdJXzDGGENBBPZGSL7dKJnwn5xSKqzszgK6CDwiBGThYQEVTo
prover_da_pub_key: vec![
2, 138, 232, 157, 214, 46, 7, 210, 235, 33, 105, 239, 71, 169, 105, 233, 239,
84, 172, 112, 13, 54, 9, 206, 106, 138, 251, 218, 15, 28, 137, 112, 127,
],
},
}
}
}

impl From<BitcoinConfig> for BitcoinServiceConfig {
fn from(v: BitcoinConfig) -> Self {
let ip = v.docker_ip.unwrap_or(String::from("127.0.0.1"));
Self {
node_url: format!("{}:{}", ip, v.rpc_port),
node_username: v.rpc_user,
node_password: v.rpc_password,
network: v.network,
da_private_key: None,
tx_backup_dir: String::new(),
}
}
}

/// A configuration type to define the behaviour of the pruner.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PruningConfig {
Expand Down
2 changes: 2 additions & 0 deletions src/config/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct BitcoinConfig {
pub docker_image: Option<String>,
pub env: Vec<(&'static str, &'static str)>,
pub idx: usize,
pub docker_ip: Option<String>,
}

impl Default for BitcoinConfig {
Expand All @@ -34,6 +35,7 @@ impl Default for BitcoinConfig {
docker_image: Some("bitcoin/bitcoin:28.0".to_string()),
env: Vec::new(),
idx: 0,
docker_ip: None,
}
}
}
Expand Down
79 changes: 49 additions & 30 deletions src/config/docker.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
use std::fmt::Debug;
use std::path::PathBuf;

use super::{BitcoinConfig, FullSequencerConfig};
use serde::Serialize;
use tracing::debug;

use super::{BitcoinConfig, FullL2NodeConfig, NodeKindMarker};
use crate::log_provider::LogPathProvider;
use crate::node::{get_citrea_args, Config, NodeKind};
use crate::utils::get_genesis_path;

const DEFAULT_BITCOIN_DOCKER_IMAGE: &str = "bitcoin/bitcoin:28.0";
const DEFAULT_CITREA_DOCKER_IMAGE: &str =
"chainwayxyz/citrea:e7db3c1c1787014ec4f7eb365bd8657d8f0917a0";

#[derive(Debug)]
pub struct VolumeConfig {
pub name: String,
Expand All @@ -16,11 +26,13 @@ pub struct DockerConfig {
pub cmd: Vec<String>,
pub log_path: PathBuf,
pub volume: VolumeConfig,
pub host_dir: Option<Vec<String>>,
pub kind: NodeKind,
}

impl From<&BitcoinConfig> for DockerConfig {
fn from(v: &BitcoinConfig) -> Self {
let mut args = v.args();
fn from(config: &BitcoinConfig) -> Self {
let mut args = config.args();

// Docker specific args
args.extend([
Expand All @@ -30,48 +42,55 @@ impl From<&BitcoinConfig> for DockerConfig {
]);

Self {
ports: vec![v.rpc_port, v.p2p_port],
image: v
ports: vec![config.rpc_port, config.p2p_port],
image: config
.docker_image
.clone()
.unwrap_or_else(|| "bitcoin/bitcoin:28.0".to_string()),
.unwrap_or_else(|| DEFAULT_BITCOIN_DOCKER_IMAGE.to_string()),
cmd: args,
log_path: v.data_dir.join("regtest").join("debug.log"),
log_path: config.data_dir.join("regtest").join("debug.log"),
volume: VolumeConfig {
name: format!("bitcoin-{}", v.idx),
name: format!("bitcoin-{}", config.idx),
target: "/home/bitcoin/.bitcoin".to_string(),
},
host_dir: None,
kind: NodeKind::Bitcoin,
}
}
}

impl From<&FullSequencerConfig> for DockerConfig {
fn from(v: &FullSequencerConfig) -> Self {
let args = vec![
"--da-layer".to_string(),
"bitcoin".to_string(),
"--rollup-config-path".to_string(),
"sequencer_rollup_config.toml".to_string(),
"--sequencer-config-path".to_string(),
"sequencer_config.toml".to_string(),
"--genesis-paths".to_string(),
get_genesis_path(v.dir.parent().expect("Couldn't get parent dir"))
.display()
.to_string(),
];
impl<T> From<FullL2NodeConfig<T>> for DockerConfig
where
T: Clone + Serialize + Debug,
FullL2NodeConfig<T>: NodeKindMarker,
{
fn from(config: FullL2NodeConfig<T>) -> Self {
let kind = FullL2NodeConfig::<T>::kind();

debug!("Converting config {config:?} for {kind} to docker config");

let args = get_citrea_args(&config);

Self {
ports: vec![v.rollup.rpc.bind_port],
image: v
.docker_image
.clone()
.unwrap_or_else(|| "citrea:latest".to_string()), // Default to local image
ports: vec![config.rollup.rpc.bind_port],
image: config.docker_image.clone().unwrap_or_else(|| {
let base_img = DEFAULT_CITREA_DOCKER_IMAGE;
match std::env::var("SHORT_PREFIX") {
Ok(_) => format!("{base_img}-short-prefix"),
_ => base_img.to_string(),
}
}),
cmd: args,
log_path: v.dir.join("stdout"),
log_path: config.dir.join("stdout.log"),
volume: VolumeConfig {
name: "sequencer".to_string(),
target: "/sequencer/data".to_string(),
name: format!("{kind}"),
target: format!("/{kind}/data"),
},
host_dir: Some(vec![
config.dir().to_owned().display().to_string(),
get_genesis_path(&config),
]),
kind,
}
}
}
Loading

0 comments on commit 40501fb

Please sign in to comment.