-
Notifications
You must be signed in to change notification settings - Fork 746
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
Add EVM profiler #2988
Add EVM profiler #2988
Conversation
Codecov Report
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. |
packages/vm/src/types.ts
Outdated
profilerOpts?: { | ||
//evmProfilerOpts: EVMProfilerOpts | ||
reportProfilerAfterTx?: boolean | ||
reportProfilerAfterBlock?: boolean |
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.
Two quick nits: I would drop the Profiler
here from the two options, so just reportAfterTx
and reportAfterBlock
, context is already clear and option gets shorter.
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 have explicitly added this profiler to VM, because we want to (?) profile VM pre-setup-before EVM call and post-setup-after-EVM call too. So after the EVM is ran, then VM will flush the StateManager and this can take some time in some situations, which we want to profile to (?)
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 was just about naming the options (please re-read in this context), so removing Profiler
from the options names since it's redundant and makes the names long. 🙂
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 you are right, will update
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 misread your comment, I thought you meant to remove profilerOpts
and put those options directly into (so without an encapsulating object)
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 would actually still be a fan of this name changes (can be along some follow-up work), so that we get to e.g. this._opts.profilerOpts?.reportAfterBlock
(still long enough 🙂).
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.
Ok, addressed
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 would actually still be a fan of this name changes (can be along some follow-up work), so that we get to e.g.
this._opts.profilerOpts?.reportAfterBlock
(still long enough 🙂).
Yes, added this :)
describe: 'Report the VM profile after running each block', | ||
boolean: true, | ||
default: 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.
Oh this is cool! 🤩
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.
Didn't know that you had integrated so deeply into client already...
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.
Yes, the only thing not to forget is; it does not work if you don't set the DEBUG=ethjs,evm:profiler
env, so this is something we can improve (but not sure how to do this cleanly)
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.
You should just be able to set the debug variable programmatically with this process.env.DEBUG = 'ethjs,evm:profiler'
. So just add a code block to the run
command in the client that checks for either of these args and then sets the debug accordingly. Or better, do something like this:
if (args.vmProfileBlocks || args.vmProfileTxs) {
let debugString = process.env.DEBUG
if debugString.startsWith('ethjs') {
debugString = debugString + ',evm:profiler'
} else {
debugString = 'ethjs,evm:profiler'
}
process.env.DEBUG=debugString
}
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, I haven't tested the above code but I do something like this in one of the trie
demos to force it to output certain debug logs.
HEAD at 2e06d87 (backup) |
2e06d87
to
f81882e
Compare
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 looks good, though left a couple of questions about syntax I'm not quite tracking.
packages/evm/src/interpreter.ts
Outdated
@@ -171,6 +177,7 @@ export class Interpreter { | |||
returnValue: undefined, | |||
selfdestruct: new Set(), | |||
} | |||
;(this.profilerOpts = profilerOpts), (this.performanceLogger = performanceLogs) |
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.
What is this syntax?
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.
No idea 😂 I definitely did not write this, I think I made a weird syntax mistake and then the linter did this. Will fix
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.
LGTM
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.
LGTM
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.
Still looks good to me 🙂
🎉 |
This PR adds the feature for an EVM profiler. It features, once enabled, tracking:
For precompiles we have the special case that the gas there is not tracked as in normal EVM calls, but instead depends upon what precompile is called. If a precompile is called, the "inner" gas used by that precompile (so without the overhead of the initial CALL opcode to the precompile) is tracked.
The VM gets extra options:
profilerOpts
, which canreportProfilerAfterBlock
andreportProfilerAfterTx
. Note that if a profiler is reported, the profiler in the EVM is cleared, so you cannot use both options.EVM itself has an extra option as well, the
profiler
(should rename this toprofilerOpts
as well for consistency) which currently only has theenable
flag. This will later support reporting the gas used for different hardforks (while the actual EVM runs on the hardfork it expects for that call) such that we can simulate running Shanghai gas on older blocks (since EVM had many underpriced situations back then).To run and test:
Add this to
BlockchainTestRunner
:Now run a blockchain test:
npm run test:blockchain -- --fork=Shanghai --test=coinbaseWarmAccountCallGasFail_d3g0v0_Shanghai
Example output:
TODOs
DEBUG=ethjs,evm:profiler npm run test:blockchain -- --fork=Shanghai --test=ContractCreationSpam_d0g0v0_Shanghai
TODOs for subsequent PRs
--profile
them