-
Notifications
You must be signed in to change notification settings - Fork 20.4k
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
core/vm: fill gaps in jump table with opUndefined #24031
Conversation
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. Any benchmarks?
This is not much, ~1%. |
core/vm/jump_table.go
Outdated
// Fill all unassigned slots with opUndefined. | ||
for i, entry := range tbl { | ||
if entry == nil { | ||
tbl[i] = &operation{execute: opUndefined} |
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.
Heh, a fun side-effect here. Since you didn't define maxStack
, it's left at 0
, so this op will (mostly) never actually execute, it will always fail since the maxStack
is reached (unless the stack is totally empty when this op is encountered). Setting maxStack to maxStack(0,0)
would solve it
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 yes, I wanted this but did not realized I need to set non-zero maxStack (in my implementation I have "stack increase").
|
@@ -193,9 +193,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( | |||
// enough stack items available to perform the operation. | |||
op = contract.GetOp(pc) | |||
operation := in.cfg.JumpTable[op] | |||
if operation == nil { |
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.
Sorry to be constantly nagging about tracing haha but this is gonna do a lot of CaptureState(opUndefined...)
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.
opUndefined
still aborts with ErrInvalidOpCode
so there shouldn't really be a change there?
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 this is a problem?
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.
@s1na Well, the fix is it's basically the same as for the previous one: whenever there are two outputs for the same step of execution (same pc twice in a row), then ignore the first and only care about the second one.
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.
opUndefined still aborts with ErrInvalidOpCode so there shouldn't really be a change there?
@axic the change is that with this PR, it will do a capturestate prior to execute
, which it didn't do previously -- erroring before it reached execute
.
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.
Gonna do a lot of...
was an exaggeration, since there aren't many txes which actually execute undefined opcodes, I think? but yeah not saying this is a show-stopper or anything. Mainly wanted to document the change.
Cherry-pick ethereum/go-ethereum#24031 Co-authored-by: Paweł Bylica <chfast@gmail.com>
Instead of checking if a slot in the jump table is
nil
, fill all unassigned slots withopUndefined()
returning expected errorErrInvalidOpCode
.