Skip to content

Commit

Permalink
Deserialize tests from BlockchainTests folder instead
Browse files Browse the repository at this point in the history
  • Loading branch information
Nashtare committed Sep 28, 2023
1 parent ae799c2 commit 9bb9281
Show file tree
Hide file tree
Showing 20 changed files with 463 additions and 560 deletions.
18 changes: 7 additions & 11 deletions Cargo.lock

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

18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,58 @@
# EVM Test

Parses and runs compatible common Ethereum tests from [ethereum/tests](https://github.com/ethereum/tests) against Polygon Zero's EVM.

> Note: This repo is currently very early in development and is not yet ready to evaluate the EVM completeness!
## Components

### Parser

Since the tests from the Ethereum test repo are meant for a full node, only certain tests are compatible with our EVM. Additionally, for the tests that are compatible, they need to be parsed (or converted) into a format that is usable by our EVM.

The parser has two responsibilities:

- Query the upstream Ethereum tests repo and check if any tests have been added/updated/removed.
- If there is a change, re-parse the tests.

### Runner

The runner feeds the parsed tests into the EVM. Successes are defined as no errors occurring (the tests themselves do not provide an expected final state). If the EVM returns an error or panics, then the test is considered to have failed.

The runner also outputs a results file (likely as a `*.md`) which contains statistics on the last test run.

## Quick Start

*TODO: Add more details...*

Run the parser to parse the Eth tests into a format usable by `plonky2`:

```sh
cd eth_test_parser
cargo run
```

Then launch the runner pointing it at the parsed tests directory:

```sh
cd ../evm_test_runner
cargo run --release -- -r summary ../generation_inputs # For a high-level summary report
cargo run --release -- -r test ../generation_inputs # For detailed information per test (likely want to use a filter with `-f`)
cargo run --release -- -r summary ../generation_inputs/BlockchainTests # For a high-level summary report
cargo run --release -- -r test ../generation_inputs/BlockchainTests # For detailed information per test (likely want to use a filter with `-f`)
```

## Other

[Polygon Hermez](https://github.com/0xPolygonHermez) is doing something similar [here](https://github.com/0xPolygonHermez/zkevm-testvectors).

## License

Licensed under either of

* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)

at your option.

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
4 changes: 2 additions & 2 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ edition = "2021"
[dependencies]
anyhow = { version = "1.0.71", features = ["backtrace"] }
ethereum-types = "0.14.1"
eth_trie_utils = "0.6.0"
eth_trie_utils = { git = "https://github.com/mir-protocol/eth_trie_utils.git", rev = "e9ec4ec2aa2ae976b7c699ef40c1ffc716d87ed5" }
flexi_logger = { version = "0.25.4", features = ["async"] }
plonky2_evm = { git = "https://github.com/mir-protocol/plonky2.git", rev = "6f98fd762885e9b5343af5f0e3f0c9c90e8cf3ab" }
plonky2_evm = { git = "https://github.com/mir-protocol/plonky2.git", rev = "1ff6d4a2839a0cd16598a5db263568885a47e7c9" }
serde = {version = "1.0.163", features = ["derive"] }
revm = { version = "3.3.0", features = ["serde"] }
ruint = { version = "1.8.0", features = ["primitive-types"] }
1 change: 1 addition & 0 deletions common/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub const GENERATION_INPUTS_DEFAULT_OUTPUT_DIR: &str = "generation_inputs";
pub const MAIN_TEST_DIR: &str = "BlockchainTests";
pub const MATIC_CHAIN_ID: u64 = 137;
pub const ETHEREUM_CHAIN_ID: u64 = 1;
73 changes: 33 additions & 40 deletions common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use std::{
};

use anyhow::{anyhow, Context};
use eth_trie_utils::partial_trie::{HashedPartialTrie, Node, PartialTrie};
use ethereum_types::{Address, H256};
use plonky2_evm::proof::TrieRoots;
use ethereum_types::{Address, H256, U256};
use plonky2_evm::proof::{BlockHashes, TrieRoots};
use plonky2_evm::{
generation::{GenerationInputs, TrieInputs},
proof::BlockMetadata,
Expand All @@ -18,7 +17,7 @@ use crate::revm::SerializableEVMInstance;

#[derive(Debug, Deserialize, Serialize)]
pub struct ParsedTestManifest {
pub plonky2_variants: Plonky2ParsedTest,
pub plonky2_variants: Vec<Plonky2ParsedTest>,
pub revm_variants: Option<Vec<SerializableEVMInstance>>,
}

Expand All @@ -40,17 +39,14 @@ impl ParsedTestManifest {
let revm_variants: Vec<Option<SerializableEVMInstance>> = match self.revm_variants {
// `revm_variants` will be parallel to `plonky2_variants`, given they are both
// generated from the same vec (`test.post.merge`).
None => (0..self.plonky2_variants.test_variants.len())
.map(|_| None)
.collect(),
None => (0..self.plonky2_variants.len()).map(|_| None).collect(),
Some(v) => v.into_iter().map(Some).collect(),
};

let tot_variants_without_filter = self.plonky2_variants.test_variants.len();
let tot_variants_without_filter = self.plonky2_variants.len();

let variants = self
.plonky2_variants
.test_variants
.into_iter()
.zip(revm_variants.into_iter())
.enumerate()
Expand All @@ -61,30 +57,29 @@ impl ParsedTestManifest {
})
.map(|(variant_idx, (t_var, revm_variant))| {
let trie_roots_after = TrieRoots {
state_root: t_var.common.expected_final_account_state_root_hash,
transactions_root: HashedPartialTrie::from(Node::Empty).hash(), // TODO: Fix this when we have transactions trie.
receipts_root: HashedPartialTrie::from(Node::Empty).hash(), // TODO: Fix this when we have receipts trie.
state_root: t_var.final_roots.state_root_hash,
transactions_root: t_var.final_roots.txn_trie_root_hash,
receipts_root: t_var.final_roots.receipts_trie_root_hash,
};
let gen_inputs = GenerationInputs {
signed_txns: vec![t_var.txn_bytes],
tries: self.plonky2_variants.const_plonky2_inputs.tries.clone(),
tries: t_var.plonky2_metadata.tries.clone(),
trie_roots_after,
contract_code: self
.plonky2_variants
.const_plonky2_inputs
.contract_code
.clone(),
block_metadata: self
.plonky2_variants
.const_plonky2_inputs
.block_metadata
.clone(),
addresses: self.plonky2_variants.const_plonky2_inputs.addresses.clone(),
genesis_state_trie_root: t_var.plonky2_metadata.genesis_state_root,
contract_code: t_var.plonky2_metadata.contract_code.clone(),
block_metadata: t_var.plonky2_metadata.block_metadata.clone(),
addresses: t_var.plonky2_metadata.addresses.clone(),
txn_number_before: U256::zero(),
gas_used_before: U256::zero(),
block_bloom_before: [U256::zero(); 8],
gas_used_after: t_var.plonky2_metadata.block_metadata.block_gas_used,
block_bloom_after: t_var.plonky2_metadata.block_metadata.block_bloom,
block_hashes: BlockHashes::default(),
};

TestVariantRunInfo {
gen_inputs,
common: t_var.common,
final_roots: t_var.final_roots,
revm_variant,
variant_idx,
}
Expand All @@ -103,37 +98,35 @@ impl ParsedTestManifest {
/// Note that for our runner we break any txn "variants" (see `indexes` under https://ethereum-tests.readthedocs.io/en/latest/test_types/gstate_tests.html#post-section) into separate sub-tests when running. This is because we don't want a single sub-test variant to cause the entire test to fail (we just want the variant to fail).
#[derive(Debug, Deserialize, Serialize)]
pub struct Plonky2ParsedTest {
pub test_variants: Vec<TestVariant>,

/// State that is constant between tests.
pub const_plonky2_inputs: ConstGenerationInputs,
}

/// A single test that
#[derive(Debug, Deserialize, Serialize)]
pub struct TestVariant {
/// The txn bytes for each txn in the test.
pub txn_bytes: Vec<u8>,
pub common: TestVariantCommon,
pub final_roots: ExpectedFinalRoots,

/// All the metadata needed to prove the transaction in the `test_variant`.
pub plonky2_metadata: TestMetadata,
}

#[derive(Debug)]
pub struct TestVariantRunInfo {
pub gen_inputs: GenerationInputs,
pub common: TestVariantCommon,
pub final_roots: ExpectedFinalRoots,
pub revm_variant: Option<SerializableEVMInstance>,
pub variant_idx: usize,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct TestVariantCommon {
pub struct ExpectedFinalRoots {
/// The root hash of the expected final state trie.
pub expected_final_account_state_root_hash: H256,
pub state_root_hash: H256,
/// The root hash of the expected final transactions trie.
pub txn_trie_root_hash: H256,
/// The root hash of the expected final receipts trie.
pub receipts_trie_root_hash: H256,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct ConstGenerationInputs {
pub struct TestMetadata {
pub tries: TrieInputs,
pub genesis_state_root: H256,
pub contract_code: HashMap<H256, Vec<u8>>,
pub block_metadata: BlockMetadata,
pub addresses: Vec<Address>,
Expand Down
4 changes: 2 additions & 2 deletions eth_test_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ edition = "2021"

[dependencies]
common = { path = "../common" }
eth_trie_utils = "0.6.0"
plonky2_evm = { git = "https://github.com/mir-protocol/plonky2.git", rev = "6f98fd762885e9b5343af5f0e3f0c9c90e8cf3ab" }
eth_trie_utils = { git = "https://github.com/mir-protocol/eth_trie_utils.git", rev = "e9ec4ec2aa2ae976b7c699ef40c1ffc716d87ed5" }
plonky2_evm = { git = "https://github.com/mir-protocol/plonky2.git", rev = "1ff6d4a2839a0cd16598a5db263568885a47e7c9" }

anyhow = { version = "1.0.71", features = ["backtrace"] }
clap = {version = "4.2.7", features = ["derive"] }
Expand Down
1 change: 1 addition & 0 deletions eth_test_parser/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub(crate) const ETH_TESTS_REPO_URL: &str = "https://github.com/ethereum/tests.git";
pub(crate) const ETH_TESTS_REPO_LOCAL_PATH: &str = "eth_tests";
pub(crate) const GENERAL_GROUP: &str = "BlockchainTests";
pub(crate) const TEST_GROUPS: [&str; 1] = ["GeneralStateTests"];
// The following subgroups contain subfolders unlike the other test folders.
pub(crate) const SPECIAL_TEST_SUBGROUPS: [&str; 2] = ["Shanghai", "VMTests"];
Loading

0 comments on commit 9bb9281

Please sign in to comment.