Skip to content

Commit

Permalink
bring back latest linking fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
elfedy committed Dec 24, 2024
1 parent 6d12151 commit c557dc8
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 20 deletions.
29 changes: 22 additions & 7 deletions crates/zksync/compilers/src/artifacts/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::artifacts::EraVM;
use alloy_json_abi::JsonAbi;
use foundry_compilers_artifacts_solc::{
Bytecode, CompactBytecode, CompactContractBytecode, CompactContractBytecodeCow,
CompactContractRef, CompactDeployedBytecode, DevDoc, Offsets, StorageLayout, UserDoc,
CompactContractRef, CompactDeployedBytecode, DevDoc, Evm, Offsets, StorageLayout, UserDoc,
};
use serde::{Deserialize, Serialize};
use std::{borrow::Cow, collections::BTreeMap};
Expand Down Expand Up @@ -35,9 +35,12 @@ pub struct Contract {
/// The contract factory dependencies.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub factory_dependencies: Option<BTreeMap<String, String>>,
/// EVM-related outputs
/// EraVM-related outputs
#[serde(default, skip_serializing_if = "Option::is_none")]
pub eravm: Option<EraVM>,
/// EVM-related outputs (deprecated)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub evm: Option<Evm>,
/// The contract's unlinked libraries
#[serde(default)]
pub missing_libraries: Vec<String>,
Expand Down Expand Up @@ -80,11 +83,21 @@ impl Contract {

/// Get bytecode
pub fn bytecode(&self) -> Option<Bytecode> {
self.eravm.as_ref().and_then(|eravm| eravm.bytecode(self.is_unlinked())).map(|object| {
let mut bytecode: Bytecode = object.into();
bytecode.link_references = self.link_references();
bytecode
})
self.eravm
.as_ref()
.and_then(|eravm| eravm.bytecode(self.is_unlinked()))
.or_else(|| {
self.evm
.as_ref()
.and_then(|evm| evm.bytecode.as_ref())
.map(|bytecode| &bytecode.object)
.cloned()
})
.map(|object| {
let mut bytecode: Bytecode = object.into();
bytecode.link_references = self.link_references();
bytecode
})
}
}

Expand Down Expand Up @@ -126,6 +139,8 @@ impl<'a> From<&'a Contract> for CompactContractRef<'a> {
fn from(c: &'a Contract) -> Self {
let (bin, bin_runtime) = if let Some(ref eravm) = c.eravm {
(eravm.bytecode.as_ref(), eravm.bytecode.as_ref())
} else if let Some(ref evm) = c.evm {
(evm.bytecode.as_ref().map(|c| &c.object), evm.bytecode.as_ref().map(|c| &c.object))
} else {
(None, None)
};
Expand Down
23 changes: 22 additions & 1 deletion crates/zksync/compilers/src/artifacts/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! zksolc artifacts to be used in `foundry-compilers`
use foundry_compilers_artifacts_solc::{
BytecodeObject, CompactContractRef, FileToContractsMap, SourceFile, SourceFiles,
Bytecode, BytecodeObject, CompactContractRef, FileToContractsMap, SourceFile, SourceFiles,
};

use semver::Version;
Expand Down Expand Up @@ -56,6 +56,27 @@ impl CompilerOutput {
}
}

/// Evm zksolc output field (deprecated)
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Evm {
/// The contract EraVM assembly code.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub assembly: Option<String>,
/// The contract EVM legacy assembly code.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub legacy_assembly: Option<serde_json::Value>,
/// The contract bytecode.
/// Is reset by that of EraVM before yielding the compiled project artifacts.
pub bytecode: Option<Bytecode>,
/// The list of function hashes
#[serde(default, skip_serializing_if = "::std::collections::BTreeMap::is_empty")]
pub method_identifiers: BTreeMap<String, String>,
/// The extra EVMLA metadata.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extra_metadata: Option<ExtraMetadata>,
}

/// `zksolc` eravm output field
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
Expand Down
2 changes: 2 additions & 0 deletions crates/zksync/compilers/src/compilers/artifact_output/zk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl ArtifactOutput for ZkArtifactOutput {
devdoc,
storage_layout,
eravm,
evm,
ir_optimized,
hash,
factory_dependencies,
Expand All @@ -134,6 +135,7 @@ impl ArtifactOutput for ZkArtifactOutput {

let (bytecode, assembly) = eravm
.map(|eravm| (eravm.bytecode(is_unlinked), eravm.assembly))
.or_else(|| evm.map(|evm| (evm.bytecode.map(|bc| bc.object), evm.assembly)))
.unwrap_or_else(|| (None, None));
let bytecode = bytecode
.map(|object| ZkArtifactBytecode::with_object(object, is_unlinked, missing_libraries));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,21 @@ use foundry_compilers_artifacts_solc::{
};
use serde::{Deserialize, Serialize};

/// This will serialize the bytecode data without a `0x` prefix
///
/// Equivalent of solc artifact bytecode's
/// [`serialize_bytecode_without_prefix`](foundry_compilers_artifacts::solc::bytecode::serialize_bytecode_without_prefix)
pub fn serialize_bytes_without_prefix<S>(code: &Bytes, s: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
s.serialize_str(&alloy_primitives::hex::encode(code))
}

/// Bytecode compiled by zksolc
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub struct ZkArtifactBytecode {
#[serde(serialize_with = "serialize_bytes_without_prefix")]
object: Bytes,
is_unlinked: bool,

Expand All @@ -34,7 +46,8 @@ impl ZkArtifactBytecode {
Self { object, is_unlinked, missing_libraries }
}

fn link_references(&self) -> BTreeMap<String, BTreeMap<String, Vec<Offsets>>> {
/// Get link references
pub fn link_references(&self) -> BTreeMap<String, BTreeMap<String, Vec<Offsets>>> {
Contract::missing_libs_to_link_references(self.missing_libraries.as_slice())
}

Expand Down Expand Up @@ -65,3 +78,24 @@ impl From<ZkArtifactBytecode> for CompactDeployedBytecode {
Self { bytecode: Some(bcode.into()), immutable_references: BTreeMap::default() }
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn serialized_bytecode_is_not_prefixed() {
let object = Bytes::from(vec![0xDEu8, 0xAD, 0xBE, 0xEF]);
let sample = ZkArtifactBytecode { object, is_unlinked: false, missing_libraries: vec![] };

let json_str =
serde_json::to_string(&sample).expect("able to serialize artifact bytecode as json");

let deserialized: serde_json::Value =
serde_json::from_str(&json_str).expect("able to deserialize json");

let bytecode_str = deserialized["object"].as_str().expect(".object to be a string");

assert!(!bytecode_str.starts_with("0x"));
}
}
11 changes: 0 additions & 11 deletions crates/zksync/compilers/test-data/yul-sample/SimpleStore.yul

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"abi":null,"bytecode":{"object":"00000001002001900000000c0000c13d000000002101043c000000000010043f000000200100043d0000000701100197000000000202043b0000000802200197000000000112019f000000200010043f0000000001000019000000000001042d000000240000043f0000002001000039000001000010044300000120000004430000000601000041000000130001042e0000001200000432000000130001042e0000001400010430000000000000000000000000000000000000000000000000000000020000000000000000000000000000004000000100000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e0e9492643af2958d06e962a0b194ca36037ef49d6167e028f1f053a54c571","is_unlinked":false,"missing_libraries":[]},"storageLayout":{"storage":[],"types":{}},"userdoc":{},"devdoc":{},"hash":"0100000b7acef21b9ea8b7897d4ebb51ecaec207df8038a10bc61b904c5c9e4b","factoryDependencies":{},"id":0}

0 comments on commit c557dc8

Please sign in to comment.