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
|
||||
+ 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,8 +195,11 @@ op sha3, inline = true, startPos, length:
|
|||
|
||||
computation.memory.extend(pos, len)
|
||||
let endRange = min(pos + len, computation.memory.len) - 1
|
||||
push:
|
||||
keccak256.digest computation.memory.bytes.toOpenArray(pos, endRange)
|
||||
if endRange == -1:
|
||||
push(EMPTY_SHA3)
|
||||
else:
|
||||
push:
|
||||
keccak256.digest computation.memory.bytes.toOpenArray(pos, endRange)
|
||||
|
||||
# ##########################################
|
||||
# 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
|
||||
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})")
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue