ApeWorX / ape-hardhat

Hardhat network provider for the Ape Framework
https://www.apeworx.io/
Apache License 2.0
18 stars 15 forks source link

Auto-cache Hardhat console ABI [APE-645] #125

Closed antazoey closed 8 months ago

antazoey commented 1 year ago

Overview

It would be nice if the Hardhat provider automatically cached the Hardhat console ABI in the session's contracts' cache. One benefit is that it will help traces know the contract type for console log statements (could potentially ignore them by modifying other methods in ape-hardhat related to getting traces. This is also probably needed for https://github.com/ApeWorX/ape/issues/685

I got this idea from looking at this code: https://github.com/Ackee-Blockchain/woke/blob/main/woke/testing/call_trace.py#L373

Specification

TBD but something like

  1. Hardcode or find a way to fetch console ABIs in the plugin
  2. On connect(), set the contract type address using the chain.contracts[addr] = ct. I think the address is "0x000000000000000000636F6e736F6c652e6c6f67" based on the woke project.
  3. Use console log in your tests and see how it looks in a trace in Ape.

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

mikeshultz commented 9 months ago

This is also probably needed for https://github.com/ApeWorX/ape/issues/685

Wouldn't this be dependent on that one?

Is the spec for this issue to recognize non-transaction calls and output them as such? Do we need/want to make an RPC call for that? Could we intercept and just log?

Some example psuedo-code on how this might be used would be helpful.

antazoey commented 9 months ago

console logs can appear in a transaction call, at any point in its call-tree (imagine the console.log in an internal method call or something). So we would need to detect when that is happening (perhaps using evm-trace and analyzing the address of the console.log contract), decode the log messages (probably using abi.decode ("string")), and use the ape logger to output them. We should probably output them in a way that separates it from the other logs, like add a prefix [CONTRACT-LOG] or something..

It definitely is not going to be easy, as it requires analyzing the call tree a bit.

Consideration: dev off the trace API work branch I have started instead of core main because traces work a bit different in 0.8.

But right now, Ape enriches traces but getting contract types, looking at method IDs and it can print a whole call tree out, so probably during that whole process we would check if the address is console log...

And also - if the ABI is known and cached (like this ticket says), we can prettify those calls in the tree as well

mikeshultz commented 9 months ago

And also - if the ABI is known and cached (like this ticket says), we can prettify those calls in the tree as well

Do you have an example of another contract that is "known and cached"? And maybe a trace that's prettified if there's an example laying around?

I just started prototyping for https://github.com/ApeWorX/ape/issues/685 to learn more about this last night and it's looking like a static ABI for decoding might not be the way to go for logging. The console.sol ABI is not the end all-be-all for input type combinations that might get used. Will consider this issue as I go though.

antazoey commented 9 months ago

the chain.contracts object is the one that can cache contract types by address. So we need to know the address from hardhat, either via RPC or hardcoding, and then we need the ABI too, either via RPC or hardcoding. Then, we do something like:

chain.contracts[address] = ContractType(abi=abi)

Then, any trace enrichment will work - itll enrich the calls. However the next thing would be to try and show the prints, that sounds wild and would probably just happen during trace enrichments.

look at the enrich_calltree stuff if you wanna see how that works... though that is the part that would be best to do afer 0.8 when traces are better, but the trace API branch exists now so we can dev it we wanted

mikeshultz commented 9 months ago

Are there any currently hardcoded contract types?

antazoey commented 9 months ago

Are there any currently hardcoded contract types?

Do you mean like this? https://github.com/ApeWorX/ape-tokens/blob/main/ape_tokens/managers.py#L8

mikeshultz commented 9 months ago

I'm not entirely sure where to put this. I'm bringing the ABI into the codebase under the ape_ethereum core plugin (https://github.com/ApeWorX/ape/pull/1930). But I'm not entirely sure where it's appropriate to inject it into the chain manager's contracts. Doing it from the provider's __init__() seems to be too early (ProviderNotConnectedError originating in pluggy somewhere).

Suggestions?

antazoey commented 9 months ago

Suggestions?

Maybe right after the connection is established?

mikeshultz commented 9 months ago

https://github.com/ApeWorX/ape/pull/1930/commits/483cac780eab284dc106b84514020463cee65fb1 will probably take care of this.