diff --git a/Cargo.lock b/Cargo.lock index 304d45c..25a0f0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1780,6 +1780,8 @@ dependencies = [ "num", "once_cell", "pallet-contracts-pvm-llapi", + "polkavm-common", + "polkavm-disassembler", "regex", "revive-builtins", "revive-common", @@ -1805,8 +1807,6 @@ dependencies = [ "num", "once_cell", "path-slash", - "polkavm-common", - "polkavm-disassembler", "rand", "rayon", "regex", diff --git a/crates/llvm-context/Cargo.toml b/crates/llvm-context/Cargo.toml index 347f92b..413dc82 100644 --- a/crates/llvm-context/Cargo.toml +++ b/crates/llvm-context/Cargo.toml @@ -28,6 +28,8 @@ sha2 = { workspace = true } sha3 = { workspace = true } md5 = { workspace = true } inkwell = { workspace = true } +polkavm-disassembler = { workspace = true } +polkavm-common = { workspace = true } zkevm_opcode_defs = { git = "https://github.com/matter-labs/era-zkevm_opcode_defs", branch = "v1.4.1" } revive-common = { path = "../common" } diff --git a/crates/llvm-context/src/polkavm/context/mod.rs b/crates/llvm-context/src/polkavm/context/mod.rs index c16c80d..7ba1931 100644 --- a/crates/llvm-context/src/polkavm/context/mod.rs +++ b/crates/llvm-context/src/polkavm/context/mod.rs @@ -278,11 +278,11 @@ where ) })?; - let assembly_text = revive_linker::link(buffer.as_slice()).map(hex::encode)?; + let encoded_hex_text = revive_linker::link(buffer.as_slice()).map(hex::encode)?; let build = match crate::polkavm::build_assembly_text( contract_path, - assembly_text.as_str(), + encoded_hex_text.as_str(), metadata_hash, self.debug_config(), ) { diff --git a/crates/llvm-context/src/polkavm/mod.rs b/crates/llvm-context/src/polkavm/mod.rs index 011e1a4..0bf3402 100644 --- a/crates/llvm-context/src/polkavm/mod.rs +++ b/crates/llvm-context/src/polkavm/mod.rs @@ -11,6 +11,10 @@ pub use self::r#const::*; use crate::debug_config::DebugConfig; use crate::optimizer::settings::Settings as OptimizerSettings; +use anyhow::{anyhow, Context as AnyhowContext}; +use polkavm_common::program::ProgramBlob; +use polkavm_disassembler::{Disassembler, DisassemblyFormat}; + use self::context::build::Build; use self::context::Context; @@ -22,64 +26,45 @@ pub fn initialize_target() { /// Builds PolkaVM assembly text. pub fn build_assembly_text( contract_path: &str, - assembly_text: &str, + encoded_hex_text: &str, _metadata_hash: Option<[u8; revive_common::BYTE_LENGTH_WORD]>, debug_config: Option<&DebugConfig>, ) -> anyhow::Result { if let Some(debug_config) = debug_config { - debug_config.dump_assembly(contract_path, assembly_text)?; + debug_config.dump_assembly(contract_path, encoded_hex_text)?; } - /* - let mut assembly = - zkevm_assembly::Assembly::from_string(assembly_text.to_owned(), metadata_hash).map_err( - |error| { - anyhow::anyhow!( - "The contract `{}` assembly parsing error: {}", - contract_path, - error, - ) - }, - )?; + let bytecode = hex::decode(encoded_hex_text) + .map_err(|e| anyhow!("Failed to decode encoded hex text:\n{}\n", e))?; - let bytecode_words = match zkevm_assembly::get_encoding_mode() { - zkevm_assembly::RunningVmEncodingMode::Production => { assembly.compile_to_bytecode_for_mode::<8, zkevm_opcode_defs::decoding::EncodingModeProduction>() }, - zkevm_assembly::RunningVmEncodingMode::Testing => { assembly.compile_to_bytecode_for_mode::<16, zkevm_opcode_defs::decoding::EncodingModeTesting>() }, - } - .map_err(|error| { - anyhow::anyhow!( - "The contract `{}` assembly-to-bytecode conversion error: {}", - contract_path, - error, - ) + let program_blob = ProgramBlob::parse(bytecode.as_slice()) + .map_err(|error| anyhow!(format!("Failed to parse program blob:\n{}\n", error)))?; + + let mut disassembler = + Disassembler::new(&program_blob, DisassemblyFormat::Guest).map_err(|error| { + anyhow!(format!( + "Failed to create disassembler for contract:\n{:?}\n\nDue to:\n{}\n", + contract_path, error + )) })?; + disassembler.display_gas()?; - let bytecode_hash = match zkevm_assembly::get_encoding_mode() { - zkevm_assembly::RunningVmEncodingMode::Production => { - zkevm_opcode_defs::utils::bytecode_to_code_hash_for_mode::< - 8, - zkevm_opcode_defs::decoding::EncodingModeProduction, - >(bytecode_words.as_slice()) - } - zkevm_assembly::RunningVmEncodingMode::Testing => { - zkevm_opcode_defs::utils::bytecode_to_code_hash_for_mode::< - 16, - zkevm_opcode_defs::decoding::EncodingModeTesting, - >(bytecode_words.as_slice()) - } - } - .map(hex::encode) - .map_err(|_error| { - anyhow::anyhow!("The contract `{}` bytecode hashing error", contract_path,) + let mut disassembled_code = Vec::new(); + disassembler + .disassemble_into(&mut disassembled_code) + .with_context(|| format!("Failed to disassemble contract: {}", contract_path))?; + + let assembly_text = String::from_utf8(disassembled_code).with_context(|| { + format!( + "Failed to convert disassembled code to string for contract: {}", + contract_path + ) })?; - let bytecode = bytecode_words.into_iter().flatten().collect(); - */ - Ok(Build::new( assembly_text.to_owned(), Default::default(), - hex::decode(assembly_text).unwrap(), + bytecode.to_owned(), Default::default(), )) } diff --git a/crates/solidity/Cargo.toml b/crates/solidity/Cargo.toml index 7987ade..2ff421e 100644 --- a/crates/solidity/Cargo.toml +++ b/crates/solidity/Cargo.toml @@ -36,8 +36,6 @@ num = { workspace = true } sha3 = { workspace = true } md5 = { workspace = true } inkwell = { workspace = true } -polkavm-disassembler = { workspace = true } -polkavm-common = { workspace = true } revive-common = { path = "../common" } revive-llvm-context = { path = "../llvm-context" } diff --git a/crates/solidity/src/build/contract.rs b/crates/solidity/src/build/contract.rs index fdd0d72..8f92552 100644 --- a/crates/solidity/src/build/contract.rs +++ b/crates/solidity/src/build/contract.rs @@ -8,9 +8,6 @@ use std::path::Path; use serde::Deserialize; use serde::Serialize; -use polkavm_common::program::ProgramBlob; -use polkavm_disassembler::{Disassembler, DisassemblyFormat}; - use crate::solc::combined_json::contract::Contract as CombinedJsonContract; use crate::solc::standard_json::output::contract::Contract as StandardJsonOutputContract; @@ -56,7 +53,6 @@ impl Contract { overwrite: bool, ) -> anyhow::Result<()> { let file_name = Self::short_path(self.path.as_str()); - let bytescode = self.build.bytecode; if output_assembly { let file_name = format!( @@ -72,33 +68,7 @@ impl Contract { "Refusing to overwrite an existing file {file_path:?} (use --overwrite to force)." ); } else { - let program_blob = ProgramBlob::parse(bytescode.as_slice()).map_err(|error| { - anyhow::anyhow!(format!("Failed to parse program blob: {}", error)) - })?; - - let mut disassembler = Disassembler::new(&program_blob, DisassemblyFormat::Guest) - .map_err(|error| { - anyhow::anyhow!(format!( - "Failed to create disassembler for contract '{:?}'\n\nDue to:\n{}", - &file_path, error - )) - })?; - - let mut disassembled_code = Vec::new(); - disassembler - .disassemble_into(&mut disassembled_code) - .map_err(|error| { - anyhow::anyhow!(format!( - "Failed to disassemble contract '{:?}'\n\nDue to:\n{}\n\nGas details:{:?}\n", - &file_path, error, disassembler.display_gas() - )) - })?; - - let assembly_text = String::from_utf8(disassembled_code) - .map_err(|error| anyhow::anyhow!(format!( - "Failed to convert disassembled code to string for contract '{:?}'\n\nDue to:\n{}", - &file_path, error - )))?; + let assembly_text = self.build.assembly_text; File::create(&file_path) .map_err(|error| { @@ -125,7 +95,7 @@ impl Contract { .map_err(|error| { anyhow::anyhow!("File {:?} creating error: {}", file_path, error) })? - .write_all(bytescode.as_slice()) + .write_all(self.build.bytecode.as_slice()) .map_err(|error| { anyhow::anyhow!("File {:?} writing error: {}", file_path, error) })?; diff --git a/crates/solidity/src/tests/cli-tests/package.json b/crates/solidity/src/tests/cli-tests/package.json index 0f786d1..4fc21fe 100644 --- a/crates/solidity/src/tests/cli-tests/package.json +++ b/crates/solidity/src/tests/cli-tests/package.json @@ -7,8 +7,7 @@ "main": "index.js", "private": true, "scripts": { - "test": "npx jest --verbose --testPathPattern=" - + "test": "npx jest --verbose --testPathIgnorePatterns=zkasm.test.ts" }, "keywords": [], "author": "Matter Labs", diff --git a/crates/solidity/src/zksolc/main.rs b/crates/solidity/src/zksolc/main.rs index b155007..515c3af 100644 --- a/crates/solidity/src/zksolc/main.rs +++ b/crates/solidity/src/zksolc/main.rs @@ -6,9 +6,6 @@ use std::str::FromStr; use self::arguments::Arguments; -use polkavm_common::program::ProgramBlob; -use polkavm_disassembler::{Disassembler, DisassemblyFormat}; - /// The rayon worker stack size. const RAYON_WORKER_STACK_SIZE: usize = 16 * 1024 * 1024; @@ -193,41 +190,17 @@ fn main_inner() -> anyhow::Result<()> { ); } else if arguments.output_assembly || arguments.output_binary { for (path, contract) in build.contracts.into_iter() { - let bytescode = contract.build.bytecode; - if arguments.output_assembly { - let program_blob = ProgramBlob::parse(bytescode.as_slice()).map_err(|error| { - anyhow::anyhow!(format!("Failed to parse program blob: {}", error)) - })?; - - let mut disassembler = Disassembler::new(&program_blob, DisassemblyFormat::Guest) - .map_err(|error| { - anyhow::anyhow!(format!( - "Failed to create disassembler for contract '{}'\n\nDue to:\n{}", - path, error - )) - })?; - - let mut disassembled_code = Vec::new(); - disassembler - .disassemble_into(&mut disassembled_code) - .map_err(|error| { - anyhow::anyhow!(format!( - "Failed to disassemble contract '{}'\n\nDue to:\n{}\n\nGas details:{:?}\n", - path, error, disassembler.display_gas() - )) - })?; - - let assembly_text = String::from_utf8(disassembled_code) - .map_err(|error| anyhow::anyhow!(format!( - "Failed to convert disassembled code to string for contract '{}'\n\nDue to:\n{}", - path, error - )))?; + let assembly_text = contract.build.assembly_text; println!("Contract `{}` assembly:\n\n{}", path, assembly_text); } if arguments.output_binary { - println!("Contract `{}` bytecode: 0x{}", path, hex::encode(bytescode)); + println!( + "Contract `{}` bytecode: 0x{}", + path, + hex::encode(contract.build.bytecode) + ); } } } else {