Skip to content

Commit

Permalink
perf: exclude source maps from ContractData
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed May 31, 2024
1 parent 31c13dc commit b5a8d8c
Showing 1 changed file with 53 additions and 9 deletions.
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

0 comments on commit b5a8d8c

Please sign in to comment.