Skip to content
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: Move interpreter.ReadOnly check into the opcode implementations #23970

Merged
merged 4 commits into from Dec 1, 2021

Conversation

axic
Copy link
Member

@axic axic commented Nov 25, 2021

Fixes #23968.

I had trouble running tests locally, but go test -v ./tests passed (and displayed a lot of state tests lines). make test runs into various failures regarding "too many files open" or networking issues. In short: this change may be broken as I couldn't 100% verify with tests.

@@ -124,6 +124,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// Make sure the readOnly is only set if we aren't in readOnly yet.
// This also makes sure that the readOnly flag isn't removed for child calls.
if readOnly && !in.readOnly {
if !in.evm.chainRules.IsByzantium {
panic("readOnly execution requested on wrong chainRules");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new addition here, which I think may even make sense without the rest of the changes. Not sure about how well panic is perceived, but seen it used occasionally in similar context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave this here if we want to do a test-run, but I think we should remove it from production code.
I'd also be fine with not having the panic here at all.

Copy link
Member Author

@axic axic Nov 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any option besides panic? I agree that panic is kind of risky as it may result in inconsistent shutdowns (and DoS), but if this is hit that is a potential consensus issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We sometimes use panic, when something has failed beyond where we can do anything about it.
We don't usually actively look for failures to panic on, unless it's a piece of new code which we want to test during some benchmark runs.

So for prod code, we'll remove this. I'm personally pretty fine with believing that this will never happen, but if you want it for test-runs, then sure, we can keep it for a while

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep this panic for running a sync or just drop it now? I am fine either way. Should a comment be kept once the code is dropped?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@holiman please give some advice on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO drop it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM aside from some nitpicks

core/vm/instructions.go Outdated Show resolved Hide resolved
core/vm/instructions.go Outdated Show resolved Hide resolved
@@ -124,6 +124,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// Make sure the readOnly is only set if we aren't in readOnly yet.
// This also makes sure that the readOnly flag isn't removed for child calls.
if readOnly && !in.readOnly {
if !in.evm.chainRules.IsByzantium {
panic("readOnly execution requested on wrong chainRules");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave this here if we want to do a test-run, but I think we should remove it from production code.
I'd also be fine with not having the panic here at all.

@holiman
Copy link
Contributor

holiman commented Nov 25, 2021

>>> build/cache/golangci-lint-1.42.0-linux-amd64/golangci-lint run --config .golangci.yml ./...
core/vm/interpreter.go:128: File is not `goimports`-ed (goimports)
			panic("readOnly execution requested on wrong chainRules");

There's not a lot of ;-usage in golang :)

@@ -204,17 +207,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
} else if sLen > operation.maxStack {
return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack}
}
// If the operation is valid, enforce write restrictions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is changing the order of operations a bit. Like one concrete change is the tracer's CaptureState will be called even on failure. Also memory will be resized, but I guess that's moot since the error will cause the call frame to fail. Another possibility is EVM returning a different error message if there are multiple failures (i.e. readonly violation AND not enough gas for memory expansion)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, this is one of my concerns, see the discussion on #23968. The order of evaluation for the most part is not covered by state tests, but in the long term I would hope it will be covered.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right missed that convo. Maybe time to revive the "trace after op execution" discussion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order of evaluation for the most part is not covered by state tests

It's not so much that it isn't covered -- the fact is that the order is opaque to state tests, in nearly all situations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had ideated to expose error codes from execution and include those in the state tests. That would be a way to ensure some common order.

@axic axic marked this pull request as ready for review November 25, 2021 12:13
core/vm/instructions.go Outdated Show resolved Hide resolved
Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM aside from a new nitpicks

if interpreter.readOnly {
return nil, ErrWriteProtection
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove empty line. I've learnt (the hard way) that the golang purists on the team disapprove of empty lines after a closing bracket, with the reasoning that the bracket is enough of a divider.

Unless the empty line precedes a comment, in which case it might be ok, because it gives the comment more spotlight.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case, opCreate I think doesn't really follows the rules you mention, as it does have empty lines in seemingly irregular places. I'll remove the empty line as you suggested though.

core/vm/instructions.go Outdated Show resolved Hide resolved
core/vm/instructions.go Outdated Show resolved Hide resolved
core/vm/instructions.go Outdated Show resolved Hide resolved
core/vm/instructions.go Outdated Show resolved Hide resolved
core/vm/instructions.go Outdated Show resolved Hide resolved
core/vm/instructions.go Outdated Show resolved Hide resolved
@axic
Copy link
Member Author

axic commented Nov 25, 2021

Removed the empty lines, I hope to have removed the correct ones 😅

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@holiman
Copy link
Contributor

holiman commented Nov 26, 2021

{"pc":0,"op":96,"gas":"0x989680","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":2,"op":96,"gas":"0x98967d","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":4,"op":96,"gas":"0x98967a","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":6,"op":96,"gas":"0x989677","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":8,"op":97,"gas":"0x989674","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH2","error":""}
{"pc":11,"op":90,"gas":"0x989671","gasCost":"0x2","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0xff0b"],"returnData":"0x","depth":1,"refund":0,"opName":"GAS","error":""}
{"pc":12,"op":250,"gas":"0x98966f","gasCost":"0x963421","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0xff0b","0x98966f"],"returnData":"0x","depth":1,"refund":0,"opName":"STATICCALL","error":""}
{"pc":0,"op":96,"gas":"0x963165","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnData":"0x","depth":2,"refund":0,"opName":"PUSH1","error":""}
{"pc":2,"op":96,"gas":"0x963162","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"PUSH1","error":""}
{"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":"write protection"}
{"pc":13,"op":0,"gas":"0x2624e","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"STOP","error":""}

After

{"pc":0,"op":96,"gas":"0x989680","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":2,"op":96,"gas":"0x98967d","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":4,"op":96,"gas":"0x98967a","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":6,"op":96,"gas":"0x989677","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
{"pc":8,"op":97,"gas":"0x989674","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH2","error":""}
{"pc":11,"op":90,"gas":"0x989671","gasCost":"0x2","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0xff0b"],"returnData":"0x","depth":1,"refund":0,"opName":"GAS","error":""}
{"pc":12,"op":250,"gas":"0x98966f","gasCost":"0x963421","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0xff0b","0x98966f"],"returnData":"0x","depth":1,"refund":0,"opName":"STATICCALL","error":""}
{"pc":0,"op":96,"gas":"0x963165","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnData":"0x","depth":2,"refund":0,"opName":"PUSH1","error":""}
{"pc":2,"op":96,"gas":"0x963162","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"PUSH1","error":""}
{"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x4e20","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":""}
{"pc":13,"op":0,"gas":"0x2624e","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0x0"],"returnData":"0x","depth":1,"refund":0,"opName":"STOP","error":""}

Diff:

< {"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":"write protection"}
---
> {"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x4e20","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":""}

This may indeed be a bit problematic for the fuzzers to handle, since the error is never surfaced. I'll think about this a bit

@holiman
Copy link
Contributor

holiman commented Nov 26, 2021

Ah, actually, the error is still sent to the logger, but the jsonlogger does not output it. So maybe we can fix it there, to give the fuzzers a better chance of handling this

@holiman
Copy link
Contributor

holiman commented Nov 26, 2021

If we add this

diff --git a/core/vm/logger_json.go b/core/vm/logger_json.go
index 364ce738a0..fac1c42dc8 100644
--- a/core/vm/logger_json.go
+++ b/core/vm/logger_json.go
@@ -46,7 +46,10 @@ func (l *JSONLogger) CaptureStart(env *EVM, from, to common.Address, create bool
 	l.env = env
 }
 
-func (l *JSONLogger) CaptureFault(uint64, OpCode, uint64, uint64, *ScopeContext, int, error) {}
+func (l *JSONLogger) CaptureFault(pc uint64, op OpCode,gas, cos uint64,scope  *ScopeContext, depth int, err error) {
+	// TODO: Add rData to this interface aswell
+	l.CaptureState(pc, op, gas, cos, scope, nil, depth,err)
+}
 
 // CaptureState outputs state information on the logger.
 func (l *JSONLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {

Then the result is

< {"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":"write protection"}
---
> {"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x4e20","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":""}
> {"pc":4,"op":85,"gas":"0x96315f","gasCost":"0x4e20","memory":"0x","memSize":0,"stack":["0x1","0x1"],"returnData":"0x","depth":2,"refund":0,"opName":"SSTORE","error":"write protection"}

@MariusVanDerWijden we should be able to work with that, right? If the same 'pc' appears twice in a row, we can just ignore the first one.

@axic
Copy link
Member Author

axic commented Nov 26, 2021

The gas discrepancy is still there, I wonder what gas value evmone outputs in most of these cases @chfast?

@holiman
Copy link
Contributor

holiman commented Nov 26, 2021

Yes, but the discrepancy is such that it was previously wrong, using the previous value on error returns. And now it's more correct is all. I think we just didn't look too closely at the gas value whenever errors were involved.

@chfast
Copy link
Contributor

chfast commented Nov 26, 2021

The gas discrepancy is still there, I wonder what gas value evmone outputs in most of these cases @chfast?

I don't output "gasCost" at all because I don't know it. The tracing spec requires to report "gasCost" before execution of an instruction and in evmone gas cost computation and execution are mixed up.

@gumb0
Copy link
Member

gumb0 commented Nov 26, 2021

I'm getting these results from running evmone benchmarks with this against master.

name                                  old time/op  new time/op  delta
main/blake2b_shifts/2805nulls         15.9ms ± 1%  17.6ms ±15%    ~     (p=0.356 n=9+10)
main/blake2b_shifts/5610nulls         31.8ms ± 1%  30.7ms ± 1%  -3.22%  (p=0.000 n=10+10)
main/blake2b_shifts/8415nulls         51.3ms ± 7%  50.0ms ± 9%    ~     (p=0.247 n=10+10)
main/weierstrudel/0                    515µs ± 1%   496µs ± 0%  -3.71%  (p=0.000 n=10+10)
main/weierstrudel/1                   1.10ms ± 0%  1.07ms ± 0%  -3.12%  (p=0.000 n=10+10)
main/weierstrudel/3                   1.72ms ± 1%  1.66ms ± 1%  -3.81%  (p=0.000 n=10+10)
main/weierstrudel/9                   3.56ms ± 0%  3.39ms ± 1%  -4.73%  (p=0.000 n=9+9)
main/weierstrudel/14                  5.06ms ± 0%  4.81ms ± 0%  -5.01%  (p=0.000 n=9+9)
main/sha1_divs/empty                   239µs ± 0%   240µs ± 0%  +0.21%  (p=0.019 n=9+9)
main/sha1_divs/1351                   4.74ms ± 1%  4.71ms ± 1%  -0.76%  (p=0.000 n=10+9)
main/sha1_divs/2737                   9.21ms ± 1%  9.14ms ± 0%  -0.82%  (p=0.000 n=9+7)
main/sha1_divs/5311                   18.0ms ± 0%  17.9ms ± 1%  -0.63%  (p=0.001 n=7+10)
main/sha1_shifts/empty                 191µs ± 1%   181µs ± 0%  -4.82%  (p=0.000 n=9+10)
main/sha1_shifts/1351                 3.78ms ± 0%  3.60ms ± 1%  -4.91%  (p=0.000 n=10+10)
main/sha1_shifts/2737                 7.36ms ± 1%  7.00ms ± 1%  -4.82%  (p=0.000 n=9+9)
main/sha1_shifts/5311                 14.4ms ± 1%  13.7ms ± 0%  -4.73%  (p=0.000 n=9+8)
main/blake2b_huff/empty                116µs ± 1%   112µs ± 1%  -3.08%  (p=0.000 n=10+10)
main/blake2b_huff/2805nulls           2.16ms ± 0%  2.10ms ± 1%  -2.85%  (p=0.000 n=9+8)
main/blake2b_huff/5610nulls           4.17ms ± 0%  4.04ms ± 0%  -3.27%  (p=0.000 n=9+9)
main/blake2b_huff/8415nulls           6.09ms ± 0%  5.92ms ± 2%  -2.77%  (p=0.000 n=9+10)
micro/JUMPDEST_n0/empty               3.31ms ± 2%  3.17ms ± 0%  -4.20%  (p=0.000 n=10+10)
micro/jump_around/empty                163µs ± 0%   157µs ± 0%  -3.44%  (p=0.000 n=10+9)
micro/memory_grow_mstore/nogrow        483µs ± 1%   480µs ± 0%  -0.64%  (p=0.000 n=10+9)
micro/memory_grow_mstore/by1           493µs ± 1%   492µs ± 1%    ~     (p=0.247 n=10+10)
micro/memory_grow_mstore/by16          601µs ± 2%   607µs ± 1%  +0.95%  (p=0.027 n=10+8)
micro/memory_grow_mstore/by32          691µs ± 1%   693µs ± 1%    ~     (p=0.481 n=10+10)
micro/signextend/zero                  493µs ± 0%   488µs ± 1%  -0.87%  (p=0.000 n=9+9)
micro/signextend/one                   510µs ± 4%   495µs ± 0%  -2.84%  (p=0.000 n=10+10)
micro/loop_with_many_jumpdests/empty  3.83µs ± 3%  3.80µs ± 1%    ~     (p=0.530 n=9+9)
micro/memory_grow_mload/nogrow         249µs ± 1%   246µs ± 1%  -1.26%  (p=0.000 n=10+10)
micro/memory_grow_mload/by1            259µs ± 1%   255µs ± 1%  -1.41%  (p=0.000 n=10+10)
micro/memory_grow_mload/by16           343µs ± 1%   343µs ± 3%    ~     (p=0.579 n=10+10)
micro/memory_grow_mload/by32           448µs ± 0%   446µs ± 1%  -0.48%  (p=0.002 n=9+8)
[Geo mean]                            1.35ms       1.33ms       -1.97%

name                                  old gas/s    new gas/s    delta
main/blake2b_shifts/2805nulls           215M ± 1%    197M ±14%    ~     (p=0.356 n=9+10)
main/blake2b_shifts/5610nulls           234M ± 1%    242M ± 1%  +3.33%  (p=0.000 n=10+10)
main/blake2b_shifts/8415nulls           236M ± 7%    242M ±10%    ~     (p=0.247 n=10+10)
main/weierstrudel/0                    92.3M ± 1%   95.9M ± 0%  +3.86%  (p=0.000 n=10+10)
main/weierstrudel/1                     118M ± 0%    122M ± 0%  +3.22%  (p=0.000 n=10+10)
main/weierstrudel/3                     117M ± 1%    122M ± 1%  +3.96%  (p=0.000 n=10+10)
main/weierstrudel/9                     117M ± 0%    123M ± 1%  +4.97%  (p=0.000 n=9+9)
main/weierstrudel/14                    118M ± 0%    124M ± 0%  +5.27%  (p=0.000 n=9+9)
main/sha1_divs/empty                    152M ± 0%    152M ± 0%  -0.21%  (p=0.019 n=9+9)
main/sha1_divs/1351                     166M ± 1%    167M ± 1%  +0.76%  (p=0.000 n=10+9)
main/sha1_divs/2737                     167M ± 1%    168M ± 0%  +0.83%  (p=0.000 n=9+7)
main/sha1_divs/5311                     166M ± 0%    168M ± 1%  +0.64%  (p=0.001 n=7+10)
main/sha1_shifts/empty                  185M ± 1%    194M ± 0%  +5.06%  (p=0.000 n=9+10)
main/sha1_shifts/1351                   201M ± 0%    211M ± 1%  +5.16%  (p=0.000 n=10+10)
main/sha1_shifts/2737                   202M ± 1%    212M ± 1%  +5.07%  (p=0.000 n=9+9)
main/sha1_shifts/5311                   202M ± 1%    212M ± 0%  +4.96%  (p=0.000 n=9+8)
main/blake2b_huff/empty                 121M ± 1%    124M ± 1%  +3.18%  (p=0.000 n=10+10)
main/blake2b_huff/2805nulls             142M ± 0%    146M ± 1%  +2.93%  (p=0.000 n=9+8)
main/blake2b_huff/5610nulls             144M ± 0%    149M ± 0%  +3.38%  (p=0.000 n=9+9)
main/blake2b_huff/8415nulls             145M ± 0%    149M ± 2%  +2.85%  (p=0.000 n=9+10)
micro/JUMPDEST_n0/empty                 160M ± 2%    167M ± 0%  +4.37%  (p=0.000 n=10+10)
micro/jump_around/empty                 302M ± 0%    312M ± 0%  +3.56%  (p=0.000 n=10+9)
micro/memory_grow_mstore/nogrow         127M ± 1%    128M ± 0%  +0.64%  (p=0.000 n=10+9)
micro/memory_grow_mstore/by1            125M ± 1%    126M ± 1%    ~     (p=0.247 n=10+10)
micro/memory_grow_mstore/by16           126M ± 2%    125M ± 1%  -0.94%  (p=0.027 n=10+8)
micro/memory_grow_mstore/by32           154M ± 1%    154M ± 1%    ~     (p=0.481 n=10+10)
micro/signextend/zero                   195M ± 0%    197M ± 1%  +0.88%  (p=0.000 n=9+9)
micro/signextend/one                    188M ± 4%    194M ± 0%  +2.88%  (p=0.000 n=10+10)
micro/loop_with_many_jumpdests/empty   8.36M ± 3%   8.41M ± 1%    ~     (p=0.530 n=9+9)
micro/memory_grow_mload/nogrow          230M ± 1%    233M ± 1%  +1.28%  (p=0.000 n=10+10)
micro/memory_grow_mload/by1             223M ± 1%    226M ± 1%  +1.42%  (p=0.000 n=10+10)
micro/memory_grow_mload/by16            209M ± 1%    209M ± 3%    ~     (p=0.579 n=10+10)
micro/memory_grow_mload/by32            229M ± 0%    230M ± 1%  +0.48%  (p=0.002 n=9+8)
[Geo mean]                              151M         155M       +2.05%

@chfast
Copy link
Contributor

chfast commented Nov 26, 2021

My benchmarks on a desktop CPU.

name                                  old time/op  new time/op  delta                                                                                                                                                             
micro/memory_grow_mload/nogrow         249µs ± 1%   245µs ± 1%  -1.70%  (p=0.000 n=20+20)                                                                                                                                         
micro/memory_grow_mload/by1            257µs ± 1%   254µs ± 1%  -1.02%  (p=0.000 n=20+19)                                                                                                                                         
micro/memory_grow_mload/by16           321µs ± 1%   320µs ± 1%  -0.32%  (p=0.001 n=20+20)                                                                                                                                         
micro/memory_grow_mload/by32           398µs ± 1%   399µs ± 1%    ~     (p=0.142 n=20+20)                                                                                                                                         
micro/signextend/zero                  462µs ± 1%   457µs ± 1%  -0.97%  (p=0.000 n=20+20)                                                                                                                                         
micro/signextend/one                   474µs ± 1%   471µs ± 1%  -0.73%  (p=0.000 n=20+20)                                                                                                                                         
micro/loop_with_many_jumpdests/empty  3.40µs ± 2%  3.40µs ± 1%    ~     (p=0.934 n=20+17)                                                                                                                                         
micro/jump_around/empty                154µs ± 1%   152µs ± 1%  -1.35%  (p=0.000 n=20+20)                                                                                                                                         
micro/memory_grow_mstore/nogrow        485µs ± 0%   483µs ± 1%  -0.51%  (p=0.000 n=19+20)                                                                                                                                         
micro/memory_grow_mstore/by1           494µs ± 1%   492µs ± 1%  -0.36%  (p=0.000 n=19+20)                                                                                                                                         
micro/memory_grow_mstore/by16          574µs ± 1%   576µs ± 0%  +0.38%  (p=0.000 n=20+20)                                                                                                                                         
micro/memory_grow_mstore/by32          644µs ± 0%   646µs ± 0%  +0.33%  (p=0.000 n=20+20)                                                                                                                                         
micro/JUMPDEST_n0/empty               3.45ms ± 1%  3.49ms ± 0%  +1.35%  (p=0.000 n=19+20)                                                                                                                                         
main/sha1_divs/empty                   222µs ± 0%   221µs ± 0%  -0.74%  (p=0.000 n=20+19)                                                                                                                                         
main/sha1_divs/1351                   4.49ms ± 0%  4.47ms ± 1%  -0.56%  (p=0.000 n=19+20)
main/sha1_divs/2737                   8.73ms ± 0%  8.65ms ± 1%  -0.88%  (p=0.000 n=19+20)
main/sha1_divs/5311                   17.1ms ± 0%  16.9ms ± 0%  -0.95%  (p=0.000 n=18+19)
main/weierstrudel/0                    492µs ± 0%   486µs ± 0%  -1.28%  (p=0.000 n=19+20)
main/weierstrudel/1                   1.04ms ± 0%  1.03ms ± 0%  -0.97%  (p=0.000 n=19+20)
main/weierstrudel/3                   1.64ms ± 0%  1.61ms ± 1%  -1.69%  (p=0.000 n=19+20)
main/weierstrudel/9                   3.41ms ± 1%  3.32ms ± 1%  -2.83%  (p=0.000 n=19+20)
main/weierstrudel/14                  4.88ms ± 1%  4.73ms ± 1%  -3.06%  (p=0.000 n=20+19)
main/sha1_shifts/empty                 176µs ± 1%   179µs ± 1%  +1.68%  (p=0.000 n=20+19)
main/sha1_shifts/1351                 3.60ms ± 0%  3.67ms ± 0%  +1.89%  (p=0.000 n=18+20)
main/sha1_shifts/2737                 7.01ms ± 0%  7.15ms ± 1%  +2.02%  (p=0.000 n=19+20)
main/sha1_shifts/5311                 13.7ms ± 1%  14.0ms ± 1%  +2.38%  (p=0.000 n=20+19)
main/blake2b_huff/empty                109µs ± 0%   108µs ± 1%  -0.82%  (p=0.000 n=20+20)
main/blake2b_huff/2805nulls           2.08ms ± 0%  2.05ms ± 0%  -1.50%  (p=0.000 n=18+20)
main/blake2b_huff/5610nulls           4.04ms ± 0%  3.98ms ± 0%  -1.64%  (p=0.000 n=20+19)
main/blake2b_huff/8415nulls           5.90ms ± 0%  5.81ms ± 0%  -1.42%  (p=0.000 n=19+17)
main/blake2b_shifts/2805nulls         16.6ms ± 1%  16.4ms ± 1%  -1.00%  (p=0.000 n=18+19)
main/blake2b_shifts/5610nulls         33.1ms ± 1%  32.8ms ± 1%  -1.10%  (p=0.000 n=20+20)
main/blake2b_shifts/8415nulls         49.3ms ± 1%  48.7ms ± 1%  -1.13%  (p=0.000 n=19+19)
[Geo mean]                            1.30ms       1.29ms       -0.56%

@holiman
Copy link
Contributor

holiman commented Nov 27, 2021

@axic can you add the diff above to this PR? You might have to rebase, because I think Sina recently moved the loggers a different location.

@axic
Copy link
Member Author

axic commented Nov 27, 2021

@axic can you add the diff above to this PR? You might have to rebase, because I think Sina recently moved the loggers a different location.

@holiman After the refactoring from @s1na I see the implementation in eth/tracers/logger/logger_json.go. Do any of the other tracers need to be updated?

@holiman
Copy link
Contributor

holiman commented Nov 29, 2021

Do any of the other tracers need to be updated?

Not for the fuzzing engines. Not sure about other usecases -- I guess we can change that later if we have to

@axic
Copy link
Member Author

axic commented Nov 29, 2021

Added the tracer change and rebased.

@holiman
Copy link
Contributor

holiman commented Nov 29, 2021

Sorry, needs another rebase now

@axic
Copy link
Member Author

axic commented Nov 29, 2021

@holiman rebased!

@chfast
Copy link
Contributor

chfast commented Nov 29, 2021

I will benchmark it after #23952.

@chfast
Copy link
Contributor

chfast commented Nov 29, 2021

New benchmarks after #23952 is merged.

name                                  old time/op  new time/op  delta                                                                                                                                                             
micro/memory_grow_mload/nogrow         237µs ± 1%   232µs ± 0%  -2.14%  (p=0.000 n=20+18)                                                                                                                                         
micro/memory_grow_mload/by1            245µs ± 1%   241µs ± 1%  -1.90%  (p=0.000 n=20+20)                                                                                                                                         
micro/memory_grow_mload/by16           310µs ± 0%   305µs ± 0%  -1.65%  (p=0.000 n=20+20)                                                                                                                                         
micro/memory_grow_mload/by32           388µs ± 0%   384µs ± 1%  -0.81%  (p=0.000 n=18+20)                                                                                                                                         
micro/signextend/zero                  444µs ± 1%   405µs ± 1%  -8.76%  (p=0.000 n=20+19)                                                                                                                                         
micro/signextend/one                   456µs ± 1%   417µs ± 0%  -8.45%  (p=0.000 n=20+19)                                                                                                                                         
micro/loop_with_many_jumpdests/empty  3.41µs ± 2%  3.40µs ± 1%    ~     (p=0.425 n=20+20)                                                                                                                                         
micro/jump_around/empty                149µs ± 1%   146µs ± 1%  -1.78%  (p=0.000 n=18+20)                                                                                                                                         
micro/memory_grow_mstore/nogrow        474µs ± 1%   467µs ± 1%  -1.53%  (p=0.000 n=20+20)                                                                                                                                         
micro/memory_grow_mstore/by1           483µs ± 1%   475µs ± 1%  -1.59%  (p=0.000 n=20+19)                                                                                                                                         
micro/memory_grow_mstore/by16          565µs ± 1%   557µs ± 0%  -1.41%  (p=0.000 n=20+19)                                                                                                                                         
micro/memory_grow_mstore/by32          636µs ± 1%   629µs ± 0%  -1.20%  (p=0.000 n=20+20)                                                                                                                                         
micro/JUMPDEST_n0/empty               3.13ms ± 0%  3.02ms ± 0%  -3.71%  (p=0.000 n=17+17)                                                                                                                                         
main/sha1_divs/empty                   207µs ± 0%   201µs ± 0%  -3.13%  (p=0.000 n=19+18)                                                                                                                                         
main/sha1_divs/1351                   4.16ms ± 0%  4.02ms ± 1%  -3.29%  (p=0.000 n=16+20)
main/sha1_divs/2737                   8.10ms ± 1%  7.82ms ± 1%  -3.44%  (p=0.000 n=19+18)
main/sha1_divs/5311                   15.8ms ± 1%  15.3ms ± 1%  -3.36%  (p=0.000 n=20+20)
main/weierstrudel/0                    473µs ± 0%   474µs ± 0%  +0.26%  (p=0.000 n=20+19)
main/weierstrudel/1                    987µs ± 0%   981µs ± 0%  -0.69%  (p=0.000 n=17+18)
main/weierstrudel/3                   1.55ms ± 1%  1.54ms ± 1%  -0.49%  (p=0.000 n=20+20)
main/weierstrudel/9                   3.19ms ± 1%  3.19ms ± 0%    ~     (p=0.443 n=18+20)
main/weierstrudel/14                  4.56ms ± 1%  4.55ms ± 1%    ~     (p=0.072 n=18+20)
main/sha1_shifts/empty                 162µs ± 1%   157µs ± 0%  -3.19%  (p=0.000 n=20+19)
main/sha1_shifts/1351                 3.26ms ± 0%  3.19ms ± 0%  -2.19%  (p=0.000 n=18+20)
main/sha1_shifts/2737                 6.36ms ± 0%  6.21ms ± 0%  -2.29%  (p=0.000 n=16+19)
main/sha1_shifts/5311                 12.4ms ± 1%  12.1ms ± 0%  -2.47%  (p=0.000 n=19+19)
main/blake2b_huff/empty                106µs ± 0%   104µs ± 0%  -1.91%  (p=0.000 n=19+18)
main/blake2b_huff/2805nulls           2.00ms ± 1%  1.96ms ± 1%  -2.08%  (p=0.000 n=20+20)
main/blake2b_huff/5610nulls           3.88ms ± 0%  3.79ms ± 1%  -2.30%  (p=0.000 n=18+18)
main/blake2b_huff/8415nulls           5.67ms ± 0%  5.55ms ± 0%  -2.13%  (p=0.000 n=19+18)
main/blake2b_shifts/2805nulls         15.7ms ± 0%  14.8ms ± 1%  -5.68%  (p=0.000 n=17+20)
main/blake2b_shifts/5610nulls         31.2ms ± 1%  29.5ms ± 1%  -5.63%  (p=0.000 n=20+20)
main/blake2b_shifts/8415nulls         46.5ms ± 1%  43.8ms ± 1%  -5.93%  (p=0.000 n=20+19)
[Geo mean]                            1.23ms       1.20ms       -2.60%

@holiman
Copy link
Contributor

holiman commented Nov 30, 2021

Not for the fuzzing engines. Not sure about other usecases -- I guess we can change that later if we have to

As @s1na pointed out during triage., this will most certainly affect the js legacy calltracer. The extra captureState("CALL"... will invoke

			this.callstack.push(call);
			this.descended = true

Then it will immediately ( on the second one, error-invocation) pop off the call again. However, it will still wind up one level too high.

Previous:

  • At depth 1
  • STATICCALL, depth 1
    • depth 2, CALL with value -> error
    • drop back
  • depth 1, continue here

Now:

  • At depth 1
  • STATICCALL, depth 1
    • depth 2, CALL with value -> error
      • depth 3, error
      • drop back
    • depth 2, continue here

This is somewhat fine -- the legacy calltracer is deprecated in favour of the scope-based calltracer. However, this might also cause problems for custom tracers. I kind of think that's fine too, but we should make a note of that in release notes.

@s1na
Copy link
Contributor

s1na commented Nov 30, 2021

I think this should fix it but haven't tested it yet:

diff --git a/eth/tracers/js/internal/tracers/call_tracer_legacy.js b/eth/tracers/js/internal/tracers/call_tracer_legacy.js
index 3ca737773..f3a756ecd 100644
--- a/eth/tracers/js/internal/tracers/call_tracer_legacy.js
+++ b/eth/tracers/js/internal/tracers/call_tracer_legacy.js
@@ -167,6 +167,19 @@
                if (this.callstack[this.callstack.length - 1].error !== undefined) {
                        return;
                }
+    // The write protection error "cancels" the last
+    // step event. We need to drop the extra calls
+    // that were potentially created and reset `descended`.
+    if (log.getError() === 'write protection') {
+        var op = log.op.toString();
+        // Pop the extra call
+        if (op === 'SELFDESTRUCT') {
+            this.callstack.pop();
+        } else if (op === 'CREATE' || op === 'CREATE2' || op === 'CALL') {
+            this.callstack.pop();
+            this.descended = false;
+        }
+    }
                // Pop off the just failed call
                var call = this.callstack.pop();
                call.error = log.getError();

@holiman holiman merged commit 9393d1f into ethereum:master Dec 1, 2021
@holiman holiman deleted the evm-readonly branch December 1, 2021 09:21
@holiman holiman added this to the 1.10.14 milestone Dec 1, 2021
JacekGlen pushed a commit to JacekGlen/go-ethereum that referenced this pull request May 26, 2022
…ons (ethereum#23970)

* core/vm: Move interpreter.ReadOnly check into the opcode implementations

Also remove the same check from the interpreter inner loop.

* core/vm: Remove obsolete operation.writes flag

* core/vm: Capture fault states in logger

Co-authored-by: Martin Holst Swende <martin@swende.se>

* core/vm: Remove panic added for testing

Co-authored-by: Martin Holst Swende <martin@swende.se>
yperbasis added a commit to ledgerwatch/erigon that referenced this pull request Dec 21, 2022
…ons (#6396)

Cherry-pick ethereum/go-ethereum#23970

Co-authored-by: Alex Beregszaszi <alex@rtfs.hu>
Co-authored-by: Martin Holst Swende <martin@swende.se>
gzliudan pushed a commit to gzliudan/XDPoSChain that referenced this pull request Feb 27, 2024
…ons (ethereum#23970)

* core/vm: Move interpreter.ReadOnly check into the opcode implementations

Also remove the same check from the interpreter inner loop.

* core/vm: Remove obsolete operation.writes flag

* core/vm: Capture fault states in logger

Co-authored-by: Martin Holst Swende <martin@swende.se>

* core/vm: Remove panic added for testing

Co-authored-by: Martin Holst Swende <martin@swende.se>
gzliudan pushed a commit to gzliudan/XDPoSChain that referenced this pull request Feb 27, 2024
…ons (ethereum#23970)

* core/vm: Move interpreter.ReadOnly check into the opcode implementations

Also remove the same check from the interpreter inner loop.

* core/vm: Remove obsolete operation.writes flag

* core/vm: Capture fault states in logger

Co-authored-by: Martin Holst Swende <martin@swende.se>

* core/vm: Remove panic added for testing

Co-authored-by: Martin Holst Swende <martin@swende.se>
gzliudan pushed a commit to gzliudan/XDPoSChain that referenced this pull request Mar 1, 2024
…ons (ethereum#23970)

* core/vm: Move interpreter.ReadOnly check into the opcode implementations

Also remove the same check from the interpreter inner loop.

* core/vm: Remove obsolete operation.writes flag

* core/vm: Capture fault states in logger

Co-authored-by: Martin Holst Swende <martin@swende.se>

* core/vm: Remove panic added for testing

Co-authored-by: Martin Holst Swende <martin@swende.se>
gzliudan pushed a commit to gzliudan/XDPoSChain that referenced this pull request Mar 1, 2024
…ons (ethereum#23970)

* core/vm: Move interpreter.ReadOnly check into the opcode implementations

Also remove the same check from the interpreter inner loop.

* core/vm: Remove obsolete operation.writes flag

* core/vm: Capture fault states in logger

Co-authored-by: Martin Holst Swende <martin@swende.se>

* core/vm: Remove panic added for testing

Co-authored-by: Martin Holst Swende <martin@swende.se>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

core/vm: Better handling of static mode violation (ErrWriteProtection)
6 participants