unifying contract collision detection
This commit is contained in:
parent
16a938d3fa
commit
73c60fe694
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue