implement aleth/geth/parity compatibility mode -- 100% pass test

This commit is contained in:
andri lim 2020-02-19 17:27:14 +07:00 committed by zah
parent 4a786d8cf7
commit 2fbabd25a4
4 changed files with 63 additions and 32 deletions

View File

@ -796,7 +796,7 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
+ CreateMessageRevertedOOGInInit.json OK
+ RevertDepthCreate2OOG.json OK
+ RevertDepthCreateAddressCollision.json OK
RevertInCreateInInitCreate2.json Skip
+ RevertInCreateInInitCreate2.json OK
+ RevertOpcodeCreate.json OK
+ RevertOpcodeInCreateReturnsCreate2.json OK
+ call_outsize_then_create2_successful_then_returndatasize.json OK
@ -822,7 +822,7 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
+ returndatacopy_following_successful_create.json OK
+ returndatasize_following_successful_create.json OK
```
OK: 42/44 Fail: 0/44 Skip: 2/44
OK: 43/44 Fail: 0/44 Skip: 1/44
## stCreateTest
```diff
+ CREATE_AcreateB_BSuicide_BStore.json OK
@ -2074,7 +2074,7 @@ OK: 38/38 Fail: 0/38 Skip: 0/38
+ RevertDepthCreateAddressCollision.json OK
+ RevertDepthCreateOOG.json OK
+ RevertInCallCode.json OK
RevertInCreateInInit.json Skip
+ RevertInCreateInInit.json OK
+ RevertInDelegateCall.json OK
+ RevertInStaticCall.json OK
+ RevertOnEmptyStack.json OK
@ -2109,7 +2109,7 @@ OK: 38/38 Fail: 0/38 Skip: 0/38
+ TouchToEmptyAccountRevert2.json OK
+ TouchToEmptyAccountRevert3.json OK
```
OK: 39/45 Fail: 0/45 Skip: 6/45
OK: 40/45 Fail: 0/45 Skip: 5/45
## stSLoadTest
```diff
+ sloadGasCost.json OK
@ -2117,7 +2117,7 @@ OK: 39/45 Fail: 0/45 Skip: 6/45
OK: 1/1 Fail: 0/1 Skip: 0/1
## stSStoreTest
```diff
InitCollision.json Skip
+ InitCollision.json OK
+ InitCollisionNonZeroNonce.json OK
+ SstoreCallToSelfSubRefundBelowZero.json OK
+ sstore_0to0.json OK
@ -2145,7 +2145,7 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
+ sstore_changeFromExternalCallInInitCode.json OK
+ sstore_gasLeft.json OK
```
OK: 26/27 Fail: 0/27 Skip: 1/27
OK: 27/27 Fail: 0/27 Skip: 0/27
## stSelfBalance
```diff
+ selfBalance.json OK
@ -3028,4 +3028,4 @@ OK: 133/133 Fail: 0/133 Skip: 0/133
OK: 130/130 Fail: 0/130 Skip: 0/130
---TOTAL---
OK: 2622/2730 Fail: 0/2730 Skip: 108/2730
OK: 2625/2730 Fail: 0/2730 Skip: 105/2730

View File

@ -393,7 +393,7 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
+ CreateMessageRevertedOOGInInit.json OK
+ RevertDepthCreate2OOG.json OK
+ RevertDepthCreateAddressCollision.json OK
RevertInCreateInInitCreate2.json Skip
+ RevertInCreateInInitCreate2.json OK
+ RevertOpcodeCreate.json OK
+ RevertOpcodeInCreateReturnsCreate2.json OK
+ call_outsize_then_create2_successful_then_returndatasize.json OK
@ -419,7 +419,7 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
+ returndatacopy_following_successful_create.json OK
+ returndatasize_following_successful_create.json OK
```
OK: 42/44 Fail: 0/44 Skip: 2/44
OK: 43/44 Fail: 0/44 Skip: 1/44
## stCreateTest
```diff
+ CREATE_AcreateB_BSuicide_BStore.json OK
@ -1671,7 +1671,7 @@ OK: 38/38 Fail: 0/38 Skip: 0/38
+ RevertDepthCreateAddressCollision.json OK
+ RevertDepthCreateOOG.json OK
+ RevertInCallCode.json OK
RevertInCreateInInit.json Skip
+ RevertInCreateInInit.json OK
+ RevertInDelegateCall.json OK
+ RevertInStaticCall.json OK
+ RevertOnEmptyStack.json OK
@ -1706,7 +1706,7 @@ OK: 38/38 Fail: 0/38 Skip: 0/38
+ TouchToEmptyAccountRevert2.json OK
+ TouchToEmptyAccountRevert3.json OK
```
OK: 39/45 Fail: 0/45 Skip: 6/45
OK: 40/45 Fail: 0/45 Skip: 5/45
## stSLoadTest
```diff
+ sloadGasCost.json OK
@ -1714,7 +1714,7 @@ OK: 39/45 Fail: 0/45 Skip: 6/45
OK: 1/1 Fail: 0/1 Skip: 0/1
## stSStoreTest
```diff
InitCollision.json Skip
+ InitCollision.json OK
+ InitCollisionNonZeroNonce.json OK
+ SstoreCallToSelfSubRefundBelowZero.json OK
+ sstore_0to0.json OK
@ -1742,7 +1742,7 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
+ sstore_changeFromExternalCallInInitCode.json OK
+ sstore_gasLeft.json OK
```
OK: 26/27 Fail: 0/27 Skip: 1/27
OK: 27/27 Fail: 0/27 Skip: 0/27
## stSelfBalance
```diff
+ selfBalance.json OK
@ -2625,4 +2625,4 @@ OK: 133/133 Fail: 0/133 Skip: 0/133
OK: 130/130 Fail: 0/130 Skip: 0/130
---TOTAL---
OK: 2305/2411 Fail: 0/2411 Skip: 106/2411
OK: 2308/2411 Fail: 0/2411 Skip: 103/2411

View File

@ -8,16 +8,49 @@
import
strformat,
chronicles, eth/[common, rlp], eth/trie/[hexary, db, trie_defs],
../constants, ../utils, storage_types
../constants, ../utils, storage_types, sets
logScope:
topics = "state_db"
# aleth/geth/parity compatibility mode:
#
# affected test cases both in GST and BCT:
# - stSStoreTest\InitCollision.json
# - stRevertTest\RevertInCreateInInit.json
# - stCreate2\RevertInCreateInInitCreate2.json
#
# pyEVM sided with original Nimbus EVM
#
# implementation difference:
# Aleth/geth/parity using accounts cache.
# When contract creation happened on an existing
# but 'empty' account with non empty storage will
# get new empty storage root.
# Aleth cs. only clear the storage cache while both pyEVM
# and Nimbus will modify the state trie.
# During the next SSTORE call, aleth cs. calculate
# gas used based on this cached 'original storage value'.
# In other hand pyEVM and Nimbus will fetch
# 'original storage value' from state trie.
#
# Both Yellow Paper and EIP2200 are not clear about this
# situation but since aleth/geth/and parity implement this
# behaviour, we perhaps also need to implement it.
#
# TODO: should this compatibility mode enabled via
# compile time switch, runtime switch, or just hard coded
# it?
const
aleth_compat = true
type
AccountStateDB* = ref object
trie: SecureHexaryTrie
originalRoot: KeccakHash # will be updated for every transaction
transactionID: TransactionID
when aleth_compat:
cleared: HashSet[EthAddress]
ReadOnlyStateDB* = distinct AccountStateDB
@ -36,6 +69,8 @@ proc newAccountStateDB*(backingStore: TrieDatabaseRef,
result.trie = initSecureHexaryTrie(backingStore, root, pruneTrie)
result.originalRoot = root
result.transactionID = backingStore.getTransactionID()
when aleth_compat:
result.cleared = initHashSet[EthAddress]()
template createRangeFromAddress(address: EthAddress): ByteRange =
## XXX: The name of this proc is intentionally long, because it
@ -97,6 +132,8 @@ proc clearStorage*(db: var AccountStateDB, address: EthAddress) =
var account = db.getAccount(address)
account.storageRoot = emptyRlpHash
db.setAccount(address, account)
when aleth_compat:
db.cleared.incl address
proc getStorageRoot*(db: AccountStateDB, address: EthAddress): Hash256 =
var account = db.getAccount(address)
@ -216,9 +253,15 @@ proc isDeadAccount*(db: AccountStateDB, address: EthAddress): bool =
proc getCommittedStorage*(db: AccountStateDB, address: EthAddress, slot: UInt256): UInt256 =
let tmpHash = db.rootHash
db.rootHash = db.originalRoot
var exists: bool
shortTimeReadOnly(trieDB(db), db.transactionID):
(result, exists) = db.getStorage(address, slot)
when aleth_compat:
if address in db.cleared:
debug "Forced contract creation on existing account detected", address
result = 0.u256
else:
result = db.getStorage(address, slot)[0]
else:
result = db.getStorage(address, slot)[0]
db.rootHash = tmpHash
proc updateOriginalRoot*(db: AccountStateDB) =
@ -228,6 +271,9 @@ proc updateOriginalRoot*(db: AccountStateDB) =
# transactionID, it will be handled elsewhere
db.transactionID = trieDB(db).getTransactionID()
when aleth_compat:
db.cleared.clear()
proc rootHash*(db: ReadOnlyStateDB): KeccakHash {.borrow.}
proc getAccount*(db: ReadOnlyStateDB, address: EthAddress): Account {.borrow.}
proc getCodeHash*(db: ReadOnlyStateDB, address: EthAddress): Hash256 {.borrow.}

View File

@ -98,14 +98,6 @@ func skipNewGSTTests*(folder: string, name: string): bool =
if skipGSTTests(folder, name):
return true
name in @[
# py-evm claims these tests are incorrect
# nimbus also agree
"RevertInCreateInInit.json",
"RevertInCreateInInitCreate2.json",
"InitCollision.json"
]
func skipVMTests*(folder: string, name: string): bool =
result = (folder == "vmPerformance" and "loop" in name)
@ -126,13 +118,6 @@ func skipNewBCTests*(folder: string, name: string): bool =
return true
name in @[
# Istanbul bc tests
# py-evm claims these tests are incorrect
# nimbus also agree
"RevertInCreateInInit.json",
"RevertInCreateInInitCreate2.json",
"InitCollision.json",
# BC huge memory consumption
"randomStatetest94.json",
"DelegateCallSpam.json"