diff --git a/eth-bytecode-db/Cargo.lock b/eth-bytecode-db/Cargo.lock index f661024b7..82bc20480 100644 --- a/eth-bytecode-db/Cargo.lock +++ b/eth-bytecode-db/Cargo.lock @@ -2130,7 +2130,7 @@ dependencies = [ "tracing", "tracing-subscriber", "url", - "verification-common", + "verification-common 0.1.0 (git+https://github.com/blockscout/blockscout-rs?rev=3892914)", "verifier-alliance-entity 0.1.0 (git+https://github.com/blockscout/blockscout-rs?rev=ec1c755)", "verifier-alliance-migration 0.1.0 (git+https://github.com/blockscout/blockscout-rs?rev=ec1c755)", ] @@ -5152,6 +5152,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "readonly" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25d631e41bfb5fdcde1d4e2215f62f7f0afa3ff11e26563765bd6ea1d229aeb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -7629,6 +7640,21 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "verification-common" +version = "0.1.0" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "anyhow", + "blockscout-display-bytes", + "bytes", + "readonly", + "serde", + "serde_json", + "serde_with 3.11.0", +] + [[package]] name = "verification-common" version = "0.1.0" @@ -7644,6 +7670,28 @@ dependencies = [ "serde_with 3.11.0", ] +[[package]] +name = "verifier-alliance-database" +version = "0.1.0" +dependencies = [ + "anyhow", + "blockscout-display-bytes", + "blockscout-service-launcher", + "keccak-hash 0.11.0", + "pretty_assertions", + "sea-orm", + "serde", + "serde_json", + "serde_with 3.11.0", + "sha2", + "sha3", + "strum", + "tokio", + "verification-common 0.1.0", + "verifier-alliance-entity 0.1.0", + "verifier-alliance-migration 0.1.0", +] + [[package]] name = "verifier-alliance-entity" version = "0.1.0" diff --git a/eth-bytecode-db/Cargo.toml b/eth-bytecode-db/Cargo.toml index c3142c73d..0f938ef10 100644 --- a/eth-bytecode-db/Cargo.toml +++ b/eth-bytecode-db/Cargo.toml @@ -8,6 +8,7 @@ members = [ "eth-bytecode-db/migration", "eth-bytecode-db/verifier-alliance-entity", "eth-bytecode-db/verifier-alliance-migration", + "verifier-alliance-database", ] [workspace.dependencies] @@ -17,9 +18,12 @@ eth-bytecode-db-proto = { path = "eth-bytecode-db-proto" } eth-bytecode-db-server = { path = "eth-bytecode-db-server" } migration = { path = "eth-bytecode-db/migration" } verifier-alliance-entity = { git = "https://github.com/blockscout/blockscout-rs", rev = "ec1c755" } +verifier-alliance-database = { path = "verifier-alliance-database" } verifier-alliance-migration = { git = "https://github.com/blockscout/blockscout-rs", rev = "ec1c755" } -#verifier-alliance-entity = { path = "eth-bytecode-db/verifier-alliance-entity" } -#verifier-alliance-migration = { path = "eth-bytecode-db/verifier-alliance-migration" } + +verifier-alliance-entity-v1 = { path = "eth-bytecode-db/verifier-alliance-entity", package = "verifier-alliance-entity" } +verifier-alliance-migration-v1 = { path = "eth-bytecode-db/verifier-alliance-migration", package = "verifier-alliance-migration" } +verification-common-v1 = { path = "../libs/verification-common", package = "verification-common" } actix-prost = { git = "https://github.com/blockscout/actix-prost", rev = "4cbba2a" } actix-prost-macros = { git = "https://github.com/blockscout/actix-prost", rev = "4cbba2a" } @@ -58,9 +62,12 @@ semver = { version = "1.0" } serde = { version = "1" } serde_json = { version = "1.0" } serde_with = { version = "3.11.0" } +sha2 = { version = "0.10.8" } +sha3 = { version = "0.10.8" } smart-contract-verifier-proto = { git = "https://github.com/blockscout/blockscout-rs", rev = "7a6e9400" } solidity-metadata = { version = "1.0" } sourcify = { git = "https://github.com/blockscout/blockscout-rs", rev = "457af68" } +strum = { version = "0.26.3", default-features = false, features = ["derive"] } thiserror = { version = "1" } tokio = { version = "1" } tokio-stream = { version = "0.1" } @@ -69,4 +76,4 @@ tonic-build = { version = "0.8" } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3" } url = { version = "2" } -verification-common = { git = "https://github.com/blockscout/blockscout-rs", rev = "3892914" } +verification-common = { git = "https://github.com/blockscout/blockscout-rs", rev = "3892914" } \ No newline at end of file diff --git a/eth-bytecode-db/verifier-alliance-database/Cargo.toml b/eth-bytecode-db/verifier-alliance-database/Cargo.toml new file mode 100644 index 000000000..aa06a3169 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "verifier-alliance-database" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = { workspace = true } +blockscout-display-bytes = { workspace = true } +keccak-hash = { workspace = true } +sea-orm = { workspace = true } +serde_json = { workspace = true } +sha2 = { workspace = true } +sha3 = { workspace = true } +strum = { workspace = true } +verification-common-v1 = { workspace = true } +verifier-alliance-entity-v1 = { workspace = true } +serde = { workspace = true } + +[dev-dependencies] +blockscout-service-launcher = { workspace = true, features = ["test-database"] } +pretty_assertions = { workspace = true } +serde_json = { workspace = true } +serde_with = { workspace = true } +tokio = { workspace = true, features = ["macros"] } +verifier-alliance-migration-v1 = { workspace = true } \ No newline at end of file diff --git a/eth-bytecode-db/verifier-alliance-database/src/helpers.rs b/eth-bytecode-db/verifier-alliance-database/src/helpers.rs new file mode 100644 index 000000000..bed19fed6 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/src/helpers.rs @@ -0,0 +1,69 @@ +macro_rules! insert_then_select { + ( $txn:expr, $entity_module:ident, $active_model:expr, $update_on_conflict:expr, [ $( ($column:ident, $value:expr) ),+ $(,)? ] ) => { + { + use anyhow::Context; + use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; + + let result: Result<_, sea_orm::DbErr> = $entity_module::Entity::insert($active_model.clone()) + .on_conflict(sea_orm::sea_query::OnConflict::new().do_nothing().to_owned()) + .exec($txn) + .await; + + // Returns the model and the bool flag showing whether the model was actually inserted. + match result { + Ok(res) => { + let last_insert_id = res.last_insert_id; + let model = $entity_module::Entity::find_by_id(last_insert_id.clone()) + .one($txn) + .await + .context(format!("select from \"{}\" by \"id\"", stringify!($entity_module)))? + .ok_or(anyhow::anyhow!( + "select from \"{}\" by \"id\"={:?} returned no data", + stringify!($entity_module), + last_insert_id + ))?; + + Ok((model, true)) + } + Err(sea_orm::DbErr::RecordNotInserted) => { + let mut model = + $entity_module::Entity::find() + $( + .filter($entity_module::Column::$column.eq($value)) + )* + .one($txn) + .await + .context(format!("select from \"{}\" by unique columns", stringify!($entity_module)))? + .ok_or(anyhow::anyhow!("select from \"{}\" by unique columns returned no data", stringify!($entity_module)))?; + // The active model have not been inserted. + // Thus, there were a value already that we need to update. + if $update_on_conflict { + let mut active_model_to_update = $active_model; + for primary_key in <$entity_module::PrimaryKey as sea_orm::Iterable>::iter() { + let column = sea_orm::PrimaryKeyToColumn::into_column(primary_key); + let value = sea_orm::ModelTrait::get(&model, column); + sea_orm::ActiveModelTrait::set(&mut active_model_to_update, column, value); + } + let updated_model = sea_orm::ActiveModelTrait::update( + active_model_to_update, $txn + ).await.context(format!("update on conflict in \"{}\"", stringify!($entity_module)))?; + + if updated_model != model { + // tracing::warn!( + // model=?model, + // updated_model=?updated_model, + // "the \"{}\" model has been updated", + // stringify!($entity_module) + // ); + model = updated_model; + } + } + + Ok((model, false)) + } + Err(err) => Err(err).context(format!("insert into \"{}\"", stringify!($entity_module))), + } + } + }; +} +pub(crate) use insert_then_select; diff --git a/eth-bytecode-db/verifier-alliance-database/src/internal.rs b/eth-bytecode-db/verifier-alliance-database/src/internal.rs new file mode 100644 index 000000000..19e192c5f --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/src/internal.rs @@ -0,0 +1,470 @@ +use crate::helpers::insert_then_select; +use anyhow::{anyhow, Context, Error}; +use blockscout_display_bytes::ToHex; +use sea_orm::{ + prelude::{Decimal, Uuid}, + ActiveValue::Set, + ColumnTrait, ConnectionTrait, EntityTrait, QueryFilter, +}; +use sha2::{Digest, Sha256}; +use sha3::Keccak256; +use std::collections::BTreeMap; +use verification_common_v1::verifier_alliance::Match; +use verifier_alliance_entity_v1::{ + code, compiled_contracts, compiled_contracts_sources, contract_deployments, contracts, sources, + verified_contracts, +}; + +pub use crate::types::{ + CompiledContract, CompiledContractCompiler, CompiledContractLanguage, ContractCode, + InsertContractDeployment, RetrieveContractDeployment, VerifiedContract, + VerifiedContractMatches, +}; + +#[derive(Clone, Debug)] +pub struct InternalContractDeploymentData { + pub chain_id: Decimal, + pub address: Vec, + pub transaction_hash: Vec, + pub block_number: Decimal, + pub transaction_index: Decimal, + pub deployer: Vec, + pub contract_code: ContractCode, +} + +impl From for InternalContractDeploymentData { + fn from(value: InsertContractDeployment) -> Self { + match value { + InsertContractDeployment::Genesis { .. } => parse_genesis_contract_deployment(value), + InsertContractDeployment::Regular { .. } => parse_regular_contract_deployment(value), + } + } +} + +#[derive(Clone, Debug, Default)] +struct InternalMatchData { + does_match: bool, + metadata_match: Option, + values: Option, + transformations: Option, +} + +pub async fn insert_verified_contract( + database_connection: &C, + contract_deployment_id: Uuid, + compiled_contract_id: Uuid, + matches: VerifiedContractMatches, +) -> Result { + let (creation_match_data, runtime_match_data) = match matches { + VerifiedContractMatches::OnlyRuntime { runtime_match } => { + let runtime_match_data = parse_verification_common_match(runtime_match); + (InternalMatchData::default(), runtime_match_data) + } + VerifiedContractMatches::OnlyCreation { creation_match } => { + let creation_match_data = parse_verification_common_match(creation_match); + (creation_match_data, InternalMatchData::default()) + } + VerifiedContractMatches::Complete { + runtime_match, + creation_match, + } => { + let creation_match_data = parse_verification_common_match(creation_match); + let runtime_match_data = parse_verification_common_match(runtime_match); + (creation_match_data, runtime_match_data) + } + }; + + let active_model = verified_contracts::ActiveModel { + id: Default::default(), + created_at: Default::default(), + updated_at: Default::default(), + created_by: Default::default(), + updated_by: Default::default(), + deployment_id: Set(contract_deployment_id), + compilation_id: Set(compiled_contract_id), + creation_match: Set(creation_match_data.does_match), + creation_values: Set(creation_match_data.values), + creation_transformations: Set(creation_match_data.transformations), + creation_metadata_match: Set(creation_match_data.metadata_match), + runtime_match: Set(runtime_match_data.does_match), + runtime_values: Set(runtime_match_data.values), + runtime_transformations: Set(runtime_match_data.transformations), + runtime_metadata_match: Set(runtime_match_data.metadata_match), + }; + + let (model, _inserted) = insert_then_select!( + database_connection, + verified_contracts, + active_model, + false, + [ + (CompilationId, compiled_contract_id), + (DeploymentId, contract_deployment_id), + ] + )?; + + Ok(model) +} + +pub async fn insert_compiled_contract( + database_connection: &C, + compiled_contract: CompiledContract, +) -> Result { + let creation_code_hash = insert_code(database_connection, compiled_contract.creation_code) + .await + .context("insert creation code")? + .code_hash; + let runtime_code_hash = insert_code(database_connection, compiled_contract.runtime_code) + .await + .context("insert runtime code")? + .code_hash; + + let active_model = compiled_contracts::ActiveModel { + id: Default::default(), + created_at: Default::default(), + updated_at: Default::default(), + created_by: Default::default(), + updated_by: Default::default(), + compiler: Set(compiled_contract.compiler.to_string()), + version: Set(compiled_contract.version), + language: Set(compiled_contract.language.to_string()), + name: Set(compiled_contract.name), + fully_qualified_name: Set(compiled_contract.fully_qualified_name), + compiler_settings: Set(compiled_contract.compiler_settings), + compilation_artifacts: Set(compiled_contract.compilation_artifacts.into()), + creation_code_hash: Set(creation_code_hash.clone()), + creation_code_artifacts: Set(compiled_contract.creation_code_artifacts.into()), + runtime_code_hash: Set(runtime_code_hash.clone()), + runtime_code_artifacts: Set(compiled_contract.runtime_code_artifacts.into()), + }; + + let (model, _inserted) = insert_then_select!( + database_connection, + compiled_contracts, + active_model, + false, + [ + (Compiler, compiled_contract.compiler.to_string()), + (Language, compiled_contract.language.to_string()), + (CreationCodeHash, creation_code_hash), + (RuntimeCodeHash, runtime_code_hash) + ] + )?; + + Ok(model) +} + +pub async fn insert_sources( + database_connection: &C, + sources: BTreeMap, +) -> Result, Error> { + let mut models = vec![]; + + for (_path, content) in sources { + let source_hash = Sha256::digest(&content).to_vec(); + let source_hash_keccak = Keccak256::digest(&content).to_vec(); + let active_model = sources::ActiveModel { + source_hash: Set(source_hash.clone()), + source_hash_keccak: Set(source_hash_keccak), + content: Set(content), + created_at: Default::default(), + updated_at: Default::default(), + created_by: Default::default(), + updated_by: Default::default(), + }; + let (model, _inserted) = insert_then_select!( + database_connection, + sources, + active_model, + false, + [(SourceHash, source_hash)] + )?; + models.push(model) + } + + Ok(models) +} + +pub async fn insert_compiled_contract_sources( + database_connection: &C, + source_hashes: BTreeMap>, + compiled_contract_id: Uuid, +) -> Result, Error> { + let mut models = vec![]; + + for (path, source_hash) in source_hashes { + let active_model = compiled_contracts_sources::ActiveModel { + id: Default::default(), + compilation_id: Set(compiled_contract_id), + path: Set(path.clone()), + source_hash: Set(source_hash), + }; + let (model, _inserted) = insert_then_select!( + database_connection, + compiled_contracts_sources, + active_model, + false, + [(CompilationId, compiled_contract_id), (Path, path)] + )?; + models.push(model); + } + + Ok(models) +} + +pub async fn insert_contract_deployment( + database_connection: &C, + internal_data: InternalContractDeploymentData, + contract_id: Uuid, +) -> Result { + let active_model = contract_deployments::ActiveModel { + id: Default::default(), + created_at: Default::default(), + updated_at: Default::default(), + created_by: Default::default(), + updated_by: Default::default(), + chain_id: Set(internal_data.chain_id), + address: Set(internal_data.address.clone()), + transaction_hash: Set(internal_data.transaction_hash.clone()), + block_number: Set(internal_data.block_number), + transaction_index: Set(internal_data.transaction_index), + deployer: Set(internal_data.deployer), + contract_id: Set(contract_id), + }; + + let (model, _inserted) = insert_then_select!( + database_connection, + contract_deployments, + active_model, + false, + [ + (ChainId, internal_data.chain_id), + (Address, internal_data.address), + (TransactionHash, internal_data.transaction_hash) + ] + )?; + + Ok(model) +} + +pub async fn retrieve_contract_deployment( + database_connection: &C, + contract_deployment: RetrieveContractDeployment, +) -> Result, Error> { + let transaction_hash = contract_deployment.transaction_hash.unwrap_or_else(|| { + let runtime_code = contract_deployment + .runtime_code + .expect("either transaction hash or runtime code must contain value"); + calculate_genesis_contract_deployment_transaction_hash(&runtime_code) + }); + + contract_deployments::Entity::find() + .filter( + contract_deployments::Column::ChainId.eq(Decimal::from(contract_deployment.chain_id)), + ) + .filter(contract_deployments::Column::Address.eq(contract_deployment.address)) + .filter(contract_deployments::Column::TransactionHash.eq(transaction_hash)) + .one(database_connection) + .await + .context("select from \"contract_deployments\"") +} + +pub async fn insert_contract( + database_connection: &C, + contract_code: ContractCode, +) -> Result { + let (creation_code_hash, runtime_code_hash) = + insert_contract_code(database_connection, contract_code).await?; + + let active_model = contracts::ActiveModel { + id: Default::default(), + created_at: Default::default(), + updated_at: Default::default(), + created_by: Default::default(), + updated_by: Default::default(), + creation_code_hash: Set(creation_code_hash.clone()), + runtime_code_hash: Set(runtime_code_hash.clone()), + }; + + let (model, _inserted) = insert_then_select!( + database_connection, + contracts, + active_model, + false, + [ + (CreationCodeHash, creation_code_hash), + (RuntimeCodeHash, runtime_code_hash) + ] + )?; + + Ok(model) +} + +pub async fn insert_code( + database_connection: &C, + code: Vec, +) -> Result { + let code_hash = Sha256::digest(&code).to_vec(); + let code_hash_keccak = Keccak256::digest(&code).to_vec(); + + let active_model = code::ActiveModel { + code_hash: Set(code_hash.clone()), + created_at: Default::default(), + updated_at: Default::default(), + created_by: Default::default(), + updated_by: Default::default(), + code_hash_keccak: Set(code_hash_keccak), + code: Set(Some(code)), + }; + + let (model, _inserted) = insert_then_select!( + database_connection, + code, + active_model, + false, + [(CodeHash, code_hash)] + )?; + + Ok(model) +} + +/// Inserts a contract defined by its runtime and creation code into `contracts` table. +/// Notice, that only creation code is optional, while runtime code should always exist. +/// It can be empty though, in case creation code execution resulted in empty code. +/// Creation code may be missed for genesis contracts. +async fn insert_contract_code( + database_connection: &C, + contract_code: ContractCode, +) -> Result<(Vec, Vec), Error> { + let mut creation_code_hash = vec![]; + let runtime_code_hash; + + match contract_code { + ContractCode::OnlyRuntimeCode { code } => { + runtime_code_hash = insert_code(database_connection, code) + .await + .context("insert runtime code")? + .code_hash; + } + ContractCode::CompleteCode { + creation_code, + runtime_code, + } => { + creation_code_hash = insert_code(database_connection, creation_code) + .await + .context("insert creation code")? + .code_hash; + runtime_code_hash = insert_code(database_connection, runtime_code) + .await + .context("insert runtime code")? + .code_hash; + } + } + + Ok((creation_code_hash, runtime_code_hash)) +} + +pub async fn retrieve_contract_by_id( + database_connection: &C, + contract_id: Uuid, +) -> Result { + contracts::Entity::find_by_id(contract_id) + .one(database_connection) + .await + .context("select from \"contracts\" by id")? + .ok_or_else(|| anyhow!("contract id was not found: {}", contract_id)) +} + +pub async fn retrieve_code_by_id( + database_connection: &C, + code_hash: Vec, +) -> Result { + code::Entity::find_by_id(code_hash.clone()) + .one(database_connection) + .await + .context("select from \"code\" by id")? + .ok_or_else(|| anyhow!("code hash was not found: {}", code_hash.to_hex())) +} + +pub fn precalculate_source_hashes(sources: &BTreeMap) -> BTreeMap> { + let mut source_hashes = BTreeMap::new(); + for (path, content) in sources { + let source_hash = Sha256::digest(content).to_vec(); + source_hashes.insert(path.clone(), source_hash); + } + + source_hashes +} + +fn parse_genesis_contract_deployment( + contract_deployment: InsertContractDeployment, +) -> InternalContractDeploymentData { + if let InsertContractDeployment::Genesis { + chain_id, + address, + runtime_code, + } = contract_deployment + { + let transaction_hash = + calculate_genesis_contract_deployment_transaction_hash(&runtime_code); + let contract_code = ContractCode::OnlyRuntimeCode { code: runtime_code }; + + return InternalContractDeploymentData { + chain_id: Decimal::from(chain_id), + address, + transaction_hash, + block_number: Decimal::from(-1), + transaction_index: Decimal::from(-1), + deployer: vec![], + contract_code, + }; + } + + unreachable!() +} + +fn parse_regular_contract_deployment( + contract_deployment: InsertContractDeployment, +) -> InternalContractDeploymentData { + if let InsertContractDeployment::Regular { + chain_id, + address, + transaction_hash, + block_number, + transaction_index, + deployer, + creation_code, + runtime_code, + } = contract_deployment + { + let contract_code = ContractCode::CompleteCode { + creation_code, + runtime_code, + }; + + return InternalContractDeploymentData { + chain_id: Decimal::from(chain_id), + address, + transaction_hash, + block_number: Decimal::from(block_number), + transaction_index: Decimal::from(transaction_index), + deployer, + contract_code, + }; + } + + unreachable!() +} + +fn calculate_genesis_contract_deployment_transaction_hash(runtime_code: &[u8]) -> Vec { + Keccak256::digest(runtime_code).to_vec() +} + +fn parse_verification_common_match(match_value: Match) -> InternalMatchData { + InternalMatchData { + does_match: true, + metadata_match: Some(match_value.metadata_match), + values: Some(match_value.values.into()), + transformations: Some(match_value.transformations.into()), + } +} diff --git a/eth-bytecode-db/verifier-alliance-database/src/lib.rs b/eth-bytecode-db/verifier-alliance-database/src/lib.rs new file mode 100644 index 000000000..8c8731389 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/src/lib.rs @@ -0,0 +1,132 @@ +/// Provides access to internal functions to access the database. +/// They mostly do not provide transactions consistency, and require +/// users to be care of transactions themselves. +/// +/// Are not recommended to be used directly. +/// Prefer methods exposed to the public instead. +pub mod internal; + +mod helpers; +mod types; + +pub use types::{ + CompiledContract, CompiledContractCompiler, CompiledContractLanguage, ContractCode, + ContractDeployment, InsertContractDeployment, RetrieveContractDeployment, VerifiedContract, + VerifiedContractMatches, +}; + +/************************ Public methods **************************/ + +use anyhow::{anyhow, Context, Error}; +use sea_orm::{DatabaseConnection, TransactionTrait}; + +pub async fn insert_contract_deployment( + database_connection: &DatabaseConnection, + to_insert: InsertContractDeployment, +) -> Result { + let chain_id = to_insert.chain_id(); + let address = to_insert.address().to_owned(); + let creation_code = to_insert.creation_code().map(ToOwned::to_owned); + let runtime_code = to_insert.runtime_code().to_owned(); + + let transaction = database_connection + .begin() + .await + .context("begin transaction")?; + + let internal_data = internal::InternalContractDeploymentData::from(to_insert); + let contract_model = + internal::insert_contract(&transaction, internal_data.contract_code.clone()).await?; + let contract_deployment_model = + internal::insert_contract_deployment(&transaction, internal_data, contract_model.id) + .await?; + + transaction.commit().await.context("commit transaction")?; + + Ok(ContractDeployment { + id: contract_deployment_model.id, + chain_id, + address, + runtime_code, + creation_code, + model: contract_deployment_model, + }) +} + +pub async fn insert_verified_contract( + database_connection: &DatabaseConnection, + mut verified_contract: VerifiedContract, +) -> Result<(), Error> { + let transaction = database_connection + .begin() + .await + .context("begin transaction")?; + + let sources = std::mem::take(&mut verified_contract.compiled_contract.sources); + let source_hashes = internal::precalculate_source_hashes(&sources); + + let compiled_contract_model = + internal::insert_compiled_contract(&transaction, verified_contract.compiled_contract) + .await?; + let compiled_contract_id = compiled_contract_model.id; + + let _source_models = internal::insert_sources(&transaction, sources).await?; + let _compiled_contract_source_models = internal::insert_compiled_contract_sources( + &transaction, + source_hashes, + compiled_contract_id, + ) + .await?; + let _verified_contract_model = internal::insert_verified_contract( + &transaction, + verified_contract.contract_deployment_id, + compiled_contract_id, + verified_contract.matches, + ) + .await?; + + transaction.commit().await.context("commit transaction")?; + + Ok(()) +} + +pub async fn find_contract_deployment( + database_connection: &DatabaseConnection, + to_retrieve: RetrieveContractDeployment, +) -> Result, Error> { + let chain_id = to_retrieve.chain_id(); + let address = to_retrieve.address().to_owned(); + + let contract_deployment_model = + internal::retrieve_contract_deployment(database_connection, to_retrieve).await?; + if let Some(contract_deployment_model) = contract_deployment_model { + let contract = internal::retrieve_contract_by_id( + database_connection, + contract_deployment_model.contract_id, + ) + .await?; + + let creation_code_model = + internal::retrieve_code_by_id(database_connection, contract.creation_code_hash.clone()) + .await?; + let creation_code = creation_code_model.code; + + let runtime_code_model = + internal::retrieve_code_by_id(database_connection, contract.runtime_code_hash.clone()) + .await?; + let runtime_code = runtime_code_model + .code + .ok_or(anyhow!("contract does not have runtime code"))?; + + return Ok(Some(ContractDeployment { + id: contract_deployment_model.id, + chain_id, + address, + runtime_code, + creation_code, + model: contract_deployment_model, + })); + } + + Ok(None) +} diff --git a/eth-bytecode-db/verifier-alliance-database/src/types.rs b/eth-bytecode-db/verifier-alliance-database/src/types.rs new file mode 100644 index 000000000..b75ddc62e --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/src/types.rs @@ -0,0 +1,164 @@ +use sea_orm::prelude::Uuid; +use std::collections::BTreeMap; +use verification_common_v1::verifier_alliance::{ + CompilationArtifacts, CreationCodeArtifacts, Match, RuntimeCodeArtifacts, +}; +use verifier_alliance_entity_v1::contract_deployments; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ContractDeployment { + pub id: Uuid, + pub chain_id: u128, + pub address: Vec, + pub runtime_code: Vec, + pub creation_code: Option>, + pub model: contract_deployments::Model, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum ContractCode { + OnlyRuntimeCode { + code: Vec, + }, + CompleteCode { + creation_code: Vec, + runtime_code: Vec, + }, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum InsertContractDeployment { + Genesis { + chain_id: u128, + address: Vec, + runtime_code: Vec, + }, + Regular { + chain_id: u128, + address: Vec, + transaction_hash: Vec, + block_number: u128, + transaction_index: u128, + deployer: Vec, + creation_code: Vec, + runtime_code: Vec, + }, +} + +impl InsertContractDeployment { + pub fn chain_id(&self) -> u128 { + match self { + InsertContractDeployment::Genesis { chain_id, .. } => *chain_id, + InsertContractDeployment::Regular { chain_id, .. } => *chain_id, + } + } + + pub fn address(&self) -> &[u8] { + match self { + InsertContractDeployment::Genesis { address, .. } => address, + InsertContractDeployment::Regular { address, .. } => address, + } + } + + pub fn runtime_code(&self) -> &[u8] { + match self { + InsertContractDeployment::Genesis { runtime_code, .. } => runtime_code, + InsertContractDeployment::Regular { runtime_code, .. } => runtime_code, + } + } + + pub fn creation_code(&self) -> Option<&[u8]> { + match self { + InsertContractDeployment::Genesis { .. } => None, + InsertContractDeployment::Regular { creation_code, .. } => Some(creation_code), + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct RetrieveContractDeployment { + pub(crate) chain_id: u128, + pub(crate) address: Vec, + pub(crate) transaction_hash: Option>, + pub(crate) runtime_code: Option>, +} + +impl RetrieveContractDeployment { + pub fn regular(chain_id: u128, address: Vec, transaction_hash: Vec) -> Self { + Self { + chain_id, + address, + transaction_hash: Some(transaction_hash), + runtime_code: None, + } + } + + pub fn genesis(chain_id: u128, address: Vec, runtime_code: Vec) -> Self { + Self { + chain_id, + address, + transaction_hash: None, + runtime_code: Some(runtime_code), + } + } + + pub fn chain_id(&self) -> u128 { + self.chain_id + } + + pub fn address(&self) -> &[u8] { + &self.address + } +} + +#[derive(Clone, Debug, strum::Display, strum::EnumString, PartialEq, Eq, Hash)] +#[strum(serialize_all = "lowercase")] +pub enum CompiledContractCompiler { + Solc, + Vyper, +} + +#[derive(Clone, Debug, strum::Display, strum::EnumString, PartialEq, Eq, Hash)] +#[strum(serialize_all = "lowercase")] +pub enum CompiledContractLanguage { + Solidity, + Yul, + Vyper, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CompiledContract { + pub compiler: CompiledContractCompiler, + pub version: String, + pub language: CompiledContractLanguage, + pub name: String, + pub fully_qualified_name: String, + pub sources: BTreeMap, + pub compiler_settings: serde_json::Value, + pub compilation_artifacts: CompilationArtifacts, + pub creation_code: Vec, + pub creation_code_artifacts: CreationCodeArtifacts, + pub runtime_code: Vec, + pub runtime_code_artifacts: RuntimeCodeArtifacts, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum VerifiedContractMatches { + OnlyCreation { + creation_match: Match, + }, + OnlyRuntime { + runtime_match: Match, + }, + Complete { + creation_match: Match, + runtime_match: Match, + }, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct VerifiedContract { + pub contract_deployment_id: Uuid, + pub compiled_contract: CompiledContract, + pub matches: VerifiedContractMatches, +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/integration/contract_deployments.rs b/eth-bytecode-db/verifier-alliance-database/tests/integration/contract_deployments.rs new file mode 100644 index 000000000..b64c02b29 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/integration/contract_deployments.rs @@ -0,0 +1,110 @@ +use crate::database; +use blockscout_display_bytes::decode_hex; +use pretty_assertions::assert_eq; +use verifier_alliance_database::{InsertContractDeployment, RetrieveContractDeployment}; + +#[tokio::test] +async fn insert_regular_deployment_works_and_can_be_retrieved() { + let db_guard = database!(); + + let chain_id = 10; + let address = decode_hex("0x8FbB39A5a79aeCE03c8f13ccEE0b96C128ec1a67").unwrap(); + let transaction_hash = + decode_hex("0xf4042e19c445551d1059ad3856f83383c48699367cfb3e0edeccd26002dd2292").unwrap(); + + let contract_deployment = InsertContractDeployment::Regular { + chain_id, + address: address.clone(), + transaction_hash: transaction_hash.clone(), + block_number: 127387809, + transaction_index: 16, + deployer: decode_hex("0x1F98431c8aD98523631AE4a59f267346ea31F984").unwrap(), + creation_code: vec![0x1, 0x2], + runtime_code: vec![0x3, 0x4], + }; + + let inserted_model = verifier_alliance_database::insert_contract_deployment( + db_guard.client().as_ref(), + contract_deployment, + ) + .await + .expect("error while inserting"); + + /********** retrieval **********/ + + let retrieve_contract_deployment = + RetrieveContractDeployment::regular(chain_id, address, transaction_hash); + + let retrieved_model = verifier_alliance_database::find_contract_deployment( + db_guard.client().as_ref(), + retrieve_contract_deployment, + ) + .await + .expect("error while retrieving") + .expect("no model has been retrieved"); + + assert_eq!( + inserted_model, retrieved_model, + "inserted and retrieved models do not match" + ); +} + +#[tokio::test] +async fn insert_genesis_deployment_works_and_can_be_retrieved() { + let db_guard = database!(); + + let chain_id = 10; + let address = decode_hex("0x4200000000000000000000000000000000000008").unwrap(); + let runtime_code = vec![0x3, 0x4]; + + let contract_deployment = InsertContractDeployment::Genesis { + chain_id: 10, + address: address.clone(), + runtime_code: runtime_code.clone(), + }; + + let inserted_model = verifier_alliance_database::insert_contract_deployment( + db_guard.client().as_ref(), + contract_deployment, + ) + .await + .expect("error while inserting"); + + /********** retrieval **********/ + + let retrieve_contract_deployment = + RetrieveContractDeployment::genesis(chain_id, address, runtime_code); + + let retrieved_model = verifier_alliance_database::find_contract_deployment( + db_guard.client().as_ref(), + retrieve_contract_deployment, + ) + .await + .expect("error while retrieving") + .expect("no model has been retrieved"); + + assert_eq!( + inserted_model, retrieved_model, + "inserted and retrieved models do not match" + ); +} + +#[tokio::test] +async fn non_existed_deployment_retrieval_returns_none() { + let db_guard = database!(); + + let retrieve_contract_deployment = + RetrieveContractDeployment::regular(10, vec![0x1], vec![0x1]); + + let retrieved_model = verifier_alliance_database::find_contract_deployment( + db_guard.client().as_ref(), + retrieve_contract_deployment, + ) + .await + .expect("error while retrieving"); + + assert_eq!( + None, retrieved_model, + "no model was expected to be retrieved" + ); +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/integration/internal_compiled_contracts.rs b/eth-bytecode-db/verifier-alliance-database/tests/integration/internal_compiled_contracts.rs new file mode 100644 index 000000000..4d2745a6c --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/integration/internal_compiled_contracts.rs @@ -0,0 +1,95 @@ +use crate::database; +use serde_json::json; +use std::collections::BTreeMap; +use verification_common_v1::verifier_alliance::{ + CompilationArtifacts, CreationCodeArtifacts, RuntimeCodeArtifacts, SourceId, +}; +use verifier_alliance_database::{ + internal, CompiledContract, CompiledContractCompiler, CompiledContractLanguage, +}; + +#[tokio::test] +async fn insert_compiled_contract_works() { + let db_guard = database!(); + + let compiled_contract = CompiledContract { + compiler: CompiledContractCompiler::Solc, + version: "".to_string(), + language: CompiledContractLanguage::Solidity, + name: "Counter".to_string(), + fully_qualified_name: "src/Counter.sol:Counter".to_string(), + sources: BTreeMap::from([( + "src/Counter.sol".into(), + "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {\n uint256 public number;\n\n function setNumber(uint256 newNumber) public {\n number = newNumber;\n }\n\n function increment() public {\n number++;\n }\n}\n".into(), + )]), + compiler_settings: json!({"evmVersion":"paris","libraries":{},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["*"]}},"remappings":[],"viaIR":false}), + compilation_artifacts: CompilationArtifacts { + abi: Some(json!({"abi": "value"})), + devdoc: Some(json!({"devdoc": "value"})), + userdoc: Some(json!({"userdoc": "value"})), + storage_layout: Some(json!({"storage": "value"})), + sources: Some(BTreeMap::from([("src/Counter.sol".into(), SourceId {id: 0})])) + }, + creation_code: vec![0x1, 0x2], + creation_code_artifacts: CreationCodeArtifacts { + source_map: Some(json!("source_map")), + link_references: Some(json!({"linkReferences": "value"})), + cbor_auxdata: Some(json!({"cborAuxdata": "value"})), + }, + runtime_code: vec![0x3, 0x4], + runtime_code_artifacts: RuntimeCodeArtifacts { + cbor_auxdata: Some(json!({"cborAuxdata": "value"})), + immutable_references: Some(json!({"immutableReferences": "value"})), + link_references: Some(json!({"linkReferences": "value"})), + source_map: Some(json!("source_map")), + }, + }; + + let _inserted_model = + internal::insert_compiled_contract(db_guard.client().as_ref(), compiled_contract) + .await + .expect("error while inserting"); +} + +#[tokio::test] +async fn insert_compiled_contract_with_empty_artifact_values() { + let db_guard = database!(); + + let compiled_contract = CompiledContract { + compiler: CompiledContractCompiler::Solc, + version: "".to_string(), + language: CompiledContractLanguage::Solidity, + name: "Counter".to_string(), + fully_qualified_name: "src/Counter.sol:Counter".to_string(), + sources: BTreeMap::from([( + "src/Counter.sol".into(), + "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {\n uint256 public number;\n\n function setNumber(uint256 newNumber) public {\n number = newNumber;\n }\n\n function increment() public {\n number++;\n }\n}\n".into(), + )]), + compiler_settings: json!({"evmVersion":"paris","libraries":{},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["*"]}},"remappings":[],"viaIR":false}), + compilation_artifacts: CompilationArtifacts { + abi: None, + devdoc: None, + userdoc: None, + storage_layout: None, + sources: None, + }, + creation_code: vec![0x1, 0x2], + creation_code_artifacts: CreationCodeArtifacts { + source_map: None, + link_references: None, + cbor_auxdata: None, + }, + runtime_code: vec![0x3, 0x4], + runtime_code_artifacts: RuntimeCodeArtifacts { + cbor_auxdata: None, + immutable_references: None, + link_references: None, + source_map: None, + }, + }; + + let _inserted_model = + internal::insert_compiled_contract(db_guard.client().as_ref(), compiled_contract) + .await + .expect("error while inserting"); +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/integration/main.rs b/eth-bytecode-db/verifier-alliance-database/tests/integration/main.rs new file mode 100644 index 000000000..7af8ca08a --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/integration/main.rs @@ -0,0 +1,23 @@ +mod contract_deployments; +mod internal_compiled_contracts; +mod transformations; +mod transformations_types; +mod verified_contracts; + +macro_rules! database { + () => {{ + let database_name = format!("{}_{}_{}", file!(), line!(), column!()); + blockscout_service_launcher::test_database::TestDbGuard::new::< + verifier_alliance_migration_v1::Migrator, + >(&database_name) + .await + }}; + ($custom_suffix:expr) => {{ + let database_name = format!("{}_{}_{}_{}", file!(), line!(), column!(), $custom_suffix); + blockscout_service_launcher::test_database::TestDbGuard::new::< + verifier_alliance_migration_v1::Migrator, + >(&database_name) + .await + }}; +} +pub(crate) use database; diff --git a/eth-bytecode-db/verifier-alliance-database/tests/integration/transformations.rs b/eth-bytecode-db/verifier-alliance-database/tests/integration/transformations.rs new file mode 100644 index 000000000..a19c11bb6 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/integration/transformations.rs @@ -0,0 +1,46 @@ +use crate::{database, transformations_types::TestCase}; +use verifier_alliance_database::{insert_contract_deployment, insert_verified_contract}; + +macro_rules! build_test { + ($test_name:ident) => { + #[tokio::test] + async fn $test_name() { + const TEST_CASE_CONTENT: &str = include_str!(std::concat!( + "../test_cases/", + stringify!($test_name), + ".json" + )); + + let database_guard = database!(); + let database_connection = database_guard.client(); + + let test_case = TestCase::from_content(TEST_CASE_CONTENT); + + let contract_deployment_data = test_case.contract_deployment_data(); + let inserted_contract_deployment = + insert_contract_deployment(&database_connection, contract_deployment_data) + .await + .expect("error while inserting contract deployment"); + + let verified_contract_data = + test_case.verified_contract_data(inserted_contract_deployment.id); + let _inserted_verified_contract = + insert_verified_contract(&database_connection, verified_contract_data) + .await + .expect("error while inserting verified contract"); + + test_case + .validate_final_database_state(&database_connection) + .await; + } + }; +} + +build_test!(constructor_arguments); +build_test!(full_match); +build_test!(immutables); +build_test!(libraries_linked_by_compiler); +build_test!(libraries_manually_linked); +build_test!(metadata_hash_absent); +build_test!(partial_match); +build_test!(partial_match_double_auxdata); diff --git a/eth-bytecode-db/verifier-alliance-database/tests/integration/transformations_types.rs b/eth-bytecode-db/verifier-alliance-database/tests/integration/transformations_types.rs new file mode 100644 index 000000000..c5b245541 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/integration/transformations_types.rs @@ -0,0 +1,461 @@ +use sea_orm::{prelude::Uuid, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter}; +use serde::{Deserialize, Deserializer}; +use serde_json::Value; +use sha3::{Digest, Keccak256}; +use std::{collections::BTreeMap, str::FromStr}; +use verification_common_v1::verifier_alliance::{ + CompilationArtifacts, CreationCodeArtifacts, Match, MatchTransformation, MatchValues, + RuntimeCodeArtifacts, +}; +use verifier_alliance_database::{ + CompiledContract, CompiledContractCompiler, CompiledContractLanguage, InsertContractDeployment, + VerifiedContract, VerifiedContractMatches, +}; +use verifier_alliance_entity_v1::{ + code, compiled_contracts, compiled_contracts_sources, contract_deployments, contracts, sources, + verified_contracts, +}; + +#[serde_with::serde_as] +#[derive(Clone, Debug, Deserialize)] +pub struct TestCase { + #[serde(deserialize_with = "string_to_u128")] + chain_id: u128, + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + address: Vec, + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + transaction_hash: Vec, + #[serde(deserialize_with = "string_to_u128")] + block_number: u128, + #[serde(deserialize_with = "string_to_u128")] + transaction_index: u128, + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + deployer: Vec, + + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + deployed_creation_code: Vec, + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + deployed_runtime_code: Vec, + + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + compiled_creation_code: Vec, + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + compiled_runtime_code: Vec, + + compiler: String, + version: String, + language: String, + name: String, + fully_qualified_name: String, + sources: BTreeMap, + compiler_settings: Value, + compilation_artifacts: CompilationArtifacts, + creation_code_artifacts: CreationCodeArtifacts, + runtime_code_artifacts: RuntimeCodeArtifacts, + + #[serde(rename = "creation_match")] + _creation_match: bool, + creation_metadata_match: bool, + creation_values: MatchValues, + creation_transformations: Vec, + + #[serde(rename = "runtime_match")] + _runtime_match: bool, + runtime_metadata_match: bool, + runtime_values: MatchValues, + runtime_transformations: Vec, +} + +fn string_to_u128<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let string = String::deserialize(deserializer)?; + u128::from_str(&string).map_err(::custom) +} + +impl TestCase { + pub fn from_content(content: &str) -> Self { + serde_json::from_str(content).expect("invalid test case format") + } + + pub fn contract_deployment_data(&self) -> InsertContractDeployment { + InsertContractDeployment::Regular { + chain_id: self.chain_id, + address: self.address.clone(), + transaction_hash: self.transaction_hash.clone(), + block_number: self.block_number, + transaction_index: self.transaction_index, + deployer: self.deployer.clone(), + creation_code: self.deployed_creation_code.clone(), + runtime_code: self.deployed_runtime_code.clone(), + } + } + + pub fn verified_contract_data(&self, contract_deployment_id: Uuid) -> VerifiedContract { + let compiler = CompiledContractCompiler::from_str(&self.compiler.to_lowercase()) + .expect("invalid compiler"); + let language = CompiledContractLanguage::from_str(&self.language.to_lowercase()) + .expect("invalid language"); + VerifiedContract { + contract_deployment_id, + compiled_contract: CompiledContract { + compiler, + version: self.version.clone(), + language, + name: self.name.clone(), + fully_qualified_name: self.fully_qualified_name.clone(), + sources: self.sources.clone(), + compiler_settings: self.compiler_settings.clone(), + compilation_artifacts: self.compilation_artifacts.clone(), + creation_code: self.compiled_creation_code.clone(), + creation_code_artifacts: self.creation_code_artifacts.clone(), + runtime_code: self.compiled_runtime_code.clone(), + runtime_code_artifacts: self.runtime_code_artifacts.clone(), + }, + matches: VerifiedContractMatches::Complete { + creation_match: Match { + metadata_match: self.creation_metadata_match, + transformations: self.creation_transformations.clone(), + values: self.creation_values.clone(), + }, + runtime_match: Match { + metadata_match: self.runtime_metadata_match, + transformations: self.runtime_transformations.clone(), + values: self.runtime_values.clone(), + }, + }, + } + } +} + +impl TestCase { + pub async fn validate_final_database_state(&self, database_connection: &DatabaseConnection) { + let _contract_deployment = self + .validate_contract_deployments_table(database_connection) + .await; + let contract = self.validate_contracts_table(database_connection).await; + self.validate_code_value( + database_connection, + contract.creation_code_hash, + self.deployed_creation_code.clone(), + ) + .await; + self.validate_code_value( + database_connection, + contract.runtime_code_hash, + self.deployed_runtime_code.clone(), + ) + .await; + + let compiled_contract = self + .validate_compiled_contracts_table(database_connection) + .await; + self.validate_code_value( + database_connection, + compiled_contract.creation_code_hash, + self.compiled_creation_code.clone(), + ) + .await; + self.validate_code_value( + database_connection, + compiled_contract.runtime_code_hash, + self.compiled_runtime_code.clone(), + ) + .await; + + let sources = self.validate_sources_table(database_connection).await; + let _compiled_contracts_sources = self + .validate_compiled_contracts_sources_table(database_connection, sources) + .await; + + let _verified_contracts = self + .validate_verified_contracts_table(database_connection) + .await; + } + + async fn validate_contract_deployments_table( + &self, + database_connection: &DatabaseConnection, + ) -> contract_deployments::Model { + let contract_deployments = contract_deployments::Entity::find() + .all(database_connection) + .await + .expect("error while retrieving contract deployments"); + assert_eq!( + contract_deployments.len(), + 1, + "invalid number of contract deployments in the database: {:?}", + contract_deployments + ); + let contract_deployment = contract_deployments[0].clone(); + + assert_eq!( + contract_deployment.address, + self.address.clone(), + "invalid contract deployment address" + ); + assert_eq!( + contract_deployment.chain_id, + self.chain_id.into(), + "invalid contract deployment chain id" + ); + assert_eq!( + contract_deployment.transaction_hash, self.transaction_hash, + "invalid contract deployment transaction hash" + ); + assert_eq!( + contract_deployment.block_number, + self.block_number.into(), + "invalid contract deployment block number" + ); + assert_eq!( + contract_deployment.transaction_index, + self.transaction_index.into(), + "invalid contract deployment transaction index" + ); + assert_eq!( + contract_deployment.deployer, self.deployer, + "invalid contract deployment deployer" + ); + + contract_deployment + } + + async fn validate_contracts_table( + &self, + database_connection: &DatabaseConnection, + ) -> contracts::Model { + let contracts = contracts::Entity::find() + .all(database_connection) + .await + .expect("error while retrieving contracts"); + assert_eq!( + contracts.len(), + 1, + "invalid number of contracts in the database: {:?}", + contracts + ); + contracts[0].clone() + } + + async fn validate_code_value( + &self, + database_connection: &DatabaseConnection, + code_hash: Vec, + code: Vec, + ) -> code::Model { + let code_model = code::Entity::find() + .filter(code::Column::CodeHash.eq(code_hash.clone())) + .one(database_connection) + .await + .expect("error while retrieving code value") + .unwrap_or_else(|| panic!("code hash does not exist in the database: {:?}", code_hash)); + + let expected_code_hash_keccak = Keccak256::digest(&code).to_vec(); + assert_eq!( + code_model.code_hash_keccak, expected_code_hash_keccak, + "invalid code code hash keccak" + ); + assert_eq!(code_model.code, Some(code), "invalid code value"); + + code_model + } + + async fn validate_compiled_contracts_table( + &self, + database_connection: &DatabaseConnection, + ) -> compiled_contracts::Model { + let compiled_contracts = compiled_contracts::Entity::find() + .all(database_connection) + .await + .expect("error while retrieving compiled contracts"); + assert_eq!( + compiled_contracts.len(), + 1, + "invalid number of compiled contracts in the database: {:?}", + compiled_contracts + ); + let compiled_contract = compiled_contracts[0].clone(); + + assert_eq!( + compiled_contract.compiler.to_string(), + self.compiler, + "invalid compiled contract compiler" + ); + assert_eq!( + compiled_contract.version, self.version, + "invalid compiled contract version" + ); + assert_eq!( + compiled_contract.language.to_string(), + self.language, + "invalid compiled contract language" + ); + assert_eq!( + compiled_contract.name, self.name, + "invalid compiled contract name" + ); + assert_eq!( + compiled_contract.fully_qualified_name, self.fully_qualified_name, + "invalid compiled contract fully qualified name" + ); + assert_eq!( + compiled_contract.compiler_settings, self.compiler_settings, + "invalid compiled contract compiler settings" + ); + assert_eq!( + compiled_contract.compilation_artifacts, + Value::from(self.compilation_artifacts.clone()), + "invalid compiled contract compilation artifacts" + ); + assert_eq!( + compiled_contract.creation_code_artifacts, + Value::from(self.creation_code_artifacts.clone()), + "invalid compiled contract creation code artifacts" + ); + assert_eq!( + compiled_contract.runtime_code_artifacts, + Value::from(self.runtime_code_artifacts.clone()), + "invalid compiled contract runtime artifacts" + ); + + compiled_contract + } + + async fn validate_sources_table( + &self, + database_connection: &DatabaseConnection, + ) -> Vec { + let sources = sources::Entity::find() + .all(database_connection) + .await + .expect("error while retrieving sources"); + assert_eq!( + sources.len(), + self.sources.len(), + "invalid number of sources in database: {:?}", + sources + ); + + for (path, content) in self.sources.iter() { + let source = sources + .iter() + .find(|source| &source.content == content) + .unwrap_or_else(|| panic!("source not found in the database for path={path}")); + let expected_source_hash_keccak = Keccak256::digest(&source.content).to_vec(); + assert_eq!( + source.source_hash_keccak, expected_source_hash_keccak, + "invalid source source hash keccak" + ); + } + + sources + } + + async fn validate_compiled_contracts_sources_table( + &self, + database_connection: &DatabaseConnection, + sources: Vec, + ) -> Vec { + let compiled_contracts_sources = compiled_contracts_sources::Entity::find() + .all(database_connection) + .await + .expect("error while retrieving compiled contracts sources"); + assert_eq!( + compiled_contracts_sources.len(), + sources.len(), + "invalid number of compiled contracts sources in the database: {:?}", + compiled_contracts_sources + ); + + for (path, content) in self.sources.iter() { + let compiled_contract_source = compiled_contracts_sources + .iter() + .find(|model| &model.path == path) + .unwrap_or_else(|| { + panic!("compiled contract source not found in database for path={path}") + }); + let source = sources + .iter() + .find(|source| &source.content == content) + .unwrap(); + let expected_source_hash = &source.source_hash; + assert_eq!( + &compiled_contract_source.source_hash, expected_source_hash, + "invalid compiled contract source source hash" + ); + } + + compiled_contracts_sources + } + + async fn validate_verified_contracts_table( + &self, + database_connection: &DatabaseConnection, + ) -> verified_contracts::Model { + let verified_contracts = verified_contracts::Entity::find() + .all(database_connection) + .await + .expect("error while retrieving verified contracts"); + assert_eq!( + verified_contracts.len(), + 1, + "invalid number of verified contracts in database: {:?}", + verified_contracts + ); + let verified_contract = verified_contracts[0].clone(); + + assert!( + verified_contract.creation_match, + "invalid verified contract creation match" + ); + assert_eq!( + verified_contract.creation_metadata_match, + Some(self.creation_metadata_match), + "invalid verified contract creation metadata match" + ); + assert_eq!( + verified_contract.creation_values, + Some(Value::from(self.creation_values.clone())), + "invalid verified contract creation values" + ); + assert_eq!( + verified_contract.creation_transformations, + Some(Value::from(self.creation_transformations.clone())), + "invalid verified contract creation transformations" + ); + assert_eq!( + verified_contract.creation_metadata_match, + Some(self.creation_metadata_match), + "invalid verified contract creation metadata match" + ); + + assert!( + verified_contract.runtime_match, + "invalid verified contract runtime match" + ); + assert_eq!( + verified_contract.runtime_metadata_match, + Some(self.creation_metadata_match), + "invalid verified contract runtime metadata match" + ); + assert_eq!( + verified_contract.runtime_values, + Some(Value::from(self.runtime_values.clone())), + "invalid verified contract runtime values" + ); + assert_eq!( + verified_contract.runtime_transformations, + Some(Value::from(self.runtime_transformations.clone())), + "invalid verified contract runtime transformations" + ); + assert_eq!( + verified_contract.runtime_metadata_match, + Some(self.runtime_metadata_match), + "invalid verified contract runtime metadata match" + ); + + verified_contract + } +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/integration/verified_contracts.rs b/eth-bytecode-db/verifier-alliance-database/tests/integration/verified_contracts.rs new file mode 100644 index 000000000..e3cd63807 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/integration/verified_contracts.rs @@ -0,0 +1,237 @@ +use crate::database; +use blockscout_display_bytes::decode_hex; +use sea_orm::{prelude::Uuid, DatabaseConnection}; +use serde_json::json; +use std::collections::BTreeMap; +use verification_common_v1::verifier_alliance::{ + CompilationArtifacts, CreationCodeArtifacts, Match, MatchTransformation, MatchValues, + RuntimeCodeArtifacts, SourceId, +}; +use verifier_alliance_database::{ + CompiledContract, CompiledContractCompiler, CompiledContractLanguage, InsertContractDeployment, + VerifiedContract, VerifiedContractMatches, +}; + +#[tokio::test] +async fn insert_verified_contract_with_complete_matches_work() { + let db_guard = database!(); + + let contract_deployment_id = insert_contract_deployment(db_guard.client().as_ref()).await; + let compiled_contract = complete_compiled_contract(); + let verified_contract = VerifiedContract { + contract_deployment_id, + compiled_contract, + matches: VerifiedContractMatches::Complete { + runtime_match: Match { + metadata_match: true, + transformations: vec![], + values: Default::default(), + }, + creation_match: Match { + metadata_match: true, + transformations: vec![], + values: Default::default(), + }, + }, + }; + + verifier_alliance_database::insert_verified_contract( + db_guard.client().as_ref(), + verified_contract, + ) + .await + .expect("error while inserting"); +} + +#[tokio::test] +async fn insert_verified_contract_with_runtime_only_matches_work() { + let db_guard = database!(); + + let contract_deployment_id = insert_contract_deployment(db_guard.client().as_ref()).await; + let compiled_contract = complete_compiled_contract(); + let verified_contract = VerifiedContract { + contract_deployment_id, + compiled_contract, + matches: VerifiedContractMatches::OnlyRuntime { + runtime_match: Match { + metadata_match: true, + transformations: vec![], + values: Default::default(), + }, + }, + }; + + verifier_alliance_database::insert_verified_contract( + db_guard.client().as_ref(), + verified_contract, + ) + .await + .expect("error while inserting"); +} + +#[tokio::test] +async fn insert_verified_contract_with_creation_only_matches_work() { + let db_guard = database!(); + + let contract_deployment_id = insert_contract_deployment(db_guard.client().as_ref()).await; + let compiled_contract = complete_compiled_contract(); + let verified_contract = VerifiedContract { + contract_deployment_id, + compiled_contract, + matches: VerifiedContractMatches::OnlyCreation { + creation_match: Match { + metadata_match: true, + transformations: vec![], + values: Default::default(), + }, + }, + }; + + verifier_alliance_database::insert_verified_contract( + db_guard.client().as_ref(), + verified_contract, + ) + .await + .expect("error while inserting"); +} + +#[tokio::test] +async fn insert_verified_contract_with_filled_matches() { + let db_guard = database!(); + + let contract_deployment_id = insert_contract_deployment(db_guard.client().as_ref()).await; + let compiled_contract = complete_compiled_contract(); + + let (runtime_match_values, runtime_match_transformations) = { + let mut match_values = MatchValues::default(); + let mut match_transformations = vec![]; + + match_values.add_immutable( + "immutable", + decode_hex("0x0000000000000000000000000000000000000000000000000000000000000032") + .unwrap() + .into(), + ); + match_transformations.push(MatchTransformation::immutable(1, "immutable")); + match_values.add_library( + "library", + decode_hex("0x0000000000000000000000000000000000000020") + .unwrap() + .into(), + ); + match_transformations.push(MatchTransformation::library(1, "library")); + match_values.add_cbor_auxdata( + "cborAuxdata", + decode_hex("0x1000000000000000000000000000000000000000000000000000000000000032") + .unwrap() + .into(), + ); + match_transformations.push(MatchTransformation::auxdata(1, "cborAuxdata")); + + (match_values, match_transformations) + }; + + let (creation_match_values, creation_match_transformations) = { + let mut match_values = MatchValues::default(); + let mut match_transformations = vec![]; + + match_values.add_constructor_arguments(decode_hex("0x01020304").unwrap().into()); + match_transformations.push(MatchTransformation::constructor(1)); + match_values.add_library( + "library", + decode_hex("0x0000000000000000000000000000000000000020") + .unwrap() + .into(), + ); + match_transformations.push(MatchTransformation::library(1, "library")); + match_values.add_cbor_auxdata( + "cborAuxdata", + decode_hex("0x1000000000000000000000000000000000000000000000000000000000000032") + .unwrap() + .into(), + ); + match_transformations.push(MatchTransformation::auxdata(1, "cborAuxdata")); + + (match_values, match_transformations) + }; + + let verified_contract = VerifiedContract { + contract_deployment_id, + compiled_contract, + matches: VerifiedContractMatches::Complete { + runtime_match: Match { + metadata_match: false, + transformations: runtime_match_transformations, + values: runtime_match_values, + }, + creation_match: Match { + metadata_match: false, + transformations: creation_match_transformations, + values: creation_match_values, + }, + }, + }; + + verifier_alliance_database::insert_verified_contract( + db_guard.client().as_ref(), + verified_contract, + ) + .await + .expect("error while inserting"); +} + +fn complete_compiled_contract() -> CompiledContract { + CompiledContract { + compiler: CompiledContractCompiler::Solc, + version: "".to_string(), + language: CompiledContractLanguage::Solidity, + name: "Counter".to_string(), + fully_qualified_name: "src/Counter.sol:Counter".to_string(), + sources: BTreeMap::from([( + "src/Counter.sol".into(), + "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {\n uint256 public number;\n\n function setNumber(uint256 newNumber) public {\n number = newNumber;\n }\n\n function increment() public {\n number++;\n }\n}\n".into(), + )]), + compiler_settings: json!({"evmVersion":"paris","libraries":{},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["*"]}},"remappings":[],"viaIR":false}), + compilation_artifacts: CompilationArtifacts { + abi: Some(json!({"abi": "value"})), + devdoc: Some(json!({"devdoc": "value"})), + userdoc: Some(json!({"userdoc": "value"})), + storage_layout: Some(json!({"storage": "value"})), + sources: Some(BTreeMap::from([("src/Counter.sol".into(), SourceId {id: 0})])) + }, + creation_code: vec![0x1, 0x2], + creation_code_artifacts: CreationCodeArtifacts { + source_map: Some(json!("source_map")), + link_references: Some(json!({"linkReferences": "value"})), + cbor_auxdata: Some(json!({"cborAuxdata": "value"})), + }, + runtime_code: vec![0x3, 0x4], + runtime_code_artifacts: RuntimeCodeArtifacts { + cbor_auxdata: Some(json!({"cborAuxdata": "value"})), + immutable_references: Some(json!({"immutableReferences": "value"})), + link_references: Some(json!({"linkReferences": "value"})), + source_map: Some(json!("source_map")), + }, + } +} + +async fn insert_contract_deployment(database_connection: &DatabaseConnection) -> Uuid { + let contract_deployment = InsertContractDeployment::Regular { + chain_id: 10, + address: decode_hex("0x8FbB39A5a79aeCE03c8f13ccEE0b96C128ec1a67").unwrap(), + transaction_hash: decode_hex( + "0xf4042e19c445551d1059ad3856f83383c48699367cfb3e0edeccd26002dd2292", + ) + .unwrap(), + block_number: 127387809, + transaction_index: 16, + deployer: decode_hex("0x1F98431c8aD98523631AE4a59f267346ea31F984").unwrap(), + creation_code: vec![0x1, 0x2], + runtime_code: vec![0x3, 0x4], + }; + + verifier_alliance_database::insert_contract_deployment(database_connection, contract_deployment) + .await + .expect("error while inserting contract deployment") + .id +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/constructor_arguments.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/constructor_arguments.json new file mode 100644 index 000000000..17c3be32d --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/constructor_arguments.json @@ -0,0 +1,82 @@ +{ + "chain_id": "11155111", + "address": "0x664EEA330e41684EFE308014A4Ba358Bc079a853", + "transaction_hash": "0x8254ff650a3a4fae6ac905cad29c6ba81c7308c75f4d5d7526cd12eff73c0d98", + "block_number": "7108951", + "transaction_index": "27", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c634300081200330000000000000000000000000000000000000000000000000000000000003039", + "deployed_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033", + + "compiled_creation_code": "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033", + "compiled_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n constructor(uint256 num) {\n number = num;\n }\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "141:262:0:-:0;;;192:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;236:3;227:6;:12;;;;192:54;141:262;;88:117:1;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:143::-;602:5;633:6;627:13;618:22;;649:33;676:5;649:33;:::i;:::-;545:143;;;;:::o;694:351::-;764:6;813:2;801:9;792:7;788:23;784:32;781:119;;;819:79;;:::i;:::-;781:119;939:1;964:64;1020:7;1011:6;1000:9;996:22;964:64;:::i;:::-;954:74;;910:128;694:351;;;;:::o;141:262:0:-;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 436, + "value": "0xa2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {}, + "sourceMap": "141:262:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;337:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;337:64;391:3;382:6;:12;;;;337:64;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 254, + "value": "0xa2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": true, + "creation_values": { + "constructorArguments": "0x0000000000000000000000000000000000000000000000000000000000003039" + }, + "creation_transformations": [ + { + "type": "insert", + "reason": "constructorArguments", + "offset": 489 + } + ], + + "runtime_match": true, + "runtime_metadata_match": true, + "runtime_values": {}, + "runtime_transformations": [] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/full_match.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/full_match.json new file mode 100644 index 000000000..5087a88c6 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/full_match.json @@ -0,0 +1,74 @@ +{ + "chain_id": "11155111", + "address": "0xa851c68517290a357ec974D0a00A2f832322DdbA", + "transaction_hash": "0x1c92eea5fc29ab6e01ed0d76e8912c3c3a6dc5d2ecd64c076e69d07e6fed50f2", + "block_number": "7118016", + "transaction_index": "34", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033", + "deployed_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033", + + "compiled_creation_code": "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033", + "compiled_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "141:202:0:-:0;;;;;;;;;;;;;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 286, + "value": "0xa26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {}, + "sourceMap": "141:202:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;277:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;277:64;331:3;322:6;:12;;;;277:64;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 254, + "value": "0xa26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": true, + "creation_values": {}, + "creation_transformations": [], + + "runtime_match": true, + "runtime_metadata_match": true, + "runtime_values": {}, + "runtime_transformations": [] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/immutables.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/immutables.json new file mode 100644 index 000000000..d0275b772 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/immutables.json @@ -0,0 +1,85 @@ +{ + "chain_id": "11155111", + "address": "0xe2c3685fD385077504A389A0Fd569Fab7E54dB7d", + "transaction_hash": "0x0e14052a4172a0adf1dc83d90b3b757539890af06665f2ecfaaf80790a697da0", + "block_number": "7118024", + "transaction_index": "49", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x60a0604052606460809081525034801561001857600080fd5b5060805161019a610033600039600060b0015261019a6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033", + "deployed_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000006481565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033", + + "compiled_creation_code": "0x60a0604052606460809081525034801561001857600080fd5b5060805161019a610033600039600060b0015261019a6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033", + "compiled_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n uint256 public immutable imm_number = 100;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[],"name":"imm_number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "141:250:0:-:0;;;230:3;192:41;;;;;141:250;;;;;;;;;;;;;;;;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 408, + "value": "0xa26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {"7":[{"length":32,"start":176}]}, + "linkReferences": {}, + "sourceMap": "141:250:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;325:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;192:41;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;325:64;379:3;370:6;:12;;;;325:64;:::o;164:21::-;;;;:::o;192:41::-;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 357, + "value": "0xa26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": true, + "creation_values": {}, + "creation_transformations": [], + + "runtime_match": true, + "runtime_metadata_match": true, + "runtime_values": { + "immutables": { + "7": "0x0000000000000000000000000000000000000000000000000000000000000064" + } + }, + "runtime_transformations": [ + { + "type": "replace", + "reason": "immutable", + "offset": 176, + "id": "7" + } + ] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/libraries_linked_by_compiler.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/libraries_linked_by_compiler.json new file mode 100644 index 000000000..18777e8af --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/libraries_linked_by_compiler.json @@ -0,0 +1,80 @@ +{ + "_comment": "Libraries have been linked using compiler settings. The placeholders are already replaced inside the compiled bytecode, and no link references provided", + + "chain_id": "11155111", + "address": "0xc586D55a9fcDCA43dE7ebd097DEc950D50559Bbd", + "transaction_hash": "0x7a980a5a51804cccd75e3b8329c3ce5213d603f66b297cee908a7cbd2151241a", + "block_number": "7118254", + "transaction_index": "26", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x608060405234801561001057600080fd5b50610249806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea2646970667358221220a89051eba557a7a71a7afa4c5011918b95b51d314ed350221cb7a2f34703340364736f6c63430008120033", + "deployed_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea2646970667358221220a89051eba557a7a71a7afa4c5011918b95b51d314ed350221cb7a2f34703340364736f6c63430008120033", + + "compiled_creation_code": "0x608060405234801561001057600080fd5b50610249806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea2646970667358221220a89051eba557a7a71a7afa4c5011918b95b51d314ed350221cb7a2f34703340364736f6c63430008120033", + "compiled_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea2646970667358221220a89051eba557a7a71a7afa4c5011918b95b51d314ed350221cb7a2f34703340364736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\nlibrary Journal {\n function record(mapping(uint256 => uint256) storage journal, uint256 num) public {\n journal[block.number] = num;\n }\n}\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n mapping(uint256 => uint256) public journal;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n Journal.record(journal, num);\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": { + "contracts/1_Storage.sol": { + "Journal": "0x7d53f102f4d4aa014db4e10d6deec2009b3cda6b" + } + }, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"journal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":22,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"},{"astId":26,"contract":"contracts/1_Storage.sol:Storage","label":"journal","offset":0,"slot":"1","type":"t_mapping(t_uint256,t_uint256)"}],"types":{"t_mapping(t_uint256,t_uint256)":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => uint256)","numberOfBytes":"32","value":"t_uint256"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "292:289:0:-:0;;;;;;;;;;;;;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 564, + "value": "0xa2646970667358221220a89051eba557a7a71a7afa4c5011918b95b51d314ed350221cb7a2f34703340364736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {}, + "sourceMap": "292:289:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;477:102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;315:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;343:42;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;477:102;531:3;522:6;:12;;;;544:7;:14;559:7;568:3;544:28;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;477:102;:::o;315:21::-;;;;:::o;343:42::-;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o;1377:132::-;1497:5;1492:3;1485:18;1377:132;;:::o;1515:126::-;1610:24;1628:5;1610:24;:::i;:::-;1605:3;1598:37;1515:126;;:::o;1647:406::-;1801:4;1839:2;1828:9;1824:18;1816:26;;1852:104;1953:1;1942:9;1938:17;1929:6;1852:104;:::i;:::-;1966:80;2042:2;2031:9;2027:18;2018:6;1966:80;:::i;:::-;1647:406;;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 532, + "value": "0xa2646970667358221220a89051eba557a7a71a7afa4c5011918b95b51d314ed350221cb7a2f34703340364736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": true, + "creation_values": {}, + "creation_transformations": [], + + "runtime_match": true, + "runtime_metadata_match": true, + "runtime_values": {}, + "runtime_transformations": [] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/libraries_manually_linked.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/libraries_manually_linked.json new file mode 100644 index 000000000..8044aa65d --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/libraries_manually_linked.json @@ -0,0 +1,98 @@ +{ + "_comment": "Libraries have been linked manually instead of using compiler settings. Placeholders are replaced with zero addresses", + + "chain_id": "11155111", + "address": "0x90aA6A3f6A111382ea3f2b909b1bE61F5CBAdFEd", + "transaction_hash": "0x977a73ee3ed5ee36bd794615311ba5a487d96db4d1e0e87ac3c9825e9be787f7", + "block_number": "7118262", + "transaction_index": "40", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x608060405234801561001057600080fd5b50610249806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033", + "deployed_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033", + + "compiled_creation_code": "0x608060405234801561001057600080fd5b50610249806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550730000000000000000000000000000000000000000632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033", + "compiled_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550730000000000000000000000000000000000000000632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\nlibrary Journal {\n function record(mapping(uint256 => uint256) storage journal, uint256 num) public {\n journal[block.number] = num;\n }\n}\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n mapping(uint256 => uint256) public journal;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n Journal.record(journal, num);\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"journal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":22,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"},{"astId":26,"contract":"contracts/1_Storage.sol:Storage","label":"journal","offset":0,"slot":"1","type":"t_mapping(t_uint256,t_uint256)"}],"types":{"t_mapping(t_uint256,t_uint256)":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => uint256)","numberOfBytes":"32","value":"t_uint256"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {"contracts/1_Storage.sol":{"Journal":[{"length":20,"start":217}]}}, + "sourceMap": "292:289:0:-:0;;;;;;;;;;;;;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 564, + "value": "0xa26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {"contracts/1_Storage.sol":{"Journal":[{"length":20,"start":185}]}}, + "sourceMap": "292:289:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;477:102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;315:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;343:42;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;477:102;531:3;522:6;:12;;;;544:7;:14;559:7;568:3;544:28;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;477:102;:::o;315:21::-;;;;:::o;343:42::-;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o;1377:132::-;1497:5;1492:3;1485:18;1377:132;;:::o;1515:126::-;1610:24;1628:5;1610:24;:::i;:::-;1605:3;1598:37;1515:126;;:::o;1647:406::-;1801:4;1839:2;1828:9;1824:18;1816:26;;1852:104;1953:1;1942:9;1938:17;1929:6;1852:104;:::i;:::-;1966:80;2042:2;2031:9;2027:18;2018:6;1966:80;:::i;:::-;1647:406;;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 532, + "value": "0xa26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": true, + "creation_values": { + "libraries": { + "contracts/1_Storage.sol:Journal": "0x7d53f102f4d4aa014db4e10d6deec2009b3cda6b" + } + }, + "creation_transformations": [ + { + "type": "replace", + "reason": "library", + "offset": 217, + "id": "contracts/1_Storage.sol:Journal" + } + ], + + "runtime_match": true, + "runtime_metadata_match": true, + "runtime_values": { + "libraries": { + "contracts/1_Storage.sol:Journal": "0x7d53f102f4d4aa014db4e10d6deec2009b3cda6b" + } + }, + "runtime_transformations": [ + { + "type": "replace", + "reason": "library", + "offset": 185, + "id": "contracts/1_Storage.sol:Journal" + } + ] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/metadata_hash_absent.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/metadata_hash_absent.json new file mode 100644 index 000000000..8d77698a3 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/metadata_hash_absent.json @@ -0,0 +1,77 @@ +{ + "chain_id": "11155111", + "address": "0x8Baf31AAb52Dca9D17f8BDeB06Da5FB3f2520D4F", + "transaction_hash": "0xce2eb694f6a6b1016ada043c9a796a254132d664ca82d6f1f6b1be4e45222cac", + "block_number": "7118270", + "transaction_index": "36", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x608060405234801561001057600080fd5b5061010a806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea164736f6c6343000812000a", + "deployed_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea164736f6c6343000812000a", + + "compiled_creation_code": "0x608060405234801561001057600080fd5b5061010a806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea164736f6c6343000812000a", + "compiled_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea164736f6c6343000812000a", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "metadata": { + "bytecodeHash": "none" + }, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "141:202:0:-:0;;;;;;;;;;;;;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 286, + "value": "0xa164736f6c6343000812000a" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {}, + "sourceMap": "141:202:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;277:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;277:64;331:3;322:6;:12;;;;277:64;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 254, + "value": "0xa164736f6c6343000812000a" + } + } + }, + + "creation_match": true, + "creation_metadata_match": false, + "creation_values": {}, + "creation_transformations": [], + + "runtime_match": true, + "runtime_metadata_match": false, + "runtime_values": {}, + "runtime_transformations": [] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/partial_match.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/partial_match.json new file mode 100644 index 000000000..6be26bc8b --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/partial_match.json @@ -0,0 +1,98 @@ +{ + "_comment": "Argument `store.num` has been updated to `store.modified_num` to change the metadata hash", + + "chain_id": "11155111", + "address": "0x1052623FD0425d216A7c2FB466f6DbF216323282", + "transaction_hash": "0x48d7e8d4853f1001e7221ab49c01c62380d1a807d138f0c419dde45093472d92", + "block_number": "7118274", + "transaction_index": "18", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033", + "deployed_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033", + + "compiled_creation_code": "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033", + "compiled_runtime_code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n /**\n * @dev Store value in variable\n * @param modified_num value to store\n */\n function store(uint256 modified_num) public {\n number = modified_num;\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"modified_num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"modified_num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "141:229:0:-:0;;;;;;;;;;;;;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 286, + "value": "0xa26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {}, + "sourceMap": "141:229:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;286:82;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;286:82;349:12;340:6;:21;;;;286:82;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o", + "cborAuxdata": { + "1": { + "offset": 254, + "value": "0xa26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": false, + "creation_values": { + "cborAuxdata": { + "1": "0xa26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033" + } + }, + "creation_transformations": [ + { + "type": "replace", + "reason": "cborAuxdata", + "offset": 286, + "id": "1" + } + ], + + "runtime_match": true, + "runtime_metadata_match": false, + "runtime_values": { + "cborAuxdata": { + "1": "0xa26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033" + } + }, + "runtime_transformations": [ + { + "type": "replace", + "reason": "cborAuxdata", + "offset": 254, + "id": "1" + } + ] +} diff --git a/eth-bytecode-db/verifier-alliance-database/tests/test_cases/partial_match_double_auxdata.json b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/partial_match_double_auxdata.json new file mode 100644 index 000000000..0ec3161a1 --- /dev/null +++ b/eth-bytecode-db/verifier-alliance-database/tests/test_cases/partial_match_double_auxdata.json @@ -0,0 +1,107 @@ +{ + "chain_id": "11155111", + "address": "0x383eEaD9Ceeb888827d40D9f194882B36590378a", + "transaction_hash": "0x097e11c77a37c93e7fa38d9a883fad1dbf0572b6785b303b1bffeebdbed75dff", + "block_number": "7118283", + "transaction_index": "17", + "deployer": "0x8dB94A1C4b68c4d44E6d2cFEE59a9A960198dc64", + + "deployed_creation_code": "0x60806040526040518060200161001490610049565b6020820181038252601f19601f820116604052506001908161003691906102a5565b5034801561004357600080fd5b50610377565b605c8061069c83390190565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806100d657607f821691505b6020821081036100e9576100e861008f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610114565b61015b8683610114565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006101a261019d61019884610173565b61017d565b610173565b9050919050565b6000819050919050565b6101bc83610187565b6101d06101c8826101a9565b848454610121565b825550505050565b600090565b6101e56101d8565b6101f08184846101b3565b505050565b5b81811015610214576102096000826101dd565b6001810190506101f6565b5050565b601f8211156102595761022a816100ef565b61023384610104565b81016020851015610242578190505b61025661024e85610104565b8301826101f5565b50505b505050565b600082821c905092915050565b600061027c6000198460080261025e565b1980831691505092915050565b6000610295838361026b565b9150826002028217905092915050565b6102ae82610055565b67ffffffffffffffff8111156102c7576102c6610060565b5b6102d182546100be565b6102dc828285610218565b600060209050601f83116001811461030f57600084156102fd578287015190505b6103078582610289565b86555061036f565b601f19841661031d866100ef565b60005b8281101561034557848901518255600182019150602085019450602081019050610320565b86831015610362578489015161035e601f89168261026b565b8355505b6001600288020188555050505b505050505050565b610316806103866000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea2646970667358221220bc2c6d72c52842d4077bb24c307576e44a078831aaa16da6611ef342fd052ec764736f6c634300081200336080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220f13d144a826a3f18798a534a4b10029a3284d9f4620ccc79750cdc48442cdaad64736f6c63430008120033", + "deployed_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea2646970667358221220bc2c6d72c52842d4077bb24c307576e44a078831aaa16da6611ef342fd052ec764736f6c63430008120033", + + "compiled_creation_code": "0x60806040526040518060200161001490610049565b6020820181038252601f19601f820116604052506001908161003691906102a5565b5034801561004357600080fd5b50610377565b605c8061069c83390190565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806100d657607f821691505b6020821081036100e9576100e861008f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610114565b61015b8683610114565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006101a261019d61019884610173565b61017d565b610173565b9050919050565b6000819050919050565b6101bc83610187565b6101d06101c8826101a9565b848454610121565b825550505050565b600090565b6101e56101d8565b6101f08184846101b3565b505050565b5b81811015610214576102096000826101dd565b6001810190506101f6565b5050565b601f8211156102595761022a816100ef565b61023384610104565b81016020851015610242578190505b61025661024e85610104565b8301826101f5565b50505b505050565b600082821c905092915050565b600061027c6000198460080261025e565b1980831691505092915050565b6000610295838361026b565b9150826002028217905092915050565b6102ae82610055565b67ffffffffffffffff8111156102c7576102c6610060565b5b6102d182546100be565b6102dc828285610218565b600060209050601f83116001811461030f57600084156102fd578287015190505b6103078582610289565b86555061036f565b601f19841661031d866100ef565b60005b8281101561034557848901518255600182019150602085019450602081019050610320565b86831015610362578489015161035e601f89168261026b565b8355505b6001600288020188555050505b505050505050565b610316806103866000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c634300081200336080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220aebf48746b808da25305449bba6945baacf1c2185dfcc58a94b1506b8b5a6dfa64736f6c63430008120033", + "compiled_runtime_code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c63430008120033", + "compiler": "solc", + "version": "v0.8.18+commit.87f61d96", + "language": "solidity", + "name": "Storage", + "fully_qualified_name": "contracts/1_Storage.sol:Storage", + "sources": { + "contracts/1_Storage.sol": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.7.0 <0.9.0;\n\ncontract A {}\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n */\ncontract Storage {\n uint256 public number;\n\n // Comment to update metadata hash\n bytes public code = type(A).creationCode;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n }\n}" + }, + "compiler_settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "libraries": {}, + "outputSelection": { + "*": { + "*": [ + "*" + ] + } + } + }, + "compilation_artifacts": { + "abi": [{"inputs":[],"name":"code","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}], + "devdoc": {"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1}, + "userdoc": {"kind":"user","methods":{},"version":1}, + "storageLayout": {"storage":[{"astId":5,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"},{"astId":11,"contract":"contracts/1_Storage.sol:Storage","label":"code","offset":0,"slot":"1","type":"t_bytes_storage"}],"types":{"t_bytes_storage":{"encoding":"bytes","label":"bytes","numberOfBytes":"32"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}, + "sources": {"contracts/1_Storage.sol": {"id": 0} } + }, + "creation_code_artifacts": { + "linkReferences": {}, + "sourceMap": "156:288:0:-:0;;;266:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;246:40;;;;;;;:::i;:::-;;156:288;;;;;;;;;;;;;;;;;;;;:::o;7:98:1:-;58:6;92:5;86:12;76:22;;7:98;;;:::o;111:180::-;159:77;156:1;149:88;256:4;253:1;246:15;280:4;277:1;270:15;297:180;345:77;342:1;335:88;442:4;439:1;432:15;466:4;463:1;456:15;483:320;527:6;564:1;558:4;554:12;544:22;;611:1;605:4;601:12;632:18;622:81;;688:4;680:6;676:17;666:27;;622:81;750:2;742:6;739:14;719:18;716:38;713:84;;769:18;;:::i;:::-;713:84;534:269;483:320;;;:::o;809:140::-;857:4;880:3;872:11;;903:3;900:1;893:14;937:4;934:1;924:18;916:26;;809:140;;;:::o;955:93::-;992:6;1039:2;1034;1027:5;1023:14;1019:23;1009:33;;955:93;;;:::o;1054:107::-;1098:8;1148:5;1142:4;1138:16;1117:37;;1054:107;;;;:::o;1167:393::-;1236:6;1286:1;1274:10;1270:18;1309:97;1339:66;1328:9;1309:97;:::i;:::-;1427:39;1457:8;1446:9;1427:39;:::i;:::-;1415:51;;1499:4;1495:9;1488:5;1484:21;1475:30;;1548:4;1538:8;1534:19;1527:5;1524:30;1514:40;;1243:317;;1167:393;;;;;:::o;1566:77::-;1603:7;1632:5;1621:16;;1566:77;;;:::o;1649:60::-;1677:3;1698:5;1691:12;;1649:60;;;:::o;1715:142::-;1765:9;1798:53;1816:34;1825:24;1843:5;1825:24;:::i;:::-;1816:34;:::i;:::-;1798:53;:::i;:::-;1785:66;;1715:142;;;:::o;1863:75::-;1906:3;1927:5;1920:12;;1863:75;;;:::o;1944:269::-;2054:39;2085:7;2054:39;:::i;:::-;2115:91;2164:41;2188:16;2164:41;:::i;:::-;2156:6;2149:4;2143:11;2115:91;:::i;:::-;2109:4;2102:105;2020:193;1944:269;;;:::o;2219:73::-;2264:3;2219:73;:::o;2298:189::-;2375:32;;:::i;:::-;2416:65;2474:6;2466;2460:4;2416:65;:::i;:::-;2351:136;2298:189;;:::o;2493:186::-;2553:120;2570:3;2563:5;2560:14;2553:120;;;2624:39;2661:1;2654:5;2624:39;:::i;:::-;2597:1;2590:5;2586:13;2577:22;;2553:120;;;2493:186;;:::o;2685:541::-;2785:2;2780:3;2777:11;2774:445;;;2819:37;2850:5;2819:37;:::i;:::-;2902:29;2920:10;2902:29;:::i;:::-;2892:8;2888:44;3085:2;3073:10;3070:18;3067:49;;;3106:8;3091:23;;3067:49;3129:80;3185:22;3203:3;3185:22;:::i;:::-;3175:8;3171:37;3158:11;3129:80;:::i;:::-;2789:430;;2774:445;2685:541;;;:::o;3232:117::-;3286:8;3336:5;3330:4;3326:16;3305:37;;3232:117;;;;:::o;3355:169::-;3399:6;3432:51;3480:1;3476:6;3468:5;3465:1;3461:13;3432:51;:::i;:::-;3428:56;3513:4;3507;3503:15;3493:25;;3406:118;3355:169;;;;:::o;3529:295::-;3605:4;3751:29;3776:3;3770:4;3751:29;:::i;:::-;3743:37;;3813:3;3810:1;3806:11;3800:4;3797:21;3789:29;;3529:295;;;;:::o;3829:1390::-;3944:36;3976:3;3944:36;:::i;:::-;4045:18;4037:6;4034:30;4031:56;;;4067:18;;:::i;:::-;4031:56;4111:38;4143:4;4137:11;4111:38;:::i;:::-;4196:66;4255:6;4247;4241:4;4196:66;:::i;:::-;4289:1;4313:4;4300:17;;4345:2;4337:6;4334:14;4362:1;4357:617;;;;5018:1;5035:6;5032:77;;;5084:9;5079:3;5075:19;5069:26;5060:35;;5032:77;5135:67;5195:6;5188:5;5135:67;:::i;:::-;5129:4;5122:81;4991:222;4327:886;;4357:617;4409:4;4405:9;4397:6;4393:22;4443:36;4474:4;4443:36;:::i;:::-;4501:1;4515:208;4529:7;4526:1;4523:14;4515:208;;;4608:9;4603:3;4599:19;4593:26;4585:6;4578:42;4659:1;4651:6;4647:14;4637:24;;4706:2;4695:9;4691:18;4678:31;;4552:4;4549:1;4545:12;4540:17;;4515:208;;;4751:6;4742:7;4739:19;4736:179;;;4809:9;4804:3;4800:19;4794:26;4852:48;4894:4;4886:6;4882:17;4871:9;4852:48;:::i;:::-;4844:6;4837:64;4759:156;4736:179;4961:1;4957;4949:6;4945:14;4941:22;4935:4;4928:36;4364:610;;;4327:886;;3919:1300;;;3829:1390;;:::o;156:288:0:-;;;;;;;", + "cborAuxdata": { + "1": { + "offset": 1639, + "value": "0xa264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c63430008120033" + }, + "2": { + "offset": 1731, + "value": "0xa2646970667358221220aebf48746b808da25305449bba6945baacf1c2185dfcc58a94b1506b8b5a6dfa64736f6c63430008120033" + } + } + }, + "runtime_code_artifacts": { + "immutableReferences": {}, + "linkReferences": {}, + "sourceMap": "156:288:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;246:40;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;378:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;179:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;246:40;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;378:64::-;432:3;423:6;:12;;;;378:64;:::o;179:21::-;;;;:::o;7:98:1:-;58:6;92:5;86:12;76:22;;7:98;;;:::o;111:168::-;194:11;228:6;223:3;216:19;268:4;263:3;259:14;244:29;;111:168;;;;:::o;285:246::-;366:1;376:113;390:6;387:1;384:13;376:113;;;475:1;470:3;466:11;460:18;456:1;451:3;447:11;440:39;412:2;409:1;405:10;400:15;;376:113;;;523:1;514:6;509:3;505:16;498:27;347:184;285:246;;;:::o;537:102::-;578:6;629:2;625:7;620:2;613:5;609:14;605:28;595:38;;537:102;;;:::o;645:373::-;731:3;759:38;791:5;759:38;:::i;:::-;813:70;876:6;871:3;813:70;:::i;:::-;806:77;;892:65;950:6;945:3;938:4;931:5;927:16;892:65;:::i;:::-;982:29;1004:6;982:29;:::i;:::-;977:3;973:39;966:46;;735:283;645:373;;;;:::o;1024:309::-;1135:4;1173:2;1162:9;1158:18;1150:26;;1222:9;1216:4;1212:20;1208:1;1197:9;1193:17;1186:47;1250:76;1321:4;1312:6;1250:76;:::i;:::-;1242:84;;1024:309;;;;:::o;1420:117::-;1529:1;1526;1519:12;1666:77;1703:7;1732:5;1721:16;;1666:77;;;:::o;1749:122::-;1822:24;1840:5;1822:24;:::i;:::-;1815:5;1812:35;1802:63;;1861:1;1858;1851:12;1802:63;1749:122;:::o;1877:139::-;1923:5;1961:6;1948:20;1939:29;;1977:33;2004:5;1977:33;:::i;:::-;1877:139;;;;:::o;2022:329::-;2081:6;2130:2;2118:9;2109:7;2105:23;2101:32;2098:119;;;2136:79;;:::i;:::-;2098:119;2256:1;2281:53;2326:7;2317:6;2306:9;2302:22;2281:53;:::i;:::-;2271:63;;2227:117;2022:329;;;;:::o;2357:118::-;2444:24;2462:5;2444:24;:::i;:::-;2439:3;2432:37;2357:118;;:::o;2481:222::-;2574:4;2612:2;2601:9;2597:18;2589:26;;2625:71;2693:1;2682:9;2678:17;2669:6;2625:71;:::i;:::-;2481:222;;;;:::o;2709:180::-;2757:77;2754:1;2747:88;2854:4;2851:1;2844:15;2878:4;2875:1;2868:15;2895:320;2939:6;2976:1;2970:4;2966:12;2956:22;;3023:1;3017:4;3013:12;3044:18;3034:81;;3100:4;3092:6;3088:17;3078:27;;3034:81;3162:2;3154:6;3151:14;3131:18;3128:38;3125:84;;3181:18;;:::i;:::-;3125:84;2946:269;2895:320;;;:::o", + "cborAuxdata": { + "1": { + "offset": 737, + "value": "0xa264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c63430008120033" + } + } + }, + + "creation_match": true, + "creation_metadata_match": false, + "creation_values": { + "cborAuxdata": { + "1": "0xa2646970667358221220bc2c6d72c52842d4077bb24c307576e44a078831aaa16da6611ef342fd052ec764736f6c63430008120033", + "2": "0xa2646970667358221220f13d144a826a3f18798a534a4b10029a3284d9f4620ccc79750cdc48442cdaad64736f6c63430008120033" + } + }, + "creation_transformations": [ + { + "type": "replace", + "reason": "cborAuxdata", + "offset": 1639, + "id": "1" + }, + { + "type": "replace", + "reason": "cborAuxdata", + "offset": 1731, + "id": "2" + } + ], + + "runtime_match": true, + "runtime_metadata_match": false, + "runtime_values": { + "cborAuxdata": { + "1": "0xa2646970667358221220bc2c6d72c52842d4077bb24c307576e44a078831aaa16da6611ef342fd052ec764736f6c63430008120033" + } + }, + "runtime_transformations": [ + { + "type": "replace", + "reason": "cborAuxdata", + "offset": 737, + "id": "1" + } + ] +} diff --git a/libs/verification-common/Cargo.toml b/libs/verification-common/Cargo.toml index 3cd80cc78..2df5fb4a3 100644 --- a/libs/verification-common/Cargo.toml +++ b/libs/verification-common/Cargo.toml @@ -11,6 +11,7 @@ alloy-json-abi = "0.8" anyhow = "1.0" blockscout-display-bytes = "1.1.0" bytes = "1" +readonly = { version = "0.2.12" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_with = "3.8" diff --git a/libs/verification-common/src/verifier_alliance/compilation_artifacts.rs b/libs/verification-common/src/verifier_alliance/compilation_artifacts.rs index ec6a57f27..dcaa40a71 100644 --- a/libs/verification-common/src/verifier_alliance/compilation_artifacts.rs +++ b/libs/verification-common/src/verifier_alliance/compilation_artifacts.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; +use std::collections::BTreeMap; pub trait ToCompilationArtifacts { fn abi(&self) -> Option { @@ -31,17 +32,20 @@ impl ToCompilationArtifacts for &T { } } +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SourceId { + pub id: u64, +} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CompilationArtifacts { - #[serde(skip_serializing_if = "Option::is_none")] pub abi: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub devdoc: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub userdoc: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub storage_layout: Option, + pub sources: Option>, } impl From for CompilationArtifacts { @@ -51,6 +55,7 @@ impl From for CompilationArtifacts { devdoc: value.devdoc(), userdoc: value.userdoc(), storage_layout: value.storage_layout(), + sources: None, } } } diff --git a/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs b/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs index 1520aff12..3877a8075 100644 --- a/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs +++ b/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs @@ -28,11 +28,8 @@ impl ToCreationCodeArtifacts for &T { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CreationCodeArtifacts { - #[serde(skip_serializing_if = "Option::is_none")] pub source_map: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub link_references: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub cbor_auxdata: Option, } diff --git a/libs/verification-common/src/verifier_alliance/mod.rs b/libs/verification-common/src/verifier_alliance/mod.rs index adb38f75b..0070d14bb 100644 --- a/libs/verification-common/src/verifier_alliance/mod.rs +++ b/libs/verification-common/src/verifier_alliance/mod.rs @@ -6,7 +6,7 @@ mod verification_match; mod verification_match_transformations; mod verification_match_values; -pub use compilation_artifacts::{CompilationArtifacts, ToCompilationArtifacts}; +pub use compilation_artifacts::{CompilationArtifacts, SourceId, ToCompilationArtifacts}; pub use creation_code_artifacts::{CreationCodeArtifacts, ToCreationCodeArtifacts}; pub use runtime_code_artifacts::{RuntimeCodeArtifacts, ToRuntimeCodeArtifacts}; -pub use verification_match::{Match, MatchBuilder, MatchTransformation, MatchType, MatchValues}; +pub use verification_match::{Match, MatchBuilder, MatchTransformation, MatchValues}; diff --git a/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs b/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs index 034a2b84f..75f10085f 100644 --- a/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs +++ b/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs @@ -34,13 +34,9 @@ impl ToRuntimeCodeArtifacts for &T { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RuntimeCodeArtifacts { - #[serde(skip_serializing_if = "Option::is_none")] pub cbor_auxdata: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub immutable_references: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub link_references: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub source_map: Option, } diff --git a/libs/verification-common/src/verifier_alliance/verification_match.rs b/libs/verification-common/src/verifier_alliance/verification_match.rs index 73c125e32..ef5a041bf 100644 --- a/libs/verification-common/src/verifier_alliance/verification_match.rs +++ b/libs/verification-common/src/verifier_alliance/verification_match.rs @@ -10,26 +10,10 @@ use alloy_dyn_abi::JsonAbiExt; use anyhow::Context; use bytes::Bytes; use serde::Deserialize; -use std::fmt::{Display, Formatter}; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum MatchType { - Full, - Partial, -} - -impl Display for MatchType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - MatchType::Full => f.write_str("full"), - MatchType::Partial => f.write_str("partial"), - } - } -} #[derive(Clone, Debug, PartialEq, Eq)] pub struct Match { - pub r#type: MatchType, + pub metadata_match: bool, pub transformations: Vec, pub values: MatchValues, } @@ -90,13 +74,9 @@ impl<'a> MatchBuilder<'a> { if !self.invalid_constructor_arguments && self.deployed_code == self.compiled_code.as_slice() { - let match_type = if self.has_cbor_auxdata_transformation || !self.has_cbor_auxdata { - MatchType::Partial - } else { - MatchType::Full - }; + let metadata_match = self.has_cbor_auxdata && !self.has_cbor_auxdata_transformation; return Some(Match { - r#type: match_type, + metadata_match, transformations: self.transformations, values: self.values, }); diff --git a/libs/verification-common/src/verifier_alliance/verification_match_transformations.rs b/libs/verification-common/src/verifier_alliance/verification_match_transformations.rs index 006509870..7b36e7150 100644 --- a/libs/verification-common/src/verifier_alliance/verification_match_transformations.rs +++ b/libs/verification-common/src/verifier_alliance/verification_match_transformations.rs @@ -10,8 +10,8 @@ enum TransformationType { #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] enum TransformationReason { - Auxdata, - Constructor, + CborAuxdata, + ConstructorArguments, Immutable, Library, } @@ -33,39 +33,39 @@ impl From for serde_json::Value { } impl Transformation { - pub fn auxdata(offset: usize, id: String) -> Self { + pub fn auxdata(offset: usize, id: impl Into) -> Self { Self { r#type: TransformationType::Replace, - reason: TransformationReason::Auxdata, + reason: TransformationReason::CborAuxdata, offset, - id: Some(id), + id: Some(id.into()), } } pub fn constructor(offset: usize) -> Self { Self { r#type: TransformationType::Insert, - reason: TransformationReason::Constructor, + reason: TransformationReason::ConstructorArguments, offset, id: None, } } - pub fn immutable(offset: usize, id: String) -> Self { + pub fn immutable(offset: usize, id: impl Into) -> Self { Self { r#type: TransformationType::Replace, reason: TransformationReason::Immutable, offset, - id: Some(id), + id: Some(id.into()), } } - pub fn library(offset: usize, id: String) -> Self { + pub fn library(offset: usize, id: impl Into) -> Self { Self { r#type: TransformationType::Replace, reason: TransformationReason::Library, offset, - id: Some(id), + id: Some(id.into()), } } } diff --git a/libs/verification-common/src/verifier_alliance/verification_match_values.rs b/libs/verification-common/src/verifier_alliance/verification_match_values.rs index 1ddab3df2..86f6cc255 100644 --- a/libs/verification-common/src/verifier_alliance/verification_match_values.rs +++ b/libs/verification-common/src/verifier_alliance/verification_match_values.rs @@ -6,19 +6,20 @@ use std::collections::BTreeMap; #[serde_as] #[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] +#[readonly::make] pub struct Values { - #[serde(skip_serializing_if = "BTreeMap::is_empty")] + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde_as(as = "BTreeMap<_, blockscout_display_bytes::serde_as::Hex>")] - cbor_auxdata: BTreeMap, - #[serde(skip_serializing_if = "Option::is_none")] + pub cbor_auxdata: BTreeMap, + #[serde(default, skip_serializing_if = "Option::is_none")] #[serde_as(as = "Option")] - constructor_arguments: Option, - #[serde(skip_serializing_if = "BTreeMap::is_empty")] + pub constructor_arguments: Option, + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde_as(as = "BTreeMap<_, blockscout_display_bytes::serde_as::Hex>")] - libraries: BTreeMap, - #[serde(skip_serializing_if = "BTreeMap::is_empty")] + pub libraries: BTreeMap, + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde_as(as = "BTreeMap<_, blockscout_display_bytes::serde_as::Hex>")] - immutables: BTreeMap, + pub immutables: BTreeMap, } impl From for serde_json::Value {