Cached compiler artifacts (#143)

* WIP compilation cache

* Implement a persistent compilation cache

* Correct the key and value encoding for the cache
This commit is contained in:
Omar
2025-08-16 19:04:13 +03:00
committed by GitHub
parent 09d56f5177
commit 185edcfad9
12 changed files with 869 additions and 299 deletions
+11 -9
View File
@@ -739,12 +739,14 @@ impl<'de> Deserialize<'de> for EtherValue {
#[cfg(test)]
mod tests {
use super::*;
use alloy::{eips::BlockNumberOrTag, json_abi::JsonAbi};
use alloy_primitives::{BlockHash, BlockNumber, BlockTimestamp, ChainId, TxHash, address};
use alloy_sol_types::SolValue;
use std::collections::HashMap;
use super::*;
use crate::metadata::ContractIdent;
struct MockResolver;
impl ResolverApi for MockResolver {
@@ -818,11 +820,11 @@ mod tests {
let mut contracts = HashMap::new();
contracts.insert(
ContractInstance::new("Contract"),
(Address::ZERO, parsed_abi),
(ContractIdent::new("Contract"), Address::ZERO, parsed_abi),
);
let resolver = MockResolver;
let context = ResolutionContext::new_from_parts(&contracts, None, None, None);
let context = ResolutionContext::default().with_deployed_contracts(&contracts);
let encoded = input.encoded_input(&resolver, context).await.unwrap();
assert!(encoded.0.starts_with(&selector));
@@ -862,11 +864,11 @@ mod tests {
let mut contracts = HashMap::new();
contracts.insert(
ContractInstance::new("Contract"),
(Address::ZERO, parsed_abi),
(ContractIdent::new("Contract"), Address::ZERO, parsed_abi),
);
let resolver = MockResolver;
let context = ResolutionContext::new_from_parts(&contracts, None, None, None);
let context = ResolutionContext::default().with_deployed_contracts(&contracts);
let encoded = input.encoded_input(&resolver, context).await.unwrap();
assert!(encoded.0.starts_with(&selector));
@@ -909,11 +911,11 @@ mod tests {
let mut contracts = HashMap::new();
contracts.insert(
ContractInstance::new("Contract"),
(Address::ZERO, parsed_abi),
(ContractIdent::new("Contract"), Address::ZERO, parsed_abi),
);
let resolver = MockResolver;
let context = ResolutionContext::new_from_parts(&contracts, None, None, None);
let context = ResolutionContext::default().with_deployed_contracts(&contracts);
let encoded = input.encoded_input(&resolver, context).await.unwrap();
assert!(encoded.0.starts_with(&selector));
@@ -927,10 +929,10 @@ mod tests {
async fn resolve_calldata_item(
input: &str,
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
deployed_contracts: &HashMap<ContractInstance, (ContractIdent, Address, JsonAbi)>,
resolver: &impl ResolverApi,
) -> anyhow::Result<U256> {
let context = ResolutionContext::new_from_parts(deployed_contracts, None, None, None);
let context = ResolutionContext::default().with_deployed_contracts(deployed_contracts);
CalldataItem::new(input).resolve(resolver, context).await
}
+14 -7
View File
@@ -6,7 +6,7 @@ use alloy::primitives::{Address, BlockHash, BlockNumber, BlockTimestamp, ChainId
use alloy_primitives::TxHash;
use anyhow::Result;
use crate::metadata::ContractInstance;
use crate::metadata::{ContractIdent, ContractInstance};
/// A trait of the interface are required to implement to be used by the resolution logic that this
/// crate implements to go from string calldata and into the bytes calldata.
@@ -48,7 +48,7 @@ pub trait ResolverApi {
/// Contextual information required by the code that's performing the resolution.
pub struct ResolutionContext<'a> {
/// When provided the contracts provided here will be used for resolutions.
deployed_contracts: Option<&'a HashMap<ContractInstance, (Address, JsonAbi)>>,
deployed_contracts: Option<&'a HashMap<ContractInstance, (ContractIdent, Address, JsonAbi)>>,
/// When provided the variables in here will be used for performing resolutions.
variables: Option<&'a HashMap<String, U256>>,
@@ -66,7 +66,9 @@ impl<'a> ResolutionContext<'a> {
}
pub fn new_from_parts(
deployed_contracts: impl Into<Option<&'a HashMap<ContractInstance, (Address, JsonAbi)>>>,
deployed_contracts: impl Into<
Option<&'a HashMap<ContractInstance, (ContractIdent, Address, JsonAbi)>>,
>,
variables: impl Into<Option<&'a HashMap<String, U256>>>,
block_number: impl Into<Option<&'a BlockNumber>>,
transaction_hash: impl Into<Option<&'a TxHash>>,
@@ -81,7 +83,9 @@ impl<'a> ResolutionContext<'a> {
pub fn with_deployed_contracts(
mut self,
deployed_contracts: impl Into<Option<&'a HashMap<ContractInstance, (Address, JsonAbi)>>>,
deployed_contracts: impl Into<
Option<&'a HashMap<ContractInstance, (ContractIdent, Address, JsonAbi)>>,
>,
) -> Self {
self.deployed_contracts = deployed_contracts.into();
self
@@ -122,17 +126,20 @@ impl<'a> ResolutionContext<'a> {
}
}
pub fn deployed_contract(&self, instance: &ContractInstance) -> Option<&(Address, JsonAbi)> {
pub fn deployed_contract(
&self,
instance: &ContractInstance,
) -> Option<&(ContractIdent, Address, JsonAbi)> {
self.deployed_contracts
.and_then(|deployed_contracts| deployed_contracts.get(instance))
}
pub fn deployed_contract_address(&self, instance: &ContractInstance) -> Option<&Address> {
self.deployed_contract(instance).map(|(a, _)| a)
self.deployed_contract(instance).map(|(_, a, _)| a)
}
pub fn deployed_contract_abi(&self, instance: &ContractInstance) -> Option<&JsonAbi> {
self.deployed_contract(instance).map(|(_, a)| a)
self.deployed_contract(instance).map(|(_, _, a)| a)
}
pub fn variable(&self, name: impl AsRef<str>) -> Option<&U256> {