Skip to content
Open
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
6 changes: 0 additions & 6 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ build:
build-world-chain-bin:
cargo build -p world-chain

devnet-up: build
@just ./pkg/devnet/devnet-up

deploy-contracts:
@just ./pkg/contracts/deploy-contracts

test *args='':
RUST_LOG="info" cargo nextest run --workspace $@

Expand Down
38 changes: 12 additions & 26 deletions pkg/devnet/README.md → crates/devnet/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# World Chain Devnet

The current local devnet path is the native Rust harness in `crates/devnet`, exposed through
`xtask` and the root `just devnet` recipe. The older Kurtosis devnet under `pkg/devnet` is still
kept for reference and fallback, but it is no longer the preferred local workflow.
This crate contains the native Rust local devnet harness, exposed through `xtask` and the root
`just devnet` recipe.

## Native Rust Devnet

Expand Down Expand Up @@ -67,16 +66,16 @@ The default HA preset starts:
- Prometheus.
- Grafana with World Chain flashblocks dashboards provisioned.

All native presets sequence directly with flashblocks enabled by default. The new path intentionally
does not wire rollup-boost or tx-proxy. PBH is disabled for native World Chain execution nodes with
zero reserved PBH blockspace and an undeployed sentinel PBH entrypoint.
All native presets sequence directly with flashblocks enabled by default. PBH is disabled for native
World Chain execution nodes with zero reserved PBH blockspace and an undeployed sentinel PBH
entrypoint.

Because rollup-boost is not present, local flashblocks use the node's dev-only override authorizer
and force-publish mode. `op-node` still drives normal Engine API payload jobs, while the native
World Chain EL self-authorizes flashblock publication for the active local sequencer.
Local flashblocks use the node's dev-only override authorizer and force-publish mode. `op-node`
still drives normal Engine API payload jobs, while the native World Chain EL self-authorizes
flashblock publication for the active local sequencer.

World contract deployment is intentionally deferred. `FeeEscrow`, `FeeRecipient`, PBH contracts,
rollup-boost, tx-proxy, and rundler are not part of the native default HA path.
and account-abstraction support contracts are not part of the native default HA path.

`op-challenger` is disabled by default because the native devnet does not yet generate the Cannon
prestates required to play local permissioned dispute games. Enable it explicitly with
Expand Down Expand Up @@ -215,9 +214,9 @@ Grafana provisions the Prometheus datasource and imports these dashboards into t
`World Chain Devnet` folder:

```text
pkg/devnet/grafana/dashboards/flashblocks-payload-builder.json
pkg/devnet/grafana/dashboards/flashblocks-validation-pipeline.json
pkg/devnet/grafana/dashboards/flashblocks-p2p.json
crates/devnet/grafana/dashboards/flashblocks-payload-builder.json
crates/devnet/grafana/dashboards/flashblocks-validation-pipeline.json
crates/devnet/grafana/dashboards/flashblocks-p2p.json
reth-overview.json
```

Expand All @@ -240,19 +239,6 @@ upstream Reth dashboard is skipped with a warning and the rest of the devnet sti
- HA failover is wired through op-conductor, but failover behavior is not yet covered by an automated test.
- Stable ports are available through `--stable-ports`; tests should continue to use dynamic ports.
- `FeeEscrow` and `FeeRecipient` are not deployed by the native devnet.
- Rundler and the multi-client EL/CL matrix are deferred until a specific test or workflow needs them.

## Legacy Kurtosis Devnet

The old Kurtosis path remains under `pkg/devnet` and can still be run explicitly:

```bash
just devnet-up
just ./pkg/devnet/devnet-down
```

That path builds and runs the Docker image and preserves the older service wiring. Keep using the
native `just devnet up` path for current local HA sequencing work.

## Testing

Expand Down
3 changes: 0 additions & 3 deletions crates/devnet/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ pub enum DevnetComponentKind {
WorldContractsDeployer,
/// Flashblocks capability on the World Chain execution node.
Flashblocks,
/// Deprecated/removed legacy component.
RemovedLegacyService,
}

impl DevnetComponentKind {
Expand All @@ -77,7 +75,6 @@ impl DevnetComponentKind {
Self::Grafana => "grafana",
Self::WorldContractsDeployer => "world-contracts-deployer",
Self::Flashblocks => "flashblocks",
Self::RemovedLegacyService => "removed-legacy-service",
}
}
}
Expand Down
11 changes: 3 additions & 8 deletions crates/devnet/src/full_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use crate::{
DevnetComponent, DevnetComponentKind, DevnetComponentStatus, DevnetPortMode, L1DevChain,
L1DevChainConfig, MetricsTarget, ObservabilityStack, WorldChainHardforkConfig,
component::ContainerImage,
op_stack::{HaSequencerConfig, HaSequencerTopology},
op_stack::HaSequencerConfig,
process_logs::{ProcessLogTarget, container_log_consumer, emit_process_log},
};

Expand Down Expand Up @@ -97,7 +97,6 @@ pub struct FullStackWorldDevnet {
observability: Option<ObservabilityStack>,
l1: L1DevChain,
components: Vec<DevnetComponent>,
removed_services: Vec<DevnetComponent>,
_tempdir: TempDir,
}

Expand Down Expand Up @@ -215,7 +214,6 @@ impl FullStackWorldDevnet {
port_mode: DevnetPortMode,
block_time: Duration,
) -> Result<Self> {
let topology = HaSequencerTopology::from_config(config.clone());
let artifacts = generate_op_artifacts(&config, &hardforks).await?;
let workdir_path = artifacts.workdir.path().to_path_buf();

Expand Down Expand Up @@ -433,7 +431,6 @@ impl FullStackWorldDevnet {
observability,
l1,
components,
removed_services: topology.removed_services,
_tempdir: artifacts.workdir,
})
}
Expand Down Expand Up @@ -480,9 +477,7 @@ impl FullStackWorldDevnet {
}

pub fn components(&self) -> Vec<DevnetComponent> {
let mut components = self.components.clone();
components.extend(self.removed_services.clone());
components
self.components.clone()
}

pub async fn wait_ready(&self) -> Result<()> {
Expand Down Expand Up @@ -2322,7 +2317,7 @@ fn build_components(
DevnetComponentStatus::Running,
)
.with_endpoint("ws", service.flashblocks_url.clone())
.with_note("flashblocks enabled by default; rollup-boost is intentionally absent"),
.with_note("flashblocks enabled by default"),
);
}

Expand Down
46 changes: 7 additions & 39 deletions crates/devnet/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
//! Native World Chain devnet harness.
//!
//! This crate is the Rust replacement path for the Kurtosis package under
//! `pkg/devnet`. The mapping is intentionally not 1:1: the new default preset
//! keeps the useful local-dev configuration, genesis, and flashblocks setup,
//! while dropping the historical rollup-boost and tx-proxy wiring. PBH
//! contracts are not part of the new deployment scope. The World Chain
//! execution node sequences directly, with lifecycle ownership held by
//! [`WorldDevnet`].
//! This crate owns the local devnet topology used by `just devnet`: an L1 dev
//! chain, World Chain execution nodes, OP Stack services, and optional
//! observability, with lifecycle ownership held by [`WorldDevnet`].

mod component;
mod full_stack;
Expand Down Expand Up @@ -66,8 +62,7 @@ pub use op_stack::{
/// Devnet topology presets.
///
/// `DirectSequencer` is the intended new local-dev shape: one L1 dev chain and
/// one World Chain sequencing execution node, with flashblocks enabled and no
/// rollup-boost or tx-proxy.
/// one World Chain sequencing execution node, with flashblocks enabled.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum WorldDevnetPreset {
/// New default topology: direct sequencing World Chain node plus L1 dev chain.
Expand Down Expand Up @@ -326,13 +321,8 @@ impl WorldDevnetBuilder {
.await
.wrap_err("failed to start Prometheus/Grafana observability stack")?;

let components = build_component_manifest(
self.preset,
&l1,
&nodes,
observability.as_ref(),
ha_topology.as_ref(),
);
let components =
build_component_manifest(&l1, &nodes, observability.as_ref(), ha_topology.as_ref());

Ok(WorldDevnet {
preset: self.preset,
Expand Down Expand Up @@ -449,7 +439,7 @@ impl WorldDevnet {
///
/// The native in-process harness serves the flashblocks capability through
/// the same HTTP RPC endpoint (`op_supportedCapabilities` and Engine API
/// extensions), rather than the old Kurtosis sidecar-style WS port.
/// extensions).
pub fn flashblocks_url(&self) -> Option<String> {
if let Some(full_stack) = &self.full_stack {
self.flashblocks
Expand Down Expand Up @@ -790,7 +780,6 @@ impl WorldDevnet {
}

fn build_component_manifest(
preset: WorldDevnetPreset,
l1: &Option<L1DevChain>,
nodes: &[WorldChainTestingNodeContext<WorldChainDefaultContext>],
observability: Option<&ObservabilityStack>,
Expand Down Expand Up @@ -858,27 +847,6 @@ fn build_component_manifest(
);
components.push(component.clone());
}
components.extend(topology.removed_services.clone());
} else if matches!(
preset,
WorldDevnetPreset::DirectSequencer | WorldDevnetPreset::Minimal
) {
components.push(
DevnetComponent::new(
"rollup-boost",
DevnetComponentKind::RemovedLegacyService,
DevnetComponentStatus::Removed,
)
.with_note("not present in direct-sequencer topology"),
);
components.push(
DevnetComponent::new(
"tx-proxy",
DevnetComponentKind::RemovedLegacyService,
DevnetComponentStatus::Removed,
)
.with_note("not present unless a future test independently needs it"),
);
}

components
Expand Down
7 changes: 3 additions & 4 deletions crates/devnet/src/observability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ const RETH_DASHBOARD_URL: &str =
"https://raw.githubusercontent.com/paradigmxyz/reth/main/etc/grafana/dashboards/overview.json";
const RETH_DASHBOARD_FETCH_TIMEOUT: Duration = Duration::from_secs(5);
const FLASHBLOCKS_PAYLOAD_BUILDER_DASHBOARD: &str =
include_str!("../../../pkg/devnet/grafana/dashboards/flashblocks-payload-builder.json");
include_str!("../grafana/dashboards/flashblocks-payload-builder.json");
const FLASHBLOCKS_VALIDATION_PIPELINE_DASHBOARD: &str =
include_str!("../../../pkg/devnet/grafana/dashboards/flashblocks-validation-pipeline.json");
const FLASHBLOCKS_P2P_DASHBOARD: &str =
include_str!("../../../pkg/devnet/grafana/dashboards/flashblocks-p2p.json");
include_str!("../grafana/dashboards/flashblocks-validation-pipeline.json");
const FLASHBLOCKS_P2P_DASHBOARD: &str = include_str!("../grafana/dashboards/flashblocks-p2p.json");
const WORLD_CHAIN_DASHBOARDS: [(&str, &str); 3] = [
(
"flashblocks-payload-builder.json",
Expand Down
25 changes: 0 additions & 25 deletions crates/devnet/src/op_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,6 @@ pub struct HaSequencerTopology {
pub config: HaSequencerConfig,
/// Planned component graph.
pub components: Vec<DevnetComponent>,
/// Explicitly removed legacy services.
pub removed_services: Vec<DevnetComponent>,
/// op-conductor runtime configs, one per sequencer.
pub conductor_configs: Vec<OpConductorConfig>,
/// op-challenger runtime config.
Expand Down Expand Up @@ -436,31 +434,9 @@ impl HaSequencerTopology {
);
}

let removed_services = vec![
DevnetComponent::new(
"rollup-boost",
DevnetComponentKind::RemovedLegacyService,
DevnetComponentStatus::Removed,
)
.with_note("removed from the new default topology; World Chain sequences directly"),
DevnetComponent::new(
"tx-proxy",
DevnetComponentKind::RemovedLegacyService,
DevnetComponentStatus::Removed,
)
.with_note("removed unless a future test independently requires it"),
DevnetComponent::new(
"rundler",
DevnetComponentKind::RemovedLegacyService,
DevnetComponentStatus::Removed,
)
.with_note("deferred with PBH/4337 local-dev flow; PBH contracts are deprecated"),
];

Self {
config,
components,
removed_services,
conductor_configs,
challenger_config,
}
Expand Down Expand Up @@ -497,7 +473,6 @@ mod tests {
assert!(topology.components.iter().any(|component| component.kind
== DevnetComponentKind::WorldContractsDeployer
&& component.status == DevnetComponentStatus::Deferred));
assert_eq!(topology.removed_services.len(), 3);
assert!(!topology.config.world_contracts.fee_vaults);
assert!(!topology.config.world_contracts.pbh_contracts);
}
Expand Down
10 changes: 10 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ cargo xtask launch-node --nodes 2 --spam --flashblocks

Starts N nodes via P2P, drives block production with `EngineDriver`, optionally runs `TxSpammer`. Prints RPC URLs for `cast` interaction.

### Local Devnet

Run the native World Chain devnet with:

```bash
just devnet up
```

See [the devnet README](../crates/devnet/README.md) for topology, endpoint, logging, and Grafana details.

## Metrics

Custom metrics are exposed via the standard reth metrics endpoint (`/metrics`). Key namespaces:
Expand Down
5 changes: 1 addition & 4 deletions pkg/contracts/Justfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
set positional-arguments

deploy-contracts:
chmod +x ./scripts/devnet/deploy_kurtosis.sh && ./scripts/devnet/deploy_kurtosis.sh

fmt:
fmt:
forge fmt
30 changes: 0 additions & 30 deletions pkg/contracts/scripts/devnet/deploy_kurtosis.sh

This file was deleted.

26 changes: 0 additions & 26 deletions pkg/devnet/Justfile

This file was deleted.

Binary file removed pkg/devnet/kurtosis-package-icon.png
Binary file not shown.
6 changes: 0 additions & 6 deletions pkg/devnet/kurtosis.yml

This file was deleted.

Loading
Loading