mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-23 10:40:51 +00:00
Bugfix: Off by 1 in EIP-170 code size checks in stateless
Fixes an off by 1 error where `EIP170_CODE_SIZE_LIMIT` was being treated as the lowest invalid value by EVM code, but the highest valid value by witness code. To remove confusion, this is renamed to `EIP170_MAX_CODE_SIZE` with value 0x6000, which matches the name (`MAX_CODE_SIZE`) and value used for this limit in [EIP-170](https://eips.ethereum.org/EIPS/eip-170). Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
40fbed49cf
commit
242dfdd5ac
@ -54,9 +54,10 @@ const
|
||||
|
||||
## Fork specific constants
|
||||
|
||||
# See: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md
|
||||
# and: https://github.com/ethereum/EIPs/issues/170
|
||||
EIP170_CODE_SIZE_LIMIT* = 24577
|
||||
# See EIP-170 (https://eips.ethereum.org/EIPS/eip-170). Maximum code size
|
||||
# that can be stored for a new contract. Init code when creating a new
|
||||
# contract is not subject to this limit.
|
||||
EIP170_MAX_CODE_SIZE* = 0x6000
|
||||
|
||||
# EIP
|
||||
MaxPrecompilesAddr* = 0xFFFF
|
||||
|
@ -232,8 +232,9 @@ proc writeContract*(c: Computation, fork: Fork): bool {.gcsafe.} =
|
||||
let contractCode = c.output
|
||||
if contractCode.len == 0: return
|
||||
|
||||
if fork >= FkSpurious and contractCode.len >= EIP170_CODE_SIZE_LIMIT:
|
||||
debug "Contract code size exceeds EIP170", limit=EIP170_CODE_SIZE_LIMIT, actual=contractCode.len
|
||||
if fork >= FkSpurious and contractCode.len > EIP170_MAX_CODE_SIZE:
|
||||
debug "Contract code size exceeds EIP170",
|
||||
max = EIP170_MAX_CODE_SIZE, actual = contractCode.len
|
||||
return false
|
||||
|
||||
if fork >= FkLondon and contractCode[0] == 0xEF.byte:
|
||||
|
@ -169,10 +169,9 @@ proc writeContract*(c: Computation, fork: Fork): bool {.gcsafe.} =
|
||||
let contractCode = c.output
|
||||
if contractCode.len == 0: return
|
||||
|
||||
if fork >= FkSpurious and contractCode.len >= EIP170_CODE_SIZE_LIMIT:
|
||||
if fork >= FkSpurious and contractCode.len > EIP170_MAX_CODE_SIZE:
|
||||
debug "Contract code size exceeds EIP170",
|
||||
limit = EIP170_CODE_SIZE_LIMIT,
|
||||
actual = contractCode.len
|
||||
max = EIP170_MAX_CODE_SIZE, actual = contractCode.len
|
||||
return false
|
||||
|
||||
if fork >= FkLondon and contractCode[0] == 0xEF.byte:
|
||||
|
@ -174,7 +174,7 @@ proc writeByteCode(wb: var WitnessBuilder, kd: KeyData, acc: Account) =
|
||||
# in current block execution
|
||||
wb.writeByte(CodeUntouched, "codeType")
|
||||
let code = get(wb.db, contractHashKey(acc.codeHash).toOpenArray)
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_CODE_SIZE_LIMIT:
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_MAX_CODE_SIZE:
|
||||
raise newException(ContractCodeError, "code len exceed EIP170 code size limit")
|
||||
wb.writeUVarint32(code.len, "codeLen")
|
||||
wb.writeHashNode(acc.codeHash.data, "codeHash")
|
||||
@ -189,7 +189,7 @@ proc writeByteCode(wb: var WitnessBuilder, kd: KeyData, acc: Account) =
|
||||
|
||||
# the account have code and the EVM use it
|
||||
let code = get(wb.db, contractHashKey(acc.codeHash).toOpenArray)
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_CODE_SIZE_LIMIT:
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_MAX_CODE_SIZE:
|
||||
raise newException(ContractCodeError, "code len exceed EIP170 code size limit")
|
||||
wb.writeUVarint32(code.len, "codeLen")
|
||||
wb.write(code, "code")
|
||||
|
@ -370,7 +370,7 @@ proc readAddress(t: var TreeBuilder): Hash256 =
|
||||
|
||||
proc readCodeLen(t: var TreeBuilder): int =
|
||||
let codeLen = t.readUVarint32()
|
||||
if wfEIP170 in t.flags and codeLen > EIP170_CODE_SIZE_LIMIT:
|
||||
if wfEIP170 in t.flags and codeLen > EIP170_MAX_CODE_SIZE:
|
||||
raise newException(ContractCodeError, "code len exceed EIP170 code size limit: " & $codeLen)
|
||||
t.keys[^1].codeLen = codeLen.int
|
||||
result = codeLen.int
|
||||
|
@ -162,7 +162,7 @@ proc writeByteCode(wb: var WitnessBuilder, kd: KeyData, acc: Account, depth: int
|
||||
# in current block execution
|
||||
wb.writeByte(CodeUntouched)
|
||||
let code = get(wb.db, contractHashKey(acc.codeHash).toOpenArray)
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_CODE_SIZE_LIMIT:
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_MAX_CODE_SIZE:
|
||||
raise newException(ContractCodeError, "code len exceed EIP170 code size limit")
|
||||
wb.writeUVarint32(code.len)
|
||||
wb.writeHashNode(acc.codeHash.data, depth, false)
|
||||
@ -177,7 +177,7 @@ proc writeByteCode(wb: var WitnessBuilder, kd: KeyData, acc: Account, depth: int
|
||||
|
||||
# the account have code and the EVM use it
|
||||
let code = get(wb.db, contractHashKey(acc.codeHash).toOpenArray)
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_CODE_SIZE_LIMIT:
|
||||
if wfEIP170 in wb.flags and code.len > EIP170_MAX_CODE_SIZE:
|
||||
raise newException(ContractCodeError, "code len exceed EIP170 code size limit")
|
||||
wb.writeUVarint32(code.len)
|
||||
wb.write(code)
|
||||
|
Loading…
x
Reference in New Issue
Block a user