Commit 8b2083da authored by ben-chain's avatar ben-chain

ovmCREATE => evmINVALID consume all test

parent 7abe5fae
...@@ -693,6 +693,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -693,6 +693,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
override override
public public
{ {
console.log("in safecreate with nuisance gas:");
console.log(messageRecord.nuisanceGasLeft);
// Since this function is public, anyone can attempt to directly call it. We need to make // Since this function is public, anyone can attempt to directly call it. We need to make
// sure that the OVM_ExecutionManager itself is the only party that can actually try to // sure that the OVM_ExecutionManager itself is the only party that can actually try to
// call this function. // call this function.
...@@ -734,6 +737,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -734,6 +737,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
// left over since contract calls can only be passed 63/64ths of total gas, so we need to // left over since contract calls can only be passed 63/64ths of total gas, so we need to
// explicitly handle this case here. // explicitly handle this case here.
if (ethAddress == address(0)) { if (ethAddress == address(0)) {
console.log("detected the create exception");
_revertWithFlag(RevertFlag.CREATE_EXCEPTION); _revertWithFlag(RevertFlag.CREATE_EXCEPTION);
} }
...@@ -780,6 +784,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -780,6 +784,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
address _created address _created
) )
{ {
console.log("createContract with addy");
console.logAddress(_contractAddress);
// We always update the nonce of the creating account, even if the creation fails. // We always update the nonce of the creating account, even if the creation fails.
_setAccountNonce(ovmADDRESS(), 1); _setAccountNonce(ovmADDRESS(), 1);
...@@ -868,6 +874,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -868,6 +874,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
bytes memory _returndata bytes memory _returndata
) )
{ {
console.log("starting _handleExternalInteraction with gasLeft");
console.log(gasleft());
// We need to switch over to our next message context for the duration of this call. // We need to switch over to our next message context for the duration of this call.
MessageContext memory prevMessageContext = messageContext; MessageContext memory prevMessageContext = messageContext;
_switchMessageContext(prevMessageContext, _nextMessageContext); _switchMessageContext(prevMessageContext, _nextMessageContext);
...@@ -904,6 +912,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -904,6 +912,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
bytes memory returndataFromFlag bytes memory returndataFromFlag
) = _decodeRevertData(returndata); ) = _decodeRevertData(returndata);
console.log("unsuccessfull safecreate with nuisance gas left post-revert:");
console.log(nuisanceGasLeftPostRevert);
// INVALID_STATE_ACCESS is the only flag that triggers an immediate abort of the // INVALID_STATE_ACCESS is the only flag that triggers an immediate abort of the
// parent EVM message. This behavior is necessary because INVALID_STATE_ACCESS must // parent EVM message. This behavior is necessary because INVALID_STATE_ACCESS must
// halt any further transaction execution that could impact the execution result. // halt any further transaction execution that could impact the execution result.
...@@ -1282,8 +1293,11 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -1282,8 +1293,11 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
bytes memory _revertdata bytes memory _revertdata
) )
{ {
// Running out of gas will return no data, so simulating it shouldn't either. // Out of gas and create exceptions will fundamentally return no data, so simulating it shouldn't either.
if (_flag == RevertFlag.OUT_OF_GAS) { if (
_flag == RevertFlag.OUT_OF_GAS
|| _flag == RevertFlag.CREATE_EXCEPTION
) {
return bytes(''); return bytes('');
} }
...@@ -1336,6 +1350,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -1336,6 +1350,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
} }
// ABI decode the incoming data. // ABI decode the incoming data.
console.log("raw revert data:");
console.logBytes(_revertdata);
return abi.decode(_revertdata, (RevertFlag, uint256, uint256, bytes)); return abi.decode(_revertdata, (RevertFlag, uint256, uint256, bytes));
} }
...@@ -1384,6 +1400,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager { ...@@ -1384,6 +1400,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
) )
internal internal
{ {
console.log("reverting with no info other than flag");
_revertWithFlag(_flag, bytes('')); _revertWithFlag(_flag, bytes(''));
} }
......
...@@ -8,11 +8,14 @@ import { ...@@ -8,11 +8,14 @@ import {
VERIFIED_EMPTY_CONTRACT_HASH, VERIFIED_EMPTY_CONTRACT_HASH,
NUISANCE_GAS_COSTS, NUISANCE_GAS_COSTS,
Helper_TestRunner_BYTELEN, Helper_TestRunner_BYTELEN,
ZERO_ADDRESS
} from '../../../../helpers' } from '../../../../helpers'
const DUMMY_REVERT_DATA = const DUMMY_REVERT_DATA =
'0xdeadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420' '0xdeadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420'
const CREATED_CONTRACT_1 = '0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb'
const test_nuisanceGas: TestDefinition = { const test_nuisanceGas: TestDefinition = {
name: 'Basic tests for nuisance gas', name: 'Basic tests for nuisance gas',
preState: { preState: {
...@@ -38,13 +41,16 @@ import { ...@@ -38,13 +41,16 @@ import {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH, codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20), ethAddress: '0x' + '00'.repeat(20),
}, },
[CREATED_CONTRACT_1]: {
codeHash: VERIFIED_EMPTY_CONTRACT_HASH,
ethAddress: '0x' + '00'.repeat(20),
},
}, },
}, },
}, },
subTests: [ subTests: [
{ {
name: 'ovmCALL consumes nuisance gas of CODESIZE * NUISANCE_GAS_PER_CONTRACT_BYTE', name: 'ovmCALL consumes nuisance gas of CODESIZE * NUISANCE_GAS_PER_CONTRACT_BYTE',
focus: true,
postState: { postState: {
ExecutionManager: { ExecutionManager: {
messageRecord: { messageRecord: {
...@@ -55,7 +61,6 @@ import { ...@@ -55,7 +61,6 @@ import {
parameters: [ parameters: [
{ {
name: 'single ovmCALL', name: 'single ovmCALL',
focus: true,
steps: [ steps: [
// do a non-nuisance-gas-consuming opcode (test runner auto-wraps in ovmCALL) // do a non-nuisance-gas-consuming opcode (test runner auto-wraps in ovmCALL)
{ {
...@@ -66,7 +71,6 @@ import { ...@@ -66,7 +71,6 @@ import {
}, },
{ {
name: 'nested ovmCALL, same address', name: 'nested ovmCALL, same address',
focus: true,
steps: [ steps: [
{ {
functionName: 'ovmCALL', functionName: 'ovmCALL',
...@@ -106,7 +110,7 @@ import { ...@@ -106,7 +110,7 @@ import {
], ],
}, },
{ {
name: 'with a call to already loaded contract inside', name: 'with a call to previously called contract too',
steps: [ steps: [
{ {
functionName: 'ovmCALL', functionName: 'ovmCALL',
...@@ -142,8 +146,7 @@ import { ...@@ -142,8 +146,7 @@ import {
}, },
parameters: [ parameters: [
{ {
name: 'give 1/2 gas to evmREVERT', name: 'give 1/2 gas to evmINVALID',
focus: true,
steps: [ steps: [
{ {
functionName: 'ovmCALL', functionName: 'ovmCALL',
...@@ -165,12 +168,12 @@ import { ...@@ -165,12 +168,12 @@ import {
], ],
}, },
{ {
name: 'with a call to already loaded contract inside', name: 'guve 1/2 gas to a sub-ovmCALL which evmINVALIDs',
steps: [ steps: [
{ {
functionName: 'ovmCALL', functionName: 'ovmCALL',
functionParams: { functionParams: {
gasLimit: OVM_TX_GAS_LIMIT, gasLimit: OVM_TX_GAS_LIMIT / 2,
target: "$DUMMY_OVM_ADDRESS_2", target: "$DUMMY_OVM_ADDRESS_2",
subSteps: [ subSteps: [
{ {
...@@ -178,9 +181,95 @@ import { ...@@ -178,9 +181,95 @@ import {
functionParams: { functionParams: {
gasLimit: OVM_TX_GAS_LIMIT, gasLimit: OVM_TX_GAS_LIMIT,
target: '$DUMMY_OVM_ADDRESS_1', target: '$DUMMY_OVM_ADDRESS_1',
subSteps: [] subSteps: [
{
functionName: 'evmINVALID'
}
]
},
expectedReturnStatus: true,
expectedReturnValue: {
ovmSuccess: false,
returnData: '0x'
}
}
]
}, },
expectedReturnStatus: true expectedReturnStatus: true
},
],
}
]
},
{
name: 'ovmCREATE consumes all allotted nuisance gas if creation code throws data-less exception',
postState: {
ExecutionManager: {
messageRecord: {
// note: this is slightly higher than the "idealized" value which would be:
// OVM_TX_GAS_LIMIT / 2 - 2 * ( Helper_TestRunner_BYTELEN * NUISANCE_GAS_PER_CONTRACT_BYTE )
// This is because there is natural gas consumption between the ovmCALL(GAS/2) and ovmCREATE, which allots nuisance gas via _getNuisanceGasLimit.
// This means that the ovmCREATE exception, DOES consumes all nuisance gas allotted, but that allotment
// is less than the full OVM_TX_GAS_LIMIT / 2 alloted to the parent call.
nuisanceGasLeft: 4603714
}
}
},
parameters: [
{
name: 'give 1/2 gas to ovmCALL => ovmCREATE, evmINVALID',
focus: true,
steps: [
{
functionName: 'ovmCALL',
functionParams: {
target: '$DUMMY_OVM_ADDRESS_1',
gasLimit: OVM_TX_GAS_LIMIT / 2,
subSteps: [
{
functionName: 'ovmCREATE',
functionParams: {
subSteps: [
{
functionName: 'evmINVALID'
}
]
},
expectedReturnStatus: true,
expectedReturnValue: ZERO_ADDRESS
},
]
},
expectedReturnStatus: true,
}
],
},
{
name: 'guve 1/2 gas to a sub-ovmCALL which evmREVERTs',
// focus: true,
steps: [
{
functionName: 'ovmCALL',
functionParams: {
gasLimit: OVM_TX_GAS_LIMIT / 2,
target: "$DUMMY_OVM_ADDRESS_2",
subSteps: [
{
functionName: 'ovmCALL',
functionParams: {
gasLimit: OVM_TX_GAS_LIMIT,
target: '$DUMMY_OVM_ADDRESS_1',
subSteps: [
{
functionName: 'evmINVALID'
}
]
},
expectedReturnStatus: true,
expectedReturnValue: {
ovmSuccess: false,
returnData: '0x'
}
} }
] ]
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment