-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
REVM tracing and gas reports #867
Conversation
Current status: Slowly refactoring towards separating trace collection, decoding and printing. Plan:
There will be a few commits that make the code a bit worse but that is because I am working through this in stages (e.g. unifying contract names and labels, returning a string instead of building on one we pass around etc.) |
Traces are now decoded and displayed, with two bugs that I have found so far:
Required missing things:
Things I want to add/achieve:
@gakonst you talked about decoding using 4byte directory. We can do this in the decoder as a fallback if you want, but I'm not sure where we have access to it currently? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great so far- the etherscan decoder is going to be a game changer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be ready to review, with two caveats:
- There is no Etherscan identifier yet
- Calls to Hardhat's
console.log
are displayed in traces - how should I proceed here? The current behaviour is that they are not in the traces. Two options: we filter them out, or we try to decode them which would require us to patch the function selectors in the tracer.
println!("Running {} {} for {}", tests.len(), term, contract_name); | ||
thread::spawn(move || runner.test(&filter, Some(tx)).unwrap()); | ||
|
||
let mut results: BTreeMap<String, BTreeMap<String, TestResult>> = BTreeMap::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spawning the MultiContractRunner
on a separate thread instead of the print loop made it a lot easier to integrate with the gas reports.
I should probably have a function in MultiContractRunner
that does not collect results itself, since it would save us a lot of clones
let should_include = match kind { | ||
// At verbosity level 4, we also display the setup trace for failed | ||
// tests At verbosity level 5, we display | ||
// all traces for all tests | ||
TraceKind::Setup => { | ||
(verbosity >= 5) || (verbosity == 4 && !result.success) | ||
} | ||
TraceKind::Execution => verbosity > 3 || !result.success, | ||
_ => false, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CallTraceArena
s from ContractRunner
are now identified by what part of the flow they are from, since we still need to at least identify contracts in the deployment traces. We only decode the ones we want to display, though.
Tried to explain the conditionals here as best I could
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
func.name, | ||
should_fail, | ||
match foundry_utils::decode_revert(result.as_ref(), abi) { | ||
let run_result = self.runner.clone().run(&strat, |calldata| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I simplified most of this and merged it with the final trace/log collection step we used to have in ContractRunner
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub struct CounterExample { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved here from ContractRunner
/// Note that a call trace decoder is required for each new set of traces, since addresses in | ||
/// different sets might overlap. | ||
#[derive(Default, Debug)] | ||
pub struct CallTraceDecoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decoder collects information about addresses in the call traces (i.e.. ABIs, labels) using TraceIdentifier
s, which allows us to pull info from different sources (locally, vm.label
, 4byte directory, etherscan, ...). It also does the final decoding step for a CallTraceArena
fn decode_cheatcode_inputs(&self, func: &Function, data: &[u8]) -> Option<Vec<String>> { | ||
match func.name.as_str() { | ||
"expectRevert" => foundry_utils::decode_revert(data, Some(&self.errors)) | ||
.ok() | ||
.map(|decoded| vec![decoded]), | ||
_ => None, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put this in a function by itself in case we want to do more cheatcode-specific decoding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is great - my main question is around how we'll get the etherscan identifier working
Cell::new("Deployment Cost").add_attribute(Attribute::Bold).fg(Color::Cyan), | ||
Cell::new("Deployment Size").add_attribute(Attribute::Bold).fg(Color::Cyan), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any easy way to make these functions no-ops if a condition is set? @brockelmore did that in an if/else which duplicates some code here. Would probably need a trait here?
trait Colorizer {
fn noop(&self) -> bool;
// do this for all `Cell`s
fn yellow(cell: Cell) -> Cell {
if !self.noop() { cell.fg(Color::Yelow) } else { cell }
}
}
struct Noop;
impl Colorizer for Noop {
fn noop(&self) -> bool { true }
}
struct Colors;
impl Colorizer for Colors {
fn noop(&self) -> bool { false }
}
let col: Box<dyn Colorizer> = if self.stdout { Box:new(Noop) } else { Box::new(Colors) }
col.magenta(col.bold(Cell::new("Function Name")))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be possible without a trait since .color
takes self
and returns Self
, so something like
struct CellColorizer {
should_color: bool
}
impl CellColorizer {
fn color(cell: Cell, color: ...) -> Cell {
if self.should_color {
cell.color(color)
} else {
cell
}
}
}
let colorizer = CellColorizer::new(self.stdout);
colorizer.color(Cell::new("Function Name"), Color::Magenta)
Same for attributes like bold etc. (maybe CellFormatter
is a better name)
/// Identify unknown addresses in the specified call trace using the specified identifier. | ||
/// | ||
/// Unknown contracts are contracts that either lack a label or an ABI. | ||
pub fn identify(&mut self, trace: &CallTraceArena, identifier: &impl TraceIdentifier) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clean
/// Trace identifiers figure out what ABIs and labels belong to all the addresses of the trace. | ||
pub trait TraceIdentifier { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would an EtherscanTraceIdentifier look like? If we have many addresses, we'd like to make all etherscan/4byte dir requests concurrently. Should the trait maybe have a fn identify_addresses
function which would fetch Name/Label/ABI for all address/code pairs provided? This would allow us to join all the etherscan futures and block_on all of them at the same time (vs having to block in a loop).
Ok(TestOutcome::new(results, allow_failure)) | ||
} else { | ||
// TODO: Re-enable when ported | ||
//let mut gas_report = GasReport::new(gas_reports.1); | ||
let local_identifier = LocalTraceIdentifier::new(&runner.known_contracts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we'd add a new identifier here for Etherscan, and then for each trace call identify
? I wonder if there's a way to pull this "out" so that we can do 1 identification step for etherscan across all traces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to do something like:
if let Some(fork_url) = fork_url {
let (mut all_addresses, mut _maybe_codes) = arena.addresses_iter().collect();
let unidentified_contracts = all_addresses.iter().filter(|address| !identified_contracts.contains(address)).collect();
let etherscan_identified = unidentified_contracts.par_iter().map(|contract| some_etherscan_contract_getter(contract)).collect();
etherscan_identified.iter().for_each(|(addr, name, abi)| identified_contracts.insert(addr, (name, abi)));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note for debugger it gets a little more challenging because we have to not just get abi but get the contract code and rerun compilation pipeline and write the contracts to files :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right. We can get the source code, byte code and ABI just fine, but there is no way for us to get the sourcemap from the Etherscan API :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we get the source code, we could always compile it with the right version and get it ourselves?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got most of the way thru this but will look more later
forge/src/trace/decoder.rs
Outdated
/// Address labels | ||
pub labels: BTreeMap<Address, String>, | ||
/// All known functions | ||
pub functions: BTreeMap<[u8; 4], Function>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to change this unfortunately... likely to BTreeMap<[u8; 4], Vec<Function>>
, reason being, short signatures don't identify differences in output types. So if a user has myFunc(uint256) external returns (uint256)
and just myFunc(uint256) external
, the one added first will be overwritten and fail to decode.
we should make it a vector (or make the key different, but having the key be the same as the calldata input is nice), and iteratively attempt decoding. Vast majority of the time there will be only one but still.
Doesnt apply to events so that can stay the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right. That's.. annoying. I'm adding a test to https://github.com/onbjerg/foundry-test that checks for this behavior:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed it using a BTreeMap<Address, BTreeMap<[u8; 4], Function>>
since the other solution (using a Vec
) would have a lot of oddities, notably if a function returns bytes
and another one string
they could both decode the output so it would show up wrong (i.e. both might be decoded as bytes
or string
) :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ehhhhhhhhh - not sure we want to do this. this then requires us to have identified the contract. When in actuality, if a sig matches, we should be able to decode it even if we haven't identified that specific contract (which can happen). I would really prefer to remain agnostic to the address and lean more on as better decoding scheme
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brockelmore what do you have in mind? The Vec
approach assumes there's a unique way to decode things as you iterate through the vector, which isn't right for the reason bjerg mentions above, although we could be opinionated and say "if it can show as ascii then go with string, else with bytes", but I suspect this can happen with any kind of fixed size return type, e.g. u256 and bytes32?
Keying by address I think might prevent us from using 4byte directory later on? How would we decode in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be relatively rare. i accidentally did it awhile back and ended up just changing my contracts. most of the time i think ppl will do it by accident. gently nudging them to change just for better decoding is probably a good idea. Maybe we leave as is (BTreeMap<[u8;4], Function>
) and emit a warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am OK with leaving as-is and maybe doing a trace::warn
(not logged by default), or not doing anything at all and waiting until a user bumps on it as a bug and decide then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesnt apply to events so that can stay the same
I'm not sure if this affects implementation here/anywhere, but just noting that events do have a similar problem but with indexed
parameters.
If you have topic 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550
, 4byte.directory tells you the sig is event TextChanged(bytes32,string,string)
. However, that's not enough to decode the event because two of those paramers are indexed but we don't know which. You'd pretty much have to guess which params are indexed, and depending on the types it's possible multiple sigs may decode and you can't tell which is correct
Ok(TestOutcome::new(results, allow_failure)) | ||
} else { | ||
// TODO: Re-enable when ported | ||
//let mut gas_report = GasReport::new(gas_reports.1); | ||
let local_identifier = LocalTraceIdentifier::new(&runner.known_contracts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to do something like:
if let Some(fork_url) = fork_url {
let (mut all_addresses, mut _maybe_codes) = arena.addresses_iter().collect();
let unidentified_contracts = all_addresses.iter().filter(|address| !identified_contracts.contains(address)).collect();
let etherscan_identified = unidentified_contracts.par_iter().map(|contract| some_etherscan_contract_getter(contract)).collect();
etherscan_identified.iter().for_each(|(addr, name, abi)| identified_contracts.insert(addr, (name, abi)));
}
Ok(TestOutcome::new(results, allow_failure)) | ||
} else { | ||
// TODO: Re-enable when ported | ||
//let mut gas_report = GasReport::new(gas_reports.1); | ||
let local_identifier = LocalTraceIdentifier::new(&runner.known_contracts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note for debugger it gets a little more challenging because we have to not just get abi but get the contract code and rerun compilation pipeline and write the contracts to files :/
let should_include = match kind { | ||
// At verbosity level 4, we also display the setup trace for failed | ||
// tests At verbosity level 5, we display | ||
// all traces for all tests | ||
TraceKind::Setup => { | ||
(verbosity >= 5) || (verbosity == 4 && !result.success) | ||
} | ||
TraceKind::Execution => verbosity > 3 || !result.success, | ||
_ => false, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
30adef9
to
20996a7
Compare
Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate.
We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself
20996a7
to
bffefcb
Compare
Looks good! Would recommend a fresh rebase of |
* feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com>
* feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com>
* feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com>
* feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com>
* feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com>
* Simple REVM test runner (#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (#789) * REVM cheatcodes (#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes #752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes #902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (#956) Ports #903 * REVM: FFI cheatcode updates (#955) * feat: only strip 0x in ffi output if present Ports #904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (#962) * Cross-crate testdata (#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes #959 * REVM fuzz dictionary (#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(config): add caching settings * feat: add none option * feat: add foundry data dir * feat: add storage map support * bump ethers * chore(clippy): make clippy happy * refactor: diskmap * feat: add rpc caching support * feat: add no storage cache option * refactor: rename cnfig value * docs: more storage caching docs * fix: with config builder function * refactor: address review Co-authored-by: Bjerg <onbjerg@users.noreply.github.com> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com>
* Simple REVM test runner (#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (#789) * REVM cheatcodes (#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes #752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes #902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (#956) Ports #903 * REVM: FFI cheatcode updates (#955) * feat: only strip 0x in ffi output if present Ports #904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (#962) * Cross-crate testdata (#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes #959 * REVM fuzz dictionary (#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(cli): Refactor cli/cmd over forge and cast (#1009) * ⚙️ refactor cli * 🧪 refactor casts * REVM: Support cheatcodes in `setUp` (#997) * fix: support cheatcodes in `setUp` * fix: subtract stipend without panic * chore: rename test * fix: set tx gas price to block basefee * fix: use `CALLER` for `is_success` check * chore: remove duplicate clap attribute * fix: set chain id correctly in fork mode * fix: separate evm block env from execution env * chore: clippy * refactor: block override without `block_env` fn * test: explain why git clone failed * test: disable maple-labs/loan * refactor: make addresses statics instead of lazies * docs: fix console address comment * refactor: make `DUMMY_CREATE_ADDRESS` a static * chore: minor nits * refactor: move inspector state collection * fix: report correct fuzz failure case (#1017) * fix: report correct fuzz failure case * docs: improve some docs in fuzzer * feat: add support for storage caching (#1006) * Simple REVM test runner (#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (#789) * REVM cheatcodes (#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes #752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes #902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (#956) Ports #903 * REVM: FFI cheatcode updates (#955) * feat: only strip 0x in ffi output if present Ports #904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (#962) * Cross-crate testdata (#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes #959 * REVM fuzz dictionary (#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(config): add caching settings * feat: add none option * feat: add foundry data dir * feat: add storage map support * bump ethers * chore(clippy): make clippy happy * refactor: diskmap * feat: add rpc caching support * feat: add no storage cache option * refactor: rename cnfig value * docs: more storage caching docs * fix: with config builder function * refactor: address review Co-authored-by: Bjerg <onbjerg@users.noreply.github.com> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: default to 80m gas * fix(evm): gracefully shutdown backendhandler (#1021) * feat(evm/cache): improve json file caching (#1025) * feat(cache): proper json cache * refactor: use new db types * chore(clippy): make clippy happy * bump revm * docs: some docs * refactor: extend Fork type * remove diskmap types * test: refactor tests * remove sharedmemcache * add tests * more tracing * chore(clippy): make clippy happy * release: 0.2.0 Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> Co-authored-by: abigger87 <abigger87@gmail.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
* Simple REVM test runner (foundry-rs#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (foundry-rs#789) * REVM cheatcodes (foundry-rs#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes foundry-rs#752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (foundry-rs#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (foundry-rs#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (foundry-rs#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes foundry-rs#902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (foundry-rs#956) Ports foundry-rs#903 * REVM: FFI cheatcode updates (foundry-rs#955) * feat: only strip 0x in ffi output if present Ports foundry-rs#904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (foundry-rs#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (foundry-rs#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (foundry-rs#962) * Cross-crate testdata (foundry-rs#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (foundry-rs#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (foundry-rs#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes foundry-rs#959 * REVM fuzz dictionary (foundry-rs#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(cli): Refactor cli/cmd over forge and cast (foundry-rs#1009) * ⚙️ refactor cli * 🧪 refactor casts * REVM: Support cheatcodes in `setUp` (foundry-rs#997) * fix: support cheatcodes in `setUp` * fix: subtract stipend without panic * chore: rename test * fix: set tx gas price to block basefee * fix: use `CALLER` for `is_success` check * chore: remove duplicate clap attribute * fix: set chain id correctly in fork mode * fix: separate evm block env from execution env * chore: clippy * refactor: block override without `block_env` fn * test: explain why git clone failed * test: disable maple-labs/loan * refactor: make addresses statics instead of lazies * docs: fix console address comment * refactor: make `DUMMY_CREATE_ADDRESS` a static * chore: minor nits * refactor: move inspector state collection * fix: report correct fuzz failure case (foundry-rs#1017) * fix: report correct fuzz failure case * docs: improve some docs in fuzzer * feat: add support for storage caching (foundry-rs#1006) * Simple REVM test runner (foundry-rs#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (foundry-rs#789) * REVM cheatcodes (foundry-rs#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes foundry-rs#752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (foundry-rs#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (foundry-rs#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (foundry-rs#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes foundry-rs#902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (foundry-rs#956) Ports foundry-rs#903 * REVM: FFI cheatcode updates (foundry-rs#955) * feat: only strip 0x in ffi output if present Ports foundry-rs#904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (foundry-rs#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (foundry-rs#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (foundry-rs#962) * Cross-crate testdata (foundry-rs#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (foundry-rs#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (foundry-rs#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes foundry-rs#959 * REVM fuzz dictionary (foundry-rs#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(config): add caching settings * feat: add none option * feat: add foundry data dir * feat: add storage map support * bump ethers * chore(clippy): make clippy happy * refactor: diskmap * feat: add rpc caching support * feat: add no storage cache option * refactor: rename cnfig value * docs: more storage caching docs * fix: with config builder function * refactor: address review Co-authored-by: Bjerg <onbjerg@users.noreply.github.com> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: default to 80m gas * fix(evm): gracefully shutdown backendhandler (foundry-rs#1021) * feat(evm/cache): improve json file caching (foundry-rs#1025) * feat(cache): proper json cache * refactor: use new db types * chore(clippy): make clippy happy * bump revm * docs: some docs * refactor: extend Fork type * remove diskmap types * test: refactor tests * remove sharedmemcache * add tests * more tracing * chore(clippy): make clippy happy * release: 0.2.0 Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> Co-authored-by: abigger87 <abigger87@gmail.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
* Simple REVM test runner (foundry-rs#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (foundry-rs#789) * REVM cheatcodes (foundry-rs#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes foundry-rs#752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (foundry-rs#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (foundry-rs#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (foundry-rs#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes foundry-rs#902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (foundry-rs#956) Ports foundry-rs#903 * REVM: FFI cheatcode updates (foundry-rs#955) * feat: only strip 0x in ffi output if present Ports foundry-rs#904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (foundry-rs#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (foundry-rs#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (foundry-rs#962) * Cross-crate testdata (foundry-rs#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (foundry-rs#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (foundry-rs#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes foundry-rs#959 * REVM fuzz dictionary (foundry-rs#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(cli): Refactor cli/cmd over forge and cast (foundry-rs#1009) * ⚙️ refactor cli * 🧪 refactor casts * REVM: Support cheatcodes in `setUp` (foundry-rs#997) * fix: support cheatcodes in `setUp` * fix: subtract stipend without panic * chore: rename test * fix: set tx gas price to block basefee * fix: use `CALLER` for `is_success` check * chore: remove duplicate clap attribute * fix: set chain id correctly in fork mode * fix: separate evm block env from execution env * chore: clippy * refactor: block override without `block_env` fn * test: explain why git clone failed * test: disable maple-labs/loan * refactor: make addresses statics instead of lazies * docs: fix console address comment * refactor: make `DUMMY_CREATE_ADDRESS` a static * chore: minor nits * refactor: move inspector state collection * fix: report correct fuzz failure case (foundry-rs#1017) * fix: report correct fuzz failure case * docs: improve some docs in fuzzer * feat: add support for storage caching (foundry-rs#1006) * Simple REVM test runner (foundry-rs#788) * refactor: nuke `evm-adapters` * refactor: simple revm test runner Current features: - Can run unit tests - Works with both revert-type tests and DSTest-type tests - Collects logs, albeit not for reverting tests - Integrated with config and CLI flags Disabled features: - Gas reports - Tracing - Cheatcodes - Fuzzing - Log decoding - Forking mode - Hardhat-style `console.log`, since those require us to decode calls to a specific address (HH does not emit logs) - The debugger In addition to this, I've disabled some tests that could never pass under the current circumstances, but that should be adjusted and re-enabled when their respective features are implemented (such as fuzz tests) * refactor: adjust CLI to new runner API * feat: log collector inspector * feat: hardhat logs * chore: lint * refactor: extract hh log converter to helper fn * refactor: return single test result if setup fails * build: use upstream revm chore: renuke `evm-adapters` * REVM fuzzer (foundry-rs#789) * REVM cheatcodes (foundry-rs#841) * feat: add `InspectorStack` Adds `InspectorStack`, an inspector that calls a stack of other inspectors sequentially. Closes foundry-rs#752 * feat: port cheatcodes to revm * feat: port `expectCall` cheatcode * feat: extract labels from cheatcode inspector * feat: port `expectEmit` cheatcode * refactor: move log decoding into `forge` crate * chore: remove unused evm patch * test: re-enable debug logs test * fix: record reads on `SSTORE` ops * refactor: rename `record` to `start_record` * docs: clarify why `DUMMY_CALL_OUTPUT` is 320 bytes * fix: handle `expectRevert` with no return data * build: bump revm * chore: remove outdated todo * refactor: use static dispatch in `InspectorStack` * build: use k256 * fix: make gas usage not so crazy * feat(revm): add forking mode (foundry-rs#835) * feat: copy-paste old forking provider * feat(fork): convert to REVM traits * chore: remove unnecessary codehash handler * feat: impl Database for shared backend * chore: fix tests * chore: fmt * fix(fork): correctly convert H256 <> U256 for storage * refactor: separate storage from accounts in cache * feat(fork): fetch block hashes * chore: remove unused DB parameter * test: add test for block hashes * feat: add forked backend to executor builder * feat(cli): set fork url on the executor * refactor: move shared backend to separate file * feat(fork): add fn for instantiating forked env * feat(cli): allow pinning block number * fix(fork): install missing listeners * feat(fork): instantiate environment with forked state * fix: use a CALLER address with maxed out balance for calls this is required because in forking mode otherwise the account wont have enough balance to transact * chore: fmt Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> * chore: fmt * REVM tracing and gas reports (foundry-rs#867) * feat: very simple traces * feat: creation traces * feat: setup and revert traces * fix: fix lib addresses * refactor: simplify tracer inspector * fix: fill traces in correct order * build: bump revm * fix: get code for newly created contracts * refactor: unify log extraction logic * feat: trace logs * refactor: unify labels and names * refactor: return string from trace Instead of passing in an empty string we then pass around inside the trace display logic, we just return strings where appropriate. * refactor: remove identified contracts * refactor: remove unused vars * refactor: simplify `construct_func_call` * refactor: name special characters in traces * refactor: rework all display logic * feat: first pass identify/decode for traces * refactor: move tracing to own module * refactor: simplify `test` * feat: traces for fuzz tests * fix: make fuzz revert reasons less verbose * feat: port gas reports * refactor: small readability nits * feat: run fuzz *and* unit tests in parallel Previously we would run each test contract in parallel, but within each `ContractRunner` we would run unit tests first (in parallel) and then fuzz tests (in parallel). * refactor: move colouring logic to its own function * fix: test contract identification We now include three kinds of traces that are used for identification of contracts: - Deployment traces: these are the initial deployments of the test contract and libraries - Setup traces: these are traces of calls to the `setUp` function - Execution traces: these are the traces of calls to the test contract itself * fix: mark setup trace as a setup trace * fix: get correct nonce in tracer * fix: log extraction outside of current memory * chore: clean up complex types * chore: remove outdated comment * fix: make tests compile * fix: add missing test filter function * feat: display full address in traces * fix: color "new" keyword in traces * fix: filter out `console.log` calls from traces * chore: remove unnecessary comment * feat: add gas cost to creation traces * fix: properly decode outputs * refactor: destructure `TestSetup` in test funcs * fix: ignore address for func output decoding * fix: fix expect emit Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> * REVM debugger (foundry-rs#920) * feat: port debugger data structures * feat: initial port of `ui` crate * chore: add `ui` crate as a workspace member * refactor: adjust ui contract identification * feat: grey out 0 values in debugger memory Closes foundry-rs#902 * style: minor debugger ui beautification * feat: better stack display in debugger ui * feat: gray out zero bytes in stack view * feat: debugger inspector * refactor: minor code cleanup * feat: port `forge run` * fix: temp fix for failing `DsTest.sol` include * chore: fix lints * test: adjust `forge run` tests * refactor: use simple bool for revert checks * chore: remove unused display impl * chore: remove unused comment * fix: display number of stack items in ui * docs: prettify cli help for some commands * feat: `forge test --debug` * refactor: `get_create_address` util * refactor: `InspectorData` * docs: more detailed err for `forge test --debug` * feat: support hardhat artifacts in `vm.getCode` (foundry-rs#956) Ports foundry-rs#903 * REVM: FFI cheatcode updates (foundry-rs#955) * feat: only strip 0x in ffi output if present Ports foundry-rs#904 * Update forge/src/executor/inspector/cheatcodes/ext.rs Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * REVM gas fixes (foundry-rs#950) * feat: account for gas refunds * refactor: merge `call_raw` and committing variant * fix: actually use refund quotient * feat: strip tx gas stipend * fix: fix reported gas usage in debugger * build: use upstream revm * test: adjust `forge run` gas values in tests * chore: remove unused copy * chore: add note on push maths * feat: make stipend reduction optional * fix: remove tx stipend in `forge run` * REVM: Pull EVM executor into own crate (foundry-rs#961) * refactor: move evm executor to own crate * refactor: `evm::executor::fuzz` -> `evm::fuzz` * refactor: `evm::debugger` -> `evm::debug` * test: fix multi runner test * feat: better ux for expect revert without reason (foundry-rs#962) * Cross-crate testdata (foundry-rs#965) * feat: cross-crate shared testdata * refactor: move `foundry-utils` to common tests * fix: fix getcode test * fix: compile once in tests * fix: fix prank cheatcode (foundry-rs#973) Correctly apply `msg.sender` prank to both transfers and calls. * fix: prank depth math * test: fix lib linking test * refactor: use revm `log` hook (foundry-rs#984) * refactor: use revm `log` hook * chore: bump revm Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * test: add lil-web3 to integration tests * test: add maple labs loans to integration tests Closes foundry-rs#959 * REVM fuzz dictionary (foundry-rs#985) * feat: fuzz dictionary Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: handle malformed bytecode * fix: limit search for push bytes * feat: collect fuzz state from logs * feat: build initial fuzz state from db * perf: use `Index` instead of `Selector` Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * feat(config): add caching settings * feat: add none option * feat: add foundry data dir * feat: add storage map support * bump ethers * chore(clippy): make clippy happy * refactor: diskmap * feat: add rpc caching support * feat: add no storage cache option * refactor: rename cnfig value * docs: more storage caching docs * fix: with config builder function * refactor: address review Co-authored-by: Bjerg <onbjerg@users.noreply.github.com> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> * fix: default to 80m gas * fix(evm): gracefully shutdown backendhandler (foundry-rs#1021) * feat(evm/cache): improve json file caching (foundry-rs#1025) * feat(cache): proper json cache * refactor: use new db types * chore(clippy): make clippy happy * bump revm * docs: some docs * refactor: extend Fork type * remove diskmap types * test: refactor tests * remove sharedmemcache * add tests * more tracing * chore(clippy): make clippy happy * release: 0.2.0 Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: brockelmore <brockelmore@users.noreply.github.com> Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com> Co-authored-by: abigger87 <abigger87@gmail.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Ports tracing to REVM (see comments below)
Closes #753
Closes #775