Fixed sstore gas computation, empty sha3, smod, sdiv (#71)
* Fixed sstore gas computation, fixed empty sha3 * Fixed smod and sdiv * Comments addressed
This commit is contained in:
parent
ca5eba20f8
commit
6c67115ef5
38
VMTests.md
38
VMTests.md
|
@ -150,12 +150,12 @@ VMTests
|
||||||
+ mulmoddivByZero2.json OK
|
+ mulmoddivByZero2.json OK
|
||||||
+ mulmoddivByZero3.json OK
|
+ mulmoddivByZero3.json OK
|
||||||
+ not1.json OK
|
+ not1.json OK
|
||||||
- sdiv0.json Fail
|
+ sdiv0.json OK
|
||||||
+ sdiv1.json OK
|
+ sdiv1.json OK
|
||||||
+ sdiv2.json OK
|
+ sdiv2.json OK
|
||||||
- sdiv3.json Fail
|
+ sdiv3.json OK
|
||||||
- sdiv4.json Fail
|
+ sdiv4.json OK
|
||||||
- sdiv5.json Fail
|
+ sdiv5.json OK
|
||||||
+ sdiv6.json OK
|
+ sdiv6.json OK
|
||||||
+ sdiv7.json OK
|
+ sdiv7.json OK
|
||||||
+ sdiv8.json OK
|
+ sdiv8.json OK
|
||||||
|
@ -164,8 +164,8 @@ VMTests
|
||||||
+ sdivByZero1.json OK
|
+ sdivByZero1.json OK
|
||||||
+ sdivByZero2.json OK
|
+ sdivByZero2.json OK
|
||||||
+ sdiv_dejavu.json OK
|
+ sdiv_dejavu.json OK
|
||||||
- sdiv_i256min.json Fail
|
+ sdiv_i256min.json OK
|
||||||
- sdiv_i256min2.json Fail
|
+ sdiv_i256min2.json OK
|
||||||
+ sdiv_i256min3.json OK
|
+ sdiv_i256min3.json OK
|
||||||
+ signextendInvalidByteNumber.json OK
|
+ signextendInvalidByteNumber.json OK
|
||||||
+ signextend_00.json OK
|
+ signextend_00.json OK
|
||||||
|
@ -180,9 +180,9 @@ VMTests
|
||||||
+ signextend_Overflow_dj42.json OK
|
+ signextend_Overflow_dj42.json OK
|
||||||
+ signextend_bigBytePlus1.json OK
|
+ signextend_bigBytePlus1.json OK
|
||||||
+ signextend_bitIsSet.json OK
|
+ signextend_bitIsSet.json OK
|
||||||
- smod0.json Fail
|
+ smod0.json OK
|
||||||
- smod1.json Fail
|
+ smod1.json OK
|
||||||
- smod2.json Fail
|
+ smod2.json OK
|
||||||
+ smod3.json OK
|
+ smod3.json OK
|
||||||
+ smod4.json OK
|
+ smod4.json OK
|
||||||
+ smod5.json OK
|
+ smod5.json OK
|
||||||
|
@ -190,7 +190,7 @@ VMTests
|
||||||
+ smod7.json OK
|
+ smod7.json OK
|
||||||
+ smod8_byZero.json OK
|
+ smod8_byZero.json OK
|
||||||
+ smod_i256min1.json OK
|
+ smod_i256min1.json OK
|
||||||
- smod_i256min2.json Fail
|
+ smod_i256min2.json OK
|
||||||
+ stop.json OK
|
+ stop.json OK
|
||||||
+ sub0.json OK
|
+ sub0.json OK
|
||||||
+ sub1.json OK
|
+ sub1.json OK
|
||||||
|
@ -198,7 +198,7 @@ VMTests
|
||||||
+ sub3.json OK
|
+ sub3.json OK
|
||||||
+ sub4.json OK
|
+ sub4.json OK
|
||||||
```
|
```
|
||||||
OK: 185/195 Fail: 10/195 Skip: 0/195
|
OK: 195/195 Fail: 0/195 Skip: 0/195
|
||||||
## vmBitwiseLogicOperation
|
## vmBitwiseLogicOperation
|
||||||
```diff
|
```diff
|
||||||
+ and0.json OK
|
+ and0.json OK
|
||||||
|
@ -349,7 +349,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
|
||||||
+ BlockNumberDynamicJumpi0.json OK
|
+ BlockNumberDynamicJumpi0.json OK
|
||||||
+ BlockNumberDynamicJumpi1.json OK
|
+ BlockNumberDynamicJumpi1.json OK
|
||||||
+ BlockNumberDynamicJumpi1_jumpdest.json OK
|
+ BlockNumberDynamicJumpi1_jumpdest.json OK
|
||||||
- BlockNumberDynamicJumpiAfterStop.json Fail
|
+ BlockNumberDynamicJumpiAfterStop.json OK
|
||||||
- BlockNumberDynamicJumpiOutsideBoundary.json Fail
|
- BlockNumberDynamicJumpiOutsideBoundary.json Fail
|
||||||
+ BlockNumberDynamicJumpifInsidePushWithJumpDest.json OK
|
+ BlockNumberDynamicJumpifInsidePushWithJumpDest.json OK
|
||||||
+ BlockNumberDynamicJumpifInsidePushWithoutJumpDest.json OK
|
+ BlockNumberDynamicJumpifInsidePushWithoutJumpDest.json OK
|
||||||
|
@ -361,7 +361,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
|
||||||
+ DynamicJump0_jumpdest2.json OK
|
+ DynamicJump0_jumpdest2.json OK
|
||||||
+ DynamicJump0_withoutJumpdest.json OK
|
+ DynamicJump0_withoutJumpdest.json OK
|
||||||
+ DynamicJump1.json OK
|
+ DynamicJump1.json OK
|
||||||
- DynamicJumpAfterStop.json Fail
|
+ DynamicJumpAfterStop.json OK
|
||||||
+ DynamicJumpInsidePushWithJumpDest.json OK
|
+ DynamicJumpInsidePushWithJumpDest.json OK
|
||||||
+ DynamicJumpInsidePushWithoutJumpDest.json OK
|
+ DynamicJumpInsidePushWithoutJumpDest.json OK
|
||||||
+ DynamicJumpJD_DependsOnJumps0.json OK
|
+ DynamicJumpJD_DependsOnJumps0.json OK
|
||||||
|
@ -378,7 +378,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
|
||||||
+ DynamicJumpi0.json OK
|
+ DynamicJumpi0.json OK
|
||||||
+ DynamicJumpi1.json OK
|
+ DynamicJumpi1.json OK
|
||||||
+ DynamicJumpi1_jumpdest.json OK
|
+ DynamicJumpi1_jumpdest.json OK
|
||||||
- DynamicJumpiAfterStop.json Fail
|
+ DynamicJumpiAfterStop.json OK
|
||||||
- DynamicJumpiOutsideBoundary.json Fail
|
- DynamicJumpiOutsideBoundary.json Fail
|
||||||
+ DynamicJumpifInsidePushWithJumpDest.json OK
|
+ DynamicJumpifInsidePushWithJumpDest.json OK
|
||||||
+ DynamicJumpifInsidePushWithoutJumpDest.json OK
|
+ DynamicJumpifInsidePushWithoutJumpDest.json OK
|
||||||
|
@ -423,13 +423,13 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
|
||||||
+ jump0_outOfBoundary.json OK
|
+ jump0_outOfBoundary.json OK
|
||||||
+ jump0_withoutJumpdest.json OK
|
+ jump0_withoutJumpdest.json OK
|
||||||
+ jump1.json OK
|
+ jump1.json OK
|
||||||
- jumpAfterStop.json Fail
|
+ jumpAfterStop.json OK
|
||||||
+ jumpDynamicJumpSameDest.json OK
|
+ jumpDynamicJumpSameDest.json OK
|
||||||
+ jumpHigh.json OK
|
+ jumpHigh.json OK
|
||||||
+ jumpInsidePushWithJumpDest.json OK
|
+ jumpInsidePushWithJumpDest.json OK
|
||||||
+ jumpInsidePushWithoutJumpDest.json OK
|
+ jumpInsidePushWithoutJumpDest.json OK
|
||||||
+ jumpOntoJump.json OK
|
+ jumpOntoJump.json OK
|
||||||
- jumpTo1InstructionafterJump.json Fail
|
+ jumpTo1InstructionafterJump.json OK
|
||||||
+ jumpTo1InstructionafterJump_jumpdestFirstInstruction.json OK
|
+ jumpTo1InstructionafterJump_jumpdestFirstInstruction.json OK
|
||||||
+ jumpTo1InstructionafterJump_noJumpDest.json OK
|
+ jumpTo1InstructionafterJump_noJumpDest.json OK
|
||||||
- jumpToUint64maxPlus1.json Fail
|
- jumpToUint64maxPlus1.json Fail
|
||||||
|
@ -438,7 +438,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
|
||||||
+ jumpi0.json OK
|
+ jumpi0.json OK
|
||||||
+ jumpi1.json OK
|
+ jumpi1.json OK
|
||||||
+ jumpi1_jumpdest.json OK
|
+ jumpi1_jumpdest.json OK
|
||||||
- jumpiAfterStop.json Fail
|
+ jumpiAfterStop.json OK
|
||||||
- jumpiOutsideBoundary.json Fail
|
- jumpiOutsideBoundary.json Fail
|
||||||
- jumpiToUint64maxPlus1.json Fail
|
- jumpiToUint64maxPlus1.json Fail
|
||||||
+ jumpiToUintmaxPlus1.json OK
|
+ jumpiToUintmaxPlus1.json OK
|
||||||
|
@ -476,14 +476,14 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
|
||||||
+ sha3MemExp.json OK
|
+ sha3MemExp.json OK
|
||||||
+ sstore_load_0.json OK
|
+ sstore_load_0.json OK
|
||||||
- sstore_load_1.json Fail
|
- sstore_load_1.json Fail
|
||||||
- sstore_load_2.json Fail
|
+ sstore_load_2.json OK
|
||||||
+ sstore_underflow.json OK
|
+ sstore_underflow.json OK
|
||||||
- stack_loop.json Fail
|
- stack_loop.json Fail
|
||||||
+ stackjump1.json OK
|
+ stackjump1.json OK
|
||||||
+ swapAt52becameMstore.json OK
|
+ swapAt52becameMstore.json OK
|
||||||
+ when.json OK
|
+ when.json OK
|
||||||
```
|
```
|
||||||
OK: 113/145 Fail: 31/145 Skip: 1/145
|
OK: 120/145 Fail: 24/145 Skip: 1/145
|
||||||
## vmLogTest
|
## vmLogTest
|
||||||
```diff
|
```diff
|
||||||
+ log0_emptyMem.json OK
|
+ log0_emptyMem.json OK
|
||||||
|
|
|
@ -46,7 +46,7 @@ const
|
||||||
GAS_LIMIT_MINIMUM* = 5000
|
GAS_LIMIT_MINIMUM* = 5000
|
||||||
|
|
||||||
BLANK_ROOT_HASH* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".toDigest
|
BLANK_ROOT_HASH* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".toDigest
|
||||||
EMPTY_SHA3* = "883f7328a6c30727a655daff17eba3a86049871bc7839a5b71e2bc26a99c4d4c".toDigest
|
EMPTY_SHA3* = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".toDigest
|
||||||
|
|
||||||
GAS_MOD_EXP_QUADRATIC_DENOMINATOR* = 20.u256
|
GAS_MOD_EXP_QUADRATIC_DENOMINATOR* = 20.u256
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,20 @@ op divide, inline = true, lhs, rhs:
|
||||||
|
|
||||||
op sdiv, inline = true, lhs, rhs:
|
op sdiv, inline = true, lhs, rhs:
|
||||||
## 0x05, Signed division
|
## 0x05, Signed division
|
||||||
push:
|
var r: UInt256
|
||||||
if rhs == 0: zero(Uint256)
|
if rhs != 0:
|
||||||
|
const min = (1.u256 shl 255) - 1.u256
|
||||||
|
var a = lhs
|
||||||
|
var b = rhs
|
||||||
|
var signA, signB: bool
|
||||||
|
extractSign(a, signA)
|
||||||
|
extractSign(b, signB)
|
||||||
|
if a == min and b == not zero(UInt256):
|
||||||
|
r = min
|
||||||
else:
|
else:
|
||||||
pseudoSignedToUnsigned(
|
r = a div b
|
||||||
lhs.unsignedToPseudoSigned div rhs.unsignedToPseudoSigned
|
setSign(r, signA xor signB)
|
||||||
)
|
push(r)
|
||||||
|
|
||||||
op modulo, inline = true, lhs, rhs:
|
op modulo, inline = true, lhs, rhs:
|
||||||
## 0x06, Modulo
|
## 0x06, Modulo
|
||||||
|
@ -59,12 +67,17 @@ op modulo, inline = true, lhs, rhs:
|
||||||
|
|
||||||
op smod, inline = true, lhs, rhs:
|
op smod, inline = true, lhs, rhs:
|
||||||
## 0x07, Signed modulo
|
## 0x07, Signed modulo
|
||||||
push:
|
var r: UInt256
|
||||||
if rhs == 0: zero(UInt256)
|
if rhs != 0:
|
||||||
else:
|
var sign: bool
|
||||||
pseudoSignedToUnsigned(
|
var v = lhs
|
||||||
lhs.unsignedToPseudoSigned mod rhs.unsignedToPseudoSigned
|
var m = rhs
|
||||||
)
|
extractSign(m, sign)
|
||||||
|
extractSign(v, sign)
|
||||||
|
r = v mod m
|
||||||
|
setSign(r, sign)
|
||||||
|
|
||||||
|
push(r)
|
||||||
|
|
||||||
op addmod, inline = true, lhs, rhs, modulus:
|
op addmod, inline = true, lhs, rhs, modulus:
|
||||||
## 0x08, Modulo addition
|
## 0x08, Modulo addition
|
||||||
|
@ -182,8 +195,11 @@ op sha3, inline = true, startPos, length:
|
||||||
|
|
||||||
computation.memory.extend(pos, len)
|
computation.memory.extend(pos, len)
|
||||||
let endRange = min(pos + len, computation.memory.len) - 1
|
let endRange = min(pos + len, computation.memory.len) - 1
|
||||||
push:
|
if endRange == -1:
|
||||||
keccak256.digest computation.memory.bytes.toOpenArray(pos, endRange)
|
push(EMPTY_SHA3)
|
||||||
|
else:
|
||||||
|
push:
|
||||||
|
keccak256.digest computation.memory.bytes.toOpenArray(pos, endRange)
|
||||||
|
|
||||||
# ##########################################
|
# ##########################################
|
||||||
# 30s: Environmental Information
|
# 30s: Environmental Information
|
||||||
|
@ -421,8 +437,8 @@ op sstore, inline = false, slot, value:
|
||||||
let (currentValue, existing) = computation.vmState.readOnlyStateDB.getStorage(computation.msg.storageAddress, slot)
|
let (currentValue, existing) = computation.vmState.readOnlyStateDB.getStorage(computation.msg.storageAddress, slot)
|
||||||
|
|
||||||
let
|
let
|
||||||
gasParam = GasParams(kind: Op.Sstore, s_isStorageEmpty: not existing)
|
gasParam = GasParams(kind: Op.Sstore, s_isStorageEmpty: currentValue.isZero)
|
||||||
(gasCost, gasRefund) = computation.gasCosts[Sstore].c_handler(currentValue, gasParam)
|
(gasCost, gasRefund) = computation.gasCosts[Sstore].c_handler(value, gasParam)
|
||||||
|
|
||||||
computation.gasMeter.consumeGas(gasCost, &"SSTORE: {computation.msg.storageAddress}[{slot}] -> {value} ({currentValue})")
|
computation.gasMeter.consumeGas(gasCost, &"SSTORE: {computation.msg.storageAddress}[{slot}] -> {value} ({currentValue})")
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,6 @@ import
|
||||||
func log256*(value: UInt256): Natural {.inline.}=
|
func log256*(value: UInt256): Natural {.inline.}=
|
||||||
(255 - value.countLeadingZeroBits) shr 3 # div 8
|
(255 - value.countLeadingZeroBits) shr 3 # div 8
|
||||||
|
|
||||||
func unsignedToPseudoSigned*(value: UInt256): UInt256 {.inline.}=
|
|
||||||
result = value
|
|
||||||
if value > INT_256_MAX_AS_UINT256:
|
|
||||||
result -= INT_256_MAX_AS_UINT256
|
|
||||||
|
|
||||||
func pseudoSignedToUnsigned*(value: UInt256): UInt256 {.inline.}=
|
|
||||||
result = value
|
|
||||||
if value > INT_256_MAX_AS_UINT256:
|
|
||||||
result += INT_256_MAX_AS_UINT256
|
|
||||||
|
|
||||||
func ceil32*(value: Natural): Natural {.inline.}=
|
func ceil32*(value: Natural): Natural {.inline.}=
|
||||||
# Round input to the nearest bigger multiple of 32
|
# Round input to the nearest bigger multiple of 32
|
||||||
|
|
||||||
|
@ -38,3 +28,16 @@ func wordCount*(length: Natural): Natural {.inline.}=
|
||||||
# Returns the number of EVM words corresponding to a specific size.
|
# Returns the number of EVM words corresponding to a specific size.
|
||||||
# EVM words is rounded up
|
# EVM words is rounded up
|
||||||
length.ceil32 shr 5 # equivalent to `div 32` (32 = 2^5)
|
length.ceil32 shr 5 # equivalent to `div 32` (32 = 2^5)
|
||||||
|
|
||||||
|
proc flipSign(value: var UInt256) =
|
||||||
|
# ⚠ Warning: low(Int256) (binary repr 0b1000...0000) cannot be negated, please handle this special case
|
||||||
|
value = not value
|
||||||
|
value += 1.u256
|
||||||
|
|
||||||
|
proc extractSign*(v: var UInt256, sign: var bool) =
|
||||||
|
sign = v > INT_256_MAX_AS_UINT256
|
||||||
|
if sign:
|
||||||
|
flipSign(v)
|
||||||
|
|
||||||
|
proc setSign*(v: var UInt256, sign: bool) {.inline.} =
|
||||||
|
if sign: flipSign(v)
|
||||||
|
|
Loading…
Reference in New Issue