Skip to content
This repository has been archived by the owner on Apr 12, 2021. It is now read-only.

Cached safety checking alternative #310

Draft
wants to merge 45 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d80af24
Remove inaccurate visibility kw
maurelian Feb 26, 2021
c897739
Add SafetyCache
maurelian Feb 26, 2021
3fc15f8
Add the caching part
maurelian Feb 26, 2021
4ffe121
[Fix] CI on merge (#251)
annieke Feb 25, 2021
aa350b8
remove uniswapv2ERC20 interface import (#258)
K-Ho Mar 1, 2021
c788737
Reset Context on invalid gaslimit (#260)
ben-chain Mar 2, 2021
cd40831
Add SafetyCache
maurelian Feb 26, 2021
8f2c15e
Add gas test output for em.run()
maurelian Mar 1, 2021
df0560d
Move gas helper code to util'
maurelian Mar 2, 2021
0abc190
Use GasMeasurement class in SM gas spec
maurelian Mar 2, 2021
99c6d7b
Add expect statements
maurelian Mar 2, 2021
c5250a9
remove only()
maurelian Mar 2, 2021
c094e1f
save wip
maurelian Mar 3, 2021
16d8069
remove console.log from solidity
maurelian Mar 3, 2021
f1bd300
Merge branch 'master' into feat/649/cachedSafetyChecking
maurelian Mar 3, 2021
18dfb9c
Merge branch 'master' into feat/649/cachedSafetyChecking
maurelian Mar 3, 2021
a5bc99a
Add cache to test-runner
maurelian Mar 3, 2021
3ef93a8
Add WIP test case.
maurelian Mar 3, 2021
d746561
Add question comments
maurelian Mar 3, 2021
61fe4ad
Save WIP
maurelian Mar 4, 2021
e4af20d
Merge branch 'master' into feat/649/cachedSafetyChecking
maurelian Mar 5, 2021
2217805
Save WIP
maurelian Mar 5, 2021
0f6c144
ongoing debugging - pre-reset
maurelian Mar 7, 2021
b9035a5
Save WIP
maurelian Mar 8, 2021
3e29b15
Simplify tests
maurelian Mar 8, 2021
63fece3
Save with interesting bug
maurelian Mar 9, 2021
c85579d
Save with interesting bug
maurelian Mar 9, 2021
2f830e2
working and heavily annotated with console.log()
maurelian Mar 9, 2021
2c668b0
Merge branch 'master' into feat/649/cachedSafetyChecking
maurelian Mar 9, 2021
4e5a286
Merge branch 'master' into feat/649/cachedSafetyChecking
maurelian Mar 9, 2021
74101a8
Tests working
maurelian Mar 9, 2021
c209482
Tests working
maurelian Mar 9, 2021
f51c0d6
Save working tests with variable bytecode deployment
maurelian Mar 9, 2021
0a6a1f0
remove smoddit
maurelian Mar 9, 2021
a768a05
Add Simple Deployer
maurelian Mar 9, 2021
23df0bd
working deployment of large bytecode
maurelian Mar 9, 2021
57b8c86
failing to deploy large bytecode
maurelian Mar 9, 2021
b1ca4aa
update benchmarks
maurelian Mar 9, 2021
4fae9f6
fix pre-existing EM tests
maurelian Mar 9, 2021
ce61e01
with .only
maurelian Mar 9, 2021
9ec03a4
lint:fix
maurelian Mar 9, 2021
4a60b19
Add getCreateAddress function
maurelian Mar 10, 2021
09fa854
Lint
maurelian Mar 10, 2021
70810c3
Merge branch 'master' into feat/649/cachedSafetyChecking
maurelian Mar 10, 2021
90a3f26
Optimize for cached safe bytecode by checking hash first
maurelian Mar 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@
pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;


/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";

/* Interface Imports */
/* Inherited Interface Imports */
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";

/* External Interface Imports */
import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
import { iOVM_SafetyCache } from "../../iOVM/execution/iOVM_SafetyCache.sol";
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";

/* Contract Imports */
import { OVM_ECDSAContractAccount } from "../accounts/OVM_ECDSAContractAccount.sol";
import { OVM_ProxyEOA } from "../accounts/OVM_ProxyEOA.sol";
import { OVM_DeployerWhitelist } from "../precompiles/OVM_DeployerWhitelist.sol";

/**
* @title OVM_ExecutionManager
Expand All @@ -39,7 +42,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
* External Contract References *
********************************/

iOVM_SafetyChecker internal ovmSafetyChecker;
iOVM_SafetyCache internal ovmSafetyCache;
iOVM_StateManager internal ovmStateManager;


Expand Down Expand Up @@ -81,7 +84,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
)
Lib_AddressResolver(_libAddressManager)
{
ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker"));
ovmSafetyCache = iOVM_SafetyCache(resolve("OVM_SafetyCache"));
gasMeterConfig = _gasMeterConfig;
globalContext = _globalContext;
_resetContext();
Expand Down Expand Up @@ -808,8 +811,15 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
_revertWithFlag(RevertFlag.CREATE_COLLISION);
}

// Check the creation bytecode against the OVM_SafetyChecker.
if (ovmSafetyChecker.isBytecodeSafe(_bytecode) == false) {
bytes32 codehash = keccak256(abi.encode(_bytecode));
// check if codehash is registered as safe in the cache
bool safe = ovmSafetyCache.isRegisteredSafeBytecode(codehash);
if (safe == false) {
// If not safe, try to register it.
safe = ovmSafetyCache.checkAndRegisterSafeBytecode(_bytecode);
}
// Check status of safe one more time.
if (safe == false) {
_revertWithFlag(RevertFlag.UNSAFE_BYTECODE);
}

Expand Down Expand Up @@ -840,7 +850,16 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// Again simply checking that the deployed code is safe too. Contracts can generate
// arbitrary deployment code, so there's no easy way to analyze this beforehand.
bytes memory deployedCode = Lib_EthUtils.getCode(ethAddress);
if (ovmSafetyChecker.isBytecodeSafe(deployedCode) == false) {

bytes32 deployedCodehash = keccak256(abi.encode(deployedCode));
// check if codehash is registered as safe in the cache
bool deployedSafe = ovmSafetyCache.isRegisteredSafeBytecode(deployedCodehash);
if (deployedSafe == false) {
// If not safe, try to register it.
deployedSafe = ovmSafetyCache.checkAndRegisterSafeBytecode(deployedCode);
}
// Check status of safe one more time.
if (deployedSafe == false) {
_revertWithFlag(RevertFlag.UNSAFE_BYTECODE);
}

Expand Down Expand Up @@ -870,7 +889,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
}

/********************************************
* Public Functions: Deployment Witelisting *
* Internal Functions: Deployment Witelisting *
********************************************/

/**
Expand Down Expand Up @@ -1095,23 +1114,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
* Internal Functions: State Manipulation *
******************************************/

/**
* Checks whether an account exists within the OVM_StateManager.
* @param _address Address of the account to check.
* @return _exists Whether or not the account exists.
*/
function _hasAccount(
address _address
)
internal
returns (
bool _exists
)
{
_checkAccountLoad(_address);
return ovmStateManager.hasAccount(_address);
}

/**
* Checks whether a known empty account exists within the OVM_StateManager.
* @param _address Address of the account to check.
Expand Down
99 changes: 99 additions & 0 deletions contracts/optimistic-ethereum/OVM/execution/OVM_SafetyCache.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.8.0;

/* Library Imports */
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";

/* External Interface Imports */
import { iOVM_SafetyCache } from "../../iOVM/execution/iOVM_SafetyCache.sol";

/* Inherited Interface Imports */
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";

/**
* @title OVM_SafetyCache
* @dev This contract implements a simple registry for caching the hash of any bytecode strings which have
* already been confirmed safe by the Safety Checker.
*
* Compiler used: solc
* Runtime target: EVM
*/
contract OVM_SafetyCache is iOVM_SafetyCache, Lib_AddressResolver {


/*******************************************
* Contract Variables: Contract References *
******************************************/

iOVM_SafetyChecker internal ovmSafetyChecker;


/****************************************
* Contract Variables: Internal Storage *
****************************************/

mapping(bytes32 => bool) internal isSafeCodehash;


/***************
* Constructor *
***************/

/**
* @param _libAddressManager Address of the Address Manager.
*/
constructor(
address _libAddressManager
)
Lib_AddressResolver(_libAddressManager)
{
ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker"));
}


/**********************
* External Functions *
*********************/


/** Checks the registry to see if the verified bytecode is registered as safe. If not, calls to the
* SafetyChecker to see.
* @param _code A bytes32 hash of the code
* @return `true` if the bytecode is safe, `false` otherwise.
*/
function checkAndRegisterSafeBytecode(
bytes memory _code
)
override
external
returns (
bool
) {
bytes32 codehash = keccak256(abi.encode(_code));
if(isSafeCodehash[codehash] == true) {
return true;
}

bool safe = ovmSafetyChecker.isBytecodeSafe(_code);
if(safe) {
isSafeCodehash[codehash] = true;
}
return safe;
}

/** Used to check if bytecode has already been recorded as safe.
* @param _codehash A bytes32 hash of the code
*/
function isRegisteredSafeBytecode(
bytes32 _codehash
)
override
external
view
returns (
bool
)
{
return isSafeCodehash[_codehash] == true;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.8.0;

/* Interface Imports */
/* Inherited Interface Imports */
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.8.0;

/**
* @title iOVM_SafetyCache
*/
interface iOVM_SafetyCache {

/*********************
* External Functions *
**********************/
function checkAndRegisterSafeBytecode(bytes memory _code) external returns (bool);

function isRegisteredSafeBytecode(bytes32 _codehash) external view returns (bool);

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ interface iOVM_SafetyChecker {
* Public Functions *
********************/

function isBytecodeSafe(bytes calldata _bytecode) external pure returns (bool);
function isBytecodeSafe(bytes calldata _bytecode) external returns (bool);
}
34 changes: 34 additions & 0 deletions contracts/test-helpers/Helper_SimpleOvmDeployer.sol

Large diffs are not rendered by default.

Loading