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:
Yuriy Glukhov 2018-07-18 12:14:28 +03:00 committed by Mamy Ratsimbazafy
parent ca5eba20f8
commit 6c67115ef5
4 changed files with 64 additions and 45 deletions

View File

@ -150,12 +150,12 @@ VMTests
+ mulmoddivByZero2.json OK
+ mulmoddivByZero3.json OK
+ not1.json OK
- sdiv0.json Fail
+ sdiv0.json OK
+ sdiv1.json OK
+ sdiv2.json OK
- sdiv3.json Fail
- sdiv4.json Fail
- sdiv5.json Fail
+ sdiv3.json OK
+ sdiv4.json OK
+ sdiv5.json OK
+ sdiv6.json OK
+ sdiv7.json OK
+ sdiv8.json OK
@ -164,8 +164,8 @@ VMTests
+ sdivByZero1.json OK
+ sdivByZero2.json OK
+ sdiv_dejavu.json OK
- sdiv_i256min.json Fail
- sdiv_i256min2.json Fail
+ sdiv_i256min.json OK
+ sdiv_i256min2.json OK
+ sdiv_i256min3.json OK
+ signextendInvalidByteNumber.json OK
+ signextend_00.json OK
@ -180,9 +180,9 @@ VMTests
+ signextend_Overflow_dj42.json OK
+ signextend_bigBytePlus1.json OK
+ signextend_bitIsSet.json OK
- smod0.json Fail
- smod1.json Fail
- smod2.json Fail
+ smod0.json OK
+ smod1.json OK
+ smod2.json OK
+ smod3.json OK
+ smod4.json OK
+ smod5.json OK
@ -190,7 +190,7 @@ VMTests
+ smod7.json OK
+ smod8_byZero.json OK
+ smod_i256min1.json OK
- smod_i256min2.json Fail
+ smod_i256min2.json OK
+ stop.json OK
+ sub0.json OK
+ sub1.json OK
@ -198,7 +198,7 @@ VMTests
+ sub3.json OK
+ sub4.json OK
```
OK: 185/195 Fail: 10/195 Skip: 0/195
OK: 195/195 Fail: 0/195 Skip: 0/195
## vmBitwiseLogicOperation
```diff
+ and0.json OK
@ -349,7 +349,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
+ BlockNumberDynamicJumpi0.json OK
+ BlockNumberDynamicJumpi1.json OK
+ BlockNumberDynamicJumpi1_jumpdest.json OK
- BlockNumberDynamicJumpiAfterStop.json Fail
+ BlockNumberDynamicJumpiAfterStop.json OK
- BlockNumberDynamicJumpiOutsideBoundary.json Fail
+ BlockNumberDynamicJumpifInsidePushWithJumpDest.json OK
+ BlockNumberDynamicJumpifInsidePushWithoutJumpDest.json OK
@ -361,7 +361,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
+ DynamicJump0_jumpdest2.json OK
+ DynamicJump0_withoutJumpdest.json OK
+ DynamicJump1.json OK
- DynamicJumpAfterStop.json Fail
+ DynamicJumpAfterStop.json OK
+ DynamicJumpInsidePushWithJumpDest.json OK
+ DynamicJumpInsidePushWithoutJumpDest.json OK
+ DynamicJumpJD_DependsOnJumps0.json OK
@ -378,7 +378,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
+ DynamicJumpi0.json OK
+ DynamicJumpi1.json OK
+ DynamicJumpi1_jumpdest.json OK
- DynamicJumpiAfterStop.json Fail
+ DynamicJumpiAfterStop.json OK
- DynamicJumpiOutsideBoundary.json Fail
+ DynamicJumpifInsidePushWithJumpDest.json OK
+ DynamicJumpifInsidePushWithoutJumpDest.json OK
@ -423,13 +423,13 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
+ jump0_outOfBoundary.json OK
+ jump0_withoutJumpdest.json OK
+ jump1.json OK
- jumpAfterStop.json Fail
+ jumpAfterStop.json OK
+ jumpDynamicJumpSameDest.json OK
+ jumpHigh.json OK
+ jumpInsidePushWithJumpDest.json OK
+ jumpInsidePushWithoutJumpDest.json OK
+ jumpOntoJump.json OK
- jumpTo1InstructionafterJump.json Fail
+ jumpTo1InstructionafterJump.json OK
+ jumpTo1InstructionafterJump_jumpdestFirstInstruction.json OK
+ jumpTo1InstructionafterJump_noJumpDest.json OK
- jumpToUint64maxPlus1.json Fail
@ -438,7 +438,7 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
+ jumpi0.json OK
+ jumpi1.json OK
+ jumpi1_jumpdest.json OK
- jumpiAfterStop.json Fail
+ jumpiAfterStop.json OK
- jumpiOutsideBoundary.json Fail
- jumpiToUint64maxPlus1.json Fail
+ jumpiToUintmaxPlus1.json OK
@ -476,14 +476,14 @@ OK: 28/52 Fail: 9/52 Skip: 15/52
+ sha3MemExp.json OK
+ sstore_load_0.json OK
- sstore_load_1.json Fail
- sstore_load_2.json Fail
+ sstore_load_2.json OK
+ sstore_underflow.json OK
- stack_loop.json Fail
+ stackjump1.json OK
+ swapAt52becameMstore.json OK
+ when.json OK
```
OK: 113/145 Fail: 31/145 Skip: 1/145
OK: 120/145 Fail: 24/145 Skip: 1/145
## vmLogTest
```diff
+ log0_emptyMem.json OK

View File

@ -46,7 +46,7 @@ const
GAS_LIMIT_MINIMUM* = 5000
BLANK_ROOT_HASH* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".toDigest
EMPTY_SHA3* = "883f7328a6c30727a655daff17eba3a86049871bc7839a5b71e2bc26a99c4d4c".toDigest
EMPTY_SHA3* = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".toDigest
GAS_MOD_EXP_QUADRATIC_DENOMINATOR* = 20.u256

View File

@ -44,12 +44,20 @@ op divide, inline = true, lhs, rhs:
op sdiv, inline = true, lhs, rhs:
## 0x05, Signed division
push:
if rhs == 0: zero(Uint256)
var r: 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:
pseudoSignedToUnsigned(
lhs.unsignedToPseudoSigned div rhs.unsignedToPseudoSigned
)
r = a div b
setSign(r, signA xor signB)
push(r)
op modulo, inline = true, lhs, rhs:
## 0x06, Modulo
@ -59,12 +67,17 @@ op modulo, inline = true, lhs, rhs:
op smod, inline = true, lhs, rhs:
## 0x07, Signed modulo
push:
if rhs == 0: zero(UInt256)
else:
pseudoSignedToUnsigned(
lhs.unsignedToPseudoSigned mod rhs.unsignedToPseudoSigned
)
var r: UInt256
if rhs != 0:
var sign: bool
var v = lhs
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:
## 0x08, Modulo addition
@ -182,6 +195,9 @@ op sha3, inline = true, startPos, length:
computation.memory.extend(pos, len)
let endRange = min(pos + len, computation.memory.len) - 1
if endRange == -1:
push(EMPTY_SHA3)
else:
push:
keccak256.digest computation.memory.bytes.toOpenArray(pos, endRange)
@ -421,8 +437,8 @@ op sstore, inline = false, slot, value:
let (currentValue, existing) = computation.vmState.readOnlyStateDB.getStorage(computation.msg.storageAddress, slot)
let
gasParam = GasParams(kind: Op.Sstore, s_isStorageEmpty: not existing)
(gasCost, gasRefund) = computation.gasCosts[Sstore].c_handler(currentValue, gasParam)
gasParam = GasParams(kind: Op.Sstore, s_isStorageEmpty: currentValue.isZero)
(gasCost, gasRefund) = computation.gasCosts[Sstore].c_handler(value, gasParam)
computation.gasMeter.consumeGas(gasCost, &"SSTORE: {computation.msg.storageAddress}[{slot}] -> {value} ({currentValue})")

View File

@ -15,16 +15,6 @@ import
func log256*(value: UInt256): Natural {.inline.}=
(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.}=
# 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.
# EVM words is rounded up
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)