Commit e596f566 authored by Alina's avatar Alina Committed by GitHub

remove unused stateTransitionIndex (#108)

* rm unused stateTransitionIndex
parent 1e438d4b
...@@ -3,4 +3,3 @@ artifacts/ ...@@ -3,4 +3,3 @@ artifacts/
cache/ cache/
yarn-error.log yarn-error.log
build/ build/
.DS_STORE
...@@ -434,7 +434,6 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -434,7 +434,6 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
} }
} }
/********************** /**********************
* Internal Functions * * Internal Functions *
**********************/ **********************/
......
...@@ -155,13 +155,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -155,13 +155,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
"Only authenticated addresses in ovmStateManager can call this function" "Only authenticated addresses in ovmStateManager can call this function"
); );
// Initialize the execution context, must be initialized before we perform any gas metering // Check whether we need to start a new epoch, do so if necessary.
// or we'll throw a nuisance gas error. _checkNeedsNewEpoch(_transaction.timestamp);
_initContext(_transaction);
// TEMPORARY: Gas metering is disabled for minnet.
// // Check whether we need to start a new epoch, do so if necessary.
// _checkNeedsNewEpoch(_transaction.timestamp);
// Make sure the transaction's gas limit is valid. We don't revert here because we reserve // Make sure the transaction's gas limit is valid. We don't revert here because we reserve
// reverts for INVALID_STATE_ACCESS. // reverts for INVALID_STATE_ACCESS.
...@@ -169,6 +164,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -169,6 +164,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
return; return;
} }
// Initialize the execution context.
_initContext(_transaction);
// Run the transaction, make sure to meter the gas usage. // Run the transaction, make sure to meter the gas usage.
uint256 gasProvided = gasleft(); uint256 gasProvided = gasleft();
ovmCALL( ovmCALL(
...@@ -178,9 +176,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -178,9 +176,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
); );
uint256 gasUsed = gasProvided - gasleft(); uint256 gasUsed = gasProvided - gasleft();
// TEMPORARY: Gas metering is disabled for minnet. // Update the cumulative gas based on the amount of gas used.
// // Update the cumulative gas based on the amount of gas used. _updateCumulativeGas(gasUsed, _transaction.l1QueueOrigin);
// _updateCumulativeGas(gasUsed, _transaction.l1QueueOrigin);
// Wipe the execution context. // Wipe the execution context.
_resetContext(); _resetContext();
...@@ -501,8 +498,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -501,8 +498,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
address(proxyEOA), address(proxyEOA),
keccak256(Lib_EthUtils.getCode(address(proxyEOA))) keccak256(Lib_EthUtils.getCode(address(proxyEOA)))
); );
// TODO: Set account nonce to zero here (changing in a different PR for auditor convenience).
} }
...@@ -828,7 +823,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -828,7 +823,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
); );
} }
/*************************************** /***************************************
* Public Functions: Execution Context * * Public Functions: Execution Context *
***************************************/ ***************************************/
...@@ -1191,15 +1185,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1191,15 +1185,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
) )
internal internal
{ {
// We don't set storage if the value didn't change. Although this acts as a convenient
// optimization, it's also necessary to avoid the case in which a contract with no storage
// attempts to store the value "0" at any key. Putting this value (and therefore requiring
// that the value be committed into the storage trie after execution) would incorrectly
// modify the storage root.
if (_getContractStorage(_contract, _key) == _value) {
return;
}
_checkContractStorageChange(_contract, _key); _checkContractStorageChange(_contract, _key);
ovmStateManager.putContractStorage(_contract, _key, _value); ovmStateManager.putContractStorage(_contract, _key, _value);
} }
...@@ -1249,17 +1234,13 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1249,17 +1234,13 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
) )
internal internal
{ {
// Start by checking for a load as we only want to charge nuisance gas proportional to
// contract size once.
_checkAccountLoad(_address);
// Check whether the account has been changed before and mark it as changed if not. We need // Check whether the account has been changed before and mark it as changed if not. We need
// this because "nuisance gas" only applies to the first time that an account is changed. // this because "nuisance gas" only applies to the first time that an account is changed.
( (
bool _wasAccountAlreadyChanged bool _wasAccountAlreadyChanged
) = ovmStateManager.testAndSetAccountChanged(_address); ) = ovmStateManager.testAndSetAccountChanged(_address);
// If we hadn't already loaded the account, then we'll need to charge "nuisance gas" based // If we hadn't already changed the account, then we'll need to charge "nuisance gas" based
// on the size of the contract code. // on the size of the contract code.
if (_wasAccountAlreadyChanged == false) { if (_wasAccountAlreadyChanged == false) {
ovmStateManager.incrementTotalUncommittedAccounts(); ovmStateManager.incrementTotalUncommittedAccounts();
...@@ -1323,9 +1304,15 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1323,9 +1304,15 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
) )
internal internal
{ {
// Start by checking for load to make sure we have the storage slot and that we charge the // See `_checkContractStorageLoad` for more information.
// "nuisance gas" necessary to prove the storage slot state. if (gasleft() < MIN_GAS_FOR_INVALID_STATE_ACCESS) {
_checkContractStorageLoad(_contract, _key); _revertWithFlag(RevertFlag.OUT_OF_GAS);
}
// See `_checkContractStorageLoad` for more information.
if (ovmStateManager.hasContractStorage(_contract, _key) == false) {
_revertWithFlag(RevertFlag.INVALID_STATE_ACCESS);
}
// Check whether the slot has been changed before and mark it as changed if not. We need // Check whether the slot has been changed before and mark it as changed if not. We need
// this because "nuisance gas" only applies to the first time that a slot is changed. // this because "nuisance gas" only applies to the first time that a slot is changed.
...@@ -1336,10 +1323,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1336,10 +1323,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// If we hadn't already changed the account, then we'll need to charge some fixed amount of // If we hadn't already changed the account, then we'll need to charge some fixed amount of
// "nuisance gas". // "nuisance gas".
if (_wasContractStorageAlreadyChanged == false) { if (_wasContractStorageAlreadyChanged == false) {
// Changing a storage slot means that we're also going to have to change the
// corresponding account, so do an account change check.
_checkAccountChange(_contract);
ovmStateManager.incrementTotalUncommittedContractStorage(); ovmStateManager.incrementTotalUncommittedContractStorage();
_useNuisanceGas(NUISANCE_GAS_SSTORE); _useNuisanceGas(NUISANCE_GAS_SSTORE);
} }
...@@ -1589,25 +1572,23 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1589,25 +1572,23 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
return false; return false;
} }
// TEMPORARY: Gas metering is disabled for minnet. GasMetadataKey cumulativeGasKey;
return true; GasMetadataKey prevEpochGasKey;
// GasMetadataKey cumulativeGasKey; if (_queueOrigin == Lib_OVMCodec.QueueOrigin.SEQUENCER_QUEUE) {
// GasMetadataKey prevEpochGasKey; cumulativeGasKey = GasMetadataKey.CUMULATIVE_SEQUENCER_QUEUE_GAS;
// if (_queueOrigin == Lib_OVMCodec.QueueOrigin.SEQUENCER_QUEUE) { prevEpochGasKey = GasMetadataKey.PREV_EPOCH_SEQUENCER_QUEUE_GAS;
// cumulativeGasKey = GasMetadataKey.CUMULATIVE_SEQUENCER_QUEUE_GAS; } else {
// prevEpochGasKey = GasMetadataKey.PREV_EPOCH_SEQUENCER_QUEUE_GAS; cumulativeGasKey = GasMetadataKey.CUMULATIVE_L1TOL2_QUEUE_GAS;
// } else { prevEpochGasKey = GasMetadataKey.PREV_EPOCH_L1TOL2_QUEUE_GAS;
// cumulativeGasKey = GasMetadataKey.CUMULATIVE_L1TOL2_QUEUE_GAS; }
// prevEpochGasKey = GasMetadataKey.PREV_EPOCH_L1TOL2_QUEUE_GAS;
// } return (
(
// return ( _getGasMetadata(cumulativeGasKey)
// ( - _getGasMetadata(prevEpochGasKey)
// _getGasMetadata(cumulativeGasKey) + _gasLimit
// - _getGasMetadata(prevEpochGasKey) ) < gasMeterConfig.maxGasPerQueuePerEpoch
// + _gasLimit );
// ) < gasMeterConfig.maxGasPerQueuePerEpoch
// );
} }
/** /**
......
...@@ -17,9 +17,8 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -17,9 +17,8 @@ contract OVM_StateManager is iOVM_StateManager {
* Contract Constants * * Contract Constants *
**********************/ **********************/
bytes32 constant internal EMPTY_ACCOUNT_STORAGE_ROOT = 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421; bytes32 constant internal EMPTY_ACCOUNT_CODE_HASH = 0x00004B1DC0DE000000004B1DC0DE000000004B1DC0DE000000004B1DC0DE0000;
bytes32 constant internal EMPTY_ACCOUNT_CODE_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; bytes32 constant internal STORAGE_XOR_VALUE = 0xFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEF;
bytes32 constant internal STORAGE_XOR_VALUE = 0xFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEF;
/******************************************* /*******************************************
...@@ -138,9 +137,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -138,9 +137,7 @@ contract OVM_StateManager is iOVM_StateManager {
public public
authenticated authenticated
{ {
Lib_OVMCodec.Account storage account = accounts[_address]; accounts[_address].codeHash = EMPTY_ACCOUNT_CODE_HASH;
account.storageRoot = EMPTY_ACCOUNT_STORAGE_ROOT;
account.codeHash = EMPTY_ACCOUNT_CODE_HASH;
} }
/** /**
...@@ -192,10 +189,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -192,10 +189,7 @@ contract OVM_StateManager is iOVM_StateManager {
bool _exists bool _exists
) )
{ {
return ( return accounts[_address].codeHash == EMPTY_ACCOUNT_CODE_HASH;
accounts[_address].codeHash == EMPTY_ACCOUNT_CODE_HASH
&& accounts[_address].nonce == 0
);
} }
/** /**
...@@ -281,8 +275,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -281,8 +275,7 @@ contract OVM_StateManager is iOVM_StateManager {
{ {
Lib_OVMCodec.Account storage account = accounts[_address]; Lib_OVMCodec.Account storage account = accounts[_address];
account.nonce = 1; account.nonce = 1;
account.storageRoot = EMPTY_ACCOUNT_STORAGE_ROOT; account.codeHash = keccak256(hex'');
account.codeHash = EMPTY_ACCOUNT_CODE_HASH;
account.isFresh = true; account.isFresh = true;
} }
...@@ -322,7 +315,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -322,7 +315,7 @@ contract OVM_StateManager is iOVM_StateManager {
) )
{ {
return _testAndSetItemState( return _testAndSetItemState(
_getItemHash(_address), keccak256(abi.encodePacked(_address)),
ItemState.ITEM_LOADED ItemState.ITEM_LOADED
); );
} }
...@@ -343,7 +336,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -343,7 +336,7 @@ contract OVM_StateManager is iOVM_StateManager {
) )
{ {
return _testAndSetItemState( return _testAndSetItemState(
_getItemHash(_address), keccak256(abi.encodePacked(_address)),
ItemState.ITEM_CHANGED ItemState.ITEM_CHANGED
); );
} }
...@@ -363,7 +356,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -363,7 +356,7 @@ contract OVM_StateManager is iOVM_StateManager {
bool _wasAccountCommitted bool _wasAccountCommitted
) )
{ {
bytes32 item = _getItemHash(_address); bytes32 item = keccak256(abi.encodePacked(_address));
if (itemStates[item] != ItemState.ITEM_CHANGED) { if (itemStates[item] != ItemState.ITEM_CHANGED) {
return false; return false;
} }
...@@ -399,45 +392,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -399,45 +392,7 @@ contract OVM_StateManager is iOVM_StateManager {
{ {
return totalUncommittedAccounts; return totalUncommittedAccounts;
} }
/**
* Checks whether a given account was changed during execution.
* @param _address Address to check.
* @return Whether or not the account was changed.
*/
function wasAccountChanged(
address _address
)
override
public
view
returns (
bool
)
{
bytes32 item = _getItemHash(_address);
return itemStates[item] >= ItemState.ITEM_CHANGED;
}
/**
* Checks whether a given account was committed after execution.
* @param _address Address to check.
* @return Whether or not the account was committed.
*/
function wasAccountCommitted(
address _address
)
override
public
view
returns (
bool
)
{
bytes32 item = _getItemHash(_address);
return itemStates[item] >= ItemState.ITEM_COMMITTED;
}
/************************************ /************************************
* Public Functions: Storage Access * * Public Functions: Storage Access *
...@@ -541,7 +496,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -541,7 +496,7 @@ contract OVM_StateManager is iOVM_StateManager {
) )
{ {
return _testAndSetItemState( return _testAndSetItemState(
_getItemHash(_contract, _key), keccak256(abi.encodePacked(_contract, _key)),
ItemState.ITEM_LOADED ItemState.ITEM_LOADED
); );
} }
...@@ -564,7 +519,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -564,7 +519,7 @@ contract OVM_StateManager is iOVM_StateManager {
) )
{ {
return _testAndSetItemState( return _testAndSetItemState(
_getItemHash(_contract, _key), keccak256(abi.encodePacked(_contract, _key)),
ItemState.ITEM_CHANGED ItemState.ITEM_CHANGED
); );
} }
...@@ -586,7 +541,7 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -586,7 +541,7 @@ contract OVM_StateManager is iOVM_StateManager {
bool _wasContractStorageCommitted bool _wasContractStorageCommitted
) )
{ {
bytes32 item = _getItemHash(_contract, _key); bytes32 item = keccak256(abi.encodePacked(_contract, _key));
if (itemStates[item] != ItemState.ITEM_CHANGED) { if (itemStates[item] != ItemState.ITEM_CHANGED) {
return false; return false;
} }
...@@ -623,92 +578,11 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -623,92 +578,11 @@ contract OVM_StateManager is iOVM_StateManager {
return totalUncommittedContractStorage; return totalUncommittedContractStorage;
} }
/**
* Checks whether a given storage slot was changed during execution.
* @param _contract Address to check.
* @param _key Key of the storage slot to check.
* @return Whether or not the storage slot was changed.
*/
function wasContractStorageChanged(
address _contract,
bytes32 _key
)
override
public
view
returns (
bool
)
{
bytes32 item = _getItemHash(_contract, _key);
return itemStates[item] >= ItemState.ITEM_CHANGED;
}
/**
* Checks whether a given storage slot was committed after execution.
* @param _contract Address to check.
* @param _key Key of the storage slot to check.
* @return Whether or not the storage slot was committed.
*/
function wasContractStorageCommitted(
address _contract,
bytes32 _key
)
override
public
view
returns (
bool
)
{
bytes32 item = _getItemHash(_contract, _key);
return itemStates[item] >= ItemState.ITEM_COMMITTED;
}
/********************** /**********************
* Internal Functions * * Internal Functions *
**********************/ **********************/
/**
* Generates a unique hash for an address.
* @param _address Address to generate a hash for.
* @return Unique hash for the given address.
*/
function _getItemHash(
address _address
)
internal
pure
returns (
bytes32
)
{
return keccak256(abi.encodePacked(_address));
}
/**
* Generates a unique hash for an address/key pair.
* @param _contract Address to generate a hash for.
* @param _key Key to generate a hash for.
* @return Unique hash for the given pair.
*/
function _getItemHash(
address _contract,
bytes32 _key
)
internal
pure
returns (
bytes32
)
{
return keccak256(abi.encodePacked(
_contract,
_key
));
}
/** /**
* Checks whether an item is in a particular state (ITEM_LOADED or ITEM_CHANGED) and sets the * Checks whether an item is in a particular state (ITEM_LOADED or ITEM_CHANGED) and sets the
* item to the provided state if not. * item to the provided state if not.
......
...@@ -44,7 +44,7 @@ contract OVM_SequencerEntrypoint { ...@@ -44,7 +44,7 @@ contract OVM_SequencerEntrypoint {
bytes32 r = Lib_BytesUtils.toBytes32(Lib_BytesUtils.slice(msg.data, 1, 32)); bytes32 r = Lib_BytesUtils.toBytes32(Lib_BytesUtils.slice(msg.data, 1, 32));
bytes32 s = Lib_BytesUtils.toBytes32(Lib_BytesUtils.slice(msg.data, 33, 32)); bytes32 s = Lib_BytesUtils.toBytes32(Lib_BytesUtils.slice(msg.data, 33, 32));
uint8 v = Lib_BytesUtils.toUint8(msg.data, 65); uint8 v = Lib_BytesUtils.toUint8(msg.data, 65);
// Remainder is the transaction to execute. // Remainder is the transaction to execute.
bytes memory compressedTx = Lib_BytesUtils.slice(msg.data, 66); bytes memory compressedTx = Lib_BytesUtils.slice(msg.data, 66);
bool isEthSignedMessage = transactionType == TransactionType.ETH_SIGNED_MESSAGE; bool isEthSignedMessage = transactionType == TransactionType.ETH_SIGNED_MESSAGE;
......
...@@ -122,11 +122,22 @@ contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_Fr ...@@ -122,11 +122,22 @@ contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_Fr
); );
require ( require (
_preStateRootBatchHeader.prevTotalElements + _preStateRootProof.index + 1 == _transactionBatchHeader.prevTotalElements + _transactionProof.index, _preStateRootBatchHeader.prevTotalElements + _preStateRootProof.index == _transactionBatchHeader.prevTotalElements + _transactionProof.index,
"Pre-state root global index must equal to the transaction root global index." "Pre-state root global index must equal to the transaction root global index."
); );
_deployTransitioner(_preStateRoot, _txHash, _preStateRootProof.index); deployTransitioner(_preStateRoot, _txHash);
}
// NB: Stack too deep :/
function deployTransitioner(bytes32 _preStateRoot, bytes32 _txHash) private {
transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] = iOVM_StateTransitionerFactory(
resolve("OVM_StateTransitionerFactory")
).create(
address(libAddressManager),
_preStateRoot,
_txHash
);
} }
/** /**
...@@ -189,11 +200,31 @@ contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_Fr ...@@ -189,11 +200,31 @@ contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_Fr
_postStateRoot != transitioner.getPostStateRoot(), _postStateRoot != transitioner.getPostStateRoot(),
"State transition has not been proven fraudulent." "State transition has not been proven fraudulent."
); );
_cancelStateTransition(_postStateRootBatchHeader, _preStateRoot);
// TEMPORARY: Remove the transitioner; for minnet. cancelStateTransition(_postStateRootBatchHeader, _preStateRoot);
transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] = iOVM_StateTransitioner(0x0000000000000000000000000000000000000000); }
// NB: Stack too deep :/
function cancelStateTransition(
Lib_OVMCodec.ChainBatchHeader memory _postStateRootBatchHeader,
bytes32 _preStateRoot
) private {
iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
iOVM_BondManager ovmBondManager = iOVM_BondManager(resolve("OVM_BondManager"));
// delete the state batch
ovmStateCommitmentChain.deleteStateBatch(
_postStateRootBatchHeader
);
// Get the timestamp and publisher for that block
(uint256 timestamp, address publisher) = abi.decode(_postStateRootBatchHeader.extraData, (uint256, address));
// slash the bonds at the bond manager
ovmBondManager.finalize(
_preStateRoot,
publisher,
timestamp
);
} }
...@@ -218,57 +249,4 @@ contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_Fr ...@@ -218,57 +249,4 @@ contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_Fr
{ {
return address(getStateTransitioner(_preStateRoot, _txHash)) != address(0); return address(getStateTransitioner(_preStateRoot, _txHash)) != address(0);
} }
/**
* Deploys a new state transitioner.
* @param _preStateRoot Pre-state root to initialize the transitioner with.
* @param _txHash Hash of the transaction this transitioner will execute.
* @param _stateTransitionIndex Index of the transaction in the chain.
*/
function _deployTransitioner(
bytes32 _preStateRoot,
bytes32 _txHash,
uint256 _stateTransitionIndex
)
internal
{
transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] = iOVM_StateTransitionerFactory(
resolve("OVM_StateTransitionerFactory")
).create(
address(libAddressManager),
_stateTransitionIndex,
_preStateRoot,
_txHash
);
}
/**
* Removes a state transition from the state commitment chain.
* @param _postStateRootBatchHeader Header for the post-state root.
* @param _preStateRoot Pre-state root hash.
*/
function _cancelStateTransition(
Lib_OVMCodec.ChainBatchHeader memory _postStateRootBatchHeader,
bytes32 _preStateRoot
)
internal
{
iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
iOVM_BondManager ovmBondManager = iOVM_BondManager(resolve("OVM_BondManager"));
// Delete the state batch.
ovmStateCommitmentChain.deleteStateBatch(
_postStateRootBatchHeader
);
// Get the timestamp and publisher for that block.
(uint256 timestamp, address publisher) = abi.decode(_postStateRootBatchHeader.extraData, (uint256, address));
// Slash the bonds at the bond manager.
ovmBondManager.finalize(
_preStateRoot,
publisher,
timestamp
);
}
} }
...@@ -6,8 +6,6 @@ pragma experimental ABIEncoderV2; ...@@ -6,8 +6,6 @@ pragma experimental ABIEncoderV2;
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol"; import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
import { Lib_Bytes32Utils } from "../../libraries/utils/Lib_Bytes32Utils.sol";
import { Lib_BytesUtils } from "../../libraries/utils/Lib_BytesUtils.sol";
import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol"; import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol";
import { Lib_RLPWriter } from "../../libraries/rlp/Lib_RLPWriter.sol"; import { Lib_RLPWriter } from "../../libraries/rlp/Lib_RLPWriter.sol";
import { Lib_RLPReader } from "../../libraries/rlp/Lib_RLPReader.sol"; import { Lib_RLPReader } from "../../libraries/rlp/Lib_RLPReader.sol";
...@@ -52,37 +50,25 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -52,37 +50,25 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
bytes32 internal preStateRoot; bytes32 internal preStateRoot;
bytes32 internal postStateRoot; bytes32 internal postStateRoot;
TransitionPhase public phase; TransitionPhase public phase;
uint256 internal stateTransitionIndex;
bytes32 internal transactionHash; bytes32 internal transactionHash;
/*************
* Constants *
*************/
bytes32 internal constant EMPTY_ACCOUNT_CODE_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
bytes32 internal constant EMPTY_ACCOUNT_STORAGE_ROOT = 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421;
/*************** /***************
* Constructor * * Constructor *
***************/ ***************/
/** /**
* @param _libAddressManager Address of the Address Manager. * @param _libAddressManager Address of the Address Manager.
* @param _stateTransitionIndex Index of the state transition being verified.
* @param _preStateRoot State root before the transition was executed. * @param _preStateRoot State root before the transition was executed.
* @param _transactionHash Hash of the executed transaction. * @param _transactionHash Hash of the executed transaction.
*/ */
constructor( constructor(
address _libAddressManager, address _libAddressManager,
uint256 _stateTransitionIndex,
bytes32 _preStateRoot, bytes32 _preStateRoot,
bytes32 _transactionHash bytes32 _transactionHash
) )
Lib_AddressResolver(_libAddressManager) Lib_AddressResolver(_libAddressManager)
{ {
stateTransitionIndex = _stateTransitionIndex;
preStateRoot = _preStateRoot; preStateRoot = _preStateRoot;
postStateRoot = _preStateRoot; postStateRoot = _preStateRoot;
transactionHash = _transactionHash; transactionHash = _transactionHash;
...@@ -158,7 +144,7 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -158,7 +144,7 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
{ {
return phase == TransitionPhase.COMPLETE; return phase == TransitionPhase.COMPLETE;
} }
/*********************************** /***********************************
* Public Functions: Pre-Execution * * Public Functions: Pre-Execution *
...@@ -167,12 +153,13 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -167,12 +153,13 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
/** /**
* Allows a user to prove the initial state of a contract. * Allows a user to prove the initial state of a contract.
* @param _ovmContractAddress Address of the contract on the OVM. * @param _ovmContractAddress Address of the contract on the OVM.
* @param _ethContractAddress Address of the corresponding contract on L1. * @param _account Claimed account state.
* @param _stateTrieWitness Proof of the account state. * @param _stateTrieWitness Proof of the account state.
*/ */
function proveContractState( function proveContractState(
address _ovmContractAddress, address _ovmContractAddress,
address _ethContractAddress, address _ethContractAddress,
Lib_OVMCodec.EVMAccount memory _account,
bytes memory _stateTrieWitness bytes memory _stateTrieWitness
) )
override override
...@@ -182,69 +169,81 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -182,69 +169,81 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
{ {
// Exit quickly to avoid unnecessary work. // Exit quickly to avoid unnecessary work.
require( require(
( ovmStateManager.hasAccount(_ovmContractAddress) == false,
ovmStateManager.hasAccount(_ovmContractAddress) == false "Account state has already been proven"
&& ovmStateManager.hasEmptyAccount(_ovmContractAddress) == false );
require(
_account.codeHash == Lib_EthUtils.getCodeHash(_ethContractAddress),
"Invalid code hash provided."
);
require(
Lib_SecureMerkleTrie.verifyInclusionProof(
abi.encodePacked(_ovmContractAddress),
Lib_OVMCodec.encodeEVMAccount(_account),
_stateTrieWitness,
preStateRoot
), ),
"Account state has already been proven." "Account state is not correct or invalid inclusion proof provided."
); );
// Function will fail if the proof is not a valid inclusion or exclusion proof. ovmStateManager.putAccount(
( _ovmContractAddress,
bool exists, Lib_OVMCodec.Account({
bytes memory encodedAccount nonce: _account.nonce,
) = Lib_SecureMerkleTrie.get( balance: _account.balance,
abi.encodePacked(_ovmContractAddress), storageRoot: _account.storageRoot,
_stateTrieWitness, codeHash: _account.codeHash,
preStateRoot ethAddress: _ethContractAddress,
isFresh: false
})
); );
}
if (exists == true) { /**
// Account exists, this was an inclusion proof. * Allows a user to prove that an account does *not* exist in the state.
Lib_OVMCodec.EVMAccount memory account = Lib_OVMCodec.decodeEVMAccount( * @param _ovmContractAddress Address of the contract on the OVM.
encodedAccount * @param _stateTrieWitness Proof of the (empty) account state.
); */
function proveEmptyContractState(
address _ovmContractAddress,
bytes memory _stateTrieWitness
)
override
public
onlyDuringPhase(TransitionPhase.PRE_EXECUTION)
contributesToFraudProof(preStateRoot, transactionHash)
{
// Exit quickly to avoid unnecessary work.
require(
ovmStateManager.hasEmptyAccount(_ovmContractAddress) == false,
"Account state has already been proven."
);
address ethContractAddress = _ethContractAddress; require(
if (account.codeHash == EMPTY_ACCOUNT_CODE_HASH) { Lib_SecureMerkleTrie.verifyExclusionProof(
// Use a known empty contract to prevent an attack in which a user provides a abi.encodePacked(_ovmContractAddress),
// contract address here and then later deploys code to it. _stateTrieWitness,
ethContractAddress = 0x0000000000000000000000000000000000000000; preStateRoot
} else { ),
// Otherwise, make sure that the code at the provided eth address matches the hash "Account is not empty or invalid inclusion proof provided."
// of the code stored on L2. );
require(
Lib_EthUtils.getCodeHash(ethContractAddress) == account.codeHash, ovmStateManager.putEmptyAccount(_ovmContractAddress);
"OVM_StateTransitioner: Provided L1 contract code hash does not match L2 contract code hash."
);
}
ovmStateManager.putAccount(
_ovmContractAddress,
Lib_OVMCodec.Account({
nonce: account.nonce,
balance: account.balance,
storageRoot: account.storageRoot,
codeHash: account.codeHash,
ethAddress: ethContractAddress,
isFresh: false
})
);
} else {
// Account does not exist, this was an exclusion proof.
ovmStateManager.putEmptyAccount(_ovmContractAddress);
}
} }
/** /**
* Allows a user to prove the initial state of a contract storage slot. * Allows a user to prove the initial state of a contract storage slot.
* @param _ovmContractAddress Address of the contract on the OVM. * @param _ovmContractAddress Address of the contract on the OVM.
* @param _key Claimed account slot key. * @param _key Claimed account slot key.
* @param _value Claimed account slot value.
* @param _storageTrieWitness Proof of the storage slot. * @param _storageTrieWitness Proof of the storage slot.
*/ */
function proveStorageSlot( function proveStorageSlot(
address _ovmContractAddress, address _ovmContractAddress,
bytes32 _key, bytes32 _key,
bytes32 _value,
bytes memory _storageTrieWitness bytes memory _storageTrieWitness
) )
override override
...@@ -263,39 +262,32 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -263,39 +262,32 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
"Contract must be verified before proving a storage slot." "Contract must be verified before proving a storage slot."
); );
bytes32 storageRoot = ovmStateManager.getAccountStorageRoot(_ovmContractAddress); (
bytes32 value; bool exists,
bytes memory encodedValue
) = Lib_SecureMerkleTrie.get(
abi.encodePacked(_key),
_storageTrieWitness,
ovmStateManager.getAccountStorageRoot(_ovmContractAddress)
);
if (storageRoot == EMPTY_ACCOUNT_STORAGE_ROOT) { if (exists == true) {
// Storage trie was empty, so the user is always allowed to insert zero-byte values. bytes memory value = Lib_RLPReader.readBytes(encodedValue);
value = bytes32(0); require(
keccak256(value) == keccak256(abi.encodePacked(_value)),
"Provided storage slot value is invalid."
);
} else { } else {
// Function will fail if the proof is not a valid inclusion or exclusion proof. require(
( _value == bytes32(0),
bool exists, "Provided storage slot value is invalid."
bytes memory encodedValue
) = Lib_SecureMerkleTrie.get(
abi.encodePacked(_key),
_storageTrieWitness,
storageRoot
); );
if (exists == true) {
// Inclusion proof.
// Stored values are RLP encoded, with leading zeros removed.
value = Lib_BytesUtils.toBytes32PadLeft(
Lib_RLPReader.readBytes(encodedValue)
);
} else {
// Exclusion proof, can only be zero bytes.
value = bytes32(0);
}
} }
ovmStateManager.putContractStorage( ovmStateManager.putContractStorage(
_ovmContractAddress, _ovmContractAddress,
_key, _key,
value _value
); );
} }
...@@ -356,13 +348,8 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -356,13 +348,8 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
contributesToFraudProof(preStateRoot, transactionHash) contributesToFraudProof(preStateRoot, transactionHash)
{ {
require( require(
ovmStateManager.getTotalUncommittedContractStorage() == 0,
"All storage must be committed before committing account states."
);
require (
ovmStateManager.commitAccount(_ovmContractAddress) == true, ovmStateManager.commitAccount(_ovmContractAddress) == true,
"Account state wasn't changed or has already been committed." "Account was not changed or has already been committed."
); );
Lib_OVMCodec.Account memory account = ovmStateManager.getAccount(_ovmContractAddress); Lib_OVMCodec.Account memory account = ovmStateManager.getAccount(_ovmContractAddress);
...@@ -375,22 +362,19 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -375,22 +362,19 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
_stateTrieWitness, _stateTrieWitness,
postStateRoot postStateRoot
); );
// Emit an event to help clients figure out the proof ordering.
emit AccountCommitted(
_ovmContractAddress
);
} }
/** /**
* Allows a user to commit the final state of a contract storage slot. * Allows a user to commit the final state of a contract storage slot.
* @param _ovmContractAddress Address of the contract on the OVM. * @param _ovmContractAddress Address of the contract on the OVM.
* @param _key Claimed account slot key. * @param _key Claimed account slot key.
* @param _stateTrieWitness Proof of the account state.
* @param _storageTrieWitness Proof of the storage slot. * @param _storageTrieWitness Proof of the storage slot.
*/ */
function commitStorageSlot( function commitStorageSlot(
address _ovmContractAddress, address _ovmContractAddress,
bytes32 _key, bytes32 _key,
bytes memory _stateTrieWitness,
bytes memory _storageTrieWitness bytes memory _storageTrieWitness
) )
override override
...@@ -400,7 +384,7 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -400,7 +384,7 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
{ {
require( require(
ovmStateManager.commitContractStorage(_ovmContractAddress, _key) == true, ovmStateManager.commitContractStorage(_ovmContractAddress, _key) == true,
"Storage slot value wasn't changed or has already been committed." "Storage slot was not changed or has already been committed."
); );
Lib_OVMCodec.Account memory account = ovmStateManager.getAccount(_ovmContractAddress); Lib_OVMCodec.Account memory account = ovmStateManager.getAccount(_ovmContractAddress);
...@@ -409,19 +393,22 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -409,19 +393,22 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
account.storageRoot = Lib_SecureMerkleTrie.update( account.storageRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_key), abi.encodePacked(_key),
Lib_RLPWriter.writeBytes( Lib_RLPWriter.writeBytes(
Lib_Bytes32Utils.removeLeadingZeros(value) abi.encodePacked(value)
), ),
_storageTrieWitness, _storageTrieWitness,
account.storageRoot account.storageRoot
); );
ovmStateManager.putAccount(_ovmContractAddress, account); postStateRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_ovmContractAddress),
// Emit an event to help clients figure out the proof ordering. Lib_OVMCodec.encodeEVMAccount(
emit ContractStorageCommitted( Lib_OVMCodec.toEVMAccount(account)
_ovmContractAddress, ),
_key _stateTrieWitness,
postStateRoot
); );
ovmStateManager.putAccount(_ovmContractAddress, account);
} }
......
...@@ -20,14 +20,12 @@ contract OVM_StateTransitionerFactory is iOVM_StateTransitionerFactory { ...@@ -20,14 +20,12 @@ contract OVM_StateTransitionerFactory is iOVM_StateTransitionerFactory {
/** /**
* Creates a new OVM_StateTransitioner * Creates a new OVM_StateTransitioner
* @param _libAddressManager Address of the Address Manager. * @param _libAddressManager Address of the Address Manager.
* @param _stateTransitionIndex Index of the state transition being verified.
* @param _preStateRoot State root before the transition was executed. * @param _preStateRoot State root before the transition was executed.
* @param _transactionHash Hash of the executed transaction. * @param _transactionHash Hash of the executed transaction.
* @return _ovmStateTransitioner New OVM_StateTransitioner instance. * @return _ovmStateTransitioner New OVM_StateTransitioner instance.
*/ */
function create( function create(
address _libAddressManager, address _libAddressManager,
uint256 _stateTransitionIndex,
bytes32 _preStateRoot, bytes32 _preStateRoot,
bytes32 _transactionHash bytes32 _transactionHash
) )
...@@ -39,7 +37,6 @@ contract OVM_StateTransitionerFactory is iOVM_StateTransitionerFactory { ...@@ -39,7 +37,6 @@ contract OVM_StateTransitionerFactory is iOVM_StateTransitionerFactory {
{ {
return new OVM_StateTransitioner( return new OVM_StateTransitioner(
_libAddressManager, _libAddressManager,
_stateTransitionIndex,
_preStateRoot, _preStateRoot,
_transactionHash _transactionHash
); );
......
...@@ -56,8 +56,6 @@ interface iOVM_StateManager { ...@@ -56,8 +56,6 @@ interface iOVM_StateManager {
function commitAccount(address _address) external returns (bool _wasAccountCommitted); function commitAccount(address _address) external returns (bool _wasAccountCommitted);
function incrementTotalUncommittedAccounts() external; function incrementTotalUncommittedAccounts() external;
function getTotalUncommittedAccounts() external view returns (uint256 _total); function getTotalUncommittedAccounts() external view returns (uint256 _total);
function wasAccountChanged(address _address) external view returns (bool);
function wasAccountCommitted(address _address) external view returns (bool);
/************************************ /************************************
...@@ -72,6 +70,4 @@ interface iOVM_StateManager { ...@@ -72,6 +70,4 @@ interface iOVM_StateManager {
function commitContractStorage(address _contract, bytes32 _key) external returns (bool _wasContractStorageCommitted); function commitContractStorage(address _contract, bytes32 _key) external returns (bool _wasContractStorageCommitted);
function incrementTotalUncommittedContractStorage() external; function incrementTotalUncommittedContractStorage() external;
function getTotalUncommittedContractStorage() external view returns (uint256 _total); function getTotalUncommittedContractStorage() external view returns (uint256 _total);
function wasContractStorageChanged(address _contract, bytes32 _key) external view returns (bool);
function wasContractStorageCommitted(address _contract, bytes32 _key) external view returns (bool);
} }
...@@ -10,20 +10,6 @@ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; ...@@ -10,20 +10,6 @@ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
*/ */
interface iOVM_StateTransitioner { interface iOVM_StateTransitioner {
/**********
* Events *
**********/
event AccountCommitted(
address _address
);
event ContractStorageCommitted(
address _address,
bytes32 _key
);
/********************************** /**********************************
* Public Functions: State Access * * Public Functions: State Access *
**********************************/ **********************************/
...@@ -40,12 +26,19 @@ interface iOVM_StateTransitioner { ...@@ -40,12 +26,19 @@ interface iOVM_StateTransitioner {
function proveContractState( function proveContractState(
address _ovmContractAddress, address _ovmContractAddress,
address _ethContractAddress, address _ethContractAddress,
Lib_OVMCodec.EVMAccount calldata _account,
bytes calldata _stateTrieWitness
) external;
function proveEmptyContractState(
address _ovmContractAddress,
bytes calldata _stateTrieWitness bytes calldata _stateTrieWitness
) external; ) external;
function proveStorageSlot( function proveStorageSlot(
address _ovmContractAddress, address _ovmContractAddress,
bytes32 _key, bytes32 _key,
bytes32 _value,
bytes calldata _storageTrieWitness bytes calldata _storageTrieWitness
) external; ) external;
...@@ -71,6 +64,7 @@ interface iOVM_StateTransitioner { ...@@ -71,6 +64,7 @@ interface iOVM_StateTransitioner {
function commitStorageSlot( function commitStorageSlot(
address _ovmContractAddress, address _ovmContractAddress,
bytes32 _key, bytes32 _key,
bytes calldata _stateTrieWitness,
bytes calldata _storageTrieWitness bytes calldata _storageTrieWitness
) external; ) external;
......
...@@ -15,7 +15,6 @@ interface iOVM_StateTransitionerFactory { ...@@ -15,7 +15,6 @@ interface iOVM_StateTransitionerFactory {
function create( function create(
address _proxyManager, address _proxyManager,
uint256 _stateTransitionIndex,
bytes32 _preStateRoot, bytes32 _preStateRoot,
bytes32 _transactionHash bytes32 _transactionHash
) )
......
...@@ -6,7 +6,6 @@ pragma experimental ABIEncoderV2; ...@@ -6,7 +6,6 @@ pragma experimental ABIEncoderV2;
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol"; import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol"; import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol"; import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol";
import { Lib_Bytes32Utils } from "../utils/Lib_Bytes32Utils.sol";
/** /**
* @title Lib_OVMCodec * @title Lib_OVMCodec
...@@ -316,16 +315,8 @@ library Lib_OVMCodec { ...@@ -316,16 +315,8 @@ library Lib_OVMCodec {
// Unfortunately we can't create this array outright because // Unfortunately we can't create this array outright because
// RLPWriter.encodeList will reject fixed-size arrays. Assigning // RLPWriter.encodeList will reject fixed-size arrays. Assigning
// index-by-index circumvents this issue. // index-by-index circumvents this issue.
raw[0] = Lib_RLPWriter.writeBytes( raw[0] = Lib_RLPWriter.writeUint(_account.nonce);
Lib_Bytes32Utils.removeLeadingZeros( raw[1] = Lib_RLPWriter.writeUint(_account.balance);
bytes32(_account.nonce)
)
);
raw[1] = Lib_RLPWriter.writeBytes(
Lib_Bytes32Utils.removeLeadingZeros(
bytes32(_account.balance)
)
);
raw[2] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.storageRoot)); raw[2] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.storageRoot));
raw[3] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.codeHash)); raw[3] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.codeHash));
......
...@@ -145,7 +145,9 @@ library Lib_MerkleTrie { ...@@ -145,7 +145,9 @@ library Lib_MerkleTrie {
{ {
// Special case when inserting the very first node. // Special case when inserting the very first node.
if (_root == KECCAK256_RLP_NULL_BYTES) { if (_root == KECCAK256_RLP_NULL_BYTES) {
return getSingleNodeRootHash(_key, _value); return keccak256(
_makeLeafNode(_key, _value).encoded
);
} }
TrieNode[] memory proof = _parseProof(_proof); TrieNode[] memory proof = _parseProof(_proof);
...@@ -210,7 +212,7 @@ library Lib_MerkleTrie { ...@@ -210,7 +212,7 @@ library Lib_MerkleTrie {
) )
{ {
return keccak256(_makeLeafNode( return keccak256(_makeLeafNode(
Lib_BytesUtils.toNibbles(_key), _key,
_value _value
).encoded); ).encoded);
} }
......
...@@ -57,36 +57,4 @@ library Lib_Bytes32Utils { ...@@ -57,36 +57,4 @@ library Lib_Bytes32Utils {
{ {
return bytes32(uint256(_in)); return bytes32(uint256(_in));
} }
function removeLeadingZeros(
bytes32 _in
)
internal
pure
returns (
bytes memory _out
)
{
bytes memory out;
assembly {
// Figure out how many leading zero bytes to remove.
let shift := 0
for { let i := 0 } and(lt(i, 32), eq(byte(i, _in), 0)) { i := add(i, 1) } {
shift := add(shift, 1)
}
// Reserve some space for our output and fix the free memory pointer.
out := mload(0x40)
mstore(0x40, add(out, 0x40))
// Shift the value and store it into the output bytes.
mstore(add(out, 0x20), shl(mul(shift, 8), _in))
// Store the new size (with leading zero bytes removed) in the output byte size.
mstore(out, sub(32, shift))
}
return out;
}
} }
...@@ -170,21 +170,6 @@ library Lib_BytesUtils { ...@@ -170,21 +170,6 @@ library Lib_BytesUtils {
return slice(_bytes, _start, _bytes.length - _start); return slice(_bytes, _start, _bytes.length - _start);
} }
function toBytes32PadLeft(
bytes memory _bytes
)
internal
pure
returns (bytes32)
{
bytes32 ret;
uint256 len = _bytes.length <= 32 ? _bytes.length : 32;
assembly {
ret := shr(mul(sub(32, len), 8), mload(add(_bytes, 32)))
}
return ret;
}
function toBytes32( function toBytes32(
bytes memory _bytes bytes memory _bytes
) )
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
"test:gas": "buidler test \"test/contracts/OVM/execution/OVM_StateManager.gas-spec.ts\" --no-compile --show-stack-traces", "test:gas": "buidler test \"test/contracts/OVM/execution/OVM_StateManager.gas-spec.ts\" --no-compile --show-stack-traces",
"lint": "yarn run lint:typescript", "lint": "yarn run lint:typescript",
"lint:typescript": "tslint --format stylish --project .", "lint:typescript": "tslint --format stylish --project .",
"lint:fix": "yarn run lint:fix:typescript",
"lint:fix:typescript": "prettier --config prettier-config.json --write \"buidler.config.ts\" \"{src,test}/**/*.ts\"", "lint:fix:typescript": "prettier --config prettier-config.json --write \"buidler.config.ts\" \"{src,test}/**/*.ts\"",
"clean": "rm -rf ./artifacts ./build ./cache", "clean": "rm -rf ./artifacts ./build ./cache",
"deploy": "./bin/deploy.js" "deploy": "./bin/deploy.js"
......
...@@ -25,11 +25,8 @@ const callPrecompile = async ( ...@@ -25,11 +25,8 @@ const callPrecompile = async (
if (gasLimit) { if (gasLimit) {
return Helper_PrecompileCaller.callPrecompile( return Helper_PrecompileCaller.callPrecompile(
precompile.address, precompile.address,
precompile.interface.encodeFunctionData( precompile.interface.encodeFunctionData(functionName, functionParams || []),
functionName, {gasLimit}
functionParams || []
),
{ gasLimit }
) )
} }
return Helper_PrecompileCaller.callPrecompile( return Helper_PrecompileCaller.callPrecompile(
...@@ -190,7 +187,7 @@ describe('OVM_ECDSAContractAccount', () => { ...@@ -190,7 +187,7 @@ describe('OVM_ECDSAContractAccount', () => {
it(`should revert on incorrect nonce`, async () => { it(`should revert on incorrect nonce`, async () => {
const alteredNonceTx = { const alteredNonceTx = {
...DEFAULT_EIP155_TX, ...DEFAULT_EIP155_TX,
nonce: 99, nonce : 99
} }
const message = serializeNativeTransaction(alteredNonceTx) const message = serializeNativeTransaction(alteredNonceTx)
const sig = await signNativeTransaction(wallet, alteredNonceTx) const sig = await signNativeTransaction(wallet, alteredNonceTx)
...@@ -244,7 +241,7 @@ describe('OVM_ECDSAContractAccount', () => { ...@@ -244,7 +241,7 @@ describe('OVM_ECDSAContractAccount', () => {
it(`should revert on insufficient gas`, async () => { it(`should revert on insufficient gas`, async () => {
const alteredInsufficientGasTx = { const alteredInsufficientGasTx = {
...DEFAULT_EIP155_TX, ...DEFAULT_EIP155_TX,
gasLimit: 200000000, gasLimit : 200000000
} }
const message = serializeNativeTransaction(alteredInsufficientGasTx) const message = serializeNativeTransaction(alteredInsufficientGasTx)
const sig = await signNativeTransaction(wallet, alteredInsufficientGasTx) const sig = await signNativeTransaction(wallet, alteredInsufficientGasTx)
...@@ -260,7 +257,7 @@ describe('OVM_ECDSAContractAccount', () => { ...@@ -260,7 +257,7 @@ describe('OVM_ECDSAContractAccount', () => {
`0x${sig.r}`, //r `0x${sig.r}`, //r
`0x${sig.s}`, //s `0x${sig.s}`, //s
], ],
40000000 40000000,
) )
const ovmREVERT: any = const ovmREVERT: any =
......
...@@ -188,7 +188,6 @@ describe('OVM_StateManager', () => { ...@@ -188,7 +188,6 @@ describe('OVM_StateManager', () => {
beforeEach(async () => { beforeEach(async () => {
await OVM_StateManager.putAccount(DUMMY_ACCOUNTS[0].address, { await OVM_StateManager.putAccount(DUMMY_ACCOUNTS[0].address, {
...DUMMY_ACCOUNTS[0].data, ...DUMMY_ACCOUNTS[0].data,
nonce: 0,
codeHash: EMPTY_ACCOUNT_CODE_HASH, codeHash: EMPTY_ACCOUNT_CODE_HASH,
}) })
}) })
......
...@@ -179,10 +179,7 @@ describe('OVM_FraudVerifier', () => { ...@@ -179,10 +179,7 @@ describe('OVM_FraudVerifier', () => {
DUMMY_OVM_TRANSACTIONS[0], DUMMY_OVM_TRANSACTIONS[0],
DUMMY_TX_CHAIN_ELEMENTS[0], DUMMY_TX_CHAIN_ELEMENTS[0],
DUMMY_BATCH_HEADERS[0], DUMMY_BATCH_HEADERS[0],
{ DUMMY_BATCH_PROOFS[0]
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 1,
}
) )
).to.not.be.reverted ).to.not.be.reverted
...@@ -229,10 +226,7 @@ describe('OVM_FraudVerifier', () => { ...@@ -229,10 +226,7 @@ describe('OVM_FraudVerifier', () => {
DUMMY_OVM_TRANSACTIONS[0], DUMMY_OVM_TRANSACTIONS[0],
DUMMY_TX_CHAIN_ELEMENTS[0], DUMMY_TX_CHAIN_ELEMENTS[0],
DUMMY_BATCH_HEADERS[0], DUMMY_BATCH_HEADERS[0],
{ DUMMY_BATCH_PROOFS[0]
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 1,
}
) )
}) })
...@@ -436,10 +430,7 @@ describe('OVM_FraudVerifier', () => { ...@@ -436,10 +430,7 @@ describe('OVM_FraudVerifier', () => {
DUMMY_OVM_TRANSACTIONS[1], DUMMY_OVM_TRANSACTIONS[1],
DUMMY_TX_CHAIN_ELEMENTS[0], DUMMY_TX_CHAIN_ELEMENTS[0],
DUMMY_BATCH_HEADERS[0], DUMMY_BATCH_HEADERS[0],
{ DUMMY_BATCH_PROOFS[0]
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 1,
}
) )
).to.not.be.reverted ).to.not.be.reverted
...@@ -482,10 +473,7 @@ describe('OVM_FraudVerifier', () => { ...@@ -482,10 +473,7 @@ describe('OVM_FraudVerifier', () => {
DUMMY_OVM_TRANSACTIONS[1], DUMMY_OVM_TRANSACTIONS[1],
DUMMY_TX_CHAIN_ELEMENTS[1], DUMMY_TX_CHAIN_ELEMENTS[1],
DUMMY_BATCH_HEADERS[1], DUMMY_BATCH_HEADERS[1],
{ DUMMY_BATCH_PROOFS[0]
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 1,
}
) )
// finalize it as well // finalize it as well
...@@ -518,10 +506,7 @@ describe('OVM_FraudVerifier', () => { ...@@ -518,10 +506,7 @@ describe('OVM_FraudVerifier', () => {
DUMMY_OVM_TRANSACTIONS[1], DUMMY_OVM_TRANSACTIONS[1],
DUMMY_TX_CHAIN_ELEMENTS[1], DUMMY_TX_CHAIN_ELEMENTS[1],
DUMMY_BATCH_HEADERS[1], DUMMY_BATCH_HEADERS[1],
{ DUMMY_BATCH_PROOFS[0]
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 1,
}
) )
// finalize the new fraud first // finalize the new fraud first
......
...@@ -84,7 +84,6 @@ describe('OVM_StateTransitioner', () => { ...@@ -84,7 +84,6 @@ describe('OVM_StateTransitioner', () => {
beforeEach(async () => { beforeEach(async () => {
OVM_StateTransitioner = await Factory__OVM_StateTransitioner.deploy( OVM_StateTransitioner = await Factory__OVM_StateTransitioner.deploy(
AddressManager.address, AddressManager.address,
0,
NULL_BYTES32, NULL_BYTES32,
NULL_BYTES32 NULL_BYTES32
) )
...@@ -96,7 +95,6 @@ describe('OVM_StateTransitioner', () => { ...@@ -96,7 +95,6 @@ describe('OVM_StateTransitioner', () => {
let account: any let account: any
beforeEach(() => { beforeEach(() => {
Mock__OVM_StateManager.smocked.hasAccount.will.return.with(false) Mock__OVM_StateManager.smocked.hasAccount.will.return.with(false)
Mock__OVM_StateManager.smocked.hasEmptyAccount.will.return.with(false)
account = { account = {
nonce: 0, nonce: 0,
balance: 0, balance: 0,
...@@ -105,6 +103,23 @@ describe('OVM_StateTransitioner', () => { ...@@ -105,6 +103,23 @@ describe('OVM_StateTransitioner', () => {
} }
}) })
describe('when provided an invalid code hash', () => {
beforeEach(() => {
account.codeHash = NON_NULL_BYTES32
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.proveContractState(
ovmContractAddress,
ethContractAddress,
account,
'0x'
)
).to.be.revertedWith('Invalid code hash provided.')
})
})
describe('when provided a valid code hash', () => { describe('when provided a valid code hash', () => {
beforeEach(async () => { beforeEach(async () => {
ethContractAddress = OVM_StateTransitioner.address ethContractAddress = OVM_StateTransitioner.address
...@@ -121,6 +136,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -121,6 +136,7 @@ describe('OVM_StateTransitioner', () => {
OVM_StateTransitioner.proveContractState( OVM_StateTransitioner.proveContractState(
ovmContractAddress, ovmContractAddress,
ethContractAddress, ethContractAddress,
account,
proof proof
) )
).to.be.reverted ).to.be.reverted
...@@ -146,18 +162,20 @@ describe('OVM_StateTransitioner', () => { ...@@ -146,18 +162,20 @@ describe('OVM_StateTransitioner', () => {
OVM_StateTransitioner = await Factory__OVM_StateTransitioner.deploy( OVM_StateTransitioner = await Factory__OVM_StateTransitioner.deploy(
AddressManager.address, AddressManager.address,
0,
test.accountTrieRoot, test.accountTrieRoot,
NULL_BYTES32 NULL_BYTES32
) )
}) })
it('should put the account in the state manager', async () => { it('should put the account in the state manager', async () => {
await OVM_StateTransitioner.proveContractState( await expect(
ovmContractAddress, OVM_StateTransitioner.proveContractState(
ethContractAddress, ovmContractAddress,
proof ethContractAddress,
) account,
proof
)
).to.not.be.reverted
expect( expect(
Mock__OVM_StateManager.smocked.putAccount.calls[0] Mock__OVM_StateManager.smocked.putAccount.calls[0]
...@@ -192,6 +210,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -192,6 +210,7 @@ describe('OVM_StateTransitioner', () => {
OVM_StateTransitioner.proveStorageSlot( OVM_StateTransitioner.proveStorageSlot(
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS,
NON_NULL_BYTES32, NON_NULL_BYTES32,
NON_NULL_BYTES32,
'0x' '0x'
) )
).to.be.revertedWith( ).to.be.revertedWith(
...@@ -229,7 +248,12 @@ describe('OVM_StateTransitioner', () => { ...@@ -229,7 +248,12 @@ describe('OVM_StateTransitioner', () => {
it('should revert', async () => { it('should revert', async () => {
await expect( await expect(
OVM_StateTransitioner.proveStorageSlot(ZERO_ADDRESS, key, proof) OVM_StateTransitioner.proveStorageSlot(
ZERO_ADDRESS,
key,
val,
proof
)
).to.be.reverted ).to.be.reverted
}) })
}) })
...@@ -259,7 +283,12 @@ describe('OVM_StateTransitioner', () => { ...@@ -259,7 +283,12 @@ describe('OVM_StateTransitioner', () => {
it('should insert the storage slot', async () => { it('should insert the storage slot', async () => {
await expect( await expect(
OVM_StateTransitioner.proveStorageSlot(ZERO_ADDRESS, key, proof) OVM_StateTransitioner.proveStorageSlot(
ZERO_ADDRESS,
key,
val,
proof
)
).to.not.be.reverted ).to.not.be.reverted
expect( expect(
...@@ -298,9 +327,6 @@ describe('OVM_StateTransitioner', () => { ...@@ -298,9 +327,6 @@ describe('OVM_StateTransitioner', () => {
describe('when the account was not changed or has already been committed', () => { describe('when the account was not changed or has already been committed', () => {
before(() => { before(() => {
Mock__OVM_StateManager.smocked.getTotalUncommittedContractStorage.will.return.with(
0
)
Mock__OVM_StateManager.smocked.commitAccount.will.return.with(false) Mock__OVM_StateManager.smocked.commitAccount.will.return.with(false)
}) })
...@@ -308,7 +334,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -308,7 +334,7 @@ describe('OVM_StateTransitioner', () => {
await expect( await expect(
OVM_StateTransitioner.commitContractState(ovmContractAddress, '0x') OVM_StateTransitioner.commitContractState(ovmContractAddress, '0x')
).to.be.revertedWith( ).to.be.revertedWith(
`Account state wasn't changed or has already been committed` 'Account was not changed or has already been committed.'
) )
}) })
}) })
...@@ -397,9 +423,14 @@ describe('OVM_StateTransitioner', () => { ...@@ -397,9 +423,14 @@ describe('OVM_StateTransitioner', () => {
it('should revert', async () => { it('should revert', async () => {
await expect( await expect(
OVM_StateTransitioner.commitStorageSlot(ovmContractAddress, key, '0x') OVM_StateTransitioner.commitStorageSlot(
ovmContractAddress,
key,
'0x',
'0x'
)
).to.be.revertedWith( ).to.be.revertedWith(
`Storage slot value wasn't changed or has already been committed.` 'Storage slot was not changed or has already been committed.'
) )
}) })
}) })
...@@ -472,6 +503,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -472,6 +503,7 @@ describe('OVM_StateTransitioner', () => {
OVM_StateTransitioner.commitStorageSlot( OVM_StateTransitioner.commitStorageSlot(
ovmContractAddress, ovmContractAddress,
key, key,
accountTrieProof,
storageTrieProof storageTrieProof
) )
).to.not.be.reverted ).to.not.be.reverted
......
...@@ -45,11 +45,8 @@ describe('Lib_RLPWriter', () => { ...@@ -45,11 +45,8 @@ describe('Lib_RLPWriter', () => {
describe('Use of library with other memory-modifying operations', () => { describe('Use of library with other memory-modifying operations', () => {
it('should allow creation of a contract beforehand and still work', async () => { it('should allow creation of a contract beforehand and still work', async () => {
const randomAddress = '0x1234123412341234123412341234123412341234' const randomAddress = '0x1234123412341234123412341234123412341234'
const rlpEncodedRandomAddress = const rlpEncodedRandomAddress = '0x941234123412341234123412341234123412341234'
'0x941234123412341234123412341234123412341234' const encoded = await Lib_RLPWriter.callStatic.writeAddressWithOtherMemory(randomAddress)
const encoded = await Lib_RLPWriter.callStatic.writeAddressWithOtherMemory(
randomAddress
)
expect(encoded).to.eq(rlpEncodedRandomAddress) expect(encoded).to.eq(rlpEncodedRandomAddress)
}) })
}) })
......
...@@ -24,7 +24,7 @@ export const ZERO_ADDRESS = makeAddress('00') ...@@ -24,7 +24,7 @@ export const ZERO_ADDRESS = makeAddress('00')
export const NON_ZERO_ADDRESS = makeAddress('11') export const NON_ZERO_ADDRESS = makeAddress('11')
export const VERIFIED_EMPTY_CONTRACT_HASH = export const VERIFIED_EMPTY_CONTRACT_HASH =
'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' '0x00004B1DC0DE000000004B1DC0DE000000004B1DC0DE000000004B1DC0DE0000'
export const STORAGE_XOR_VALUE = export const STORAGE_XOR_VALUE =
'0xFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEF' '0xFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEF'
...@@ -47,6 +47,6 @@ export const getStorageXOR = (key: string): string => { ...@@ -47,6 +47,6 @@ export const getStorageXOR = (key: string): string => {
} }
export const EMPTY_ACCOUNT_CODE_HASH = export const EMPTY_ACCOUNT_CODE_HASH =
'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' '0x00004B1DC0DE000000004B1DC0DE000000004B1DC0DE000000004B1DC0DE0000'
export const KECCAK_256_NULL = export const KECCAK_256_NULL =
'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
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