Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: exclude source maps from ContractData #8022

Merged
merged 1 commit into from
Jun 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 53 additions & 9 deletions crates/common/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,42 @@ use std::{
const CALL_PROTECTION_BYTECODE_PREFIX: [u8; 21] =
hex!("730000000000000000000000000000000000000000");

/// Subset of [CompactBytecode] excluding sourcemaps.
#[allow(missing_docs)]
#[derive(Debug, Clone)]
pub struct BytecodeData {
pub object: Option<BytecodeObject>,
pub link_references: BTreeMap<String, BTreeMap<String, Vec<Offsets>>>,
pub immutable_references: BTreeMap<String, Vec<Offsets>>,
}

impl BytecodeData {
fn bytes(&self) -> Option<&Bytes> {
self.object.as_ref().and_then(|b| b.as_bytes())
}
}

impl From<CompactBytecode> for BytecodeData {
fn from(bytecode: CompactBytecode) -> Self {
Self {
object: Some(bytecode.object),
link_references: bytecode.link_references,
immutable_references: BTreeMap::new(),
}
}
}

impl From<CompactDeployedBytecode> for BytecodeData {
fn from(bytecode: CompactDeployedBytecode) -> Self {
let (object, link_references) = if let Some(compact) = bytecode.bytecode {
(Some(compact.object), compact.link_references)
} else {
(None, BTreeMap::new())
};
Self { object, link_references, immutable_references: bytecode.immutable_references }
}
}

/// Container for commonly used contract data.
#[derive(Debug, Clone)]
pub struct ContractData {
Expand All @@ -31,9 +67,9 @@ pub struct ContractData {
/// Contract ABI.
pub abi: JsonAbi,
/// Contract creation code.
pub bytecode: Option<CompactBytecode>,
pub bytecode: Option<BytecodeData>,
/// Contract runtime code.
pub deployed_bytecode: Option<CompactDeployedBytecode>,
pub deployed_bytecode: Option<BytecodeData>,
}

impl ContractData {
Expand Down Expand Up @@ -68,7 +104,15 @@ impl ContractsByArtifact {

let CompactContractBytecode { abi, bytecode, deployed_bytecode } = artifact;

Some((id, ContractData { name, abi: abi?, bytecode, deployed_bytecode }))
Some((
id,
ContractData {
name,
abi: abi?,
bytecode: bytecode.map(Into::into),
deployed_bytecode: deployed_bytecode.map(Into::into),
},
))
})
.collect(),
)
Expand Down Expand Up @@ -103,11 +147,11 @@ impl ContractsByArtifact {
let Some(deployed_bytecode) = &contract.deployed_bytecode else {
return false;
};
let Some(deployed_code) = &deployed_bytecode.bytecode else {
let Some(deployed_code) = &deployed_bytecode.object else {
return false;
};

let len = match deployed_code.object {
let len = match deployed_code {
BytecodeObject::Bytecode(ref bytes) => bytes.len(),
BytecodeObject::Unlinked(ref bytes) => bytes.len() / 2,
};
Expand All @@ -120,7 +164,7 @@ impl ContractsByArtifact {
let mut ignored = deployed_bytecode
.immutable_references
.values()
.chain(deployed_code.link_references.values().flat_map(|v| v.values()))
.chain(deployed_bytecode.link_references.values().flat_map(|v| v.values()))
.flatten()
.cloned()
.collect::<Vec<_>>();
Expand All @@ -129,7 +173,7 @@ impl ContractsByArtifact {
// ignore it as it includes library address determined at runtime.
// See https://docs.soliditylang.org/en/latest/contracts.html#call-protection-for-libraries and
// https://github.com/NomicFoundation/hardhat/blob/af7807cf38842a4f56e7f4b966b806e39631568a/packages/hardhat-verify/src/internal/solc/bytecode.ts#L172
let has_call_protection = match deployed_code.object {
let has_call_protection = match deployed_code {
BytecodeObject::Bytecode(ref bytes) => {
bytes.starts_with(&CALL_PROTECTION_BYTECODE_PREFIX)
}
Expand All @@ -154,7 +198,7 @@ impl ContractsByArtifact {
for offset in ignored {
let right = offset.start as usize;

let matched = match deployed_code.object {
let matched = match deployed_code {
BytecodeObject::Bytecode(ref bytes) => bytes[left..right] == code[left..right],
BytecodeObject::Unlinked(ref bytes) => {
if let Ok(bytes) = Bytes::from_str(&bytes[left * 2..right * 2]) {
Expand All @@ -173,7 +217,7 @@ impl ContractsByArtifact {
}

if left < code.len() {
match deployed_code.object {
match deployed_code {
BytecodeObject::Bytecode(ref bytes) => bytes[left..] == code[left..],
BytecodeObject::Unlinked(ref bytes) => {
if let Ok(bytes) = Bytes::from_str(&bytes[left * 2..]) {
Expand Down
Loading