Skip to content

Commit

Permalink
initial fix for sourcemaps in debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
emo-eth committed Feb 9, 2024
1 parent 6be2e77 commit e7515d8
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 20 deletions.
36 changes: 34 additions & 2 deletions crates/common/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,41 @@ impl ProjectCompiler {
}
}

/// Map over artifacts contract sources name -> file_id -> (source, contract)
/// Contract source code and bytecode.
#[derive(Clone, Debug, Default)]
pub struct ContractSources(pub HashMap<String, HashMap<u32, (String, ContractBytecodeSome)>>);
pub struct ContractSources {
/// Map over artifacts contract sources name -> file_id -> (source, contract)
pub sources_by_name: HashMap<String, HashMap<u32, (String, ContractBytecodeSome)>>,
/// Map over artifacts contract sources file_id -> (source, contract)
pub sources_by_id: HashMap<u32, (String, ContractBytecodeSome)>,
}

impl ContractSources {
/// Inserts a contract into the sources.
pub fn insert(
&mut self,
artifact_id: &ArtifactId,
file_id: u32,
source: String,
bytecode: ContractBytecodeSome,
) {
self.sources_by_name
.entry(artifact_id.name.clone())
.or_default()
.insert(file_id, (source.clone(), bytecode.clone()));
self.sources_by_id.insert(file_id, (source, bytecode));
}

/// Returns the sources for contracts by name.
pub fn get(&self, name: &str) -> Option<&HashMap<u32, (String, ContractBytecodeSome)>> {
self.sources_by_name.get(name)
}

/// Returns the source for a contract by file ID.
pub fn get_by_id(&self, id: u32) -> Option<&(String, ContractBytecodeSome)> {
self.sources_by_id.get(&id)
}
}

// https://eips.ethereum.org/EIPS/eip-170
const CONTRACT_SIZE_LIMIT: usize = 24576;
Expand Down
19 changes: 17 additions & 2 deletions crates/debugger/src/tui/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,9 @@ impl DebuggerContext<'_> {
return Err(format!("Unknown contract at address {address}"));
};

let Some(files_source_code) = self.debugger.contracts_sources.0.get(contract_name) else {
let Some(files_source_code) =
self.debugger.contracts_sources.sources_by_name.get(contract_name)
else {
return Err(format!("No source map index for contract {contract_name}"));
};

Expand All @@ -356,7 +358,20 @@ impl DebuggerContext<'_> {
let pc_ic_map = if is_create { create_map } else { rt_map };
let ic = pc_ic_map.get(pc)?;
let source_element = source_map.swap_remove(ic);
(*file_id == source_element.index?).then_some((source_element, source_code))
// if the source element has an index, find the sourcemap for that index
source_element.index.and_then(|index| {
// if index matches current file_id, return current source code
(index == *file_id).then_some((source_element.clone(), source_code)).or_else(
|| {
// otherwise find the source code for the element's index
self.debugger
.contracts_sources
.sources_by_id
.get(&index)
.map(|(source_code, _)| (source_element.clone(), source_code))
},
)
})
})
else {
return Err(format!("No source map for contract {contract_name}"));
Expand Down
2 changes: 1 addition & 1 deletion crates/debugger/src/tui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Debugger {
breakpoints: Breakpoints,
) -> Self {
let pc_ic_maps = contracts_sources
.0
.sources_by_name
.iter()
.flat_map(|(contract_name, files_sources)| {
files_sources.iter().filter_map(|(_, (_, contract))| {
Expand Down
6 changes: 1 addition & 5 deletions crates/evm/traces/src/identifier/etherscan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,7 @@ impl EtherscanIdentifier {
for (results, (_, metadata)) in artifacts.into_iter().zip(contracts_iter) {
// get the inner type
let (artifact_id, file_id, bytecode) = results?;
sources
.0
.entry(artifact_id.clone().name)
.or_default()
.insert(file_id, (metadata.source_code(), bytecode));
sources.insert(&artifact_id, file_id, metadata.source_code(), bytecode);
}

Ok(sources)
Expand Down
6 changes: 1 addition & 5 deletions crates/forge/bin/cmd/script/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,7 @@ impl ScriptArgs {
})?;
let contract = artifact.clone().into_contract_bytecode();
let source_contract = compact_to_contract(contract)?;
sources
.0
.entry(id.clone().name)
.or_default()
.insert(source.id, (source_code, source_contract));
sources.insert(&id, source.id, source_code, source_contract);
} else {
warn!(?id, "source not found");
}
Expand Down
6 changes: 1 addition & 5 deletions crates/forge/bin/cmd/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,7 @@ impl TestArgs {
let source_code = fs::read_to_string(abs_path)?;
let contract = artifact.clone().into_contract_bytecode();
let source_contract = compact_to_contract(contract)?;
sources
.0
.entry(id.name.clone())
.or_default()
.insert(source.id, (source_code, source_contract));
sources.insert(&id, source.id, source_code, source_contract);
}
}

Expand Down

0 comments on commit e7515d8

Please sign in to comment.