Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1,486 changes: 1,069 additions & 417 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["host", "lib", "methods"]
members = ["host", "lib", "methods", "methods/guest"]
resolver = "2"

# Always optimize; building and running the guest takes much longer without optimization.
Expand All @@ -14,12 +14,16 @@ lto = true
edition = "2024"

[workspace.dependencies]
ethereum_hashing = { git = "https://github.com/ReamLabs/ethereum_hashing" }
ethereum_ssz = "0.9"
ream-consensus = { git = "https://github.com/ReamLabs/ream.git", package = "ream-consensus", features = ["zkvm"] }
ream-consensus = { git = "https://github.com/ReamLabs/ream.git", package = "ream-consensus-beacon", features = ["zkvm"] }
sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use sha2 here? Deletting this dependency doesn't make any trouble in my local environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was introduced by @SuccinctPaul for benchmarks using this precompile. It significantly reduces the execution cycles and time. From cargo.lock, it seems sha2 is being used extensively by several packages.
If we delete this dependency it would switch to the original sha2 crate and the timings almost double.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep.

ssz_types = { git = "https://github.com/ReamLabs/ssz_types", branch = "magic-extended-list" }
tracing = "0.1"
tree_hash = "0.10"
tree_hash_derive = "0.10"

[patch.crates-io]
ethereum_hashing = { git = "https://github.com/ReamLabs/ethereum_hashing" }
sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
ssz_types = { git = "https://github.com/ReamLabs/ssz_types", branch = "magic-extended-list" } # Extends 2^29 to 2^40 list root
2 changes: 1 addition & 1 deletion host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ derive_more = { version = "2.0.1", features = ["full"] }
dotenv = "0.15.0"
hex = "0.4.3"
methods = { path = "../methods" }
risc0-zkvm = { version = "2.0.1" }
risc0-zkvm = { version = "3.0.1" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about updating this version with the latest one? (3.0.3)

serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.139", default-features = false, features = ["alloc"] }
tracing = { workspace = true }
Expand Down
50 changes: 37 additions & 13 deletions host/Makefile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess these changes should be also applied to the README.md in the project root.

Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,63 @@ DOWNLOAD_SCRIPT = ./subscripts/download_ef_data.sh
PARSE_SCRIPT = ./subscripts/parse_log_to_table.sh
SORT_SCRIPT = ./subscripts/sort_table.sh

OPERATIONS = attestation attester_slashing block_header bls_to_execution_change deposit execution_payload proposer_slashing sync_aggregate voluntary_exit withdrawals
BLOCK_OPERATIONS = attestation attester_slashing block_header bls_to_execution_change deposit execution_payload proposer_slashing sync_aggregate voluntary_exit withdrawals
EPOCH_OPERATIONS = justification_and_finalization inactivity_updates rewards_and_penalties registry_updates slashings eth1_data_reset pending_deposits pending_consolidations effective_balance_updates slashings_reset randao_mixes_reset historical_summaries_update participation_flag_updates

RISC0_DEV_MODE = 1
RUST_BACKTRACE = 0
RUST_BACKTRACE = full

.PHONY: all download run clean $(addprefix run-, $(OPERATIONS))
.PHONY: all download run clean $(addprefix run-block-, $(BLOCK_OPERATIONS)) $(addprefix run-epoch-, $(EPOCH_OPERATIONS)) block-all epoch-all

# run-execution_payload (not implemented) and run-withdrawals (incompatible with BeaconState workaround) are excluded
all: download run-attestation run-attester_slashing run-block_header run-bls_to_execution_change run-deposit run-proposer_slashing run-sync_aggregate run-voluntary_exit
# run-block-execution_payload (not implemented) and run-block-withdrawals (incompatible with BeaconState workaround) are excluded
all: download run-block-attestation run-block-attester_slashing run-block-block_header run-block-bls_to_execution_change run-block-deposit run-block-proposer_slashing run-block-sync_aggregate run-block-voluntary_exit

# Run all block processing benchmarks
block-all: $(addprefix run-block-, $(BLOCK_OPERATIONS))

# Run all epoch processing benchmarks
epoch-all: $(addprefix run-epoch-, $(EPOCH_OPERATIONS))

download:
@echo "Running download script..."
@chmod +x $(DOWNLOAD_SCRIPT)
@$(DOWNLOAD_SCRIPT)

run:
@echo "Specify an operation: $(OPERATIONS)"
@echo "Specify a block operation: $(BLOCK_OPERATIONS)"
@echo "Specify an epoch operation: $(EPOCH_OPERATIONS)"
@echo "Use: make run-block-<operation> or make run-epoch-<operation>"
@exit 1

$(addprefix run-, $(OPERATIONS)): run-%: $(EXTRACT_DIR)
$(addprefix run-block-, $(BLOCK_OPERATIONS)): run-block-%: $(EXTRACT_DIR)
@mkdir -p $(LOGS_DIR)
@mkdir -p $(SUMMARIES_DIR)
@echo "##################################################"
@echo "Running benchmarks for $*..."
@echo "Running block benchmarks for $*..."
@echo "##################################################"
@NO_COLOR=1 RISC0_DEV_MODE=$(RISC0_DEV_MODE) RUST_BACKTRACE=$(RUST_BACKTRACE) \
cargo run --release -- -o $* \
cargo run --release -- \
--excluded-cases multi_proposer_index_iterations \
--excluded-cases random_with_exits_with_duplicates \
2>&1 | tee $(LOGS_DIR)/execution_$*.log
@echo "Execution complete for $*."
@$(PARSE_SCRIPT) $*
@$(SORT_SCRIPT) $(SUMMARIES_DIR)/summary_$*.md
block $* \
2>&1 | tee $(LOGS_DIR)/execution_block_$*.log
@echo "Execution complete for block $*."
@$(PARSE_SCRIPT) block_$*
@$(SORT_SCRIPT) $(SUMMARIES_DIR)/summary_block_$*.md

$(addprefix run-epoch-, $(EPOCH_OPERATIONS)): run-epoch-%: $(EXTRACT_DIR)
@mkdir -p $(LOGS_DIR)
@mkdir -p $(SUMMARIES_DIR)
@echo "##################################################"
@echo "Running epoch processing benchmarks for $*..."
@echo "##################################################"
@NO_COLOR=1 RISC0_DEV_MODE=$(RISC0_DEV_MODE) RUST_BACKTRACE=$(RUST_BACKTRACE) \
cargo run --release -- \
epoch $* \
2>&1 | tee $(LOGS_DIR)/execution_epoch_$*.log
@echo "Execution complete for epoch $*."
@$(PARSE_SCRIPT) epoch_$*
@$(SORT_SCRIPT) $(SUMMARIES_DIR)/summary_epoch_$*.md

clean:
@echo "Cleaning up downloaded/execution files..."
Expand Down
188 changes: 172 additions & 16 deletions host/src/bin/cli/operation.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
use clap::{Parser, ValueEnum};
use clap::{Parser, Subcommand, ValueEnum};
use derive_more::Display;
use ream_lib::input::{BlockOperationType, EpochOperationType};
use std::path::PathBuf;

#[derive(Debug, Clone, Parser)]
pub struct OperationArgs {
#[clap(long, short)]
pub operation_name: OperationName,
#[clap(subcommand)]
pub operation: Operation,
}

#[derive(Debug, Clone, Subcommand)]
pub enum Operation {
Block {
#[clap(value_enum)]
operation: BlockOperation,
},
Epoch {
#[clap(value_enum)]
operation: EpochOperation,
},
}

#[derive(ValueEnum, Debug, Clone, Display)]
#[clap(rename_all = "snake_case")]
pub enum OperationName {
pub enum BlockOperation {
#[display("attestation")]
Attestation,
#[display("attester_slashing")]
Expand All @@ -32,19 +46,161 @@ pub enum OperationName {
Withdrawals,
}

impl OperationName {
pub fn to_input_name(&self) -> String {
#[derive(ValueEnum, Debug, Clone, Display)]
#[clap(rename_all = "snake_case")]
pub enum EpochOperation {
#[display("justification_and_finalization")]
JustificationAndFinalization,
#[display("inactivity_updates")]
InactivityUpdates,
#[display("rewards_and_penalties")]
RewardsAndPenalties,
#[display("registry_updates")]
RegistryUpdates,
#[display("slashings")]
Slashings,
#[display("eth1_data_reset")]
Eth1DataReset,
#[display("pending_deposits")]
PendingDeposits,
#[display("pending_consolidations")]
PendingConsolidations,
#[display("effective_balance_updates")]
EffectiveBalanceUpdates,
#[display("slashings_reset")]
SlashingsReset,
#[display("randao_mixes_reset")]
RandaoMixesReset,
#[display("historical_summaries_update")]
HistoricalSummariesUpdate,
#[display("participation_flag_updates")]
ParticipationFlagUpdates,
}

// Generic traits for operation handling
pub trait OperationHandler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub trait OperationHandler {
pub trait OperationHandler: std::fmt::Display {

If you want this to implement Display trait, you can inherit the trait like this. This can also make run_tests more clean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aah got it, makes much more sense this way.

fn prepare_input(&self, case_dir: &PathBuf) -> ream_lib::input::OperationInput;
fn load_test_cases(&self, fork: &crate::cli::fork::Fork) -> (PathBuf, Vec<String>);
fn get_operation_category(&self) -> &'static str;
}

// Block operation trait implementation
impl OperationHandler for BlockOperation {
fn prepare_input(&self, case_dir: &PathBuf) -> ream_lib::input::OperationInput {
use ream_lib::{file::ssz_from_file, input::{OperationInput, BlockOperationWrapper}};

let input_path = case_dir.join(format!("{}.ssz_snappy", self.get_input_filename()));
let ssz_bytes = ssz_from_file(&input_path);

OperationInput::Block(BlockOperationWrapper {
operation_type: self.to_block_operation_type(),
ssz_bytes,
})
}

fn load_test_cases(&self, fork: &crate::cli::fork::Fork) -> (PathBuf, Vec<String>) {
let test_case_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("mainnet")
.join("tests")
.join("mainnet");

let base_dir = test_case_dir
.join(format!("{}", fork))
.join(self.get_operation_category())
.join(self.to_string())
.join("pyspec_tests");

let test_cases = ream_lib::file::get_test_cases(&base_dir);
(base_dir, test_cases)
}

fn get_operation_category(&self) -> &'static str {
"operations"
}
}

// Epoch operation trait implementation
impl OperationHandler for EpochOperation {
fn prepare_input(&self, _case_dir: &PathBuf) -> ream_lib::input::OperationInput {
use ream_lib::input::{OperationInput, EpochOperationWrapper};

OperationInput::Epoch(EpochOperationWrapper {
operation_type: self.to_epoch_operation_type(),
})
}

fn load_test_cases(&self, fork: &crate::cli::fork::Fork) -> (PathBuf, Vec<String>) {
let test_case_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("mainnet")
.join("tests")
.join("mainnet");

let base_dir = test_case_dir
.join(format!("{}", fork))
.join(self.get_operation_category())
.join(self.to_string())
.join("pyspec_tests");

let test_cases = ream_lib::file::get_test_cases(&base_dir);
(base_dir, test_cases)
}

fn get_operation_category(&self) -> &'static str {
"epoch_processing"
}
}

// Block operation specific methods
impl BlockOperation {
fn get_input_filename(&self) -> &'static str {
match self {
BlockOperation::Attestation => "attestation",
BlockOperation::AttesterSlashing => "attester_slashing",
BlockOperation::BlockHeader => "block",
BlockOperation::BLSToExecutionChange => "address_change",
BlockOperation::Deposit => "deposit",
BlockOperation::ExecutionPayload => "body",
BlockOperation::ProposerSlashing => "proposer_slashing",
BlockOperation::SyncAggregate => "sync_aggregate",
BlockOperation::VoluntaryExit => "voluntary_exit",
BlockOperation::Withdrawals => "execution_payload",
}
}

fn to_block_operation_type(&self) -> BlockOperationType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe to_* functions can be implemented with From trait (https://doc.rust-lang.org/std/convert/trait.From.html)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll use the From trait instead

match self {
BlockOperation::Attestation => BlockOperationType::Attestation,
BlockOperation::AttesterSlashing => BlockOperationType::AttesterSlashing,
BlockOperation::BlockHeader => BlockOperationType::BlockHeader,
BlockOperation::BLSToExecutionChange => BlockOperationType::BLSToExecutionChange,
BlockOperation::Deposit => BlockOperationType::Deposit,
BlockOperation::ExecutionPayload => BlockOperationType::ExecutionPayload,
BlockOperation::ProposerSlashing => BlockOperationType::ProposerSlashing,
BlockOperation::SyncAggregate => BlockOperationType::SyncAggregate,
BlockOperation::VoluntaryExit => BlockOperationType::VoluntaryExit,
BlockOperation::Withdrawals => BlockOperationType::Withdrawals,
}
}
}

// Epoch operation specific methods
impl EpochOperation {
fn to_epoch_operation_type(&self) -> EpochOperationType {
match self {
OperationName::Attestation => "attestation".to_string(),
OperationName::AttesterSlashing => "attester_slashing".to_string(),
OperationName::BlockHeader => "block".to_string(),
OperationName::BLSToExecutionChange => "address_change".to_string(),
OperationName::Deposit => "deposit".to_string(),
OperationName::ExecutionPayload => "body".to_string(),
OperationName::ProposerSlashing => "proposer_slashing".to_string(),
OperationName::SyncAggregate => "sync_aggregate".to_string(),
OperationName::VoluntaryExit => "voluntary_exit".to_string(),
OperationName::Withdrawals => "execution_payload".to_string(),
EpochOperation::JustificationAndFinalization => EpochOperationType::JustificationAndFinalization,
EpochOperation::InactivityUpdates => EpochOperationType::InactivityUpdates,
EpochOperation::RewardsAndPenalties => EpochOperationType::RewardsAndPenalties,
EpochOperation::RegistryUpdates => EpochOperationType::RegistryUpdates,
EpochOperation::Slashings => EpochOperationType::Slashings,
EpochOperation::Eth1DataReset => EpochOperationType::Eth1DataReset,
EpochOperation::PendingDeposits => EpochOperationType::PendingDeposits,
EpochOperation::PendingConsolidations => EpochOperationType::PendingConsolidations,
EpochOperation::EffectiveBalanceUpdates => EpochOperationType::EffectiveBalanceUpdates,
EpochOperation::SlashingsReset => EpochOperationType::SlashingsReset,
EpochOperation::RandaoMixesReset => EpochOperationType::RandaoMixesReset,
EpochOperation::HistoricalSummariesUpdate => EpochOperationType::HistoricalSummariesUpdate,
EpochOperation::ParticipationFlagUpdates => EpochOperationType::ParticipationFlagUpdates,
}
}
}

Loading
Loading