-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
1) enable reporter for imported contracts 2) gas-reporter discrepancies with mainnet #46
Comments
Hi @gitpusha, Yes, agree this would be really useful and should be straightforward to implement. If there was a gasReporter option like [
{
contractName: <string>
address: <string>
abi: any
},
]
Do you have a repo I could test an option like this with? |
Yes, such an option would be great ! Here is a repo you can test this with. We have some massive integration tests in there. Maybe just test with this one. Here you can find all the pre-compiles this test uses. And here are the addresses of the pre-compiles. If you wanna, you can release and |
Have published an experimental
To test, I added the following to your const fs = require('fs');
const path = require('path');
// Load remote contract address and ABI data
const remoteContracts = [];
const preCompilesPath = 'pre-compiles';
for (const fileName of fs.readdirSync(preCompilesPath)){
const artifactPath = path.join(process.cwd(), preCompilesPath, fileName)
const preDeployed = require(artifactPath);
const address = mainnetDeployments[preDeployed.contractName]
if (address){
remoteContracts.push({
name: preDeployed.contractName,
abi: preDeployed.abi,
address: address
})
}
} and added gasReporter: {
enabled: process.env.REPORT_GAS ? true : false,
maxMethodDiff: 25,
coinmarketcap: process.env.COINMARKETCAP_API_KEY,
+ remoteContracts
}, However I'm not sure the results are what is expected. Only caught a couple of additional method calls, to ConnectAuth and InstaConnectors. Are you expecting more data here? Do you have lots of calls routed through a proxy or call-forwarding contract? |
Amazing! Thanks so much for the hands-on support. The table looks pretty good to me. I was opening this issue with generality in mind but I only had a couple of methods missing. So yes, looks good to me.
Yes, that is why there aren't too many new methods shown, but that's expected. I will use your rc and test it myself. When do you think will you make it a stable release? I see that your method only requires: remoteContracts.push({
name: preDeployed.contractName,
abi: preDeployed.abi,
address: address Hence a Also I wanted to ask about how the |
There's an option available which lets you to pass the reporter a method to resolve the real identity of proxy calls. It's a little complicated (but it's theoretically possible...).
Yes, exactly.
Oh! Super interesting. How did you measure manually? The hardhat reporter really just wraps the Ethers provider - it would be great to track down exactly where the gap you're seeing comes from. We run the eth-gas-reporter test suite against ganache and geth and their results differ by a few hundred gas for very simple methods. Also, recently a bug was reported at ganache that gas readings are substantially off when running in forked mode. (Don't know how closely HH tracks geth - should add the same test to this repo.) |
Missed a question...
I'm not sure...it might be a couple weeks. There are a couple other fixes I'd like to get in here |
I had a look at it. Pretty cool. But actually we are not making typical Proxy calls via a fallback method. The problem for gas reporting is rather that we use a single entry point function for different payloads. This function wraps around many different paths of execution. And we want to measure gas for those different execution paths. So even though the important stuff for gas-reporting is hidden in the payload, the gas-reporter tool will average out gasUsed across all our tested execution paths, which renders it kind of useless in that context because we want to differentiate between them distinctly. The difference in execution paths are nested deep down, so I cannot think of a simple way to write a general Resolver for this. I think it's easier for now to just Mock the different paths by giving them all a distinct method name and then submit the respective payloads via this distinct method name, thereby tricking the tool into reporting gas for these different paths. The real system will only have one entry method though, not several.
Just using ethers TransactionReceipt.gasUsed property. Probably similar to what you do.
We also run our tests in I will probably have some files where you can review this soon and share them with you. |
Yes this makes a lot of sense.
Ok cool, yes I'd really like to see this and get reproduction steps for the difference. |
Ok, so I just tried to reproduce myself and for me the manual ethers method const txResponse = await contract.method();
const { gasUsed } = await txResponse.wait();
console.log(gasUsed); yields exactly the same results as However, what is clear is that both And I believe that my colleague really did find these disrepancies in testing because we went with the higher gas values he found during testing using the manual However, I am still confused why now both the tool and the manual method report the same apparently too-low gasUsed value. We run this stuff on a hardhat-network fork of mainnet. |
Actually new finding: I added some Clearly hardhat network console.logs also think there is more gas consumed than both ethers.js and hardhat-gas-reporter. Is there ever a scenario where hardhat-gas-reporter's values could diverge from vanilla ethers.js values? No right? They are the same values read from the same thing basically right? If you want to you can run the test yourself: Here is the repo. Here is the test to run with:
If you wanna look at where the TX is sent, you can find that here. And you can look at the contract we call here. |
Thanks for this!
Could you give a quick example of where/what/how you're console.logging in Solidity? (It's possible the logging itself distorts gas values a little at runtime.) Also, is there a difference in the optimization levels you use to deploy to mainnet vs. local testing?
Yes they are supposed to be, there could be a bug somewhere though. |
Here in the contract I shared you can see the function execViaRoute0AndOpenVault(TaskReceipt memory _taskReceipt) public {
uint256 gasLeft = gasleft();
IGelatoCore(gelatoCore).exec(_taskReceipt);
console.log(
"Gas Cost execViaRoute0AndOpenVault: %s",
gasLeft - gasleft()
);
} And here is the TX from mainnet which is almost identical to the As you can see |
This got solved with the new hardhat release! https://github.com/nomiclabs/hardhat/releases/tag/hardhat-core-v2.0.4 Yeah!! Closing! |
Reopening because I still observe about 10% higher gasUsed values on mainnet when comparing with hardhat network in forking mode. |
@gitpusha The Going to close this for now. Thanks for reporting all this stuff though. |
Ok ! |
Hi @cgewecke ,
I realized that
hardhat-gas-reporter
only seems to report for contracts who were compiled withhardhat
and thus have certain files associated with them inartifacts/
.Is this correct?
In our integration testing we make use of
forking
and thus instantiate many contracts withawait ethers.getContractAt(abi, addresss)
, where theabi
is in apre-compiled/
folder.It would be amazing if
hardhat-gas-reporter
would also report gas usage of methods called on those instances.What would need to change for that to happen?
The text was updated successfully, but these errors were encountered: