Skip to content

Commit

Permalink
Merge branch 'main' into levm/transact-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ilitteri authored Dec 2, 2024
2 parents 2ef311a + 7f72d73 commit f12fd22
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/hive_coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Daily Hive Coverage
on:
schedule:
# Every day at UTC midnight
- cron: "0 0 * * *"
- cron: "0 0 * * 1,2,3,4,5"
workflow_dispatch:

env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/levm_reporter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Daily LEVM Reporter
on:
schedule:
# Every day at midnight
- cron: "0 0 * * *"
- cron: "0 0 * * 1,2,3,4,5"
workflow_dispatch:

env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/loc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Daily Lines of Code Report
on:
schedule:
# Every day at midnight
- cron: "0 0 * * *"
- cron: "0 0 * * 1,2,3,4,5"
workflow_dispatch:

env:
Expand Down
2 changes: 1 addition & 1 deletion crates/common/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ pub fn calculate_base_fee_per_blob_gas(parent_excess_blob_gas: u64) -> u64 {
}

// Defined in [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844)
fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> u64 {
pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> u64 {
let mut i = 1;
let mut output = 0;
let mut numerator_accum = factor * denominator;
Expand Down
12 changes: 12 additions & 0 deletions crates/common/types/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ pub enum TxType {
Privileged = 0x7e,
}

impl From<TxType> for u8 {
fn from(val: TxType) -> Self {
match val {
TxType::Legacy => 0x00,
TxType::EIP2930 => 0x01,
TxType::EIP1559 => 0x02,
TxType::EIP4844 => 0x03,
TxType::Privileged => 0x7e,
}
}
}

pub trait Signable {
fn sign(&self, private_key: &SecretKey) -> Self
where
Expand Down
2 changes: 2 additions & 0 deletions crates/l2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ path = "./l2.rs"
unwrap_used = "deny"
expect_used = "deny"
indexing_slicing = "deny"
as_conversions = "deny"
unnecessary_cast = "warn"
2 changes: 2 additions & 0 deletions crates/l2/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ path = "./deployer.rs"
unwrap_used = "deny"
expect_used = "deny"
indexing_slicing = "deny"
as_conversions = "deny"
unnecessary_cast = "warn"
4 changes: 4 additions & 0 deletions crates/l2/proposer/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ pub enum CommitterError {
InvalidWithdrawalTransaction,
#[error("Blob estimation failed: {0}")]
BlobEstimationError(#[from] BlobEstimationError),
#[error("length does not fit in u16")]
TryIntoError(#[from] std::num::TryFromIntError),
}

#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -131,4 +133,6 @@ pub enum StateDiffError {
BytecodeAndBytecodeHashSet,
#[error("Empty account diff")]
EmptyAccountDiff,
#[error("The length of the vector is too big to fit in u16: {0}")]
LengthTooBig(#[from] core::num::TryFromIntError),
}
37 changes: 22 additions & 15 deletions crates/l2/proposer/l1_committer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ use crate::{
use bytes::Bytes;
use ethrex_core::{
types::{
blobs_bundle, BlobsBundle, Block, PrivilegedL2Transaction, PrivilegedTxType, Transaction,
TxKind, BLOB_BASE_FEE_UPDATE_FRACTION,
blobs_bundle, fake_exponential, BlobsBundle, Block, PrivilegedL2Transaction,
PrivilegedTxType, Transaction, TxKind, BLOB_BASE_FEE_UPDATE_FRACTION,
MIN_BASE_FEE_PER_BLOB_GAS,
},
Address, H256, U256,
};
use ethrex_storage::{error::StoreError, Store};
use ethrex_vm::{evm_state, execute_block, get_state_transitions};
use keccak_hash::keccak;
use secp256k1::SecretKey;
use std::f64::consts::E;
use std::{collections::HashMap, time::Duration};
use tokio::time::sleep;
use tracing::{error, info};
Expand Down Expand Up @@ -211,9 +211,13 @@ impl Committer {

pub 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()
.try_into()
.map_err(CommitterError::from)?;
Ok(H256::from_slice(
[
&(deposit_hashes.len() as u16).to_be_bytes(),
&deposit_hashes_len.to_be_bytes(),
keccak(
deposit_hashes
.iter()
Expand Down Expand Up @@ -270,7 +274,9 @@ impl Committer {
.clone()
.ok_or(CommitterError::FailedToRetrieveDataFromStorage)?
.nonce
- prev_nonce) as u16,
- prev_nonce)
.try_into()
.map_err(CommitterError::from)?,
storage: account_update.added_storage.clone().into_iter().collect(),
bytecode: account_update.code.clone(),
bytecode_hash: None,
Expand Down Expand Up @@ -347,7 +353,7 @@ impl Committer {
let le_bytes = estimate_blob_gas(
&self.eth_client,
self.arbitrary_base_blob_gas_price,
1.2, // 20% of headroom
20, // 20% of headroom
)
.await?
.to_le_bytes();
Expand Down Expand Up @@ -393,7 +399,7 @@ impl Committer {
/// # Parameters:
/// - `eth_client`: The Ethereum client used to fetch the latest block.
/// - `arbitrary_base_blob_gas_price`: The base gas price that serves as the minimum price for blob transactions.
/// - `headroom`: A multiplier (as a float) applied to the estimated gas price to provide a buffer against fluctuations.
/// - `headroom`: Percentage applied to the estimated gas price to provide a buffer against fluctuations.
///
/// # Formula:
/// The gas price is estimated using an exponential function based on the blob gas used in the latest block and the
Expand All @@ -404,7 +410,7 @@ impl Committer {
async fn estimate_blob_gas(
eth_client: &EthClient,
arbitrary_base_blob_gas_price: u64,
headroom: f64,
headroom: u64,
) -> Result<u64, CommitterError> {
let latest_block = eth_client
.get_block_by_number(BlockByNumber::Latest)
Expand Down Expand Up @@ -432,15 +438,16 @@ async fn estimate_blob_gas(
};

// If the blob's market is in high demand, the equation may give a really big number.
let exponent = (total_blob_gas as f64) / (BLOB_BASE_FEE_UPDATE_FRACTION as f64);
let blob_gas = match E.powf(exponent) {
result if result.is_finite() => result,
_ => return Err(BlobEstimationError::NonFiniteResult.into()),
};
let blob_gas = fake_exponential(
MIN_BASE_FEE_PER_BLOB_GAS,
total_blob_gas,
BLOB_BASE_FEE_UPDATE_FRACTION,
);

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

// Check if we have an overflow when we take the headroom into account.
let gas_with_headroom = blob_gas * headroom;
let blob_gas = match arbitrary_base_blob_gas_price.checked_add(gas_with_headroom as u64) {
let blob_gas = match arbitrary_base_blob_gas_price.checked_add(gas_with_headroom) {
Some(gas) => gas,
None => return Err(BlobEstimationError::OverflowError.into()),
};
Expand Down
7 changes: 6 additions & 1 deletion crates/l2/proposer/prover_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,12 @@ impl ProverServer {
calldata.extend(journal_digest.as_bytes());

// extend with size of seal
calldata.extend(H256::from_low_u64_be(seal.len() as u64).as_bytes());
calldata.extend(
H256::from_low_u64_be(seal.len().try_into().map_err(|err| {
ProverServerError::Custom(format!("Seal length does not fit in u64: {}", err))
})?)
.as_bytes(),
);
// extend with seal
calldata.extend(seal);
// extend with zero padding
Expand Down
48 changes: 40 additions & 8 deletions crates/l2/proposer/state_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,32 @@ impl Default for StateDiff {
}
}

impl From<AccountStateDiffType> for u8 {
fn from(value: AccountStateDiffType) -> Self {
match value {
AccountStateDiffType::NewBalance => 1,
AccountStateDiffType::NonceDiff => 2,
AccountStateDiffType::Storage => 4,
AccountStateDiffType::Bytecode => 8,
AccountStateDiffType::BytecodeHash => 16,
}
}
}

impl StateDiff {
pub fn encode(&self) -> Result<Bytes, StateDiffError> {
if self.version != 1 {
return Err(StateDiffError::UnsupportedVersion(self.version));
}
let modified_accounts_len: u16 = self
.modified_accounts
.len()
.try_into()
.map_err(StateDiffError::from)?;

let mut encoded: Vec<u8> = Vec::new();
encoded.push(self.version);
encoded.extend((self.modified_accounts.len() as u16).to_be_bytes());
encoded.extend(modified_accounts_len.to_be_bytes());

for (address, diff) in &self.modified_accounts {
let (r#type, diff_encoded) = diff.encode()?;
Expand Down Expand Up @@ -119,20 +136,28 @@ impl AccountStateDiff {
let mut encoded: Vec<u8> = Vec::new();

if let Some(new_balance) = self.new_balance {
r#type += AccountStateDiffType::NewBalance as u8;
let r_type: u8 = AccountStateDiffType::NewBalance.into();
r#type += r_type;
let buf = &mut [0u8; 32];
new_balance.to_big_endian(buf);
encoded.extend_from_slice(buf);
}

if self.nonce_diff != 0 {
r#type += AccountStateDiffType::NonceDiff as u8;
let r_type: u8 = AccountStateDiffType::NonceDiff.into();
r#type += r_type;
encoded.extend(self.nonce_diff.to_be_bytes());
}

if !self.storage.is_empty() {
r#type += AccountStateDiffType::Storage as u8;
encoded.extend((self.storage.len() as u16).to_be_bytes());
let r_type: u8 = AccountStateDiffType::Storage.into();
let storage_len: u16 = self
.storage
.len()
.try_into()
.map_err(StateDiffError::from)?;
r#type += r_type;
encoded.extend(storage_len.to_be_bytes());
for (key, value) in &self.storage {
encoded.extend_from_slice(&key.0);
let buf = &mut [0u8; 32];
Expand All @@ -142,13 +167,20 @@ impl AccountStateDiff {
}

if let Some(bytecode) = &self.bytecode {
r#type += AccountStateDiffType::Bytecode as u8;
encoded.extend((bytecode.len() as u16).to_be_bytes());
let r_type: u8 = AccountStateDiffType::Bytecode.into();
let bytecode_len: u16 = self
.storage
.len()
.try_into()
.map_err(StateDiffError::from)?;
r#type += r_type;
encoded.extend(bytecode_len.to_be_bytes());
encoded.extend(bytecode);
}

if let Some(bytecode_hash) = &self.bytecode_hash {
r#type += AccountStateDiffType::BytecodeHash as u8;
let r_type: u8 = AccountStateDiffType::BytecodeHash.into();
r#type += r_type;
encoded.extend(&bytecode_hash.0);
}

Expand Down
2 changes: 2 additions & 0 deletions crates/l2/prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ gpu = ["risc0-zkvm/cuda"]
unwrap_used = "deny"
expect_used = "deny"
indexing_slicing = "deny"
as_conversions = "deny"
unnecessary_cast = "warn"
2 changes: 2 additions & 0 deletions crates/l2/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ path = "src/sdk.rs"
unwrap_used = "deny"
expect_used = "deny"
indexing_slicing = "deny"
as_conversions = "deny"
unnecessary_cast = "warn"
9 changes: 7 additions & 2 deletions crates/l2/sdk/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ pub async fn get_withdraw_merkle_proof(
Transaction::PrivilegedL2Transaction(privileged_l2_transaction) => {
privileged_l2_transaction
.get_withdrawal_hash()
.map(|withdrawal_hash| (i as u64, (withdrawal_hash)))
.map(|withdrawal_hash| (i, (withdrawal_hash)))
}
_ => unreachable!(),
})
Expand All @@ -283,5 +283,10 @@ pub async fn get_withdraw_merkle_proof(
"Failed to generate merkle proof, element is not on the tree".to_string(),
))?;

Ok((index, path))
Ok((
index
.try_into()
.map_err(|err| EthClientError::Custom(format!("index does not fit in u64: {}", err)))?,
path,
))
}
6 changes: 5 additions & 1 deletion crates/l2/utils/eth_client/eth_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ impl EthClient {
let encoded_from = deployer.encode_to_vec();
// FIXME: We'll probably need to use nonce - 1 since it was updated above.
let encoded_nonce = self.get_nonce(deployer).await?.encode_to_vec();
let mut encoded = vec![(0xc0 + encoded_from.len() + encoded_nonce.len()) as u8];
let mut encoded = vec![(0xc0 + encoded_from.len() + encoded_nonce.len())
.try_into()
.map_err(|err| {
EthClientError::Custom(format!("Failed to encode deployed_address {}", err))
})?];
encoded.extend(encoded_from.clone());
encoded.extend(encoded_nonce.clone());
let deployed_address = Address::from(keccak(encoded));
Expand Down
Loading

0 comments on commit f12fd22

Please sign in to comment.