-
Notifications
You must be signed in to change notification settings - Fork 20k
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, cmd/eofdump: implement eof validation #30418
base: master
Are you sure you want to change the base?
Conversation
e1feb9c
to
6ebbbd9
Compare
INVALID: { | ||
execute: opUndefined, | ||
minStack: minStack(0, 0), | ||
maxStack: maxStack(0, 0), | ||
}, |
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 IMO very wonky, see discussion here: https://github.com/ethereum/go-ethereum/pull/29518/files#r1753395744 .
ErrUndefinedInstruction = errors.New("undefined instruction") | ||
ErrTruncatedImmediate = errors.New("truncated immediate") | ||
ErrInvalidSectionArgument = errors.New("invalid section argument") | ||
ErrInvalidCallArgument = errors.New("callf into non-returning section") | ||
ErrInvalidDataloadNArgument = errors.New("invalid dataloadN argument") | ||
ErrInvalidJumpDest = errors.New("invalid jump destination") | ||
ErrInvalidBackwardJump = errors.New("invalid backward jump") | ||
//ErrConflictingStack = errors.New("conflicting stack height") | ||
//ErrInvalidBranchCount = errors.New("invalid number of branches in jump table") | ||
ErrInvalidOutputs = errors.New("invalid number of outputs") | ||
ErrInvalidMaxStackHeight = errors.New("invalid max stack height") | ||
ErrInvalidCodeTermination = errors.New("invalid code termination") | ||
ErrEOFCreateWithTruncatedSection = errors.New("eofcreate with truncated section") | ||
ErrOrphanedSubcontainer = errors.New("subcontainer not referenced at all") | ||
ErrIncompatibleContainerKind = errors.New("incompatible container kind") | ||
ErrStopAndReturnContract = errors.New("Stop/Return and Returncontract in the same code section") | ||
ErrStopInInitCode = errors.New("initcode contains a RETURN or STOP opcode") | ||
ErrTruncatedTopLevelContainer = errors.New("truncated top level container") | ||
ErrUnreachableCode = errors.New("unreachable code") | ||
ErrInvalidNonReturningFlag = errors.New("invalid non-returning flag, bad RETF") |
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.
Not all of these methods are mapped in the eofparser error-to-number mapping function. Should they be?
6ebbbd9
to
666abfe
Compare
666abfe
to
6cfe117
Compare
ErrTooManyInputs = errors.New("invalid type content, too many inputs") | ||
ErrTooManyOutputs = errors.New("invalid type content, too many outputs") |
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.
Why are these needed, when we already have ErrInvalidInputs
/Outputs
?
Added benchmarks, based on some of the worst-cases from the consensus-tests + fuzzing vectors.
|
a80b89a
to
5099626
Compare
Sped it up quite a bit, the slowest vector is now improved by a factor of 10 :)
|
cmd/eofdump: benchmarks of eof validation speeds core/vm: move eof instructions to separate file core/vm: unexport fields Co-authored-by: lightclient <lightclient@protonmail.com> Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de> Co-authored-by: Danno Ferrin <danno.ferrin@shemnon.com>
33cc41e
to
8196b46
Compare
} | ||
} | ||
|
||
func BenchmarkEOFValidation2(b *testing.B) { |
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.
All the benchmark-function in this file appears to be non-functional, should we nuke them or salvage them, @MariusVanDerWijden ?
example
[user@work vm]$ go test . -run - -bench EOFV
--- FAIL: BenchmarkEOFValidation
validate_test.go:353: callf into non-returning section: section 1
--- FAIL: BenchmarkEOFValidation2
validate_test.go:403: callf into non-returning section: section 1
--- FAIL: BenchmarkEOFValidation3
validate_test.go:452: callf into non-returning section: section 1
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 will try to salvage
e262a9f
to
50dcc67
Compare
core/vm: some clarifications in the eof code core/vm: clarifications + minor speedup core/vm: clarifications + lint + minor speedup core/vm, core/asm: support eof in asm instruction iteration core/vm: comment out unused core/vm: remove gasfunctions
50dcc67
to
8783059
Compare
The bulk of this PR is authored by @lightclient , in the original EOF-work.
More recently, the code has been picked up and reworked for the new EOF specification, by @MariusVanDerWijden , in #29518, and also @shemnon has contributed with fixes.
They are the main authors to be credited for the code in this PR.
This PR is an attempt to start eating the elephant one small bite at a time, by selecting only the eof-validation as a standalone piece which can be merged without interfering too much in the core stuff.
In this PR:
undefined
to a jumptable entry item. I'm not super-happy with this, but for the moment it seems the least invasive way to do it. A better way might be to go back and allowing nil-items or nil execute-functions to denote "undefined".It would have been nice to break it up further,
core/vm
is growing very very large. However, it's not easy to puteof
in a submodule.So what we might do is move the opcodes, and the jumptable definition to a new low-level module. And in
core/vm
keep the jumptable instantiations, so we can pass the actual jumptables toeof
. Theneof
doesn't have to importcore/vm
, I think.Even with this smaller piece cherry-picked, there's quite a bit of work to do to improve it, better documentation and test coverage. I'll push commits here and rebase quite a bit.
To do in follow-up PR(s) is to modify the interpreter a bit more in-depth, to operate differently in eof-mode versus non-eof-mode.
Co-authored-by: @lightclient
Co-authored-by: @MariusVanDerWijden
Co-authored-by: @shemnon