holiman / goevmlab

Evm laboratory
GNU Lesser General Public License v3.0
241 stars 43 forks source link

Blockhash difference in state tests #17

Open MariusVanDerWijden opened 4 years ago

MariusVanDerWijden commented 4 years ago

So basically Geth, Besu and OE all return 0x0 on BLOCKHASH(0x831fc01b15af74fc30c) while Nethermind returns Keccak(0x831fc01b15af74fc30c).

Netherminds Blockhash provider: https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs

The state test documentation also states that " Since the data of the blockchain is not given, the opcode BLOCKHASH could not return the hashes of the corresponding blocks. Therefore we define the hash of block number n to be SHA256("n")." https://www.ethdocs.org/en/latest/contracts-and-transactions/ethereum-tests/state_tests/index.html (first paragraph)

Geth replaces the function correctly in state tests (https://github.com/ethereum/go-ethereum/blob/71c37d82adaa2b69ea98ce0c5505489d6b711c1e/tests/vm_test_util.go#L157) but I think it is not patched in the evm binary.

Test ``` { "nethermind-caller": { "env": { "currentCoinbase": "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "currentDifficulty": "0x20000", "currentGasLimit": "0x26e1f476fe1e22", "currentNumber": "0x1", "currentTimestamp": "0x3e8", "previousHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, "pre": { "0x00000000000000000000000000000000000000aa": { "code": "0x6000600060006000600060bb612d28f1", "storage": {}, "balance": "0x5", "nonce": "0x0" }, "0x00000000000000000000000000000000000000bb": { "code": "0x690831fc01b15af74fc30c40805260006000f3", "storage": {}, "balance": "0x5", "nonce": "0x0" }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "code": "0x", "storage": {}, "balance": "0xffffffff", "nonce": "0x0" } }, "transaction": { "gasPrice": "0x1", "nonce": "0x0", "to": "0x00000000000000000000000000000000000000AA", "data": [ "0x" ], "gasLimit": [ "0x7a1200" ], "value": [ "0x01" ], "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" }, "out": "0x", "post": { "Istanbul": [ { "hash": "0000000000000000000000000000000000000000000000000000000000000000", "logs": "0000000000000000000000000000000000000000000000000000000000000000", "indexes": { "data": 0, "gas": 0, "value": 0 } } ] } } } ```
Geth output Geth: ``` ~/go/src/github.com/ethereum/go-ethereum/build/bin/evm --json --nomemory statetest test.json {"pc":0,"op":96,"gas":"0x79bff8","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":2,"op":96,"gas":"0x79bff5","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":4,"op":96,"gas":"0x79bff2","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":6,"op":96,"gas":"0x79bfef","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":8,"op":96,"gas":"0x79bfec","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":10,"op":96,"gas":"0x79bfe9","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":12,"op":97,"gas":"0x79bfe6","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH2","error":""} {"pc":15,"op":241,"gas":"0x79bfe3","gasCost":"0x2fe4","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb","0x2d28"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"CALL","error":""} {"pc":0,"op":105,"gas":"0x2d28","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH10","error":""} {"pc":11,"op":64,"gas":"0x2d25","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x831fc01b15af74fc30c"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"BLOCKHASH","error":""} {"pc":12,"op":128,"gas":"0x2d11","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"DUP1","error":""} {"pc":13,"op":82,"gas":"0x2d0e","gasCost":"0x6","memory":"0x","memSize":32,"stack":["0x0","0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"MSTORE","error":""} {"pc":14,"op":96,"gas":"0x2d08","gasCost":"0x3","memory":"0x","memSize":32,"stack":[],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH1","error":""} {"pc":16,"op":96,"gas":"0x2d05","gasCost":"0x3","memory":"0x","memSize":32,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH1","error":""} {"pc":18,"op":243,"gas":"0x2d02","gasCost":"0x0","memory":"0x","memSize":32,"stack":["0x0","0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"RETURN","error":""} {"pc":16,"op":0,"gas":"0x79bd01","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0x1"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"STOP","error":""} {"output":"","gasUsed":"0x2f7","time":234049} {"stateRoot": "aeadb62508a708210e49bbde6840e63ea913fa65b566dd7fc3bf26157a5ee44f"} [ { "name": "nethermind-caller", "pass": false, "fork": "Istanbul", "error": "post state root mismatch: got aeadb62508a708210e49bbde6840e63ea913fa65b566dd7fc3bf26157a5ee44f, want 0000000000000000000000000000000000000000000000000000000000000000" } ] ```
Nethermind output Nethermind: ``` ~/ethereum/nethermind/nethtest -i test.json {"pc":0,"op":96,"gas":"0x79bff8","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":2,"op":96,"gas":"0x79bff5","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":4,"op":96,"gas":"0x79bff2","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":6,"op":96,"gas":"0x79bfef","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":8,"op":96,"gas":"0x79bfec","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":10,"op":96,"gas":"0x79bfe9","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":12,"op":97,"gas":"0x79bfe6","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb"],"depth":1,"refund":0,"opname":"PUSH2","error":""} {"pc":15,"op":241,"gas":"0x79bfe3","gasCost":"0x2fe4","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb","0x2d28"],"depth":1,"refund":0,"opname":"CALL","error":""} {"pc":0,"op":105,"gas":"0x2d28","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"depth":2,"refund":0,"opname":"PUSH10","error":""} {"pc":11,"op":64,"gas":"0x2d25","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x831fc01b15af74fc30c"],"depth":2,"refund":0,"opname":"BLOCKHASH","error":""} {"pc":12,"op":128,"gas":"0x2d11","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0xc23afaf993bef633220c94fba7cf577103b120a2701d597660dfbab0720a8ab4"],"depth":2,"refund":0,"opname":"DUP1","error":""} {"pc":13,"op":82,"gas":"0x2d0e","gasCost":"0x2d0e","memory":"0x","memSize":0,"stack":["0xc23afaf993bef633220c94fba7cf577103b120a2701d597660dfbab0720a8ab4","0xc23afaf993bef633220c94fba7cf577103b120a2701d597660dfbab0720a8ab4"],"depth":2,"refund":0,"opname":"MSTORE","error":"gas uint64 overflow"} {"output":"0x","gasUsed":"0x2ff9","time":3} {"stateRoot":"0xde9086cdde32b9293313af622ef8553330f85a7a955a4e4a5a7413c25ccf1c19"} [ { "name": "nethermind-caller_d0g0v0", "pass": false, "fork": "Istanbul" } ] ```
holiman commented 4 years ago

Geth replaces the function correctly in state tests (https://github.com/ethereum/go-ethereum/blob/71c37d82adaa2b69ea98ce0c5505489d6b711c1e/tests/vm_test_util.go#L157) but I think it is not patched in the evm binary.

Nope, that's not statetests, it's for VM-tests.

holiman commented 4 years ago

But let's try to properly change it for statestests too, and see if the tests still pass

holiman commented 1 year ago
{"pc":0,"op":96,"gas":"0x130daf8","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":2,"op":96,"gas":"0x130daf5","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":4,"op":64,"gas":"0x130daf2","gasCost":"0x14","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"BLOCKHASH"}
Requested blockhash 0. Scope for blockhash: 0 - 1
vmTestBlockHash(0)
{"pc":5,"op":85,"gas":"0x130dade","gasCost":"0x320","memSize":0,"stack":["0x0","0x44852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"],"depth":1,"refund":0,"opName":"SSTORE"}
{"pc":6,"op":96,"gas":"0x130d7be","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":8,"op":96,"gas":"0x130d7bb","gasCost":"0x3","memSize":0,"stack":["0x10"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":10,"op":64,"gas":"0x130d7b8","gasCost":"0x14","memSize":0,"stack":["0x10","0x1"],"depth":1,"refund":0,"opName":"BLOCKHASH"}
Requested blockhash 1. Scope for blockhash: 0 - 1

So what happens is:

holiman commented 1 year ago

The example trace from this issue report:

{"pc":11,"op":64,"gas":"0x2d25","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x831fc01b15af74fc30c"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"BLOCKHASH","error":""}
{"pc":12,"op":128,"gas":"0x2d11","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"DUP1","error":""}
BLOCKHASH(0x831fc01b15af74fc30c) -> 0x0

That is, BLOCKHASH(38700981312745718661900) is only "defined" if BLOCKNUM is somewhere within a 256 large window of that number. Otherwise, the correct returnvalue is 0x0.

holiman commented 1 year ago

Also relevant: https://github.com/NethermindEth/nethermind/issues/3201

amethystens commented 1 week ago

So basically Geth, Besu and OE all return 0x0 on BLOCKHASH(0x831fc01b15af74fc30c) while Nethermind returns Keccak(0x831fc01b15af74fc30c).

Netherminds Blockhash provider: https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs

The state test documentation also states that " Since the data of the blockchain is not given, the opcode BLOCKHASH could not return the hashes of the corresponding blocks. Therefore we define the hash of block number n to be SHA256("n")." https://www.ethdocs.org/en/latest/contracts-and-transactions/ethereum-tests/state_tests/index.html (first paragraph)

Geth replaces the function correctly in state tests (https://github.com/ethereum/go-ethereum/blob/71c37d82adaa2b69ea98ce0c5505489d6b711c1e/tests/vm_test_util.go#L157) but I think it is not patched in the evm binary.

Test ``` { "nethermind-caller": { "env": { "currentCoinbase": "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "currentDifficulty": "0x20000", "currentGasLimit": "0x26e1f476fe1e22", "currentNumber": "0x1", "currentTimestamp": "0x3e8", "previousHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, "pre": { "0x00000000000000000000000000000000000000aa": { "code": "0x6000600060006000600060bb612d28f1", "storage": {}, "balance": "0x5", "nonce": "0x0" }, "0x00000000000000000000000000000000000000bb": { "code": "0x690831fc01b15af74fc30c40805260006000f3", "storage": {}, "balance": "0x5", "nonce": "0x0" }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "code": "0x", "storage": {}, "balance": "0xffffffff", "nonce": "0x0" } }, "transaction": { "gasPrice": "0x1", "nonce": "0x0", "to": "0x00000000000000000000000000000000000000AA", "data": [ "0x" ], "gasLimit": [ "0x7a1200" ], "value": [ "0x01" ], "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" }, "out": "0x", "post": { "Istanbul": [ { "hash": "0000000000000000000000000000000000000000000000000000000000000000", "logs": "0000000000000000000000000000000000000000000000000000000000000000", "indexes": { "data": 0, "gas": 0, "value": 0 } } ] } } } ```
Geth output Geth: ``` ~/go/src/github.com/ethereum/go-ethereum/build/bin/evm --json --nomemory statetest test.json {"pc":0,"op":96,"gas":"0x79bff8","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":2,"op":96,"gas":"0x79bff5","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":4,"op":96,"gas":"0x79bff2","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":6,"op":96,"gas":"0x79bfef","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":8,"op":96,"gas":"0x79bfec","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":10,"op":96,"gas":"0x79bfe9","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH1","error":""} {"pc":12,"op":97,"gas":"0x79bfe6","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"PUSH2","error":""} {"pc":15,"op":241,"gas":"0x79bfe3","gasCost":"0x2fe4","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb","0x2d28"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"CALL","error":""} {"pc":0,"op":105,"gas":"0x2d28","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH10","error":""} {"pc":11,"op":64,"gas":"0x2d25","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x831fc01b15af74fc30c"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"BLOCKHASH","error":""} {"pc":12,"op":128,"gas":"0x2d11","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"DUP1","error":""} {"pc":13,"op":82,"gas":"0x2d0e","gasCost":"0x6","memory":"0x","memSize":32,"stack":["0x0","0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"MSTORE","error":""} {"pc":14,"op":96,"gas":"0x2d08","gasCost":"0x3","memory":"0x","memSize":32,"stack":[],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH1","error":""} {"pc":16,"op":96,"gas":"0x2d05","gasCost":"0x3","memory":"0x","memSize":32,"stack":["0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH1","error":""} {"pc":18,"op":243,"gas":"0x2d02","gasCost":"0x0","memory":"0x","memSize":32,"stack":["0x0","0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"RETURN","error":""} {"pc":16,"op":0,"gas":"0x79bd01","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0x1"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"STOP","error":""} {"output":"","gasUsed":"0x2f7","time":234049} {"stateRoot": "aeadb62508a708210e49bbde6840e63ea913fa65b566dd7fc3bf26157a5ee44f"} [ { "name": "nethermind-caller", "pass": false, "fork": "Istanbul", "error": "post state root mismatch: got aeadb62508a708210e49bbde6840e63ea913fa65b566dd7fc3bf26157a5ee44f, want 0000000000000000000000000000000000000000000000000000000000000000" } ] ```
Nethermind output Nethermind: ``` ~/ethereum/nethermind/nethtest -i test.json {"pc":0,"op":96,"gas":"0x79bff8","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":2,"op":96,"gas":"0x79bff5","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":4,"op":96,"gas":"0x79bff2","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":6,"op":96,"gas":"0x79bfef","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":8,"op":96,"gas":"0x79bfec","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":10,"op":96,"gas":"0x79bfe9","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opname":"PUSH1","error":""} {"pc":12,"op":97,"gas":"0x79bfe6","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb"],"depth":1,"refund":0,"opname":"PUSH2","error":""} {"pc":15,"op":241,"gas":"0x79bfe3","gasCost":"0x2fe4","memory":"0x","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xbb","0x2d28"],"depth":1,"refund":0,"opname":"CALL","error":""} {"pc":0,"op":105,"gas":"0x2d28","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"depth":2,"refund":0,"opname":"PUSH10","error":""} {"pc":11,"op":64,"gas":"0x2d25","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x831fc01b15af74fc30c"],"depth":2,"refund":0,"opname":"BLOCKHASH","error":""} {"pc":12,"op":128,"gas":"0x2d11","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0xc23afaf993bef633220c94fba7cf577103b120a2701d597660dfbab0720a8ab4"],"depth":2,"refund":0,"opname":"DUP1","error":""} {"pc":13,"op":82,"gas":"0x2d0e","gasCost":"0x2d0e","memory":"0x","memSize":0,"stack":["0xc23afaf993bef633220c94fba7cf577103b120a2701d597660dfbab0720a8ab4","0xc23afaf993bef633220c94fba7cf577103b120a2701d597660dfbab0720a8ab4"],"depth":2,"refund":0,"opname":"MSTORE","error":"gas uint64 overflow"} {"output":"0x","gasUsed":"0x2ff9","time":3} {"stateRoot":"0xde9086cdde32b9293313af622ef8553330f85a7a955a4e4a5a7413c25ccf1c19"} [ { "name": "nethermind-caller_d0g0v0", "pass": false, "fork": "Istanbul" } ] ```