unifying contract collision detection

This commit is contained in:
andri lim 2020-01-15 13:28:05 +07:00 committed by zah
parent 16a938d3fa
commit 73c60fe694
4 changed files with 11 additions and 16 deletions

View File

@ -29,7 +29,6 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
if balance < upfrontGasCost: break if balance < upfrontGasCost: break
let recipient = tx.getRecipient() let recipient = tx.getRecipient()
let isCollision = vmState.readOnlyStateDb().hasCodeOrNonce(recipient)
var c = setupComputation(vmState, tx, sender, recipient, fork) var c = setupComputation(vmState, tx, sender, recipient, fork)
if c.isNil: # OOG in setupComputation if c.isNil: # OOG in setupComputation
@ -40,7 +39,6 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
db.incNonce(sender) db.incNonce(sender)
db.subBalance(sender, upfrontGasCost) db.subBalance(sender, upfrontGasCost)
if tx.isContractCreation and isCollision: break
execComputation(c) execComputation(c)
if not c.shouldBurnGas: if not c.shouldBurnGas:
gasUsed = c.refundGas(tx, sender) gasUsed = c.refundGas(tx, sender)

View File

@ -144,7 +144,13 @@ proc applyMessage*(c: Computation, opCode: static[Op]) =
defer: defer:
c.dispose() c.dispose()
when opCode in {Create, Create2}: when opCode == Create:
if c.vmState.readOnlyStateDb().hasCodeOrNonce(c.msg.contractAddress):
c.setError("Address collision when creating contract address={c.msg.contractAddress.toHex}", true)
c.rollback()
c.nextProc()
return
c.vmState.mutateStateDb: c.vmState.mutateStateDb:
db.clearStorage(c.msg.contractAddress) db.clearStorage(c.msg.contractAddress)
if c.fork >= FkSpurious: if c.fork >= FkSpurious:

View File

@ -539,8 +539,7 @@ proc setupCreate(c: Computation, memPos, len: int, value: Uint256, opCode: stati
callData = c.memory.read(memPos, len) callData = c.memory.read(memPos, len)
var var
createMsgGas = c.getGasRemaining() createMsgGas = c.gasMeter.gasRemaining
if c.fork >= FkTangerine: if c.fork >= FkTangerine:
createMsgGas -= createMsgGas div 64 createMsgGas -= createMsgGas div 64
@ -555,25 +554,16 @@ proc setupCreate(c: Computation, memPos, len: int, value: Uint256, opCode: stati
when opCode == Create: when opCode == Create:
const callKind = evmcCreate const callKind = evmcCreate
c.vmState.mutateStateDB: c.vmState.mutateStateDB:
# Regarding collisions, see: https://github.com/status-im/nimbus/issues/133
# See: https://github.com/ethereum/EIPs/issues/684
let creationNonce = db.getNonce(c.msg.contractAddress) let creationNonce = db.getNonce(c.msg.contractAddress)
db.setNonce(c.msg.contractAddress, creationNonce + 1) db.setNonce(c.msg.contractAddress, creationNonce + 1)
contractAddress = generateAddress(c.msg.contractAddress, creationNonce) contractAddress = generateAddress(c.msg.contractAddress, creationNonce)
isCollision = db.hasCodeOrNonce(contractAddress)
else: else:
const callKind = evmcCreate2 const callKind = evmcCreate2
c.vmState.mutateStateDB: c.vmState.mutateStateDB:
db.incNonce(c.msg.contractAddress) db.incNonce(c.msg.contractAddress)
let salt = c.stack.popInt() let salt = c.stack.popInt()
contractAddress = generateSafeAddress(c.msg.contractAddress, salt, callData) contractAddress = generateSafeAddress(c.msg.contractAddress, salt, callData)
isCollision = db.hasCodeOrNonce(contractAddress)
if isCollision:
debug "Address collision while creating contract", address = contractAddress.toHex
push: 0
return
let childMsg = Message( let childMsg = Message(
kind: callKind, kind: callKind,

View File

@ -70,6 +70,7 @@ proc execComputation*(c: Computation) =
if c.fork >= FkSpurious: if c.fork >= FkSpurious:
c.collectTouchedAccounts() c.collectTouchedAccounts()
if c.isSuccess:
c.refundSelfDestruct() c.refundSelfDestruct()
c.vmState.suicides = c.getSuicides() c.vmState.suicides = c.getSuicides()