Skip to content
Merged
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
2 changes: 1 addition & 1 deletion contracts/src/deploy-config/holesky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const config = {
l2BaseFee: 0.1, // Gwei

// verify contract config
programVkey: '0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076',
programVkey: '0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 600,
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/deploy-config/hoodi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const config = {
l2BaseFee: 0.1, // Gwei

// verify contract config
programVkey: '0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076',
programVkey: '0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 600,
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/deploy-config/l1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const config = {
l2BaseFee: 0.1, // Gwei

// verify contract config
programVkey: '0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076',
programVkey: '0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 10,
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/deploy-config/qanetl1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const config = {
l2BaseFee: 0.1, // Gwei

// verify contract config
programVkey: '0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076',
programVkey: '0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 600,
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/deploy-config/sepolia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const config = {
/**
* ---to---legacy property
*/
programVkey: '0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076',
programVkey: '0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63',
rollupMinDeposit: 0.0001,
rollupProofWindow: 86400,
rollupGenesisBlockNumber: 0,
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/deploy-config/testnetl1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const config = {
sequencerWindowSize: 200,
channelTimeout: 120,

programVkey: '0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076',
programVkey: '0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63',
rollupMinDeposit: 1,
rollupProofWindow: 100,
rollupGenesisBlockNumber: 0,
Expand Down
Binary file modified prover/bin/client/elf/verifier-client
Binary file not shown.
28 changes: 15 additions & 13 deletions prover/bin/server/src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,17 @@ impl Prover {
let prove_rt = self.batch_prover.prove(&mut input, !shadow).await;

match prove_rt {
Ok(Some(proof)) => {
save_proof(batch_index, proof);
PROVE_RESULT.set(1);
let duration_mins = start.elapsed().as_secs() / 60;
PROVE_TIME.set(duration_mins.try_into().unwrap_or_default());
}
Ok(Some(proof)) => match save_proof(batch_index, proof) {
Ok(()) => {
PROVE_RESULT.set(1);
let duration_mins = start.elapsed().as_secs() / 60;
PROVE_TIME.set(duration_mins.try_into().unwrap_or_default());
}
Err(e) => {
PROVE_RESULT.set(2);
log::error!("Save evm proof of batch-{:?} error: {:?}", batch_index, e);
}
},
Ok(None) => {
PROVE_RESULT.set(2);
log::error!("Gen proof of batch-{:?} is none", batch_index)
Expand Down Expand Up @@ -196,16 +201,13 @@ async fn gen_client_input(
}

/// Save evm proof to file.
fn save_proof(batch_index: u64, proof: EvmProofFixture) {
fn save_proof(batch_index: u64, proof: EvmProofFixture) -> Result<(), anyhow::Error> {
let batch_dir =
PathBuf::from(PROVER_PROOF_DIR.to_string()).join(format!("batch_{batch_index}"));
std::fs::create_dir_all(&batch_dir).expect("failed to create proof path");
std::fs::write(
batch_dir.join("plonk_proof.json"),
serde_json::to_string_pretty(&proof).unwrap(),
)
.expect("failed to write proof");
std::fs::create_dir_all(&batch_dir)?;
std::fs::write(batch_dir.join("plonk_proof.json"), serde_json::to_string_pretty(&proof)?)?;
log::info!("Successfully save evm proof of batch-{:?}", batch_index);
Ok(())
}

#[allow(dead_code)]
Expand Down
2 changes: 1 addition & 1 deletion prover/bin/shadow-prove/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ forge build

EvmVerifier:
```
forge create --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545 src/libs/EvmVerifier.sol:EvmVerifier --constructor-args 0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076
forge create --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545 src/libs/EvmVerifier.sol:EvmVerifier --constructor-args 0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63
```

ShadowRollup
Expand Down
2 changes: 1 addition & 1 deletion prover/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ $ forge test

### Deploy
```
forge create --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545 prover/contracts/src/EvmVerifier.sol:EvmVerifier --constructor-args 0x001fe18a35489f0e7ae203bc2b1f26b7696f00bafa8000518c94a479d29c4076
forge create --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545 prover/contracts/src/EvmVerifier.sol:EvmVerifier --constructor-args 0x00b450ec2a1b8dfba81ade90afbcc96842055548b814c991bb13bdca34980c63
```
2 changes: 2 additions & 0 deletions prover/crates/executor/client/src/types/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub enum ClientError {
MissingTrie(Address),
#[error("Invalid block number found in headers \n expected: {} found: {}", .0, .1)]
InvalidHeaderBlockNumber(u64, u64),
#[error("Invalid base fee found in header \n expected: {} found: {}", .0, .1)]
InvalidHeaderBaseFee(u64, u64),
#[error("Invalid parent header found for block \n expected: {}, found: {}", .0, .1)]
InvalidHeaderParentHash(FixedBytes<32>, FixedBytes<32>),
#[error("Failed to validate post exectution state {}", 0)]
Expand Down
33 changes: 26 additions & 7 deletions prover/crates/executor/client/src/types/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use alloy_primitives::{map::HashMap, U256};
use prover_mpt::EthereumState;
use prover_primitives::{types::block::L2Block, Address};
use prover_storage_witness::TrieDB;
use reth_trie::{TrieAccount, EMPTY_ROOT_HASH};
use revm::{primitives::keccak256, state::Bytecode};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
Expand Down Expand Up @@ -30,12 +31,26 @@ pub struct BlockInput {
}

impl BlockInput {
pub fn witness_db(&self) -> Result<TrieDB<'_>, ClientError> {
// verify the state root
fn validate_parent_state(&self) -> Result<(), ClientError> {
if self.current_block.prev_state_root != self.parent_state.state_root() {
return Err(ClientError::InvalidHeaderStateRoot);
}

for (hashed_address, storage_trie) in &self.parent_state.storage_tries {
let account =
self.parent_state.state_trie.get_rlp::<TrieAccount>(hashed_address.as_slice())?;
let storage_root = account.map_or(EMPTY_ROOT_HASH, |account| account.storage_root);
if storage_trie.hash() != storage_root {
return Err(ClientError::MismatchedStorageRoot);
}
}

Ok(())
}

pub fn witness_db(&self) -> Result<TrieDB<'_>, ClientError> {
self.validate_parent_state()?;

let bytecodes_by_hash =
self.bytecodes.iter().map(|code| (code.hash_slow(), code)).collect::<HashMap<_, _>>();

Expand All @@ -50,17 +65,21 @@ impl BlockInput {
/// Get storage value of address at index.
pub fn get_storage_value(&self, address: Address, index: U256) -> Result<U256, ClientError> {
let hashed_address = keccak256(address);
let hashed_address = hashed_address.as_slice();

let storage_trie = self
.parent_state
.storage_tries
.get(hashed_address)
.expect("A storage trie must be provided for each account");
.get(&hashed_address)
.ok_or(ClientError::MissingTrie(address))?;
let account =
self.parent_state.state_trie.get_rlp::<TrieAccount>(hashed_address.as_slice())?;
let storage_root = account.map_or(EMPTY_ROOT_HASH, |account| account.storage_root);
if storage_trie.hash() != storage_root {
return Err(ClientError::MismatchedStorageRoot);
}

Ok(storage_trie
.get_rlp::<U256>(keccak256(index.to_be_bytes::<32>()).as_slice())
.expect("Can get from MPT")
.get_rlp::<U256>(keccak256(index.to_be_bytes::<32>()).as_slice())?
.unwrap_or_default())
}
}
Expand Down
28 changes: 21 additions & 7 deletions prover/crates/executor/client/src/verifier/evm_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use revm::database::State;
// use Verifier;
pub struct EVMVerifier;

const L2_BASE_FEE: u64 = 1_000_000;

impl EVMVerifier {
pub fn verify(blocks: Vec<BlockInput>) -> Result<BatchInfo, ClientError> {
// Edge case: nothing to execute.
Expand All @@ -18,13 +20,20 @@ impl EVMVerifier {
"empty batch: no block inputs provided".to_owned(),
));
}
// Verify that each block's `prev_state_root` matches the previous block's `post_state_root`.
// This ensures the batch is contiguous.
if blocks
.windows(2)
.any(|w| w[0].current_block.post_state_root != w[1].current_block.prev_state_root)
{
return Err(ClientError::DiscontinuousStateRoot);
// Verify that block numbers and state roots are consecutive within the batch.
for window in blocks.windows(2) {
let previous = window[0].current_block.header.number.to::<u64>();
let current = window[1].current_block.header.number.to::<u64>();
let expected = previous
.checked_add(1)
.ok_or(ClientError::InvalidHeaderBlockNumber(previous, current))?;
if current != expected {
return Err(ClientError::InvalidHeaderBlockNumber(expected, current));
}

if window[0].current_block.post_state_root != window[1].current_block.prev_state_root {
return Err(ClientError::DiscontinuousStateRoot);
}
}
execute(blocks)
}
Expand Down Expand Up @@ -70,7 +79,12 @@ fn execute_block(block_input: &mut BlockInput) -> Result<(), ClientError> {
}
return Ok(());
}

let header = &block.header;
let base_fee = header.base_fee_per_gas.unwrap_or_default().to::<u64>();
if base_fee != L2_BASE_FEE {
return Err(ClientError::InvalidHeaderBaseFee(L2_BASE_FEE, base_fee));
}
let chain_id = block.chain_id;
let _tx_count = block.transactions.len();
let _block_num = header.number.to::<u64>();
Expand Down
30 changes: 0 additions & 30 deletions prover/crates/primitives/src/predeployed.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,3 @@
/// Predeployed Gas Price Oracle
pub mod l1_gas_price_oracle {
use alloy_primitives::{address, Address, U256};

/// L1GasPriceOracle predeployed address
pub const ADDRESS: Address = address!("5300000000000000000000000000000000000002");
/// L1 base fee slot in L1GasPriceOracle
pub const BASE_FEE_SLOT: U256 = U256::from_limbs([1, 0, 0, 0]);

/// The following 2 slots will be depreciated after curie fork
/// L1 overhead slot in L1GasPriceOracle
pub const OVERHEAD_SLOT: U256 = U256::from_limbs([2, 0, 0, 0]);
/// L1 scalar slot in L1GasPriceOracle
pub const SCALAR_SLOT: U256 = U256::from_limbs([3, 0, 0, 0]);

/// THe following 3 slots plus `BASE_FEE_SLOT` will be used for l1 fee after curie fork
/// L1 BlobBaseFee slot in L1GasPriceOracle after Curie fork
pub const L1_BLOB_BASEFEE_SLOT: U256 = U256::from_limbs([5, 0, 0, 0]);
/// L1 commitScalar slot in L1GasPriceOracle after Curie fork
pub const COMMIT_SCALAR_SLOT: U256 = U256::from_limbs([6, 0, 0, 0]);
/// L1 blob_scalar slot in L1GasPriceOracle after Curie fork
pub const BLOB_SCALAR_SLOT: U256 = U256::from_limbs([7, 0, 0, 0]);
/// L1 isCurie slot in L1GasPriceOracle after Curie fork
pub const IS_CURIE_SLOT: U256 = U256::from_limbs([8, 0, 0, 0]);
/// Initial commit scalar after curie fork
pub const INITIAL_COMMIT_SCALAR: U256 = U256::from_limbs([230759955285, 0, 0, 0]);
/// Initial blob scalar after curie fork
pub const INITIAL_BLOB_SCALAR: U256 = U256::from_limbs([417565260, 0, 0, 0]);
}

/// Predeployed L2ToL1Message
pub mod l2_to_l1_message {
use alloy_primitives::{address, uint, Address, U256};
Expand Down
8 changes: 6 additions & 2 deletions prover/crates/storage/witness-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,15 @@ impl DatabaseRef for TrieDB<'_> {
.inner
.storage_tries
.get(hashed_address)
.expect("A storage trie must be provided for each account");
.ok_or(TrieDBError(format!("storage trie not found for address: {:?}", address)))?;

Ok(storage_trie
.get_rlp::<U256>(keccak256(index.to_be_bytes::<32>()).as_slice())
.expect("Can get from MPT")
.map_err(|_| {
TrieDBError(format!(
"failed to read storage slot from trie: address={address:?}, slot={index:?}"
))
})?
.unwrap_or_default())
}

Expand Down
Loading