Skip to content

Commit

Permalink
wip: testing no_panic
Browse files Browse the repository at this point in the history
  • Loading branch information
fborello-lambda committed Dec 3, 2024
1 parent 94df083 commit b9d01a9
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 48 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cmd/ethrex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ libmdbx = ["dep:libmdbx", "ethrex-storage/libmdbx"]
redb = ["dep:redb", "ethrex-storage/redb"]
l2 = ["ethrex-vm/l2"]
levm = ["ethrex-vm/levm", "ethrex-blockchain/levm"]

[profile.release]
lto = "fat"
codegen-units = 1
42 changes: 42 additions & 0 deletions crates/common/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,48 @@ pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> u64 {
output / denominator
}

#[derive(Debug, thiserror::Error)]
pub enum FakeExponentialError {
#[error("Denominator cannot be zero.")]
DenominatorIsZero,
#[error("Checked div failed is None.")]
CheckedDiv,
#[error("Checked mul failed is None.")]
CheckedMul,
}

pub fn fake_exponential_checked(
factor: u64,
numerator: u64,
denominator: u64,
) -> Result<u64, FakeExponentialError> {
let mut i = 1_u64;
let mut output = 0_u64;
let mut numerator_accum = factor * denominator;
if denominator == 0 {
return Err(FakeExponentialError::DenominatorIsZero);
}

while numerator_accum > 0 {
output = output.saturating_add(numerator_accum);

let denominator_i = denominator
.checked_mul(i)
.ok_or(FakeExponentialError::CheckedMul)?;

if denominator_i == 0 {
return Err(FakeExponentialError::DenominatorIsZero);
}

numerator_accum = numerator_accum * numerator / denominator_i;
i += 1;
}

output
.checked_div(denominator)
.ok_or(FakeExponentialError::CheckedDiv)
}

// Calculates the base fee for the current block based on its gas_limit and parent's gas and fee
// Returns None if the block gas limit is not valid in relation to its parent's gas limit
pub fn calculate_base_fee_per_gas(
Expand Down
2 changes: 1 addition & 1 deletion crates/l2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ secp256k1.workspace = true
keccak-hash = "0.10.0"
envy = "0.4.2"
thiserror.workspace = true
no-panic = "0.1"
zkvm_interface = { path = "./prover/zkvm/interface/", default-features = false }

# risc0
risc0-zkvm = { version = "1.1.2" }

Expand Down
4 changes: 3 additions & 1 deletion crates/l2/proposer/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::mpsc::SendError;
use crate::utils::merkle_tree::MerkleError;
use crate::utils::{config::errors::ConfigError, eth_client::errors::EthClientError};
use ethereum_types::FromStrRadixErr;
use ethrex_core::types::BlobsBundleError;
use ethrex_core::types::{BlobsBundleError, FakeExponentialError};
use ethrex_dev::utils::engine_client::errors::EngineClientError;
use ethrex_storage::error::StoreError;
use ethrex_vm::EvmError;
Expand Down Expand Up @@ -115,6 +115,8 @@ pub enum BlobEstimationError {
CalculationError,
#[error("Blob gas estimation resulted in an infinite or undefined value. Outside valid or expected ranges")]
NonFiniteResult,
#[error("{0}")]
FakeExponentialError(#[from] FakeExponentialError),
}

#[derive(Debug, thiserror::Error)]
Expand Down
35 changes: 21 additions & 14 deletions crates/l2/proposer/l1_committer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
use bytes::Bytes;
use ethrex_core::{
types::{
blobs_bundle, fake_exponential, BlobsBundle, Block, PrivilegedL2Transaction,
blobs_bundle, fake_exponential_checked, BlobsBundle, Block, PrivilegedL2Transaction,
PrivilegedTxType, Transaction, TxKind, BLOB_BASE_FEE_UPDATE_FRACTION,
MIN_BASE_FEE_PER_BLOB_GAS,
},
Expand All @@ -28,6 +28,8 @@ use tracing::{error, info};

use super::errors::BlobEstimationError;

use no_panic::no_panic;

const COMMIT_FUNCTION_SELECTOR: [u8; 4] = [132, 97, 12, 179];

pub struct Committer {
Expand Down Expand Up @@ -159,7 +161,8 @@ impl Committer {
}
}

pub fn get_block_withdrawals(
//#[no_panic]
fn get_block_withdrawals(
&self,
block: &Block,
) -> Result<Vec<(H256, PrivilegedL2Transaction)>, CommitterError> {
Expand All @@ -180,7 +183,8 @@ impl Committer {
Ok(withdrawals)
}

pub fn get_withdrawals_merkle_root(
//#[no_panic]
fn get_withdrawals_merkle_root(
&self,
withdrawals_hashes: Vec<H256>,
) -> Result<H256, CommitterError> {
Expand All @@ -191,7 +195,8 @@ impl Committer {
}
}

pub fn get_block_deposits(&self, block: &Block) -> Vec<PrivilegedL2Transaction> {
//#[no_panic]
fn get_block_deposits(&self, block: &Block) -> Vec<PrivilegedL2Transaction> {
let deposits = block
.body
.transactions
Expand All @@ -209,7 +214,8 @@ impl Committer {
deposits
}

pub fn get_deposit_hash(&self, deposit_hashes: Vec<H256>) -> Result<H256, CommitterError> {
//#[no_panic]
fn get_deposit_hash(&self, deposit_hashes: Vec<H256>) -> Result<H256, CommitterError> {
if !deposit_hashes.is_empty() {
let deposit_hashes_len: u16 = deposit_hashes
.len()
Expand Down Expand Up @@ -237,14 +243,15 @@ impl Committer {
}
}
/// Prepare the state diff for the block.
pub fn prepare_state_diff(
//#[no_panic]
fn prepare_state_diff(
&self,
block: &Block,
store: Store,
withdrawals: Vec<(H256, PrivilegedL2Transaction)>,
deposits: Vec<PrivilegedL2Transaction>,
) -> Result<StateDiff, CommitterError> {
info!("Preparing state diff for block {}", block.header.number);
//info!("Preparing state diff for block {}", block.header.number);

let mut state = evm_state(store.clone(), block.header.parent_hash);
execute_block(block, &mut state).map_err(CommitterError::from)?;
Expand Down Expand Up @@ -314,18 +321,16 @@ impl Committer {
}

/// Generate the blob bundle necessary for the EIP-4844 transaction.
pub fn generate_blobs_bundle(
&self,
state_diff: &StateDiff,
) -> Result<BlobsBundle, CommitterError> {
//#[no_panic]
fn generate_blobs_bundle(&self, state_diff: &StateDiff) -> Result<BlobsBundle, CommitterError> {
let blob_data = state_diff.encode().map_err(CommitterError::from)?;

let blob = blobs_bundle::blob_from_bytes(blob_data).map_err(CommitterError::from)?;

BlobsBundle::create_from_blobs(&vec![blob]).map_err(CommitterError::from)
}

pub async fn send_commitment(
async fn send_commitment(
&self,
block_number: u64,
withdrawal_logs_merkle_root: H256,
Expand Down Expand Up @@ -438,11 +443,13 @@ async fn estimate_blob_gas(
};

// If the blob's market is in high demand, the equation may give a really big number.
let blob_gas = fake_exponential(
// This function doesn't panic, it performs checked/saturating operations.
let blob_gas = fake_exponential_checked(
MIN_BASE_FEE_PER_BLOB_GAS,
total_blob_gas,
BLOB_BASE_FEE_UPDATE_FRACTION,
);
)
.map_err(BlobEstimationError::FakeExponentialError)?;

let gas_with_headroom = (blob_gas * (100 + headroom)) / 100;

Expand Down
63 changes: 45 additions & 18 deletions crates/l2/proposer/prover_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use keccak_hash::keccak;
use secp256k1::SecretKey;
use serde::{Deserialize, Serialize};
use std::{
io::{BufReader, BufWriter},
io::{BufReader, BufWriter, Write},
net::{IpAddr, Shutdown, TcpListener, TcpStream},
sync::mpsc::{self, Receiver},
thread,
Expand All @@ -28,6 +28,8 @@ use tokio::{
};
use tracing::{debug, error, info, warn};

use no_panic::no_panic;

use risc0_zkvm::sha::{Digest, Digestible};

#[derive(Debug, Serialize, Deserialize, Default)]
Expand Down Expand Up @@ -78,6 +80,34 @@ pub enum ProofData {
SubmitAck { block_number: u64 },
}

impl ProofData {
/// Builder function for creating a Request
pub fn request() -> Self {
ProofData::Request
}

/// Builder function for creating a Response
pub fn response(block_number: Option<u64>, input: Option<ProverInputData>) -> Self {
ProofData::Response {
block_number,
input,
}
}

/// Builder function for creating a Submit
pub fn submit(block_number: u64, receipt: (risc0_zkvm::Receipt, Vec<u32>)) -> Self {
ProofData::Submit {
block_number,
receipt: Box::new(receipt),
}
}

/// Builder function for creating a SubmitAck
pub fn submit_ack(block_number: u64) -> Self {
ProofData::SubmitAck { block_number }
}
}

pub async fn start_prover_server(store: Store) -> Result<(), ConfigError> {
let server_config = ProverServerConfig::from_env()?;
let eth_config = EthConfig::from_env()?;
Expand Down Expand Up @@ -219,10 +249,7 @@ impl ProverServer {
let data: Result<ProofData, _> = serde_json::de::from_reader(buf_reader);
match data {
Ok(ProofData::Request) => {
if let Err(e) = self
.handle_request(&mut stream, last_verified_block + 1)
.await
{
if let Err(e) = self.handle_request(&stream, last_verified_block + 1).await {
warn!("Failed to handle request: {e}");
}
}
Expand Down Expand Up @@ -252,7 +279,7 @@ impl ProverServer {

async fn handle_request(
&self,
stream: &mut TcpStream,
stream: &TcpStream,
block_number: u64,
) -> Result<(), ProverServerError> {
debug!("Request received");
Expand All @@ -263,18 +290,12 @@ impl ProverServer {
.ok_or(ProverServerError::StorageDataIsNone)?;

let response = if block_number > latest_block_number {
let response = ProofData::Response {
block_number: None,
input: None,
};
let response = ProofData::response(None, None);
warn!("Didn't send response");
response
} else {
let input = self.create_prover_input(block_number)?;
let response = ProofData::Response {
block_number: Some(block_number),
input: Some(input),
};
let response = ProofData::response(Some(block_number), Some(input));
info!("Sent Response for block_number: {block_number}");
response
};
Expand All @@ -284,17 +305,22 @@ impl ProverServer {
.map_err(|e| ProverServerError::ConnectionError(e.into()))
}

#[no_panic]
fn handle_submit(
&self,
stream: &mut TcpStream,
block_number: u64,
) -> Result<(), ProverServerError> {
debug!("Submit received for BlockNumber: {block_number}");

let response = ProofData::SubmitAck { block_number };
let writer = BufWriter::new(stream);
serde_json::to_writer(writer, &response)
.map_err(|e| ProverServerError::ConnectionError(e.into()))
let response = ProofData::submit_ack(block_number);
let json_string = serde_json::to_string(&response)
.map_err(|e| ProverServerError::Custom(format!("serde_json::to_string(): {e}")))?;
stream
.write_all(json_string.as_bytes())
.map_err(ProverServerError::ConnectionError)?;

Ok(())
}

async fn handle_proof_submission(
Expand Down Expand Up @@ -342,6 +368,7 @@ impl ProverServer {
Ok(())
}

//#[no_panic]
fn create_prover_input(&self, block_number: u64) -> Result<ProverInputData, ProverServerError> {
let header = self
.store
Expand Down
4 changes: 4 additions & 0 deletions crates/l2/proposer/state_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use ethereum_types::{Address, H256, U256};

use super::errors::StateDiffError;

use no_panic::no_panic;

#[derive(Clone)]
pub struct AccountStateDiff {
pub new_balance: Option<U256>,
Expand Down Expand Up @@ -82,6 +84,7 @@ impl From<AccountStateDiffType> for u8 {
}

impl StateDiff {
//#[no_panic]
pub fn encode(&self) -> Result<Bytes, StateDiffError> {
if self.version != 1 {
return Err(StateDiffError::UnsupportedVersion(self.version));
Expand Down Expand Up @@ -127,6 +130,7 @@ impl StateDiff {
}

impl AccountStateDiff {
//#[no_panic]
pub fn encode(&self) -> Result<(u8, Bytes), StateDiffError> {
if self.bytecode.is_some() && self.bytecode_hash.is_some() {
return Err(StateDiffError::BytecodeAndBytecodeHashSet);
Expand Down
1 change: 1 addition & 0 deletions crates/l2/prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tokio-util.workspace = true
tracing-subscriber = { workspace = true, features = ["env-filter"] }
tracing.workspace = true
hex.workspace = true
no-panic = "0.1"

# ethrex
ethrex-core.workspace = true
Expand Down
Loading

0 comments on commit b9d01a9

Please sign in to comment.