Merge branch 'jangko-evm_transform'

This commit is contained in:
Ștefan Talpalaru 2019-04-05 02:08:29 +02:00
commit 4d29677f5a
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
11 changed files with 217 additions and 197 deletions

View File

@ -52,10 +52,10 @@ GeneralStateTests
OK: 0/46 Fail: 0/46 Skip: 46/46 OK: 0/46 Fail: 0/46 Skip: 46/46
## stAttackTest ## stAttackTest
```diff ```diff
ContractCreationSpam.json Skip + ContractCreationSpam.json OK
+ CrashingTransaction.json OK + CrashingTransaction.json OK
``` ```
OK: 1/2 Fail: 0/2 Skip: 1/2 OK: 2/2 Fail: 0/2 Skip: 0/2
## stBadOpcode ## stBadOpcode
```diff ```diff
+ badOpcodes.json OK + badOpcodes.json OK
@ -89,7 +89,7 @@ OK: 2/3 Fail: 0/3 Skip: 1/3
+ callcallcallcode_001_OOGMBefore.json OK + callcallcallcode_001_OOGMBefore.json OK
+ callcallcallcode_001_SuicideEnd.json OK + callcallcallcode_001_SuicideEnd.json OK
+ callcallcallcode_001_SuicideMiddle.json OK + callcallcallcode_001_SuicideMiddle.json OK
callcallcallcode_ABCB_RECURSIVE.json Skip + callcallcallcode_ABCB_RECURSIVE.json OK
+ callcallcode_01.json OK + callcallcode_01.json OK
+ callcallcode_01_OOGE.json OK + callcallcode_01_OOGE.json OK
+ callcallcode_01_SuicideEnd.json OK + callcallcode_01_SuicideEnd.json OK
@ -99,14 +99,14 @@ OK: 2/3 Fail: 0/3 Skip: 1/3
+ callcallcodecall_010_OOGMBefore.json OK + callcallcodecall_010_OOGMBefore.json OK
+ callcallcodecall_010_SuicideEnd.json OK + callcallcodecall_010_SuicideEnd.json OK
+ callcallcodecall_010_SuicideMiddle.json OK + callcallcodecall_010_SuicideMiddle.json OK
callcallcodecall_ABCB_RECURSIVE.json Skip + callcallcodecall_ABCB_RECURSIVE.json OK
+ callcallcodecallcode_011.json OK + callcallcodecallcode_011.json OK
+ callcallcodecallcode_011_OOGE.json OK + callcallcodecallcode_011_OOGE.json OK
+ callcallcodecallcode_011_OOGMAfter.json OK + callcallcodecallcode_011_OOGMAfter.json OK
+ callcallcodecallcode_011_OOGMBefore.json OK + callcallcodecallcode_011_OOGMBefore.json OK
+ callcallcodecallcode_011_SuicideEnd.json OK + callcallcodecallcode_011_SuicideEnd.json OK
+ callcallcodecallcode_011_SuicideMiddle.json OK + callcallcodecallcode_011_SuicideMiddle.json OK
callcallcodecallcode_ABCB_RECURSIVE.json Skip + callcallcodecallcode_ABCB_RECURSIVE.json OK
+ callcodeDynamicCode.json OK + callcodeDynamicCode.json OK
+ callcodeDynamicCode2SelfCall.json OK + callcodeDynamicCode2SelfCall.json OK
+ callcodeEmptycontract.json OK + callcodeEmptycontract.json OK
@ -124,14 +124,14 @@ OK: 2/3 Fail: 0/3 Skip: 1/3
+ callcodecallcall_100_OOGMBefore.json OK + callcodecallcall_100_OOGMBefore.json OK
+ callcodecallcall_100_SuicideEnd.json OK + callcodecallcall_100_SuicideEnd.json OK
+ callcodecallcall_100_SuicideMiddle.json OK + callcodecallcall_100_SuicideMiddle.json OK
callcodecallcall_ABCB_RECURSIVE.json Skip + callcodecallcall_ABCB_RECURSIVE.json OK
+ callcodecallcallcode_101.json OK + callcodecallcallcode_101.json OK
+ callcodecallcallcode_101_OOGE.json OK + callcodecallcallcode_101_OOGE.json OK
+ callcodecallcallcode_101_OOGMAfter.json OK + callcodecallcallcode_101_OOGMAfter.json OK
+ callcodecallcallcode_101_OOGMBefore.json OK + callcodecallcallcode_101_OOGMBefore.json OK
+ callcodecallcallcode_101_SuicideEnd.json OK + callcodecallcallcode_101_SuicideEnd.json OK
+ callcodecallcallcode_101_SuicideMiddle.json OK + callcodecallcallcode_101_SuicideMiddle.json OK
callcodecallcallcode_ABCB_RECURSIVE.json Skip + callcodecallcallcode_ABCB_RECURSIVE.json OK
+ callcodecallcode_11.json OK + callcodecallcode_11.json OK
+ callcodecallcode_11_OOGE.json OK + callcodecallcode_11_OOGE.json OK
+ callcodecallcode_11_SuicideEnd.json OK + callcodecallcode_11_SuicideEnd.json OK
@ -141,25 +141,25 @@ OK: 2/3 Fail: 0/3 Skip: 1/3
+ callcodecallcodecall_110_OOGMBefore.json OK + callcodecallcodecall_110_OOGMBefore.json OK
+ callcodecallcodecall_110_SuicideEnd.json OK + callcodecallcodecall_110_SuicideEnd.json OK
+ callcodecallcodecall_110_SuicideMiddle.json OK + callcodecallcodecall_110_SuicideMiddle.json OK
callcodecallcodecall_ABCB_RECURSIVE.json Skip + callcodecallcodecall_ABCB_RECURSIVE.json OK
+ callcodecallcodecallcode_111.json OK + callcodecallcodecallcode_111.json OK
+ callcodecallcodecallcode_111_OOGE.json OK + callcodecallcodecallcode_111_OOGE.json OK
+ callcodecallcodecallcode_111_OOGMAfter.json OK + callcodecallcodecallcode_111_OOGMAfter.json OK
+ callcodecallcodecallcode_111_OOGMBefore.json OK + callcodecallcodecallcode_111_OOGMBefore.json OK
+ callcodecallcodecallcode_111_SuicideEnd.json OK + callcodecallcodecallcode_111_SuicideEnd.json OK
+ callcodecallcodecallcode_111_SuicideMiddle.json OK + callcodecallcodecallcode_111_SuicideMiddle.json OK
callcodecallcodecallcode_ABCB_RECURSIVE.json Skip + callcodecallcodecallcode_ABCB_RECURSIVE.json OK
``` ```
OK: 72/79 Fail: 0/79 Skip: 7/79 OK: 79/79 Fail: 0/79 Skip: 0/79
## stCallCreateCallCodeTest ## stCallCreateCallCodeTest
```diff ```diff
Call1024BalanceTooLow.json Skip + Call1024BalanceTooLow.json OK
Call1024OOG.json Skip + Call1024OOG.json OK
Call1024PreCalls.json Skip + Call1024PreCalls.json OK
+ CallLoseGasOOG.json OK + CallLoseGasOOG.json OK
CallRecursiveBombPreCall.json Skip + CallRecursiveBombPreCall.json OK
+ Callcode1024BalanceTooLow.json OK + Callcode1024BalanceTooLow.json OK
Callcode1024OOG.json Skip + Callcode1024OOG.json OK
+ CallcodeLoseGasOOG.json OK + CallcodeLoseGasOOG.json OK
+ callOutput1.json OK + callOutput1.json OK
+ callOutput2.json OK + callOutput2.json OK
@ -193,7 +193,7 @@ OK: 72/79 Fail: 0/79 Skip: 7/79
+ createNameRegistratorPreStore1NotEnoughGas.json OK + createNameRegistratorPreStore1NotEnoughGas.json OK
+ createNameRegistratorendowmentTooHigh.json OK + createNameRegistratorendowmentTooHigh.json OK
``` ```
OK: 34/39 Fail: 0/39 Skip: 5/39 OK: 39/39 Fail: 0/39 Skip: 0/39
## stCallDelegateCodesCallCodeHomestead ## stCallDelegateCodesCallCodeHomestead
```diff ```diff
+ callcallcallcode_001.json OK + callcallcallcode_001.json OK
@ -202,7 +202,7 @@ OK: 34/39 Fail: 0/39 Skip: 5/39
+ callcallcallcode_001_OOGMBefore.json OK + callcallcallcode_001_OOGMBefore.json OK
+ callcallcallcode_001_SuicideEnd.json OK + callcallcallcode_001_SuicideEnd.json OK
+ callcallcallcode_001_SuicideMiddle.json OK + callcallcallcode_001_SuicideMiddle.json OK
callcallcallcode_ABCB_RECURSIVE.json Skip + callcallcallcode_ABCB_RECURSIVE.json OK
+ callcallcode_01.json OK + callcallcode_01.json OK
+ callcallcode_01_OOGE.json OK + callcallcode_01_OOGE.json OK
+ callcallcode_01_SuicideEnd.json OK + callcallcode_01_SuicideEnd.json OK
@ -212,14 +212,14 @@ OK: 34/39 Fail: 0/39 Skip: 5/39
+ callcallcodecall_010_OOGMBefore.json OK + callcallcodecall_010_OOGMBefore.json OK
+ callcallcodecall_010_SuicideEnd.json OK + callcallcodecall_010_SuicideEnd.json OK
+ callcallcodecall_010_SuicideMiddle.json OK + callcallcodecall_010_SuicideMiddle.json OK
callcallcodecall_ABCB_RECURSIVE.json Skip + callcallcodecall_ABCB_RECURSIVE.json OK
+ callcallcodecallcode_011.json OK + callcallcodecallcode_011.json OK
+ callcallcodecallcode_011_OOGE.json OK + callcallcodecallcode_011_OOGE.json OK
+ callcallcodecallcode_011_OOGMAfter.json OK + callcallcodecallcode_011_OOGMAfter.json OK
+ callcallcodecallcode_011_OOGMBefore.json OK + callcallcodecallcode_011_OOGMBefore.json OK
+ callcallcodecallcode_011_SuicideEnd.json OK + callcallcodecallcode_011_SuicideEnd.json OK
+ callcallcodecallcode_011_SuicideMiddle.json OK + callcallcodecallcode_011_SuicideMiddle.json OK
callcallcodecallcode_ABCB_RECURSIVE.json Skip + callcallcodecallcode_ABCB_RECURSIVE.json OK
+ callcodecall_10.json OK + callcodecall_10.json OK
+ callcodecall_10_OOGE.json OK + callcodecall_10_OOGE.json OK
+ callcodecall_10_SuicideEnd.json OK + callcodecall_10_SuicideEnd.json OK
@ -229,14 +229,14 @@ OK: 34/39 Fail: 0/39 Skip: 5/39
+ callcodecallcall_100_OOGMBefore.json OK + callcodecallcall_100_OOGMBefore.json OK
+ callcodecallcall_100_SuicideEnd.json OK + callcodecallcall_100_SuicideEnd.json OK
+ callcodecallcall_100_SuicideMiddle.json OK + callcodecallcall_100_SuicideMiddle.json OK
callcodecallcall_ABCB_RECURSIVE.json Skip + callcodecallcall_ABCB_RECURSIVE.json OK
+ callcodecallcallcode_101.json OK + callcodecallcallcode_101.json OK
+ callcodecallcallcode_101_OOGE.json OK + callcodecallcallcode_101_OOGE.json OK
+ callcodecallcallcode_101_OOGMAfter.json OK + callcodecallcallcode_101_OOGMAfter.json OK
+ callcodecallcallcode_101_OOGMBefore.json OK + callcodecallcallcode_101_OOGMBefore.json OK
+ callcodecallcallcode_101_SuicideEnd.json OK + callcodecallcallcode_101_SuicideEnd.json OK
+ callcodecallcallcode_101_SuicideMiddle.json OK + callcodecallcallcode_101_SuicideMiddle.json OK
callcodecallcallcode_ABCB_RECURSIVE.json Skip + callcodecallcallcode_ABCB_RECURSIVE.json OK
+ callcodecallcode_11.json OK + callcodecallcode_11.json OK
+ callcodecallcode_11_OOGE.json OK + callcodecallcode_11_OOGE.json OK
+ callcodecallcode_11_SuicideEnd.json OK + callcodecallcode_11_SuicideEnd.json OK
@ -246,16 +246,16 @@ OK: 34/39 Fail: 0/39 Skip: 5/39
+ callcodecallcodecall_110_OOGMBefore.json OK + callcodecallcodecall_110_OOGMBefore.json OK
+ callcodecallcodecall_110_SuicideEnd.json OK + callcodecallcodecall_110_SuicideEnd.json OK
+ callcodecallcodecall_110_SuicideMiddle.json OK + callcodecallcodecall_110_SuicideMiddle.json OK
callcodecallcodecall_ABCB_RECURSIVE.json Skip + callcodecallcodecall_ABCB_RECURSIVE.json OK
+ callcodecallcodecallcode_111.json OK + callcodecallcodecallcode_111.json OK
+ callcodecallcodecallcode_111_OOGE.json OK + callcodecallcodecallcode_111_OOGE.json OK
+ callcodecallcodecallcode_111_OOGMAfter.json OK + callcodecallcodecallcode_111_OOGMAfter.json OK
+ callcodecallcodecallcode_111_OOGMBefore.json OK + callcodecallcodecallcode_111_OOGMBefore.json OK
+ callcodecallcodecallcode_111_SuicideEnd.json OK + callcodecallcodecallcode_111_SuicideEnd.json OK
+ callcodecallcodecallcode_111_SuicideMiddle.json OK + callcodecallcodecallcode_111_SuicideMiddle.json OK
callcodecallcodecallcode_ABCB_RECURSIVE.json Skip + callcodecallcodecallcode_ABCB_RECURSIVE.json OK
``` ```
OK: 51/58 Fail: 0/58 Skip: 7/58 OK: 58/58 Fail: 0/58 Skip: 0/58
## stCallDelegateCodesHomestead ## stCallDelegateCodesHomestead
```diff ```diff
+ callcallcallcode_001.json OK + callcallcallcode_001.json OK
@ -264,7 +264,7 @@ OK: 51/58 Fail: 0/58 Skip: 7/58
+ callcallcallcode_001_OOGMBefore.json OK + callcallcallcode_001_OOGMBefore.json OK
+ callcallcallcode_001_SuicideEnd.json OK + callcallcallcode_001_SuicideEnd.json OK
+ callcallcallcode_001_SuicideMiddle.json OK + callcallcallcode_001_SuicideMiddle.json OK
callcallcallcode_ABCB_RECURSIVE.json Skip + callcallcallcode_ABCB_RECURSIVE.json OK
+ callcallcode_01.json OK + callcallcode_01.json OK
+ callcallcode_01_OOGE.json OK + callcallcode_01_OOGE.json OK
+ callcallcode_01_SuicideEnd.json OK + callcallcode_01_SuicideEnd.json OK
@ -274,14 +274,14 @@ OK: 51/58 Fail: 0/58 Skip: 7/58
+ callcallcodecall_010_OOGMBefore.json OK + callcallcodecall_010_OOGMBefore.json OK
+ callcallcodecall_010_SuicideEnd.json OK + callcallcodecall_010_SuicideEnd.json OK
+ callcallcodecall_010_SuicideMiddle.json OK + callcallcodecall_010_SuicideMiddle.json OK
callcallcodecall_ABCB_RECURSIVE.json Skip + callcallcodecall_ABCB_RECURSIVE.json OK
+ callcallcodecallcode_011.json OK + callcallcodecallcode_011.json OK
+ callcallcodecallcode_011_OOGE.json OK + callcallcodecallcode_011_OOGE.json OK
+ callcallcodecallcode_011_OOGMAfter.json OK + callcallcodecallcode_011_OOGMAfter.json OK
+ callcallcodecallcode_011_OOGMBefore.json OK + callcallcodecallcode_011_OOGMBefore.json OK
+ callcallcodecallcode_011_SuicideEnd.json OK + callcallcodecallcode_011_SuicideEnd.json OK
+ callcallcodecallcode_011_SuicideMiddle.json OK + callcallcodecallcode_011_SuicideMiddle.json OK
callcallcodecallcode_ABCB_RECURSIVE.json Skip + callcallcodecallcode_ABCB_RECURSIVE.json OK
+ callcodecall_10.json OK + callcodecall_10.json OK
+ callcodecall_10_OOGE.json OK + callcodecall_10_OOGE.json OK
+ callcodecall_10_SuicideEnd.json OK + callcodecall_10_SuicideEnd.json OK
@ -291,14 +291,14 @@ OK: 51/58 Fail: 0/58 Skip: 7/58
+ callcodecallcall_100_OOGMBefore.json OK + callcodecallcall_100_OOGMBefore.json OK
+ callcodecallcall_100_SuicideEnd.json OK + callcodecallcall_100_SuicideEnd.json OK
+ callcodecallcall_100_SuicideMiddle.json OK + callcodecallcall_100_SuicideMiddle.json OK
callcodecallcall_ABCB_RECURSIVE.json Skip + callcodecallcall_ABCB_RECURSIVE.json OK
+ callcodecallcallcode_101.json OK + callcodecallcallcode_101.json OK
+ callcodecallcallcode_101_OOGE.json OK + callcodecallcallcode_101_OOGE.json OK
+ callcodecallcallcode_101_OOGMAfter.json OK + callcodecallcallcode_101_OOGMAfter.json OK
+ callcodecallcallcode_101_OOGMBefore.json OK + callcodecallcallcode_101_OOGMBefore.json OK
+ callcodecallcallcode_101_SuicideEnd.json OK + callcodecallcallcode_101_SuicideEnd.json OK
+ callcodecallcallcode_101_SuicideMiddle.json OK + callcodecallcallcode_101_SuicideMiddle.json OK
callcodecallcallcode_ABCB_RECURSIVE.json Skip + callcodecallcallcode_ABCB_RECURSIVE.json OK
+ callcodecallcode_11.json OK + callcodecallcode_11.json OK
+ callcodecallcode_11_OOGE.json OK + callcodecallcode_11_OOGE.json OK
+ callcodecallcode_11_SuicideEnd.json OK + callcodecallcode_11_SuicideEnd.json OK
@ -308,20 +308,20 @@ OK: 51/58 Fail: 0/58 Skip: 7/58
+ callcodecallcodecall_110_OOGMBefore.json OK + callcodecallcodecall_110_OOGMBefore.json OK
+ callcodecallcodecall_110_SuicideEnd.json OK + callcodecallcodecall_110_SuicideEnd.json OK
+ callcodecallcodecall_110_SuicideMiddle.json OK + callcodecallcodecall_110_SuicideMiddle.json OK
callcodecallcodecall_ABCB_RECURSIVE.json Skip + callcodecallcodecall_ABCB_RECURSIVE.json OK
+ callcodecallcodecallcode_111.json OK + callcodecallcodecallcode_111.json OK
+ callcodecallcodecallcode_111_OOGE.json OK + callcodecallcodecallcode_111_OOGE.json OK
+ callcodecallcodecallcode_111_OOGMAfter.json OK + callcodecallcodecallcode_111_OOGMAfter.json OK
+ callcodecallcodecallcode_111_OOGMBefore.json OK + callcodecallcodecallcode_111_OOGMBefore.json OK
+ callcodecallcodecallcode_111_SuicideEnd.json OK + callcodecallcodecallcode_111_SuicideEnd.json OK
+ callcodecallcodecallcode_111_SuicideMiddle.json OK + callcodecallcodecallcode_111_SuicideMiddle.json OK
callcodecallcodecallcode_ABCB_RECURSIVE.json Skip + callcodecallcodecallcode_ABCB_RECURSIVE.json OK
``` ```
OK: 51/58 Fail: 0/58 Skip: 7/58 OK: 58/58 Fail: 0/58 Skip: 0/58
## stChangedEIP150 ## stChangedEIP150
```diff ```diff
Call1024BalanceTooLow.json Skip + Call1024BalanceTooLow.json OK
Call1024PreCalls.json Skip + Call1024PreCalls.json OK
+ Callcode1024BalanceTooLow.json OK + Callcode1024BalanceTooLow.json OK
+ callcall_00_OOGE_1.json OK + callcall_00_OOGE_1.json OK
+ callcall_00_OOGE_2.json OK + callcall_00_OOGE_2.json OK
@ -351,7 +351,7 @@ OK: 51/58 Fail: 0/58 Skip: 7/58
+ contractCreationMakeCallThatAskMoreGasThenTransactionProvided.jsonOK + contractCreationMakeCallThatAskMoreGasThenTransactionProvided.jsonOK
+ createInitFail_OOGduringInit.json OK + createInitFail_OOGduringInit.json OK
``` ```
OK: 28/30 Fail: 0/30 Skip: 2/30 OK: 30/30 Fail: 0/30 Skip: 0/30
## stCodeCopyTest ## stCodeCopyTest
```diff ```diff
+ ExtCodeCopyTests.json OK + ExtCodeCopyTests.json OK
@ -400,14 +400,14 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
OK: 23/30 Fail: 0/30 Skip: 7/30 OK: 23/30 Fail: 0/30 Skip: 7/30
## stDelegatecallTestHomestead ## stDelegatecallTestHomestead
```diff ```diff
Call1024BalanceTooLow.json Skip + Call1024BalanceTooLow.json OK
Call1024OOG.json Skip + Call1024OOG.json OK
Call1024PreCalls.json Skip + Call1024PreCalls.json OK
+ CallLoseGasOOG.json OK + CallLoseGasOOG.json OK
CallRecursiveBombPreCall.json Skip + CallRecursiveBombPreCall.json OK
+ CallcodeLoseGasOOG.json OK + CallcodeLoseGasOOG.json OK
Delegatecall1024.json Skip + Delegatecall1024.json OK
Delegatecall1024OOG.json Skip + Delegatecall1024OOG.json OK
+ callOutput1.json OK + callOutput1.json OK
+ callOutput2.json OK + callOutput2.json OK
+ callOutput3.json OK + callOutput3.json OK
@ -435,7 +435,7 @@ OK: 23/30 Fail: 0/30 Skip: 7/30
+ delegatecodeDynamicCode.json OK + delegatecodeDynamicCode.json OK
+ delegatecodeDynamicCode2SelfCall.json OK + delegatecodeDynamicCode2SelfCall.json OK
``` ```
OK: 28/34 Fail: 0/34 Skip: 6/34 OK: 34/34 Fail: 0/34 Skip: 0/34
## stEIP150Specific ## stEIP150Specific
```diff ```diff
CallAndCallcodeConsumeMoreGasThenTransactionHas.json Skip CallAndCallcodeConsumeMoreGasThenTransactionHas.json Skip
@ -1518,10 +1518,10 @@ OK: 321/327 Fail: 0/327 Skip: 6/327
OK: 223/227 Fail: 0/227 Skip: 4/227 OK: 223/227 Fail: 0/227 Skip: 4/227
## stRecursiveCreate ## stRecursiveCreate
```diff ```diff
recursiveCreate.json Skip + recursiveCreate.json OK
recursiveCreateReturnValue.json Skip + recursiveCreateReturnValue.json OK
``` ```
OK: 0/2 Fail: 0/2 Skip: 2/2 OK: 2/2 Fail: 0/2 Skip: 0/2
## stRefundTest ## stRefundTest
```diff ```diff
+ refund50_1.json OK + refund50_1.json OK
@ -1700,8 +1700,8 @@ OK: 16/16 Fail: 0/16 Skip: 0/16
## stSpecialTest ## stSpecialTest
```diff ```diff
+ FailedCreateRevertsDeletion.json OK + FailedCreateRevertsDeletion.json OK
JUMPDEST_Attack.json Skip + JUMPDEST_Attack.json OK
JUMPDEST_AttackwithJump.json Skip + JUMPDEST_AttackwithJump.json OK
OverflowGasMakeMoney.json Skip OverflowGasMakeMoney.json Skip
+ StackDepthLimitSEC.json OK + StackDepthLimitSEC.json OK
block504980.json Skip block504980.json Skip
@ -1713,7 +1713,7 @@ OK: 16/16 Fail: 0/16 Skip: 0/16
txCost-sec73.json Skip txCost-sec73.json Skip
+ tx_e1c174e2.json OK + tx_e1c174e2.json OK
``` ```
OK: 5/13 Fail: 0/13 Skip: 8/13 OK: 7/13 Fail: 0/13 Skip: 6/13
## stStackTests ## stStackTests
```diff ```diff
shallowStack.json Skip shallowStack.json Skip
@ -2016,19 +2016,19 @@ OK: 0/284 Fail: 0/284 Skip: 284/284
## stSystemOperationsTest ## stSystemOperationsTest
```diff ```diff
+ ABAcalls0.json OK + ABAcalls0.json OK
ABAcalls1.json Skip + ABAcalls1.json OK
ABAcalls2.json Skip + ABAcalls2.json OK
+ ABAcalls3.json OK + ABAcalls3.json OK
+ ABAcallsSuicide0.json OK + ABAcallsSuicide0.json OK
+ ABAcallsSuicide1.json OK + ABAcallsSuicide1.json OK
+ Call10.json OK + Call10.json OK
CallRecursiveBomb0.json Skip + CallRecursiveBomb0.json OK
CallRecursiveBomb0_OOG_atMaxCallDepth.json Skip + CallRecursiveBomb0_OOG_atMaxCallDepth.json OK
CallRecursiveBomb1.json Skip + CallRecursiveBomb1.json OK
CallRecursiveBomb2.json Skip + CallRecursiveBomb2.json OK
+ CallRecursiveBomb3.json OK + CallRecursiveBomb3.json OK
CallRecursiveBombLog.json Skip + CallRecursiveBombLog.json OK
CallRecursiveBombLog2.json Skip + CallRecursiveBombLog2.json OK
+ CallToNameRegistrator0.json OK + CallToNameRegistrator0.json OK
+ CallToNameRegistratorAddressTooBigLeft.json OK + CallToNameRegistratorAddressTooBigLeft.json OK
+ CallToNameRegistratorAddressTooBigRight.json OK + CallToNameRegistratorAddressTooBigRight.json OK
@ -2083,7 +2083,7 @@ OK: 0/284 Fail: 0/284 Skip: 284/284
+ suicideSendEtherToMe.json OK + suicideSendEtherToMe.json OK
+ testRandomTest.json OK + testRandomTest.json OK
``` ```
OK: 57/67 Fail: 0/67 Skip: 10/67 OK: 65/67 Fail: 0/67 Skip: 2/67
## stTransactionTest ## stTransactionTest
```diff ```diff
+ ContractStoreClearsOOG.json OK + ContractStoreClearsOOG.json OK
@ -2377,13 +2377,13 @@ OK: 24/24 Fail: 0/24 Skip: 0/24
ecpairing_two_point_match_5.json Skip ecpairing_two_point_match_5.json Skip
ecpairing_two_point_oog.json Skip ecpairing_two_point_oog.json Skip
ecpairing_two_points_with_one_g2_zero.json Skip ecpairing_two_points_with_one_g2_zero.json Skip
pairingTest.json Skip + pairingTest.json OK
pointAdd.json Skip + pointAdd.json OK
pointAddTrunc.json Skip + pointAddTrunc.json OK
pointMulAdd.json Skip + pointMulAdd.json OK
pointMulAdd2.json Skip + pointMulAdd2.json OK
``` ```
OK: 0/133 Fail: 0/133 Skip: 133/133 OK: 5/133 Fail: 0/133 Skip: 128/133
## stZeroKnowledge2 ## stZeroKnowledge2
```diff ```diff
ecadd_0-0_0-0_21000_0.json Skip ecadd_0-0_0-0_21000_0.json Skip
@ -2520,4 +2520,4 @@ OK: 0/133 Fail: 0/133 Skip: 133/133
OK: 0/130 Fail: 0/130 Skip: 130/130 OK: 0/130 Fail: 0/130 Skip: 130/130
---TOTAL--- ---TOTAL---
OK: 1433/2334 Fail: 0/2334 Skip: 901/2334 OK: 1485/2334 Fail: 0/2334 Skip: 849/2334

View File

@ -34,6 +34,9 @@ proc newBaseComputation*(vmState: BaseVMState, blockNumber: UInt256, message: Me
else: else:
blockNumber.toFork.forkToSchedule blockNumber.toFork.forkToSchedule
result.forkOverride = forkOverride result.forkOverride = forkOverride
# a dummy/terminus continuation proc
result.nextProc = proc() =
discard
proc isOriginComputation*(c: BaseComputation): bool = proc isOriginComputation*(c: BaseComputation): bool =
# Is this computation the computation initiated by a transaction # Is this computation the computation initiated by a transaction
@ -61,7 +64,7 @@ func output*(c: BaseComputation): seq[byte] =
else: else:
c.rawOutput c.rawOutput
func `output=`*(c: var BaseComputation, value: openarray[byte]) = func `output=`*(c: BaseComputation, value: openarray[byte]) =
c.rawOutput = @value c.rawOutput = @value
proc outputHex*(c: BaseComputation): string = proc outputHex*(c: BaseComputation): string =
@ -69,11 +72,11 @@ proc outputHex*(c: BaseComputation): string =
return "0x" return "0x"
c.rawOutput.bytesToHex c.rawOutput.bytesToHex
proc isSuicided*(c: var BaseComputation, address: EthAddress): bool = proc isSuicided*(c: BaseComputation, address: EthAddress): bool =
result = address in c.accountsToDelete result = address in c.accountsToDelete
proc prepareChildMessage*( proc prepareChildMessage*(
c: var BaseComputation, c: BaseComputation,
gas: GasInt, gas: GasInt,
to: EthAddress, to: EthAddress,
value: UInt256, value: UInt256,
@ -111,6 +114,14 @@ proc commit*(comp: BaseComputation) =
proc dispose*(comp: BaseComputation) {.inline.} = proc dispose*(comp: BaseComputation) {.inline.} =
comp.dbsnapshot.transaction.dispose() comp.dbsnapshot.transaction.dispose()
proc rollback*(comp: BaseComputation) =
comp.dbsnapshot.transaction.rollback()
comp.vmState.accountDb.rootHash = comp.dbsnapshot.intermediateRoot
comp.vmState.blockHeader.stateRoot = comp.dbsnapshot.intermediateRoot
proc setError*(comp: BaseComputation, msg: string, burnsGas = false) {.inline.} =
comp.error = Error(info: msg, burnsGas: burnsGas)
proc getFork*(computation: BaseComputation): Fork = proc getFork*(computation: BaseComputation): Fork =
result = result =
if computation.forkOverride.isSome: if computation.forkOverride.isSome:
@ -118,7 +129,7 @@ proc getFork*(computation: BaseComputation): Fork =
else: else:
computation.vmState.blockNumber.toFork computation.vmState.blockNumber.toFork
proc writeContract*(computation: var BaseComputation, fork: Fork): bool = proc writeContract*(computation: BaseComputation, fork: Fork): bool =
result = true result = true
let contractCode = computation.output let contractCode = computation.output
@ -142,65 +153,68 @@ proc writeContract*(computation: var BaseComputation, fork: Fork): bool =
if fork < FkHomestead: computation.output = @[] if fork < FkHomestead: computation.output = @[]
result = false result = false
proc transferBalance(computation: var BaseComputation, opCode: static[Op]): bool = proc transferBalance(computation: BaseComputation, opCode: static[Op]) =
if computation.msg.depth > MaxCallDepth: if computation.msg.depth > MaxCallDepth:
debug "Stack depth limit reached", depth=computation.msg.depth computation.setError(&"Stack depth limit reached depth={computation.msg.depth}")
return false return
let senderBalance = computation.vmState.readOnlyStateDb(). let senderBalance = computation.vmState.readOnlyStateDb().
getBalance(computation.msg.sender) getBalance(computation.msg.sender)
if senderBalance < computation.msg.value: if senderBalance < computation.msg.value:
debug "insufficient funds", available=senderBalance, needed=computation.msg.value computation.setError(&"insufficient funds available={senderBalance}, needed={computation.msg.value}")
return false return
when opCode in {Call, Create}: when opCode in {Call, Create}:
computation.vmState.mutateStateDb: computation.vmState.mutateStateDb:
db.subBalance(computation.msg.sender, computation.msg.value) db.subBalance(computation.msg.sender, computation.msg.value)
db.addBalance(computation.msg.storageAddress, computation.msg.value) db.addBalance(computation.msg.storageAddress, computation.msg.value)
result = true template continuation*(comp: BaseComputation, body: untyped) =
# this is a helper template to implement continuation
# passing and convert all recursion into tail call
var tmpNext = comp.nextProc
comp.nextProc = proc() =
body
tmpNext()
proc executeOpcodes*(computation: var BaseComputation) {.gcsafe.} proc postExecuteVM(computation: BaseComputation) =
if computation.isSuccess and computation.msg.isCreate:
let fork = computation.getFork
let contractFailed = not computation.writeContract(fork)
if contractFailed and fork == FkHomestead:
computation.setError(&"writeContract failed, depth={computation.msg.depth}", true)
proc applyMessage*(computation: var BaseComputation, opCode: static[Op]): bool = if computation.isSuccess:
computation.commit()
else:
computation.rollback()
proc executeOpcodes*(computation: BaseComputation) {.gcsafe.}
proc applyMessage*(computation: BaseComputation, opCode: static[Op]) =
computation.snapshot() computation.snapshot()
defer: computation.dispose() defer:
computation.dispose()
when opCode in {CallCode, Call, Create}: when opCode in {CallCode, Call, Create}:
if not computation.transferBalance(opCode): computation.transferBalance(opCode)
computation.revert() if computation.isError():
computation.rollback()
computation.nextProc()
return return
if computation.gasMeter.gasRemaining < 0: if computation.gasMeter.gasRemaining < 0:
computation.commit() computation.commit()
computation.nextProc()
return return
try: continuation(computation):
postExecuteVM(computation)
executeOpcodes(computation) executeOpcodes(computation)
result = not computation.isError
except VMError:
result = false
debug "applyMessage VM Error",
msg = getCurrentExceptionMsg(),
depth = computation.msg.depth
except ValueError:
result = false
debug "applyMessage Value Error",
msg = getCurrentExceptionMsg(),
depth = computation.msg.depth
if result and computation.msg.isCreate: proc addChildComputation*(computation: BaseComputation, child: BaseComputation) =
var fork = computation.getFork
let contractFailed = not computation.writeContract(fork)
result = not(contractFailed and fork == FkHomestead)
if result:
computation.commit()
else:
computation.revert(true)
proc addChildComputation(computation: var BaseComputation, child: BaseComputation) =
if child.isError: if child.isError:
if child.msg.isCreate: if child.msg.isCreate:
computation.returnData = child.output computation.returnData = child.output
@ -216,21 +230,19 @@ proc addChildComputation(computation: var BaseComputation, child: BaseComputatio
for k, v in child.accountsToDelete: for k, v in child.accountsToDelete:
computation.accountsToDelete[k] = v computation.accountsToDelete[k] = v
computation.logEntries.add child.logEntries computation.logEntries.add child.logEntries
if not child.shouldBurnGas:
computation.gasMeter.returnGas(child.gasMeter.gasRemaining)
computation.children.add(child) computation.children.add(child)
proc applyChildComputation*(parentComp, childComp: var BaseComputation, opCode: static[Op]) = proc registerAccountForDeletion*(c: BaseComputation, beneficiary: EthAddress) =
## Apply the vm message childMsg as a child computation.
discard childComp.applyMessage(opCode)
parentComp.addChildComputation(childComp)
proc registerAccountForDeletion*(c: var BaseComputation, beneficiary: EthAddress) =
if c.msg.storageAddress in c.accountsToDelete: if c.msg.storageAddress in c.accountsToDelete:
raise newException(ValueError, raise newException(ValueError,
"invariant: should be impossible for an account to be " & "invariant: should be impossible for an account to be " &
"registered for deletion multiple times") "registered for deletion multiple times")
c.accountsToDelete[c.msg.storageAddress] = beneficiary c.accountsToDelete[c.msg.storageAddress] = beneficiary
proc addLogEntry*(c: var BaseComputation, log: Log) {.inline.} = proc addLogEntry*(c: BaseComputation, log: Log) {.inline.} =
c.logEntries.add(log) c.logEntries.add(log)
# many methods are basically TODO, but they still return valid values # many methods are basically TODO, but they still return valid values

View File

@ -452,7 +452,7 @@ op sstore, inline = false, slot, value:
computation.vmState.mutateStateDB: computation.vmState.mutateStateDB:
db.setStorage(computation.msg.storageAddress, slot, value) db.setStorage(computation.msg.storageAddress, slot, value)
proc jumpImpl(computation: var BaseComputation, jumpTarget: UInt256) = proc jumpImpl(computation: BaseComputation, jumpTarget: UInt256) =
if jumpTarget >= computation.code.len.u256: if jumpTarget >= computation.code.len.u256:
raise newException(InvalidJumpDestination, "Invalid Jump Destination") raise newException(InvalidJumpDestination, "Invalid Jump Destination")
@ -537,7 +537,7 @@ proc canTransfer(computation: BaseComputation, memPos, memLen: int, value: Uint2
result = true result = true
proc setupCreate(computation: var BaseComputation, memPos, len: int, value: Uint256): BaseComputation = proc setupCreate(computation: BaseComputation, memPos, len: int, value: Uint256): BaseComputation =
let let
callData = computation.memory.read(memPos, len) callData = computation.memory.read(memPos, len)
createMsgGas = computation.getGasRemaining() createMsgGas = computation.getGasRemaining()
@ -593,17 +593,18 @@ op create, inline = false, value, startPosition, size:
var childComp = setupCreate(computation, memPos, len, value) var childComp = setupCreate(computation, memPos, len, value)
if childComp.isNil: return if childComp.isNil: return
computation.applyChildComputation(childComp, Create) computation.child = childComp
continuation(childComp):
computation.addChildComputation(childComp)
if childComp.isError: if childComp.isError:
push: 0 push: 0
else: else:
push: childComp.msg.storageAddress push: childComp.msg.storageAddress
if not childComp.shouldBurnGas: childComp.applyMessage(Create)
computation.gasMeter.returnGas(childComp.gasMeter.gasRemaining)
proc callParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) = proc callParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) =
let gas = computation.stack.popInt() let gas = computation.stack.popInt()
let codeAddress = computation.stack.popAddress() let codeAddress = computation.stack.popAddress()
@ -625,7 +626,7 @@ proc callParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress
memoryOutputSize, memoryOutputSize,
computation.msg.flags) computation.msg.flags)
proc callCodeParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) = proc callCodeParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) =
let gas = computation.stack.popInt() let gas = computation.stack.popInt()
let to = computation.stack.popAddress() let to = computation.stack.popAddress()
@ -644,7 +645,7 @@ proc callCodeParams(computation: var BaseComputation): (UInt256, UInt256, EthAdd
memoryOutputSize, memoryOutputSize,
computation.msg.flags) computation.msg.flags)
proc delegateCallParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) = proc delegateCallParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) =
let gas = computation.stack.popInt() let gas = computation.stack.popInt()
let codeAddress = computation.stack.popAddress() let codeAddress = computation.stack.popAddress()
@ -666,7 +667,7 @@ proc delegateCallParams(computation: var BaseComputation): (UInt256, UInt256, Et
memoryOutputSize, memoryOutputSize,
computation.msg.flags) computation.msg.flags)
proc staticCallParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) = proc staticCallParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) =
let gas = computation.stack.popInt() let gas = computation.stack.popInt()
let to = computation.stack.popAddress() let to = computation.stack.popAddress()
@ -685,7 +686,7 @@ proc staticCallParams(computation: var BaseComputation): (UInt256, UInt256, EthA
emvcStatic) # is_static emvcStatic) # is_static
template genCall(callName: untyped, opCode: Op): untyped = template genCall(callName: untyped, opCode: Op): untyped =
proc `callName Setup`(computation: var BaseComputation, callNameStr: string): (BaseComputation, int, int) = proc `callName Setup`(computation: BaseComputation, callNameStr: string): BaseComputation =
let (gas, value, to, sender, let (gas, value, to, sender,
codeAddress, codeAddress,
memoryInputStartPosition, memoryInputSize, memoryInputStartPosition, memoryInputSize,
@ -752,16 +753,20 @@ template genCall(callName: untyped, opCode: Op): untyped =
childMsg, childMsg,
some(computation.getFork)) some(computation.getFork))
result = (childComp, memOutPos, memOutLen) computation.memOutPos = memOutPos
computation.memOutLen = memOutLen
result = childComp
op callName, inline = false: op callName, inline = false:
## CALL, 0xf1, Message-Call into an account ## CALL, 0xf1, Message-Call into an account
## CALLCODE, 0xf2, Message-call into this account with an alternative account's code. ## CALLCODE, 0xf2, Message-call into this account with an alternative account's code.
## DELEGATECALL, 0xf4, Message-call into this account with an alternative account's code, but persisting the current values for sender and value. ## DELEGATECALL, 0xf4, Message-call into this account with an alternative account's code, but persisting the current values for sender and value.
## STATICCALL, 0xfa, Static message-call into an account. ## STATICCALL, 0xfa, Static message-call into an account.
var (childComp, memOutPos, memOutLen) = `callName Setup`(computation, callName.astToStr) var childComp = `callName Setup`(computation, callName.astToStr)
applyChildComputation(computation, childComp, opCode) computation.child = childComp
continuation(childComp):
addChildComputation(computation, childComp)
if childComp.isError: if childComp.isError:
push: 0 push: 0
@ -769,15 +774,12 @@ template genCall(callName: untyped, opCode: Op): untyped =
push: 1 push: 1
if not childComp.shouldEraseReturnData: if not childComp.shouldEraseReturnData:
let actualOutputSize = min(memOutLen, childComp.output.len) let actualOutputSize = min(computation.memOutLen, childComp.output.len)
computation.memory.write( computation.memory.write(
memOutPos, computation.memOutPos,
childComp.output.toOpenArray(0, actualOutputSize - 1)) childComp.output.toOpenArray(0, actualOutputSize - 1))
if not childComp.shouldBurnGas:
computation.gasMeter.returnGas(childComp.gasMeter.gasRemaining)
if computation.gasMeter.gasRemaining <= 0: childComp.applyMessage(opCode)
raise newException(OutOfGas, "computation out of gas after contract call (" & callName.astToStr & ")")
genCall(call, Call) genCall(call, Call)
genCall(callCode, CallCode) genCall(callCode, CallCode)

View File

@ -59,12 +59,12 @@ macro op*(procname: untyped, inline: static[bool], stackParams_body: varargs[unt
# TODO: replace by func to ensure no side effects # TODO: replace by func to ensure no side effects
if inline: if inline:
result = quote do: result = quote do:
proc `procname`*(`computation`: var BaseComputation) {.inline.} = proc `procname`*(`computation`: BaseComputation) {.inline.} =
`popStackStmt` `popStackStmt`
`body` `body`
else: else:
result = quote do: result = quote do:
proc `procname`*(`computation`: var BaseComputation) = proc `procname`*(`computation`: BaseComputation) =
`popStackStmt` `popStackStmt`
`body` `body`
@ -76,7 +76,7 @@ macro genPush*(): untyped =
for size in 1 .. 32: for size in 1 .. 32:
let name = genName(size) let name = genName(size)
result.add quote do: result.add quote do:
func `name`*(computation: var BaseComputation) {.inline.}= func `name`*(computation: BaseComputation) {.inline.}=
## Push `size`-byte(s) on the stack ## Push `size`-byte(s) on the stack
computation.stack.push computation.code.readVmWord(`size`) computation.stack.push computation.code.readVmWord(`size`)
@ -87,7 +87,7 @@ macro genDup*(): untyped =
for pos in 1 .. 16: for pos in 1 .. 16:
let name = genName(pos) let name = genName(pos)
result.add quote do: result.add quote do:
func `name`*(computation: var BaseComputation) {.inline.}= func `name`*(computation: BaseComputation) {.inline.}=
computation.stack.dup(`pos`) computation.stack.dup(`pos`)
macro genSwap*(): untyped = macro genSwap*(): untyped =
@ -97,10 +97,10 @@ macro genSwap*(): untyped =
for pos in 1 .. 16: for pos in 1 .. 16:
let name = genName(pos) let name = genName(pos)
result.add quote do: result.add quote do:
func `name`*(computation: var BaseComputation) {.inline.}= func `name`*(computation: BaseComputation) {.inline.}=
computation.stack.swap(`pos`) computation.stack.swap(`pos`)
proc logImpl(c: var BaseComputation, opcode: Op, topicCount: int) = proc logImpl(c: BaseComputation, opcode: Op, topicCount: int) =
doAssert(topicCount in 0 .. 4) doAssert(topicCount in 0 .. 4)
let (memStartPosition, size) = c.stack.popInt(2) let (memStartPosition, size) = c.stack.popInt(2)
let (memPos, len) = (memStartPosition.cleanMemRef, size.cleanMemRef) let (memPos, len) = (memStartPosition.cleanMemRef, size.cleanMemRef)
@ -122,8 +122,8 @@ proc logImpl(c: var BaseComputation, opcode: Op, topicCount: int) =
c.addLogEntry(log) c.addLogEntry(log)
template genLog*() = template genLog*() =
proc log0*(c: var BaseComputation) {.inline.} = logImpl(c, Log0, 0) proc log0*(c: BaseComputation) {.inline.} = logImpl(c, Log0, 0)
proc log1*(c: var BaseComputation) {.inline.} = logImpl(c, Log1, 1) proc log1*(c: BaseComputation) {.inline.} = logImpl(c, Log1, 1)
proc log2*(c: var BaseComputation) {.inline.} = logImpl(c, Log2, 2) proc log2*(c: BaseComputation) {.inline.} = logImpl(c, Log2, 2)
proc log3*(c: var BaseComputation) {.inline.} = logImpl(c, Log3, 3) proc log3*(c: BaseComputation) {.inline.} = logImpl(c, Log3, 3)
proc log4*(c: var BaseComputation) {.inline.} = logImpl(c, Log4, 4) proc log4*(c: BaseComputation) {.inline.} = logImpl(c, Log4, 4)

View File

@ -16,7 +16,7 @@ import
logScope: logScope:
topics = "vm opcode" topics = "vm opcode"
func invalidInstruction*(computation: var BaseComputation) {.inline.} = func invalidInstruction*(computation: BaseComputation) {.inline.} =
raise newException(InvalidInstruction, "Invalid instruction, received an opcode not implemented in the current fork.") raise newException(InvalidInstruction, "Invalid instruction, received an opcode not implemented in the current fork.")
let FrontierOpDispatch {.compileTime.}: array[Op, NimNode] = block: let FrontierOpDispatch {.compileTime.}: array[Op, NimNode] = block:
@ -211,7 +211,6 @@ proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNo
`opImpl`(`computation`) `opImpl`(`computation`)
if `computation`.tracingEnabled: if `computation`.tracingEnabled:
`computation`.traceOpCodeEnded(`asOp`, `computation`.opIndex) `computation`.traceOpCodeEnded(`asOp`, `computation`.opIndex)
`instr` = `computation`.code.next()
else: else:
quote do: quote do:
if `computation`.tracingEnabled: if `computation`.tracingEnabled:
@ -221,8 +220,6 @@ proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNo
`computation`.traceOpCodeEnded(`asOp`, `computation`.opIndex) `computation`.traceOpCodeEnded(`asOp`, `computation`.opIndex)
when `asOp` in {Return, Revert, SelfDestruct}: when `asOp` in {Return, Revert, SelfDestruct}:
break break
else:
`instr` = `computation`.code.next()
result.add nnkOfBranch.newTree( result.add nnkOfBranch.newTree(
newIdentNode($op), newIdentNode($op),
@ -233,9 +230,11 @@ proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNo
result = quote do: result = quote do:
if `computation`.tracingEnabled: if `computation`.tracingEnabled:
`computation`.prepareTracer() `computation`.prepareTracer()
`computation`.instr = `computation`.code.next()
while true: while true:
{.computedGoto.} `instr` = `computation`.code.next()
#{.computedGoto.}
# computed goto causing stack overflow, it consumes a lot of space
# we could use manual jump table instead
# TODO lots of macro magic here to unravel, with chronicles... # TODO lots of macro magic here to unravel, with chronicles...
# `computation`.logger.log($`computation`.stack & "\n\n", fgGreen) # `computation`.logger.log($`computation`.stack & "\n\n", fgGreen)
`result` `result`
@ -246,18 +245,14 @@ macro genFrontierDispatch(computation: BaseComputation): untyped =
macro genHomesteadDispatch(computation: BaseComputation): untyped = macro genHomesteadDispatch(computation: BaseComputation): untyped =
result = opTableToCaseStmt(HomesteadOpDispatch, computation) result = opTableToCaseStmt(HomesteadOpDispatch, computation)
proc frontierVM(computation: var BaseComputation) = proc frontierVM(computation: BaseComputation) =
if not computation.execPrecompiles:
genFrontierDispatch(computation) genFrontierDispatch(computation)
proc homesteadVM(computation: var BaseComputation) = proc homesteadVM(computation: BaseComputation) =
if not computation.execPrecompiles:
genHomesteadDispatch(computation) genHomesteadDispatch(computation)
proc executeOpcodes(computation: var BaseComputation) = proc selectVM(computation: BaseComputation, fork: Fork) =
# TODO: Optimise getting fork and updating opCodeExec only when necessary # TODO: Optimise getting fork and updating opCodeExec only when necessary
let fork = computation.getFork
case fork case fork
of FkFrontier..FkThawing: of FkFrontier..FkThawing:
computation.frontierVM() computation.frontierVM()
@ -265,3 +260,15 @@ proc executeOpcodes(computation: var BaseComputation) =
computation.homesteadVM() computation.homesteadVM()
else: else:
raise newException(VMError, "Unknown or not implemented fork: " & $fork) raise newException(VMError, "Unknown or not implemented fork: " & $fork)
proc executeOpcodes(computation: BaseComputation) =
try:
let fork = computation.getFork
if `computation`.execPrecompiles(fork):
computation.nextProc()
return
computation.selectVM(fork)
except:
let msg = getCurrentExceptionMsg()
computation.setError(&"Opcode Dispatch Error msg={msg}, depth={computation.msg.depth}", true)
computation.nextProc()

View File

@ -1,15 +1,16 @@
import import
../vm_types, interpreter/[gas_meter, gas_costs, utils/utils_numeric], ../vm_types, interpreter/[gas_meter, gas_costs, utils/utils_numeric, vm_forks],
../errors, stint, eth/[keys, common], chronicles, tables, macros, ../errors, stint, eth/[keys, common], chronicles, tables, macros,
message, math, nimcrypto, bncurve/[fields, groups] message, math, nimcrypto, bncurve/[fields, groups]
type type
PrecompileAddresses* = enum PrecompileAddresses* = enum
# Frontier to Spurious Dragron
paEcRecover = 1, paEcRecover = 1,
paSha256, paSha256,
paRipeMd160, paRipeMd160,
paIdentity, paIdentity,
# # Byzantium onward
paModExp, paModExp,
paEcAdd, paEcAdd,
paEcMul, paEcMul,
@ -62,7 +63,7 @@ proc getFR(data: openarray[byte]): FR =
if not result.fromBytes2(data): if not result.fromBytes2(data):
raise newException(ValidationError, "Could not get FR value") raise newException(ValidationError, "Could not get FR value")
proc ecRecover*(computation: var BaseComputation) = proc ecRecover*(computation: BaseComputation) =
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
GasECRecover, GasECRecover,
reason="ECRecover Precompile") reason="ECRecover Precompile")
@ -78,7 +79,7 @@ proc ecRecover*(computation: var BaseComputation) =
computation.rawOutput[12..31] = pubKey.toCanonicalAddress() computation.rawOutput[12..31] = pubKey.toCanonicalAddress()
trace "ECRecover precompile", derivedKey = pubKey.toCanonicalAddress() trace "ECRecover precompile", derivedKey = pubKey.toCanonicalAddress()
proc sha256*(computation: var BaseComputation) = proc sha256*(computation: BaseComputation) =
let let
wordCount = wordCount(computation.msg.data.len) wordCount = wordCount(computation.msg.data.len)
gasFee = GasSHA256 + wordCount * GasSHA256Word gasFee = GasSHA256 + wordCount * GasSHA256Word
@ -87,7 +88,7 @@ proc sha256*(computation: var BaseComputation) =
computation.rawOutput = @(nimcrypto.sha_256.digest(computation.msg.data).data) computation.rawOutput = @(nimcrypto.sha_256.digest(computation.msg.data).data)
trace "SHA256 precompile", output = computation.rawOutput.toHex trace "SHA256 precompile", output = computation.rawOutput.toHex
proc ripemd160*(computation: var BaseComputation) = proc ripemd160*(computation: BaseComputation) =
let let
wordCount = wordCount(computation.msg.data.len) wordCount = wordCount(computation.msg.data.len)
gasFee = GasRIPEMD160 + wordCount * GasRIPEMD160Word gasFee = GasRIPEMD160 + wordCount * GasRIPEMD160Word
@ -97,7 +98,7 @@ proc ripemd160*(computation: var BaseComputation) =
computation.rawOutput[12..31] = @(nimcrypto.ripemd160.digest(computation.msg.data).data) computation.rawOutput[12..31] = @(nimcrypto.ripemd160.digest(computation.msg.data).data)
trace "RIPEMD160 precompile", output = computation.rawOutput.toHex trace "RIPEMD160 precompile", output = computation.rawOutput.toHex
proc identity*(computation: var BaseComputation) = proc identity*(computation: BaseComputation) =
let let
wordCount = wordCount(computation.msg.data.len) wordCount = wordCount(computation.msg.data.len)
gasFee = GasIdentity + wordCount * GasIdentityWord gasFee = GasIdentity + wordCount * GasIdentityWord
@ -106,7 +107,7 @@ proc identity*(computation: var BaseComputation) =
computation.rawOutput = computation.msg.data computation.rawOutput = computation.msg.data
trace "Identity precompile", output = computation.rawOutput.toHex trace "Identity precompile", output = computation.rawOutput.toHex
proc modExpInternal(computation: var BaseComputation, base_len, exp_len, mod_len: int, T: type StUint) = proc modExpInternal(computation: BaseComputation, base_len, exp_len, mod_len: int, T: type StUint) =
template rawMsg: untyped {.dirty.} = template rawMsg: untyped {.dirty.} =
computation.msg.data computation.msg.data
@ -170,7 +171,7 @@ proc modExpInternal(computation: var BaseComputation, base_len, exp_len, mod_len
else: else:
computation.rawOutput = @(powmod(base, exp, modulo).toByteArrayBE) computation.rawOutput = @(powmod(base, exp, modulo).toByteArrayBE)
proc modExp*(computation: var BaseComputation) = proc modExp*(computation: BaseComputation) =
## Modular exponentiation precompiled contract ## Modular exponentiation precompiled contract
## Yellow Paper Appendix E ## Yellow Paper Appendix E
## EIP-198 - https://github.com/ethereum/EIPs/blob/master/EIPS/eip-198.md ## EIP-198 - https://github.com/ethereum/EIPs/blob/master/EIPS/eip-198.md
@ -199,7 +200,7 @@ proc modExp*(computation: var BaseComputation) =
else: else:
raise newException(ValueError, "The Nimbus VM doesn't support modular exponentiation with numbers larger than uint8192") raise newException(ValueError, "The Nimbus VM doesn't support modular exponentiation with numbers larger than uint8192")
proc bn256ecAdd*(computation: var BaseComputation) = proc bn256ecAdd*(computation: BaseComputation) =
var var
input: array[128, byte] input: array[128, byte]
output: array[64, byte] output: array[64, byte]
@ -219,7 +220,7 @@ proc bn256ecAdd*(computation: var BaseComputation) =
# computation.gasMeter.consumeGas(gasFee, reason = "ecAdd Precompile") # computation.gasMeter.consumeGas(gasFee, reason = "ecAdd Precompile")
computation.rawOutput = @output computation.rawOutput = @output
proc bn256ecMul*(computation: var BaseComputation) = proc bn256ecMul*(computation: BaseComputation) =
var var
input: array[96, byte] input: array[96, byte]
output: array[64, byte] output: array[64, byte]
@ -241,7 +242,7 @@ proc bn256ecMul*(computation: var BaseComputation) =
# computation.gasMeter.consumeGas(gasFee, reason="ecMul Precompile") # computation.gasMeter.consumeGas(gasFee, reason="ecMul Precompile")
computation.rawOutput = @output computation.rawOutput = @output
proc bn256ecPairing*(computation: var BaseComputation) = proc bn256ecPairing*(computation: BaseComputation) =
var output: array[32, byte] var output: array[32, byte]
let msglen = len(computation.msg.data) let msglen = len(computation.msg.data)
@ -274,12 +275,13 @@ proc bn256ecPairing*(computation: var BaseComputation) =
# computation.gasMeter.consumeGas(gasFee, reason="ecPairing Precompile") # computation.gasMeter.consumeGas(gasFee, reason="ecPairing Precompile")
computation.rawOutput = @output computation.rawOutput = @output
proc execPrecompiles*(computation: var BaseComputation): bool {.inline.} = proc execPrecompiles*(computation: BaseComputation, fork: Fork): bool {.inline.} =
for i in 0..18: for i in 0..18:
if computation.msg.codeAddress[i] != 0: return if computation.msg.codeAddress[i] != 0: return
let lb = computation.msg.codeAddress[19] let lb = computation.msg.codeAddress[19]
if lb in PrecompileAddresses.low.byte .. PrecompileAddresses.high.byte: let maxPrecompileAddr = if fork < FkByzantium: paIdentity else: PrecompileAddresses.high
if lb in PrecompileAddresses.low.byte .. maxPrecompileAddr.byte:
result = true result = true
let precompile = PrecompileAddresses(lb) let precompile = PrecompileAddresses(lb)
trace "Call precompile", precompile = precompile, codeAddr = computation.msg.codeAddress trace "Call precompile", precompile = precompile, codeAddr = computation.msg.codeAddress

View File

@ -65,9 +65,9 @@ proc setupComputation*(vmState: BaseVMState, tx: Transaction, sender, recipient:
proc execComputation*(computation: var BaseComputation): bool = proc execComputation*(computation: var BaseComputation): bool =
if computation.msg.isCreate: if computation.msg.isCreate:
result = computation.applyMessage(Create) computation.applyMessage(Create)
else: else:
result = computation.applyMessage(Call) computation.applyMessage(Call)
computation.vmState.mutateStateDB: computation.vmState.mutateStateDB:
var suicidedCount = 0 var suicidedCount = 0
@ -79,6 +79,7 @@ proc execComputation*(computation: var BaseComputation): bool =
const RefundSelfDestruct = 24_000 const RefundSelfDestruct = 24_000
computation.gasMeter.refundGas(RefundSelfDestruct * suicidedCount) computation.gasMeter.refundGas(RefundSelfDestruct * suicidedCount)
result = computation.isSuccess
if result: if result:
computation.vmState.addLogs(computation.logEntries) computation.vmState.addLogs(computation.logEntries)
else: else:

View File

@ -67,6 +67,11 @@ type
dbsnapshot*: Snapshot dbsnapshot*: Snapshot
instr*: Op instr*: Op
opIndex*: int opIndex*: int
# continuation helpers
nextProc*: proc()
memOutLen*: int
memOutPos*: int
child*: BaseComputation
Error* = ref object Error* = ref object
info*: string info*: string

View File

@ -283,7 +283,7 @@
"0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000060" "0000000000000000000000000000000000000000000000000000000000000060"
], ],
"error": "" "error": "Opcode Dispatch Error msg=Out of gas: Needed 20000 - Remaining 412 - Reason: SSTORE: 9a049f5d18c239efaa258af9f3e7002949a977a0[0] -> 924236965777326770894530693462975209021625492404 (0), depth=0"
} }
], ],
"stateDiff": { "stateDiff": {
@ -704,7 +704,7 @@
"0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000060" "0000000000000000000000000000000000000000000000000000000000000060"
], ],
"error": "" "error": "Opcode Dispatch Error msg=Out of gas: Needed 20000 - Remaining 412 - Reason: SSTORE: 9a049f5d18c239efaa258af9f3e7002949a977a0[0] -> 924236965777326770894530693462975209021625492404 (0), depth=0"
} }
] ]
}, },

View File

@ -13,16 +13,10 @@
# being mostly used for short-term regression prevention. # being mostly used for short-term regression prevention.
func allowedFailingGeneralStateTest*(folder, name: string): bool = func allowedFailingGeneralStateTest*(folder, name: string): bool =
let allowedFailingGeneralStateTests = @[ let allowedFailingGeneralStateTests = @[
"randomStatetest14.json", "randomStatetest14.json", # SHA3 offset
"randomStatetest85.json", "randomStatetest85.json", # CALL* memoffset
# 2019-02-17:
"pairingTest.json",
"pointAdd.json",
"pointAddTrunc.json",
"pointMulAdd.json",
"pointMulAdd2.json",
# Homestead recursives # Homestead recursives
"ContractCreationSpam.json", #["ContractCreationSpam.json",
"Call1024OOG.json", "Call1024OOG.json",
"Call1024PreCalls.json", "Call1024PreCalls.json",
"CallRecursiveBombPreCall.json", "CallRecursiveBombPreCall.json",
@ -49,6 +43,6 @@ func allowedFailingGeneralStateTest*(folder, name: string): bool =
"callcodecallcallcode_ABCB_RECURSIVE.json", "callcodecallcallcode_ABCB_RECURSIVE.json",
"callcodecallcodecall_ABCB_RECURSIVE.json", "callcodecallcodecall_ABCB_RECURSIVE.json",
"callcodecallcodecallcode_ABCB_RECURSIVE.json", "callcodecallcodecallcode_ABCB_RECURSIVE.json",
"callcallcallcode_ABCB_RECURSIVE.json", "callcallcallcode_ABCB_RECURSIVE.json",]#
] ]
result = name in allowedFailingGeneralStateTests result = name in allowedFailingGeneralStateTests

View File

@ -56,10 +56,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
createAddress = toAddress)) createAddress = toAddress))
var computation = newBaseComputation(vmState, header.blockNumber, message) var computation = newBaseComputation(vmState, header.blockNumber, message)
try:
computation.executeOpcodes() computation.executeOpcodes()
except VMError:
computation.error = Error(info: getCurrentExceptionMsg())
if not fixture{"post"}.isNil: if not fixture{"post"}.isNil:
# Success checks # Success checks