Skip to content

Commit

Permalink
Merge pull request #185 from alpenlabs/feature/reth-el-integration
Browse files Browse the repository at this point in the history
Feature/reth el integration
  • Loading branch information
delbonis authored Jul 30, 2024
2 parents 1edb77f + 36c6e9a commit fd5de94
Show file tree
Hide file tree
Showing 45 changed files with 1,506 additions and 331 deletions.
389 changes: 389 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ members = [
"crates/prover/zkvm",
"crates/prover/adapters/risc0",
"sequencer",
"reth",
]

default-members = ["sequencer"]
default-members = ["sequencer", "reth"]

resolver = "2"

Expand All @@ -28,12 +29,14 @@ alpen-vertex-common = { path = "crates/common" }
alpen-vertex-consensus-logic = { path = "crates/consensus-logic" }
alpen-vertex-db = { path = "crates/db" }
alpen-vertex-evmctl = { path = "crates/evmctl" }
alpen-vertex-evmexec = { path = "crates/evmexec" }
alpen-vertex-mmr = { path = "crates/util/mmr" }
alpen-vertex-primitives = { path = "crates/primitives" }
alpen-vertex-rpc-api = { path = "crates/rpc/api" }
alpen-vertex-state = { path = "crates/state" }
zkvm = { path = "crates/prover/zkvm" }

alloy-genesis = { version = "0.1", default-features = false }
anyhow = "1.0.86"
arbitrary = { version = "1.3.2", features = ["derive"] }
argh = "0.1"
Expand All @@ -57,6 +60,8 @@ num_enum = "0.7"
parking_lot = "0.12.3"
rand = "0.8.5"
reqwest = { version = "0.12.4", features = ["json"] }
reth = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-chainspec = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-db = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-ipc = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-node-ethereum = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
Expand All @@ -66,6 +71,7 @@ reth-rpc = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-rpc-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-rpc-types = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
reth-rpc-types-compat = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.0.1" }
rockbound = { git = "https://github.com/sovereign-Labs/rockbound", tag = "v2.0.1" }
rocksdb = "0.21"
secp256k1 = "0.29.0"
Expand Down
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,56 @@ These exist in `crates/`.
* `util/` - independent utility libraries
* `mmr` - "merkle mountain range" util
* `vtxjmt` - extensions to JMT crate for our purposes

### How to run

Prerequisite:
* bitcoin regtest instance with json-rpc access
* host:port for bitcoind rpc `BITCOIND_HOST`,
* auth for bitcoind rpc: `BITCOIND_USER`:`BITCOIND_PASSWORD`
* 32 byte sequencer key saved to file `SEQUENCER_KEY_PATH`
* 32 byte EL client jwt secret saved as **hex** to file `JWT_SECRET_PATH`

Create `config.toml` for rollup (Or use `example_config.toml` as template)

```toml
[bitcoind_rpc]
rpc_url = "{BITCOIND_HOST}"
rpc_user = "{BITCOIND_USER}"
rpc_password = "{BITCOIND_PASSWORD}"
network = "regtest"

[client]
rpc_port = 8432
datadir = ".data/rollup"
sequencer_key = "{SEQUENCER_KEY_PATH}"

[sync]
l1_follow_distance = 6
max_reorg_depth = 4
client_poll_dur_ms = 2000

[exec.reth]
rpc_url = "http://localhost:8551"
secret = "{JWT_SECRET_PATH}"
```

Ensure bitcoin has some blocks

in `sequencer/src/main.rs`, adjust rollup configs:
* `horizon_l1_height`
* `genesis_l1_height`

ensure `horizon_l1_height` <= `genesis_l1_height` < bitcoin_block_height

Start EL Client:

```sh
cargo run --bin alpen-vertex-reth -- --datadir .data/reth --http -vvvv
```

Start CL Client/Sequencer

```sh
cargo run --bin alpen-vertex-sequencer -- --config config.toml
```
51 changes: 41 additions & 10 deletions crates/consensus-logic/src/duty_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;
use std::{thread, time};

use alpen_vertex_state::exec_update::{ExecUpdate, UpdateInput, UpdateOutput};
use borsh::{BorshDeserialize, BorshSerialize};
use tokio::sync::broadcast;
use tracing::*;
Expand All @@ -14,8 +15,10 @@ use alpen_vertex_evmctl::engine::{ExecEngineCtl, PayloadStatus};
use alpen_vertex_evmctl::errors::EngineError;
use alpen_vertex_evmctl::messages::{ExecPayloadData, PayloadEnv};
use alpen_vertex_primitives::buf::{Buf32, Buf64};
use alpen_vertex_state::block::{ExecSegment, L1Segment};
use alpen_vertex_primitives::params::RollupParams;
use alpen_vertex_state::block::{ExecSegment, L1Segment, L2BlockAccessory, L2BlockBundle};
use alpen_vertex_state::client_state::ClientState;
use alpen_vertex_state::exec_update::{ExecUpdate, UpdateOutput};
use alpen_vertex_state::header::L2BlockHeader;
use alpen_vertex_state::prelude::*;

Expand Down Expand Up @@ -46,7 +49,7 @@ impl IdentityData {
}
}

pub fn duty_tracker_task<D: Database, E: ExecEngineCtl>(
pub fn duty_tracker_task<D: Database>(
mut cupdate_rx: broadcast::Receiver<Arc<ClientUpdateNotif>>,
batch_queue: broadcast::Sender<DutyBatch>,
ident: Identity,
Expand Down Expand Up @@ -130,6 +133,7 @@ pub fn duty_dispatch_task<
database: Arc<D>,
engine: Arc<E>,
pool: Arc<threadpool::ThreadPool>,
params: &RollupParams,
) {
// TODO make this actually work
let mut pending_duties: HashMap<u64, ()> = HashMap::new();
Expand Down Expand Up @@ -166,7 +170,8 @@ pub fn duty_dispatch_task<
let sm = sync_man.clone();
let db = database.clone();
let e = engine.clone();
pool.execute(move || duty_exec_task(d, ik, sm, db, e));
let params = params.clone();
pool.execute(move || duty_exec_task(d, ik, sm, db, e, params));
trace!(%id, "dispatched duty exec task");
pending_duties.insert(id, ());
}
Expand All @@ -184,8 +189,16 @@ fn duty_exec_task<D: Database, E: ExecEngineCtl>(
sync_man: Arc<SyncManager>,
database: Arc<D>,
engine: Arc<E>,
params: RollupParams,
) {
if let Err(e) = perform_duty(&duty, &ik, &sync_man, database.as_ref(), engine.as_ref()) {
if let Err(e) = perform_duty(
&duty,
&ik,
&sync_man,
database.as_ref(),
engine.as_ref(),
params,
) {
error!(err = %e, "error performing duty");
} else {
debug!("completed duty successfully");
Expand All @@ -198,11 +211,13 @@ fn perform_duty<D: Database, E: ExecEngineCtl>(
sync_man: &SyncManager,
database: &D,
engine: &E,
params: RollupParams,
) -> Result<(), Error> {
match duty {
Duty::SignBlock(data) => {
let target = data.target_slot();
let Some((blkid, _block)) = sign_and_store_block(target, ik, database, engine)? else {
let Some((blkid, _block)) = sign_and_store_block(target, ik, database, engine, params)?
else {
return Ok(());
};

Expand All @@ -227,6 +242,7 @@ fn sign_and_store_block<D: Database, E: ExecEngineCtl>(
ik: &IdentityKey,
database: &D,
engine: &E,
params: RollupParams,
) -> Result<Option<(L2BlockId, L2Block)>, Error> {
debug!(%slot, "prepating to publish block");

Expand Down Expand Up @@ -257,11 +273,24 @@ fn sign_and_store_block<D: Database, E: ExecEngineCtl>(

let prev_block_id = *last_ss.chain_tip_blkid();

let prev_block = database
.l2_provider()
.get_block_data(prev_block_id)?
.expect("prev block must exist");

// TODO: get from rollup config
let block_time = params.block_time;
let target_ts = prev_block.block().header().timestamp() + block_time;
let current_ts = now_millis();

if current_ts < target_ts {
sleep(Duration::from_millis(target_ts - current_ts));
}

// Start preparing the EL payload.
let ts = now_millis();
let prev_global_sr = Buf32::zero(); // TODO
let safe_l1_block = Buf32::zero(); // TODO
let payload_env = PayloadEnv::new(ts, prev_global_sr, safe_l1_block, Vec::new());
let payload_env = PayloadEnv::new(ts, prev_block_id, safe_l1_block, Vec::new());
let key = engine.prepare_payload(payload_env)?;
trace!(%slot, "submitted EL payload job, waiting for completion");

Expand All @@ -282,7 +311,7 @@ fn sign_and_store_block<D: Database, E: ExecEngineCtl>(

// TODO correctly assemble the exec segment, since this is bodging out how
// the inputs/outputs should be structured
let eui = UpdateInput::new(slot, Buf32::zero(), payload_data.el_payload().to_vec());
let eui = payload_data.update_input().clone();
let exec_update = ExecUpdate::new(eui, UpdateOutput::new_from_state(Buf32::zero()));
let exec_seg = ExecSegment::new(exec_update);

Expand All @@ -293,12 +322,14 @@ fn sign_and_store_block<D: Database, E: ExecEngineCtl>(
let header_sig = sign_header(&header, ik);
let signed_header = SignedL2BlockHeader::new(header, header_sig);
let blkid = signed_header.get_blockid();
let block_accessory = L2BlockAccessory::new(payload_data.accessory_data().to_vec());
let final_block = L2Block::new(signed_header, body);
let final_block_bundle = L2BlockBundle::new(final_block.clone(), block_accessory);
info!(%slot, ?blkid, "finished building new block");

// Store the block in the database.
let l2store = database.l2_store();
l2store.put_block_data(final_block.clone())?;
l2store.put_block_data(final_block_bundle)?;
debug!(?blkid, "wrote block to datastore");

Ok(Some((blkid, final_block)))
Expand Down
15 changes: 7 additions & 8 deletions crates/consensus-logic/src/fork_choice_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,14 @@ fn process_ct_msg<D: Database, E: ExecEngineCtl>(

ForkChoiceMessage::NewBlock(blkid) => {
let l2prov = state.database.l2_provider();
let block = l2prov
let block_bundle = l2prov
.get_block_data(blkid)?
.ok_or(Error::MissingL2Block(blkid))?;

// First, decide if the block seems correctly signed and we haven't
// already marked it as invalid.
let cstate = state.cur_csm_state.clone();
let correctly_signed = check_new_block(&blkid, &block, &cstate, state)?;
let correctly_signed = check_new_block(&blkid, &block_bundle, &cstate, state)?;
if !correctly_signed {
// It's invalid, write that and return.
state.set_block_status(&blkid, BlockStatus::Invalid)?;
Expand All @@ -376,11 +376,8 @@ fn process_ct_msg<D: Database, E: ExecEngineCtl>(

// Try to execute the payload, seeing if *that's* valid.
// TODO take implicit input produced by the CL STF and include that in the payload data
// TODO include the full exec update input from the CL block
let exec_hash = block.header().exec_payload_hash();
let exec_seg = block.exec_segment();
let dummy_payload = exec_seg.update().input().extra_payload();
let eng_payload = ExecPayloadData::new_simple(dummy_payload.to_vec());
let exec_hash = block_bundle.header().exec_payload_hash();
let eng_payload = ExecPayloadData::from_l2_block_bundle(&block_bundle);
debug!(?blkid, ?exec_hash, "submitting execution payload");
let res = engine.submit_payload(eng_payload)?;

Expand All @@ -398,7 +395,9 @@ fn process_ct_msg<D: Database, E: ExecEngineCtl>(
// should switch to it as a potential head. This returns if we
// created a new tip instead of advancing an existing tip.
let cur_tip = state.cur_best_block;
let new_tip = state.chain_tracker.attach_block(blkid, block.header())?;
let new_tip = state
.chain_tracker
.attach_block(blkid, block_bundle.header())?;
if new_tip {
debug!(?blkid, "created new pending tip");
}
Expand Down
26 changes: 18 additions & 8 deletions crates/consensus-logic/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use tracing::*;
use alpen_vertex_db::{errors::DbError, traits::*};
use alpen_vertex_primitives::{
buf::{Buf32, Buf64},
evm_exec::create_evm_extra_payload,
l1::L1BlockManifest,
params::Params,
};
use alpen_vertex_state::{
block::{ExecSegment, L1Segment},
block::{ExecSegment, L1Segment, L2BlockAccessory, L2BlockBundle},
chain_state::ChainState,
client_state::ClientState,
exec_env::ExecEnvState,
Expand Down Expand Up @@ -60,10 +61,14 @@ pub fn init_genesis_chainstate(
// Create a dummy exec state that we can build the rest of the genesis block
// around and insert into the genesis state.
// TODO this might need to talk to the EL to do the genesus setup *properly*
let geui = UpdateInput::new(0, Buf32::zero(), Vec::new());
let gees = ExecEnvState::from_base_input(geui.clone(), Buf32::zero());
let genesis_ee_state = Buf32::zero();
let geu = ExecUpdate::new(geui.clone(), UpdateOutput::new_from_state(genesis_ee_state));
let extra_payload = create_evm_extra_payload(params.rollup.evm_genesis_block_hash);
let geui = UpdateInput::new(0, Buf32::zero(), extra_payload);
let gees =
ExecEnvState::from_base_input(geui.clone(), params.rollup.evm_genesis_block_state_root);
let geu = ExecUpdate::new(
geui.clone(),
UpdateOutput::new_from_state(params.rollup.evm_genesis_block_state_root),
);

// Build the genesis block and genesis consensus states.
let gblock = make_genesis_block(params, geu);
Expand Down Expand Up @@ -106,7 +111,7 @@ fn load_pre_genesis_l1_manifests(
Ok(manifests)
}

fn make_genesis_block(params: &Params, genesis_update: ExecUpdate) -> L2Block {
fn make_genesis_block(params: &Params, genesis_update: ExecUpdate) -> L2BlockBundle {
// This has to be empty since everyone should have an unambiguous view of the genesis block.
let l1_seg = L1Segment::new_empty();

Expand All @@ -115,7 +120,11 @@ fn make_genesis_block(params: &Params, genesis_update: ExecUpdate) -> L2Block {

let body = L2BlockBody::new(l1_seg, exec_seg);

// Assemble the genesis header core, pulling in data from whatever
// TODO stub
let exec_payload = vec![];
let accessory = L2BlockAccessory::new(exec_payload);

// Assemble the genesis header template, pulling in data from whatever
// sources we need.
// FIXME this isn't the right timestamp to start the blockchain, this should
// definitely be pulled from the database or the rollup parameters maybe
Expand All @@ -124,7 +133,8 @@ fn make_genesis_block(params: &Params, genesis_update: ExecUpdate) -> L2Block {
let genesis_sr = Buf32::zero();
let header = L2BlockHeader::new(0, genesis_ts, zero_blkid, &body, genesis_sr);
let signed_genesis_header = SignedL2BlockHeader::new(header, Buf64::zero());
L2Block::new(signed_genesis_header, body)
let block = L2Block::new(signed_genesis_header, body);
L2BlockBundle::new(block, accessory)
}

/// Check if the database needs to have client init done to it.
Expand Down
12 changes: 7 additions & 5 deletions crates/consensus-logic/src/unfinalized_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,17 +317,18 @@ mod tests {
use alpen_test_utils::ArbitraryGenerator;
use alpen_vertex_db::traits::{Database, L2DataProvider, L2DataStore};
use alpen_vertex_state::{
block::{L2Block, L2BlockBody},
block::{L2Block, L2BlockAccessory, L2BlockBody, L2BlockBundle},
header::{L2BlockHeader, L2Header, SignedL2BlockHeader},
id::L2BlockId,
};

use crate::unfinalized_tracker;

fn get_genesis_block() -> L2Block {
fn get_genesis_block() -> L2BlockBundle {
let arb = ArbitraryGenerator::new();
let gen_header: SignedL2BlockHeader = arb.generate();
let body: L2BlockBody = arb.generate();
let accessory: L2BlockAccessory = arb.generate();

let empty_hash = L2BlockId::default();
let header = L2BlockHeader::new(
Expand All @@ -338,13 +339,14 @@ mod tests {
*gen_header.state_root(),
);
let signed_header = SignedL2BlockHeader::new(header, *gen_header.sig());
L2Block::new(signed_header, body)
L2BlockBundle::new(L2Block::new(signed_header, body), accessory)
}

fn get_mock_block_with_parent(parent: &SignedL2BlockHeader) -> L2Block {
fn get_mock_block_with_parent(parent: &SignedL2BlockHeader) -> L2BlockBundle {
let arb = ArbitraryGenerator::new();
let gen_header: SignedL2BlockHeader = arb.generate();
let body: L2BlockBody = arb.generate();
let accessory: L2BlockAccessory = arb.generate();

let header = L2BlockHeader::new(
parent.blockidx() + 1,
Expand All @@ -354,7 +356,7 @@ mod tests {
*gen_header.state_root(),
);
let signed_header = SignedL2BlockHeader::new(header, *gen_header.sig());
L2Block::new(signed_header, body)
L2BlockBundle::new(L2Block::new(signed_header, body), accessory)
}

fn setup_test_chain(l2_prov: &impl L2DataStore) -> [L2BlockId; 7] {
Expand Down
Loading

0 comments on commit fd5de94

Please sign in to comment.