Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/code_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,22 @@ jobs:
with:
version: "latest"
args: "--workspace --all-features --all-targets"

test:
name: Run Tests
runs-on: ubuntu-latest
strategy:
matrix:
short_prefix: [0, 1]

steps:
- uses: actions/checkout@v4

- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable

- name: Run Cargo test
run: SHORT_PREFIX=${{ matrix.short_prefix }} 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_host.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_host: 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_host: None,
}
}
}
Expand Down
81 changes: 51 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-test:f4e3f560c083d949779b5bd0706f945ebd405622";

#[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,57 @@ 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;
let img = match std::env::var("SHORT_PREFIX") {
Ok(v) if v == "1" || v == "true" => format!("{base_img}-short-prefix"),
_ => base_img.to_string(),
};
println!("img : {:?}", img);
img
}),
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
Loading