From 8880514d293454cbe3c02373797a01138a48307e Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Tue, 20 Aug 2024 15:25:05 -0700 Subject: [PATCH 1/4] feat: Add FaultProofFixture definition --- crates/op-test-vectors/src/faultproof.rs | 114 +++++++++++++++++++++++ crates/op-test-vectors/src/lib.rs | 2 + 2 files changed, 116 insertions(+) create mode 100644 crates/op-test-vectors/src/faultproof.rs diff --git a/crates/op-test-vectors/src/faultproof.rs b/crates/op-test-vectors/src/faultproof.rs new file mode 100644 index 0000000..e833f61 --- /dev/null +++ b/crates/op-test-vectors/src/faultproof.rs @@ -0,0 +1,114 @@ +//! Module containing the fault proof test fixture. + +use alloy_primitives::{BlockNumber, Bytes, ChainId, B256, U256}; +use serde::{Deserialize, Serialize}; +use hashbrown::HashMap; + +/// The fault proof fixture is the top-level object that contains +/// everything needed to run a fault proof test. +#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct FaultProofFixture { + /// The inputs to the fault proof test. + pub inputs: FaultProofInputs, + /// The expected status of the fault proof test. + pub expected_status: FaultProofStatus, + /// The witness data for the fault proof test. + pub witness_data: HashMap, +} + +/// The fault proof inputs are the inputs to the fault proof test. +#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct FaultProofInputs { + /// The L1 head block hash. + pub l1_head: B256, + /// The L2 head block hash. + pub l2_head: B256, + /// The claimed L2 output root to validate. + pub l2_claim: B256, + /// The agreed L2 output root to start derivation from. + pub l2_output_root: B256, + /// The L2 block number that the claim is from. + pub l2_block_number: BlockNumber, + /// The L2 chain ID that the claim is from. + pub l2_chain_id: ChainId, +} + +/// The fault proof status is the result of executing the fault proof program. +#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] +pub enum FaultProofStatus { + /// The claim is valid. + #[default] + Valid, + /// The claim is invalid. + Invalid, + /// Executing the program resulted in a panic. + Panic, + /// The status is unknown. + Unknown +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_serialize_fault_proof_status() { + let statuses = vec![ + FaultProofStatus::Valid, + FaultProofStatus::Invalid, + FaultProofStatus::Panic, + FaultProofStatus::Unknown, + ]; + + for status in statuses { + let serialized_status = serde_json::to_string(&status).expect("failed to serialize status"); + let deserialized_status = serde_json::from_str::(&serialized_status) + .expect("failed to deserialize status"); + assert_eq!(status, deserialized_status); + } + } + + #[test] + fn test_serialize_fault_proof_inputs() { + let inputs = FaultProofInputs { + l1_head: B256::from([1; 32]), + l2_head: B256::from([2; 32]), + l2_claim: B256::from([3; 32]), + l2_output_root: B256::from([4; 32]), + l2_block_number: 1337, + l2_chain_id: 42, + }; + + let serialized_inputs = serde_json::to_string(&inputs).expect("failed to serialize inputs"); + let deserialized_inputs = serde_json::from_str::(&serialized_inputs) + .expect("failed to deserialize inputs"); + assert_eq!(inputs, deserialized_inputs); + } + + #[test] + fn test_serialize_fault_proof_fixture() { + let mut witness_data = HashMap::new(); + witness_data.insert(U256::from(1), Bytes::from([1; 32])); + witness_data.insert(U256::from(2), Bytes::from([2; 32])); + + let fixture = FaultProofFixture { + inputs: FaultProofInputs { + l1_head: B256::from([1; 32]), + l2_head: B256::from([2; 32]), + l2_claim: B256::from([3; 32]), + l2_output_root: B256::from([4; 32]), + l2_block_number: 1337, + l2_chain_id: 42, + }, + expected_status: FaultProofStatus::Valid, + witness_data: witness_data, + }; + + let serialized_fixture = serde_json::to_string(&fixture).expect("failed to serialize fixture"); + let deserialized_fixture = serde_json::from_str::(&serialized_fixture) + .expect("failed to deserialize fixture"); + assert_eq!(fixture, deserialized_fixture); + } +} \ No newline at end of file diff --git a/crates/op-test-vectors/src/lib.rs b/crates/op-test-vectors/src/lib.rs index b11d233..4b265d1 100644 --- a/crates/op-test-vectors/src/lib.rs +++ b/crates/op-test-vectors/src/lib.rs @@ -10,4 +10,6 @@ pub mod derivation; +pub mod faultproof; + pub mod execution; From 4bfc9fcbcdf4c314d7a4f9181cee344eb8da6232 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Wed, 21 Aug 2024 16:00:52 -0700 Subject: [PATCH 2/4] Improve FaultProofStatus serialization, options --- Cargo.lock | 1 + Cargo.toml | 1 + crates/op-test-vectors/Cargo.toml | 1 + crates/op-test-vectors/src/faultproof.rs | 19 ++++++++++++------- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e747958..4d93c43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4595,6 +4595,7 @@ dependencies = [ "op-alloy-rpc-types", "serde", "serde_json", + "serde_repr", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 73df50b..592579c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ exclude = ["**/target", "benches/"] # General serde = { version = "1", features = ["derive"] } serde_json = "1" +serde_repr = "0.1" thiserror = "1" color-eyre = "0.6" lazy_static = "1" diff --git a/crates/op-test-vectors/Cargo.toml b/crates/op-test-vectors/Cargo.toml index 95eff10..882e9d2 100644 --- a/crates/op-test-vectors/Cargo.toml +++ b/crates/op-test-vectors/Cargo.toml @@ -12,6 +12,7 @@ edition.workspace = true [dependencies] # Core serde.workspace = true +serde_repr.workspace = true color-eyre.workspace = true hashbrown.workspace = true diff --git a/crates/op-test-vectors/src/faultproof.rs b/crates/op-test-vectors/src/faultproof.rs index e833f61..54fd876 100644 --- a/crates/op-test-vectors/src/faultproof.rs +++ b/crates/op-test-vectors/src/faultproof.rs @@ -1,7 +1,8 @@ //! Module containing the fault proof test fixture. -use alloy_primitives::{BlockNumber, Bytes, ChainId, B256, U256}; +use alloy_primitives::{BlockHash, BlockNumber, Bytes, ChainId, B256, U256}; use serde::{Deserialize, Serialize}; +use serde_repr::{Deserialize_repr, Serialize_repr}; use hashbrown::HashMap; /// The fault proof fixture is the top-level object that contains @@ -22,9 +23,9 @@ pub struct FaultProofFixture { #[serde(rename_all = "camelCase")] pub struct FaultProofInputs { /// The L1 head block hash. - pub l1_head: B256, + pub l1_head: BlockHash, /// The L2 head block hash. - pub l2_head: B256, + pub l2_head: BlockHash, /// The claimed L2 output root to validate. pub l2_claim: B256, /// The agreed L2 output root to start derivation from. @@ -36,15 +37,18 @@ pub struct FaultProofInputs { } /// The fault proof status is the result of executing the fault proof program. -#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, PartialEq, Eq)] +#[repr(u8)] pub enum FaultProofStatus { /// The claim is valid. #[default] - Valid, + Valid = 0, /// The claim is invalid. - Invalid, + Invalid = 1, /// Executing the program resulted in a panic. - Panic, + Panic = 2, + /// The program has not exited. + Unfinished = 3, /// The status is unknown. Unknown } @@ -59,6 +63,7 @@ mod tests { FaultProofStatus::Valid, FaultProofStatus::Invalid, FaultProofStatus::Panic, + FaultProofStatus::Unfinished, FaultProofStatus::Unknown, ]; From 7df4f782c55aaf7c975f585b93777cb69aa454a9 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Thu, 22 Aug 2024 14:34:13 -0700 Subject: [PATCH 3/4] Add rollup_config to FaultProofInputs --- crates/op-test-vectors/src/faultproof.rs | 175 ++++++++++++----------- 1 file changed, 90 insertions(+), 85 deletions(-) diff --git a/crates/op-test-vectors/src/faultproof.rs b/crates/op-test-vectors/src/faultproof.rs index 54fd876..0bd1e63 100644 --- a/crates/op-test-vectors/src/faultproof.rs +++ b/crates/op-test-vectors/src/faultproof.rs @@ -1,119 +1,124 @@ //! Module containing the fault proof test fixture. -use alloy_primitives::{BlockHash, BlockNumber, Bytes, ChainId, B256, U256}; +use alloy_primitives::{BlockHash, BlockNumber, Bytes, B256}; +use hashbrown::HashMap; +use kona_derive::types::RollupConfig; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use hashbrown::HashMap; /// The fault proof fixture is the top-level object that contains /// everything needed to run a fault proof test. #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct FaultProofFixture { - /// The inputs to the fault proof test. - pub inputs: FaultProofInputs, - /// The expected status of the fault proof test. - pub expected_status: FaultProofStatus, - /// The witness data for the fault proof test. - pub witness_data: HashMap, + /// The inputs to the fault proof test. + pub inputs: FaultProofInputs, + /// The expected status of the fault proof test. + pub expected_status: FaultProofStatus, + /// The witness data for the fault proof test. + pub witness_data: HashMap, } /// The fault proof inputs are the inputs to the fault proof test. #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct FaultProofInputs { - /// The L1 head block hash. - pub l1_head: BlockHash, - /// The L2 head block hash. - pub l2_head: BlockHash, - /// The claimed L2 output root to validate. - pub l2_claim: B256, - /// The agreed L2 output root to start derivation from. - pub l2_output_root: B256, - /// The L2 block number that the claim is from. - pub l2_block_number: BlockNumber, - /// The L2 chain ID that the claim is from. - pub l2_chain_id: ChainId, + /// The L1 head block hash. + pub l1_head: BlockHash, + /// The L2 head block hash. + pub l2_head: BlockHash, + /// The claimed L2 output root to validate. + pub l2_claim: B256, + /// The agreed L2 output root to start derivation from. + pub l2_output_root: B256, + /// The L2 block number that the claim is from. + pub l2_block_number: BlockNumber, + /// The configuration of the l2 chain. + pub rollup_config: RollupConfig, } /// The fault proof status is the result of executing the fault proof program. #[derive(Serialize_repr, Deserialize_repr, Debug, Default, PartialEq, Eq)] #[repr(u8)] pub enum FaultProofStatus { - /// The claim is valid. - #[default] - Valid = 0, - /// The claim is invalid. - Invalid = 1, - /// Executing the program resulted in a panic. - Panic = 2, - /// The program has not exited. - Unfinished = 3, - /// The status is unknown. - Unknown + /// The claim is valid. + #[default] + Valid = 0, + /// The claim is invalid. + Invalid = 1, + /// Executing the program resulted in a panic. + Panic = 2, + /// The program has not exited. + Unfinished = 3, + /// The status is unknown. + Unknown, } #[cfg(test)] mod tests { - use super::*; + use kona_derive::types::BASE_MAINNET_CONFIG; + + use super::*; - #[test] - fn test_serialize_fault_proof_status() { - let statuses = vec![ - FaultProofStatus::Valid, - FaultProofStatus::Invalid, - FaultProofStatus::Panic, - FaultProofStatus::Unfinished, - FaultProofStatus::Unknown, - ]; + #[test] + fn test_serialize_fault_proof_status() { + let statuses = vec![ + FaultProofStatus::Valid, + FaultProofStatus::Invalid, + FaultProofStatus::Panic, + FaultProofStatus::Unfinished, + FaultProofStatus::Unknown, + ]; - for status in statuses { - let serialized_status = serde_json::to_string(&status).expect("failed to serialize status"); - let deserialized_status = serde_json::from_str::(&serialized_status) - .expect("failed to deserialize status"); - assert_eq!(status, deserialized_status); + for status in statuses { + let serialized_status = + serde_json::to_string(&status).expect("failed to serialize status"); + let deserialized_status = serde_json::from_str::(&serialized_status) + .expect("failed to deserialize status"); + assert_eq!(status, deserialized_status); + } } - } - #[test] - fn test_serialize_fault_proof_inputs() { - let inputs = FaultProofInputs { - l1_head: B256::from([1; 32]), - l2_head: B256::from([2; 32]), - l2_claim: B256::from([3; 32]), - l2_output_root: B256::from([4; 32]), - l2_block_number: 1337, - l2_chain_id: 42, - }; + #[test] + fn test_serialize_fault_proof_inputs() { + let inputs = FaultProofInputs { + l1_head: B256::from([1; 32]), + l2_head: B256::from([2; 32]), + l2_claim: B256::from([3; 32]), + l2_output_root: B256::from([4; 32]), + l2_block_number: 1337, + rollup_config: BASE_MAINNET_CONFIG, + }; - let serialized_inputs = serde_json::to_string(&inputs).expect("failed to serialize inputs"); - let deserialized_inputs = serde_json::from_str::(&serialized_inputs) - .expect("failed to deserialize inputs"); - assert_eq!(inputs, deserialized_inputs); - } + let serialized_inputs = serde_json::to_string(&inputs).expect("failed to serialize inputs"); + let deserialized_inputs = serde_json::from_str::(&serialized_inputs) + .expect("failed to deserialize inputs"); + assert_eq!(inputs, deserialized_inputs); + } - #[test] - fn test_serialize_fault_proof_fixture() { - let mut witness_data = HashMap::new(); - witness_data.insert(U256::from(1), Bytes::from([1; 32])); - witness_data.insert(U256::from(2), Bytes::from([2; 32])); + #[test] + fn test_serialize_fault_proof_fixture() { + let mut witness_data = HashMap::new(); + witness_data.insert(B256::random(), Bytes::from([1; 32])); + witness_data.insert(B256::random(), Bytes::from([2; 32])); - let fixture = FaultProofFixture { - inputs: FaultProofInputs { - l1_head: B256::from([1; 32]), - l2_head: B256::from([2; 32]), - l2_claim: B256::from([3; 32]), - l2_output_root: B256::from([4; 32]), - l2_block_number: 1337, - l2_chain_id: 42, - }, - expected_status: FaultProofStatus::Valid, - witness_data: witness_data, - }; + let fixture = FaultProofFixture { + inputs: FaultProofInputs { + l1_head: B256::from([1; 32]), + l2_head: B256::from([2; 32]), + l2_claim: B256::from([3; 32]), + l2_output_root: B256::from([4; 32]), + l2_block_number: 1337, + rollup_config: BASE_MAINNET_CONFIG, + }, + expected_status: FaultProofStatus::Valid, + witness_data: witness_data, + }; - let serialized_fixture = serde_json::to_string(&fixture).expect("failed to serialize fixture"); - let deserialized_fixture = serde_json::from_str::(&serialized_fixture) - .expect("failed to deserialize fixture"); - assert_eq!(fixture, deserialized_fixture); - } -} \ No newline at end of file + let serialized_fixture = + serde_json::to_string(&fixture).expect("failed to serialize fixture"); + let deserialized_fixture = serde_json::from_str::(&serialized_fixture) + .expect("failed to deserialize fixture"); + assert_eq!(fixture, deserialized_fixture); + } +} From 70afc00273ef82da612c62b7c1a9c835f47e9847 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Mon, 26 Aug 2024 10:51:00 -0700 Subject: [PATCH 4/4] Add TryFrom --- crates/op-test-vectors/Cargo.toml | 4 +++- crates/op-test-vectors/src/faultproof.rs | 26 +++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/crates/op-test-vectors/Cargo.toml b/crates/op-test-vectors/Cargo.toml index 882e9d2..0a7bd88 100644 --- a/crates/op-test-vectors/Cargo.toml +++ b/crates/op-test-vectors/Cargo.toml @@ -25,6 +25,8 @@ alloy-consensus.workspace = true op-alloy-rpc-types.workspace = true op-alloy-consensus.workspace = true +# Kona +kona-primitives.workspace = true + [dev-dependencies] serde_json.workspace = true -kona-primitives.workspace = true diff --git a/crates/op-test-vectors/src/faultproof.rs b/crates/op-test-vectors/src/faultproof.rs index 0bd1e63..c74ac51 100644 --- a/crates/op-test-vectors/src/faultproof.rs +++ b/crates/op-test-vectors/src/faultproof.rs @@ -2,7 +2,7 @@ use alloy_primitives::{BlockHash, BlockNumber, Bytes, B256}; use hashbrown::HashMap; -use kona_derive::types::RollupConfig; +use kona_primitives::RollupConfig; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -54,9 +54,29 @@ pub enum FaultProofStatus { Unknown, } +impl TryFrom for FaultProofStatus { + type Error = String; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(FaultProofStatus::Valid), + 1 => Ok(FaultProofStatus::Invalid), + 2 => Ok(FaultProofStatus::Panic), + 3 => Ok(FaultProofStatus::Unfinished), + _ => Ok(FaultProofStatus::Unknown), + } + } +} + +impl From for u8 { + fn from(status: FaultProofStatus) -> u8 { + status as u8 + } +} + #[cfg(test)] mod tests { - use kona_derive::types::BASE_MAINNET_CONFIG; + use kona_primitives::BASE_MAINNET_CONFIG; use super::*; @@ -112,7 +132,7 @@ mod tests { rollup_config: BASE_MAINNET_CONFIG, }, expected_status: FaultProofStatus::Valid, - witness_data: witness_data, + witness_data, }; let serialized_fixture =