Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: revm bn254 mul issue + cancun support + misc issues #222

Merged
merged 6 commits into from
May 19, 2024
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
17 changes: 9 additions & 8 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ raiko-lib = { path = "./lib", features = ["std"] }
raiko-primitives = { path = "./primitives" }

# revm
revm-primitives = { git = "https://github.com/taikoxyz/revm.git", branch = "feat/zk-op", default-features = false }
revm = { git = "https://github.com/taikoxyz/revm.git", branch = "feat/zk-op", default-features = false, features = [
revm-primitives = { git = "https://github.com/taikoxyz/revm.git", branch = "v35_taiko_v2", default-features = false }
revm = { git = "https://github.com/taikoxyz/revm.git", branch = "v35_taiko_v2", default-features = false, features = [
"serde",
"std",
"c-kzg",
"taiko",
] }

Expand Down Expand Up @@ -130,8 +131,7 @@ reqwest = { version = "0.11.22", features = ["json"] }
url = "2.5.0"

# crypto
c-kzg = "1.0.0"
c-kzg-taiko = { git = "https://github.com/smtmfft/c-kzg-4844", branch = "for-alpha7", default-features = false, features = [
c-kzg = { package = "c-kzg-taiko", git = "https://github.com/smtmfft/c-kzg-4844", branch = "for-alpha7", default-features = false, features = [
Brechtpd marked this conversation as resolved.
Show resolved Hide resolved
"preload-kzg-settings",
"no-threads",
] }
Expand Down
2 changes: 1 addition & 1 deletion host/config/chain_spec_list_default.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"l1_contract": null,
"l2_contract": null,
"rpc": "https://ethereum-holesky-rpc.publicnode.com",
"beacon_rpc": "https://api.holesky.blobscan.com",
"beacon_rpc": "https://fabled-weathered-cherry.ethereum-holesky.quiknode.pro/8f1c66935fa5f9afbda0db43318fe3c9e7b061e1/",
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we hide this one into maybe CI secrets to prevent unauthorized accesses from others?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we should have a dedicated account for our CI. I'm not paying for this one yet because I just picked the free tier but can buy more capacity if needed. I guess we can see if it's a problem or not, hopefully there's enough free rpcs out there that people won't abuse this one.

"sgx_verifier_address": null,
"genesis_time": 1695902400,
"seconds_per_slot": 12,
Expand Down
117 changes: 56 additions & 61 deletions host/src/preflight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,67 +83,63 @@ pub async fn preflight<BDP: BlockDataProvider>(
};
measurement.stop();

let input =
GuestInput {
chain_spec: taiko_chain_spec.clone(),
block_number,
gas_used: block.header.gas_used.try_into().map_err(|_| {
HostError::Conversion("Failed converting gas used to u64".to_string())
})?,
block_hash_reference: hash,
block_header_reference: to_header(&block.header),
beneficiary: block.header.miner,
gas_limit: block.header.gas_limit.try_into().map_err(|_| {
HostError::Conversion("Failed converting gas limit to u64".to_string())
})?,
timestamp: block.header.timestamp,
extra_data: block.header.extra_data.clone(),
mix_hash: if let Some(mix_hash) = block.header.mix_hash {
mix_hash
} else {
return Err(HostError::Preflight(
"No mix hash for the requested block".to_owned(),
));
let input = GuestInput {
chain_spec: taiko_chain_spec.clone(),
block_number,
block_hash_reference: hash,
block_header_reference: to_header(&block.header),
beneficiary: block.header.miner,
gas_limit: block
.header
.gas_limit
.try_into()
.map_err(|_| HostError::Conversion("Failed converting gas limit to u64".to_string()))?,
timestamp: block.header.timestamp,
extra_data: block.header.extra_data.clone(),
mix_hash: if let Some(mix_hash) = block.header.mix_hash {
mix_hash
} else {
return Err(HostError::Preflight(
"No mix hash for the requested block".to_owned(),
));
},
withdrawals: block.withdrawals.clone().unwrap_or_default(),
parent_state_trie: Default::default(),
parent_storage: Default::default(),
contracts: Default::default(),
parent_header: to_header(&parent_block.header),
ancestor_headers: Default::default(),
base_fee_per_gas: block.header.base_fee_per_gas.map_or_else(
|| {
Err(HostError::Preflight(
"No base fee per gas for the requested block".to_owned(),
))
},
withdrawals: block.withdrawals.clone().unwrap_or_default(),
parent_state_trie: Default::default(),
parent_storage: Default::default(),
contracts: Default::default(),
parent_header: to_header(&parent_block.header),
ancestor_headers: Default::default(),
base_fee_per_gas: block.header.base_fee_per_gas.map_or_else(
|| {
Err(HostError::Preflight(
"No base fee per gas for the requested block".to_owned(),
))
},
|base_fee_per_gas| {
base_fee_per_gas.try_into().map_err(|_| {
HostError::Conversion(
"Failed converting base fee per gas to u64".to_owned(),
)
})
},
)?,
blob_gas_used: block.header.blob_gas_used.map_or_else(
|| Ok(None),
|b: u128| -> HostResult<Option<u64>> {
b.try_into().map(Some).map_err(|_| {
HostError::Conversion("Failed converting blob gas used to u64".to_owned())
})
},
)?,
excess_blob_gas: block.header.excess_blob_gas.map_or_else(
|| Ok(None),
|b: u128| -> HostResult<Option<u64>> {
b.try_into().map(Some).map_err(|_| {
HostError::Conversion("Failed converting excess blob gas to u64".to_owned())
})
},
)?,
parent_beacon_block_root: block.header.parent_beacon_block_root,
taiko: taiko_guest_input,
};
|base_fee_per_gas| {
base_fee_per_gas.try_into().map_err(|_| {
HostError::Conversion("Failed converting base fee per gas to u64".to_owned())
})
},
)?,
blob_gas_used: block.header.blob_gas_used.map_or_else(
|| Ok(None),
|b: u128| -> HostResult<Option<u64>> {
b.try_into().map(Some).map_err(|_| {
HostError::Conversion("Failed converting blob gas used to u64".to_owned())
})
},
)?,
excess_blob_gas: block.header.excess_blob_gas.map_or_else(
|| Ok(None),
|b: u128| -> HostResult<Option<u64>> {
b.try_into().map(Some).map_err(|_| {
HostError::Conversion("Failed converting excess blob gas to u64".to_owned())
})
},
)?,
parent_beacon_block_root: block.header.parent_beacon_block_root,
taiko: taiko_guest_input,
};

// Create the block builder, run the transactions and extract the DB
let provider_db = ProviderDb::new(
Expand Down Expand Up @@ -177,7 +173,6 @@ pub async fn preflight<BDP: BlockDataProvider>(
}
num_iterations += 1;
}
builder = builder.prepare_header::<TaikoHeaderPrepStrategy>()?;
let provider_db = builder.mut_db().unwrap();

// Gather inclusion proofs for the initial and final state
Expand Down
3 changes: 2 additions & 1 deletion host/src/raiko.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ impl Raiko {
assert_eq!(
Into::<FixedBytes<32>>::into(header.hash().0),
input.block_hash_reference,
"block hash unexpected"
"block hash unexpected for block {}",
input.block_number,
);
let output = GuestOutput::Success { header, hash: pi };

Expand Down
2 changes: 1 addition & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ serde_with = { workspace = true, optional = true }
thiserror-no-std = { workspace = true }
url = { workspace = true }
hex = { workspace = true }
c-kzg-taiko = { workspace = true }
c-kzg = { workspace = true }
sha2 = { workspace = true }
cfg-if = { workspace = true }

Expand Down
7 changes: 7 additions & 0 deletions lib/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ impl SupportedChainSpecs {
pub fn get_chain_spec(&self, network: &String) -> Option<ChainSpec> {
self.0.get(network).cloned()
}

pub fn get_chain_spec_with_chain_id(&self, chain_id: u64) -> Option<ChainSpec> {
self.0
.values()
.find(|spec| spec.chain_id == chain_id)
.map(|spec| spec.clone())
}
}

/// The condition at which a fork is activated.
Expand Down
2 changes: 0 additions & 2 deletions lib/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ pub struct GuestInput {
pub chain_spec: ChainSpec,
/// Block number
pub block_number: u64,
/// Block gas used
pub gas_used: u64,
/// Block hash - for reference!
pub block_hash_reference: B256,
/// Block header - for reference!
Expand Down
39 changes: 38 additions & 1 deletion lib/src/protocol_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use alloy_consensus::Header as AlloyConsensusHeader;
use alloy_primitives::{Address, TxHash, B256};
use alloy_sol_types::SolValue;
use anyhow::{ensure, Result};
use c_kzg_taiko::{Blob, KzgCommitment, KzgSettings};
use c_kzg::{Blob, KzgCommitment, KzgSettings};
use raiko_primitives::keccak::keccak;
use sha2::{Digest as _, Sha256};

use super::utils::ANCHOR_GAS_LIMIT;
#[cfg(not(feature = "std"))]
use crate::no_std::*;
use crate::{
consts::SupportedChainSpecs,
input::{BlockMetadata, EthDeposit, GuestInput, Transition},
utils::HeaderHasher,
};
Expand Down Expand Up @@ -114,6 +115,42 @@ pub fn assemble_protocol_instance(
TxHash::from(keccak(input.taiko.tx_data.as_slice()))
};

// If the passed in chain spec contains a known chain id, the chain spec NEEDS to match the
// one we expect, because the prover could otherwise just fill in any values.
// The chain id is used because that is the value that is put onchain,
// and so all other chain data needs to be derived from it.
// For unknown chain ids we just skip this check so that tests using test data can still pass.
// TODO: we should probably split things up in critical and non-critical parts
// in the chain spec itself so we don't have to manually all the ones we have to care about.
if let Some(verified_chain_spec) =
SupportedChainSpecs::default().get_chain_spec_with_chain_id(input.chain_spec.chain_id)
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems it also relies on fixed image_id checking on-chain (in sgx it's mrenclave, in r0/sp1 it's image_id), as the default value can be override by user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep! But the config is injected in the code, so it's part of the program itself for both SGX and zkVMs so it will already be part of whatever system is used to ensure the correct code is executed.

{
assert_eq!(
input.chain_spec.max_spec_id, verified_chain_spec.max_spec_id,
"unexpected max_spec_id"
);
assert_eq!(
input.chain_spec.hard_forks, verified_chain_spec.hard_forks,
"unexpected hard_forks"
);
assert_eq!(
input.chain_spec.eip_1559_constants, verified_chain_spec.eip_1559_constants,
"unexpected eip_1559_constants"
);
assert_eq!(
input.chain_spec.l1_contract, verified_chain_spec.l1_contract,
"unexpected l1_contract"
);
assert_eq!(
input.chain_spec.l2_contract, verified_chain_spec.l2_contract,
"unexpected l2_contract"
);
assert_eq!(
input.chain_spec.is_taiko, verified_chain_spec.is_taiko,
"unexpected eip_1559_constants"
);
}

let deposits = input
.withdrawals
.iter()
Expand Down
2 changes: 1 addition & 1 deletion primitives/src/mpt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ impl MptNode {
/// the value and returns `false`.
#[inline]
pub fn insert(&mut self, key: &[u8], value: Vec<u8>) -> Result<bool, Error> {
assert!(value.is_empty(), "value must not be empty");
assert!(!value.is_empty(), "value must not be empty");
self.insert_internal(&to_nibs(key), value)
}

Expand Down
Loading
Loading