Commit acb50b70 authored by Kelvin Fichter's avatar Kelvin Fichter

Added proxy and fixed bugs in StateManager

parent b1d71b87
......@@ -2,6 +2,9 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Proxy Imports */
import { Proxy_Resolver } from "../../proxy/Proxy_Resolver.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_MerkleUtils } from "../../libraries/utils/Lib_MerkleUtils.sol";
......@@ -16,7 +19,7 @@ import { OVM_BaseChain } from "./OVM_BaseChain.sol";
/**
* @title OVM_CanonicalTransactionChain
*/
contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_BaseChain {
contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_BaseChain, Proxy_Resolver {
/*******************************************
* Contract Variables: Contract References *
......@@ -39,17 +42,18 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba
***************/
/**
* @param _ovmL1ToL2TransactionQueue Address of the OVM_L1ToL2TransactionQueue.
* @param _sequencer Address of the current sequencer.
* @param _proxyManager Address of the Proxy_Manager.
* @param _forceInclusionPeriodSeconds Period during which only the sequencer can submit.
*/
constructor(
address _ovmL1ToL2TransactionQueue,
address _sequencer,
address _proxyManager,
uint256 _forceInclusionPeriodSeconds
) {
ovmL1ToL2TransactionQueue = iOVM_L1ToL2TransactionQueue(_ovmL1ToL2TransactionQueue);
sequencer = _sequencer;
)
Proxy_Resolver(_proxyManager)
{
ovmL1ToL2TransactionQueue = iOVM_L1ToL2TransactionQueue(resolve("OVM_L1ToL2TransactionQueue"));
sequencer = resolve("Sequencer");
forceInclusionPeriodSeconds = _forceInclusionPeriodSeconds;
}
......
......@@ -2,6 +2,9 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Proxy Imports */
import { Proxy_Resolver } from "../../proxy/Proxy_Resolver.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
......@@ -16,7 +19,7 @@ import { OVM_BaseChain } from "./OVM_BaseChain.sol";
/**
* @title OVM_StateCommitmentChain
*/
contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain {
contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, Proxy_Resolver {
/*******************************************
* Contract Variables: Contract References *
......@@ -31,15 +34,15 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain {
***************/
/**
* @param _ovmCanonicalTransactionChain Address of the OVM_CanonicalTransactionChain.
* @param _ovmFraudVerifier Address of the OVM_FraudVerifier.
* @param _proxyManager Address of the Proxy_Manager.
*/
constructor(
address _ovmCanonicalTransactionChain,
address _ovmFraudVerifier
) {
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(_ovmCanonicalTransactionChain);
ovmFraudVerifier = iOVM_FraudVerifier(_ovmFraudVerifier);
address _proxyManager
)
Proxy_Resolver(_proxyManager)
{
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain"));
ovmFraudVerifier = iOVM_FraudVerifier(resolve("OVM_FraudVerifier"));
}
......
......@@ -2,6 +2,9 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Proxy Imports */
import { Proxy_Resolver } from "../../proxy/Proxy_Resolver.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
......@@ -14,7 +17,7 @@ import { iOVM_StateManagerFactory } from "../../iOVM/execution/iOVM_StateManager
import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol";
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
contract OVM_FraudVerifier is iOVM_FraudVerifier {
contract OVM_FraudVerifier is iOVM_FraudVerifier, Proxy_Resolver {
/*******************************************
* Contract Variables: Contract References *
......@@ -22,8 +25,6 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
iOVM_StateCommitmentChain internal ovmStateCommitmentChain;
iOVM_CanonicalTransactionChain internal ovmCanonicalTransactionChain;
iOVM_ExecutionManager internal ovmExecutionManager;
iOVM_StateManagerFactory internal ovmStateManagerFactory;
/*******************************************
......@@ -38,21 +39,15 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
***************/
/**
* @param _ovmStateCommitmentChain Address of the OVM_StateCommitmentChain.
* @param _ovmCanonicalTransactionChain Address of the OVM_CanonicalTransactionChain.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _ovmStateManagerFactory Address of the OVM_StateManagerFactory.
* @param _proxyManager Address of the Proxy_Manager.
*/
constructor(
address _ovmStateCommitmentChain,
address _ovmCanonicalTransactionChain,
address _ovmExecutionManager,
address _ovmStateManagerFactory,
) {
ovmStateCommitmentChain = iOVM_StateCommitmentChain(_ovmStateCommitmentChain);
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(_ovmCanonicalTransactionChain);
ovmExecutionManager = iOVM_ExecutionManager(_ovmExecutionManager);
ovmStateManagerFactory = iOVM_StateManagerFactory(_ovmStateManagerFactory);
address _proxyManager
)
Proxy_Resolver(_proxyManager)
{
ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain"));
}
......@@ -73,7 +68,7 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
bytes32 _preStateRoot,
Lib_OVMCodec.ChainBatchHeader memory _preStateRootBatchHeader,
Lib_OVMCodec.ChainInclusionProof memory _preStateRootProof,
Lib_OVMCodec.TransactionData memory _transaction,
Lib_OVMCodec.Transaction memory _transaction,
Lib_OVMCodec.ChainBatchHeader memory _transactionBatchHeader,
Lib_OVMCodec.ChainInclusionProof memory _transactionProof
)
......@@ -105,10 +100,10 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
transitioners[_preStateRoot] = iOVM_StateTransitionerFactory(
resolve("OVM_StateTransitionerFactory")
).create(
address(libContractProxyManager),
address(proxyManager),
_preStateRootProof.index,
_preStateRoot,
Lib_OVMCodec.hash(_transaction)
Lib_OVMCodec.hashTransaction(_transaction)
);
}
......@@ -163,7 +158,7 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
);
require(
_postStateRoot != transitioner.postStateRoot(),
_postStateRoot != transitioner.getPostStateRoot(),
"State transition has not been proven fraudulent."
);
......@@ -212,7 +207,7 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
bool _verified
)
{
return ovmStateCommitmentChain.ovmBaseChain().verifyElement(
return ovmStateCommitmentChain.verifyElement(
abi.encodePacked(_stateRoot),
_stateRootBatchHeader,
_stateRootProof
......@@ -227,7 +222,7 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
* @return _verified Whether or not the transaction was included.
*/
function _verifyTransaction(
Lib_OVMCodec.TransactionData memory _transaction,
Lib_OVMCodec.Transaction memory _transaction,
Lib_OVMCodec.ChainBatchHeader memory _transactionBatchHeader,
Lib_OVMCodec.ChainInclusionProof memory _transactionProof
)
......@@ -237,8 +232,8 @@ contract OVM_FraudVerifier is iOVM_FraudVerifier {
bool _verified
)
{
return ovmCanonicalTransactionChain.ovmBaseChain().verifyElement(
Lib_OVMCodec.encode(_transaction),
return ovmCanonicalTransactionChain.verifyElement(
Lib_OVMCodec.encodeTransaction(_transaction),
_transactionBatchHeader,
_transactionProof
);
......
......@@ -13,6 +13,14 @@ import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
*/
contract OVM_StateManager is iOVM_StateManager {
/*******************************************
* Contract Variables: Contract References *
*******************************************/
address internal owner;
address internal ovmExecutionManager;
/****************************************
* Contract Variables: Internal Storage *
****************************************/
......@@ -21,6 +29,58 @@ contract OVM_StateManager is iOVM_StateManager {
mapping (address => mapping (bytes32 => bytes32)) internal contractStorage;
mapping (address => mapping (bytes32 => bool)) internal verifiedContractStorage;
mapping (bytes32 => ItemState) internal itemStates;
uint256 internal totalUncommittedAccounts;
uint256 internal totalUncommittedContractStorage;
/***************
* Constructor *
***************/
/**
* @param _owner Address of the owner of this contract.
*/
constructor(
address _owner
) {
owner = _owner;
}
/**********************
* Function Modifiers *
**********************/
/**
* Simple authentication, this contract should only be accessible to the owner or to the
* OVM_ExecutionManager during the transaction execution process.
*/
modifier authenticated() {
require(
msg.sender == owner || msg.sender == ovmExecutionManager,
"Function can only be called by authenticated addresses"
);
_;
}
/***************************
* Public Functions: Setup *
***************************/
/**
* Sets the address of the OVM_ExecutionManager.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
*/
function setExecutionManager(
address _ovmExecutionManager
)
override
public
authenticated
{
ovmExecutionManager = _ovmExecutionManager;
}
/************************************
......@@ -38,6 +98,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
{
accounts[_address] = _account;
}
......@@ -50,6 +111,7 @@ contract OVM_StateManager is iOVM_StateManager {
function getAccount(address _address)
override
public
authenticated
returns (
Lib_OVMCodec.Account memory _account
)
......@@ -67,6 +129,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bool _exists
)
......@@ -85,6 +148,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
{
accounts[_address].nonce = _nonce;
}
......@@ -99,6 +163,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
uint256 _nonce
)
......@@ -116,6 +181,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
address _ethAddress
)
......@@ -132,6 +198,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
{
Lib_OVMCodec.Account storage account = accounts[_address];
account.nonce = 1;
......@@ -151,6 +218,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
{
Lib_OVMCodec.Account storage account = accounts[_address];
account.ethAddress = _ethAddress;
......@@ -167,11 +235,12 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bool _wasAccountAlreadyLoaded
)
{
return _testItemState(
return _testAndSetItemState(
keccak256(abi.encodePacked(_address)),
ItemState.ITEM_LOADED
);
......@@ -187,14 +256,62 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bool _wasAccountAlreadyChanged
)
{
return _testItemState(
bool wasAccountAlreadyChanged = _testAndSetItemState(
keccak256(abi.encodePacked(_address)),
ItemState.ITEM_CHANGED
);
if (!wasAccountAlreadyChanged) {
totalUncommittedAccounts += 1;
}
return wasAccountAlreadyChanged;
}
/**
* Attempts to mark an account as committed.
* @param _address Address of the account to commit.
* @return _wasAccountCommitted Whether or not the account was committed.
*/
function commitAccount(
address _address
)
override
public
authenticated
returns (
bool _wasAccountCommitted
)
{
bytes32 item = keccak256(abi.encodePacked(_address));
if (itemStates[item] != ItemState.ITEM_CHANGED) {
return false;
}
itemStates[item] = ItemState.ITEM_COMMITTED;
totalUncommittedAccounts -= 1;
return true;
}
/**
* Gets the total number of uncommitted accounts.
* @return _total Total uncommitted accounts.
*/
function getTotalUncommittedAccounts()
override
public
authenticated
returns (
uint256 _total
)
{
return totalUncommittedAccounts;
}
......@@ -215,6 +332,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
{
contractStorage[_contract][_key] = _value;
verifiedContractStorage[_contract][_key] = true;
......@@ -232,6 +350,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bytes32 _value
)
......@@ -251,6 +370,7 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bool _exists
)
......@@ -270,11 +390,12 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bool _wasContractStorageAlreadyLoaded
)
{
return _testItemState(
return _testAndSetItemState(
keccak256(abi.encodePacked(_contract, _key)),
ItemState.ITEM_LOADED
);
......@@ -292,14 +413,64 @@ contract OVM_StateManager is iOVM_StateManager {
)
override
public
authenticated
returns (
bool _wasContractStorageAlreadyChanged
)
{
return _testItemState(
bool wasContractStorageAlreadyChanged = _testAndSetItemState(
keccak256(abi.encodePacked(_contract, _key)),
ItemState.ITEM_CHANGED
);
if (!wasContractStorageAlreadyChanged) {
totalUncommittedContractStorage += 1;
}
return wasContractStorageAlreadyChanged;
}
/**
* Attempts to mark a storage slot as committed.
* @param _contract Address of the account to commit.
* @param _key 32 byte slot key to commit.
* @return _wasContractStorageCommitted Whether or not the slot was committed.
*/
function commitContractStorage(
address _contract,
bytes32 _key
)
override
public
authenticated
returns (
bool _wasContractStorageCommitted
)
{
bytes32 item = keccak256(abi.encodePacked(_contract, _key));
if (itemStates[item] != ItemState.ITEM_CHANGED) {
return false;
}
itemStates[item] = ItemState.ITEM_COMMITTED;
totalUncommittedContractStorage -= 1;
return true;
}
/**
* Gets the total number of uncommitted storage slots.
* @return _total Total uncommitted storage slots.
*/
function getTotalUncommittedContractStorage()
override
public
authenticated
returns (
uint256 _total
)
{
return totalUncommittedContractStorage;
}
......@@ -314,7 +485,7 @@ contract OVM_StateManager is iOVM_StateManager {
* @param _minItemState Minumum state that must be satisfied by the item.
* @return _wasItemState Whether or not the item was already in the state.
*/
function _testItemState(
function _testAndSetItemState(
bytes32 _item,
ItemState _minItemState
)
......@@ -323,8 +494,7 @@ contract OVM_StateManager is iOVM_StateManager {
bool _wasItemState
)
{
ItemState itemState = itemStates[_item];
bool wasItemState = itemState >= _minItemState;
bool wasItemState = itemStates[_item] >= _minItemState;
if (wasItemState == false) {
itemStates[_item] = _minItemState;
......
......@@ -17,13 +17,20 @@ contract OVM_StateManagerFactory is iOVM_StateManagerFactory {
* Public Functions: Contract Creation *
***************************************/
function create()
/**
* Creates a new OVM_StateManager
* @param _owner Owner of the created contract.
* @return _ovmStateManager New OVM_StateManager instance.
*/
function create(
address _owner
)
override
public
returns (
iOVM_StateManager _ovmStateManager
)
{
return new OVM_StateManager();
return new OVM_StateManager(_owner);
}
}
......@@ -2,10 +2,13 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Proxy Imports */
import { Proxy_Resolver } from "../../proxy/Proxy_Resolver.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_EthUtils } from "../../../libraries/utils/Lib_EthUtils.sol";
import { Lib_EthMerkleTrie } from "../../../libraries/trie/Lib_EthMerkleTrie.sol";
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
import { Lib_EthMerkleTrie } from "../../libraries/trie/Lib_EthMerkleTrie.sol";
/* Interface Imports */
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";
......@@ -16,7 +19,7 @@ import { iOVM_StateTransitioner } from "../../iOVM/execution/iOVM_StateTransitio
/**
* @title OVM_StateTransitioner
*/
contract OVM_StateTransitioner is iOVM_StateTransitioner {
contract OVM_StateTransitioner is iOVM_StateTransitioner, Proxy_Resolver {
/*******************
* Data Structures *
......@@ -44,8 +47,8 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
bytes32 internal preStateRoot;
bytes32 internal postStateRoot;
TransitionPhase internal phase;
uint256 public stateTransitionIndex;
bytes32 public transactionHash;
uint256 internal stateTransitionIndex;
bytes32 internal transactionHash;
/***************
......@@ -53,26 +56,26 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
***************/
/**
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _ovmStateManagerFactory Address of the OVM_StateManagerFactory.
* @param _proxyManager Address of the Proxy_Manager.
* @param _stateTransitionIndex Index of the state transition being verified.
* @param _preStateRoot State root before the transition was executed.
* @param _transactionHash Hash of the executed transaction.
*/
constructor(
address _ovmExecutionManager,
address _ovmStateManagerFactory,
address _proxyManager,
uint256 _stateTransitionIndex,
bytes32 _preStateRoot,
bytes32 _transactionHash
) {
)
Proxy_Resolver(_proxyManager)
{
stateTransitionIndex = _stateTransitionIndex;
preStateRoot = _preStateRoot;
postStateRoot = _preStateRoot;
transactionHash = _transactionHash;
ovmExecutionManager = iOVM_ExecutionManager(_ovmExecutionManager);
ovmStateManager = iOVM_StateManagerFactory(_ovmStateManagerFactory).create();
ovmExecutionManager = iOVM_ExecutionManager(resolve("OVM_ExecutionManager"));
ovmStateManager = iOVM_StateManagerFactory(resolve("OVM_StateManagerFactory")).create(address(this));
}
......@@ -116,7 +119,7 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
/**
* Retrieves the state root after execution.
* @return _preStateRoot State root after execution.
* @return _postStateRoot State root after execution.
*/
function getPostStateRoot()
override
......@@ -189,9 +192,9 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
* Allows a user to prove the initial state of a contract storage slot.
* @param _ovmContractAddress Address of the contract on the OVM.
* @param _key Claimed account slot key.
* @param _key Claimed account slot value.
* @param _value Claimed account slot value.
* @param _stateTrieWitness Proof of the account state.
* @param _stateTrieWitness Proof of the storage slot.
* @param _storageTrieWitness Proof of the storage slot.
*/
function proveStorageSlot(
address _ovmContractAddress,
......@@ -244,13 +247,14 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
public
{
require(
libOVMCodec.hash(_transaction) == transactionHash,
Lib_OVMCodec.hashTransaction(_transaction) == transactionHash,
"Invalid transaction provided."
);
// TODO: Set state manager for EM here.
ovmExecutionManager.run(_transaction);
ovmStateManager.setExecutionManager(resolveTarget("OVM_ExecutionManager"));
ovmExecutionManager.run(_transaction, address(ovmStateManager));
phase = TransitionPhase.POST_EXECUTION;
}
......@@ -276,8 +280,8 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
onlyDuringPhase(TransitionPhase.POST_EXECUTION)
{
require(
ovmStateManager.isUncommittedAccount(_ovmContractAddress) == true,
"Provided account is not uncommitted."
ovmStateManager.commitAccount(_ovmContractAddress) == true,
"Cannot commit an account that has not been changed."
);
postStateRoot = Lib_EthMerkleTrie.updateAccountState(
......@@ -286,17 +290,15 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
_stateTrieWitness,
postStateRoot
);
ovmStateManager.commitAccount(_ovmContractAddress);
}
/**
* Allows a user to commit the final state of a contract storage slot.
* @param _ovmContractAddress Address of the contract on the OVM.
* @param _key Claimed account slot key.
* @param _key Claimed account slot value.
* @param _value Claimed account slot value.
* @param _stateTrieWitness Proof of the account state.
* @param _stateTrieWitness Proof of the storage slot.
* @param _storageTrieWitness Proof of the storage slot.
*/
function commitStorageSlot(
address _ovmContractAddress,
......@@ -310,8 +312,8 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
onlyDuringPhase(TransitionPhase.POST_EXECUTION)
{
require(
ovmStateManager.isUncommittedStorage(_ovmContractAddress, _key, _value) == true,
"Provided storage slot is not uncommitted."
ovmStateManager.commitContractStorage(_ovmContractAddress, _key) == true,
"Cannot commit a storage slot that has not been changed."
);
postStateRoot = Lib_EthMerkleTrie.updateAccountStorageSlotValue(
......@@ -322,8 +324,6 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
_storageTrieWitness,
postStateRoot
);
ovmStateManager.commitStorage(_ovmContractAddress, _key, _value);
}
......@@ -340,12 +340,12 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner {
onlyDuringPhase(TransitionPhase.POST_EXECUTION)
{
require(
ovmStateManager.totalUncommittedAccounts() == 0,
ovmStateManager.getTotalUncommittedAccounts() == 0,
"All accounts must be committed before completing a transition."
);
require(
ovmStateManager.totalUncommittedStorage() == 0,
ovmStateManager.getTotalUncommittedContractStorage() == 0,
"All storage must be committed before completing a transition."
);
......
......@@ -17,8 +17,16 @@ contract OVM_StateTransitionerFactory is iOVM_StateTransitionerFactory {
* Public Functions: Contract Creation *
***************************************/
/**
* Creates a new OVM_StateTransitioner
* @param _proxyManager Address of the Proxy_Manager.
* @param _stateTransitionIndex Index of the state transition being verified.
* @param _preStateRoot State root before the transition was executed.
* @param _transactionHash Hash of the executed transaction.
* @return _ovmStateTransitioner New OVM_StateTransitioner instance.
*/
function create(
address _libContractProxyManager,
address _proxyManager,
uint256 _stateTransitionIndex,
bytes32 _preStateRoot,
bytes32 _transactionHash
......@@ -30,7 +38,7 @@ contract OVM_StateTransitionerFactory is iOVM_StateTransitionerFactory {
)
{
return new OVM_StateTransitioner(
_libContractProxyManager,
_proxyManager,
_stateTransitionIndex,
_preStateRoot,
_transactionHash
......
......@@ -2,6 +2,9 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Proxy Imports */
import { Proxy_Resolver } from "../../proxy/Proxy_Resolver.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
......@@ -15,7 +18,7 @@ import { OVM_BaseQueue } from "./OVM_BaseQueue.sol";
/**
* @title OVM_L1ToL2TransactionQueue
*/
contract OVM_L1ToL2TransactionQueue is iOVM_L1ToL2TransactionQueue, OVM_BaseQueue {
contract OVM_L1ToL2TransactionQueue is iOVM_L1ToL2TransactionQueue, OVM_BaseQueue, Proxy_Resolver {
/*******************************************
* Contract Variables: Contract References *
......@@ -29,12 +32,14 @@ contract OVM_L1ToL2TransactionQueue is iOVM_L1ToL2TransactionQueue, OVM_BaseQueu
***************/
/**
* @param _ovmCanonicalTransactionChain Address of the OVM_CanonicalTransactionChain.
* @param _proxyManager Address of the Proxy_Manager.
*/
constructor(
address _ovmCanonicalTransactionChain
) {
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(_ovmCanonicalTransactionChain);
address _proxyManager
)
Proxy_Resolver(_proxyManager)
{
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain"));
}
......
......@@ -17,10 +17,18 @@ interface iOVM_StateManager {
enum ItemState {
ITEM_UNTOUCHED,
ITEM_LOADED,
ITEM_CHANGED
ITEM_CHANGED,
ITEM_COMMITTED
}
/***************************
* Public Functions: Setup *
***************************/
function setExecutionManager(address _ovmExecutionManager) external;
/************************************
* Public Functions: Account Access *
************************************/
......@@ -35,6 +43,8 @@ interface iOVM_StateManager {
function commitPendingAccount(address _address, address _ethAddress, bytes32 _codeHash) external;
function testAndSetAccountLoaded(address _address) external returns (bool _wasAccountAlreadyLoaded);
function testAndSetAccountChanged(address _address) external returns (bool _wasAccountAlreadyChanged);
function commitAccount(address _address) external returns (bool _wasAccountCommitted);
function getTotalUncommittedAccounts() external returns (uint256 _total);
/************************************
......@@ -46,4 +56,6 @@ interface iOVM_StateManager {
function hasContractStorage(address _contract, bytes32 _key) external returns (bool _exists);
function testAndSetContractStorageLoaded(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyLoaded);
function testAndSetContractStorageChanged(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyChanged);
function commitContractStorage(address _contract, bytes32 _key) external returns (bool _wasContractStorageCommitted);
function getTotalUncommittedContractStorage() external returns (uint256 _total);
}
......@@ -13,7 +13,9 @@ interface iOVM_StateManagerFactory {
* Public Functions: Contract Creation *
***************************************/
function create()
function create(
address _owner
)
external
returns (
iOVM_StateManager _ovmStateManager
......
......@@ -43,7 +43,7 @@ interface iOVM_StateTransitioner {
*******************************/
function applyTransaction(
Lib_OVMCodec.TransactionData calldata _transaction
Lib_OVMCodec.Transaction calldata _transaction
) external;
......
......@@ -14,7 +14,7 @@ interface iOVM_StateTransitionerFactory {
***************************************/
function create(
address _libContractProxyManager,
address _proxyManager,
uint256 _stateTransitionIndex,
bytes32 _preStateRoot,
bytes32 _transactionHash
......
......@@ -105,4 +105,36 @@ library Lib_OVMCodec {
data: Lib_RLPReader.toBytes(decoded[5])
});
}
function encodeTransaction(
Transaction memory _transaction
)
public
pure
returns (
bytes memory _encoded
)
{
return abi.encodePacked(
_transaction.timestamp,
_transaction.queueOrigin,
_transaction.entrypoint,
_transaction.origin,
_transaction.msgSender,
_transaction.gasLimit,
_transaction.data
);
}
function hashTransaction(
Transaction memory _transaction
)
public
pure
returns (
bytes32 _hash
)
{
return keccak256(encodeTransaction(_transaction));
}
}
......@@ -4,8 +4,10 @@ pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_SecureMerkleTrie } from "./Lib_SecureMerkleTrie.sol";
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
import { Lib_OVMCodec } from "../codec/Lib_OVMCodec.sol";
import { Lib_ByteUtils } from "../utils/Lib_ByteUtils.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
/**
* @title Lib_EthMerkleTrie
......@@ -16,6 +18,7 @@ library Lib_EthMerkleTrie {
* Contract Constants *
**********************/
bytes constant private RLP_NULL_BYTES = hex'80';
bytes32 constant private BYTES32_NULL = bytes32('');
uint256 constant private UINT256_NULL = uint256(0);
......@@ -56,7 +59,7 @@ library Lib_EthMerkleTrie {
);
// Verify inclusion of the given k/v pair in the storage trie.
return verifyInclusionProof(
return Lib_SecureMerkleTrie.verifyInclusionProof(
abi.encodePacked(_key),
abi.encodePacked(_value),
_storageTrieWitness,
......@@ -96,7 +99,7 @@ library Lib_EthMerkleTrie {
);
// Generate a new storage root.
accountState.storageRoot = update(
accountState.storageRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_key),
abi.encodePacked(_value),
_storageTrieWitness,
......@@ -677,13 +680,13 @@ library Lib_EthMerkleTrie {
view
returns (Lib_OVMCodec.EVMAccount memory)
{
Lib_RLPReader.RLPItem[] memory accountState = libRLPReader.toList(libRLPReader.toRlpItem(_encodedAccountState));
Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(_encodedAccountState));
return Lib_OVMCodec.EVMAccount({
nonce: libRLPReader.toUint(accountState[0]),
balance: libRLPReader.toUint(accountState[1]),
storageRoot: libByteUtils.toBytes32(libRLPReader.toBytes(accountState[2])),
codeHash: libByteUtils.toBytes32(libRLPReader.toBytes(accountState[3]))
nonce: Lib_RLPReader.toUint(accountState[0]),
balance: Lib_RLPReader.toUint(accountState[1]),
storageRoot: Lib_ByteUtils.toBytes32(Lib_RLPReader.toBytes(accountState[2])),
codeHash: Lib_ByteUtils.toBytes32(Lib_RLPReader.toBytes(accountState[3]))
});
}
......@@ -704,12 +707,12 @@ library Lib_EthMerkleTrie {
// Unfortunately we can't create this array outright because
// RLPWriter.encodeList will reject fixed-size arrays. Assigning
// index-by-index circumvents this issue.
raw[0] = libRLPWriter.encodeUint(_accountState.nonce);
raw[1] = libRLPWriter.encodeUint(_accountState.balance);
raw[2] = _accountState.storageRoot == 0 ? RLP_NULL_BYTES : libRLPWriter.encodeBytes(abi.encodePacked(_accountState.storageRoot));
raw[3] = _accountState.codeHash == 0 ? RLP_NULL_BYTES : libRLPWriter.encodeBytes(abi.encodePacked(_accountState.codeHash));
raw[0] = Lib_RLPWriter.encodeUint(_accountState.nonce);
raw[1] = Lib_RLPWriter.encodeUint(_accountState.balance);
raw[2] = _accountState.storageRoot == 0 ? RLP_NULL_BYTES : Lib_RLPWriter.encodeBytes(abi.encodePacked(_accountState.storageRoot));
raw[3] = _accountState.codeHash == 0 ? RLP_NULL_BYTES : Lib_RLPWriter.encodeBytes(abi.encodePacked(_accountState.codeHash));
return libRLPWriter.encodeList(raw);
return Lib_RLPWriter.encodeList(raw);
}
/**
......@@ -738,7 +741,7 @@ library Lib_EthMerkleTrie {
(
bool exists,
bytes memory encodedAccountState
) = get(
) = Lib_SecureMerkleTrie.get(
abi.encodePacked(_address),
_stateTrieWitness,
_stateTrieRoot
......@@ -768,7 +771,7 @@ library Lib_EthMerkleTrie {
{
bytes memory encodedAccountState = encodeAccountState(_accountState);
return update(
return Lib_SecureMerkleTrie.update(
abi.encodePacked(_address),
encodedAccountState,
_stateTrieWitness,
......
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/* Proxy Imports */
import { Proxy_Manager } from "./Proxy_Manager.sol";
/**
* @title Proxy_Forwarder
*/
contract Proxy_Forwarder {
Proxy_Manager private proxyManager;
constructor(
address _proxyManager
) {
proxyManager = Proxy_Manager(_proxyManager);
}
fallback()
external
{
address target = _getTarget();
bytes memory data = msg.data;
require(
target != address(0),
"Proxy does not have a target."
);
assembly {
let success := call(
gas(),
target,
0,
add(data, 0x20),
mload(data),
0,
0
)
let size := returndatasize()
let returndata := mload(0x40)
mstore(0x40, add(returndata, add(size, 0x20)))
returndatacopy(add(returndata, 0x20), 0, size)
if iszero(success) {
revert(add(returndata, 0x20), size)
}
return(add(returndata, 0x20), size)
}
}
function _getTarget()
internal
view
returns (
address _target
)
{
address target;
if (proxyManager.isProxy(msg.sender)) {
target = proxyManager.getTarget(msg.sender);
} else if (proxyManager.hasProxy(msg.sender)) {
target = proxyManager.getProxy(msg.sender);
} else {
target = proxyManager.getTarget(address(this));
}
return target;
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* @title Proxy_Manager
*/
contract Proxy_Manager {
mapping (bytes32 => address) private proxyByName;
mapping (bytes32 => address) private targetByName;
mapping (address => bytes32) private nameByProxy;
mapping (address => bytes32) private nameByTarget;
function setProxy(
string memory _name,
address _proxy
)
public
{
proxyByName[_getNameHash(_name)] = _proxy;
nameByProxy[_proxy] = _getNameHash(_name);
}
function getProxy(
string memory _name
)
public
view
returns (
address _proxy
)
{
return proxyByName[_getNameHash(_name)];
}
function getProxy(
address _target
)
public
view
returns (
address _proxy
)
{
return proxyByName[nameByTarget[_target]];
}
function hasProxy(
string memory _name
)
public
view
returns (
bool _hasProxy
)
{
return getProxy(_name) != address(0);
}
function hasProxy(
address _target
)
public
view
returns (
bool _hasProxy
)
{
return getProxy(_target) != address(0);
}
function isProxy(
address _proxy
)
public
view
returns (
bool _isProxy
)
{
return nameByProxy[_proxy] != bytes32('');
}
function setTarget(
string memory _name,
address _target
)
public
{
targetByName[_getNameHash(_name)] = _target;
nameByTarget[_target] = _getNameHash(_name);
}
function getTarget(
string memory _name
)
public
view
returns (
address _target
)
{
return targetByName[_getNameHash(_name)];
}
function getTarget(
address _proxy
)
public
view
returns (
address _target
)
{
return targetByName[nameByProxy[_proxy]];
}
function hasTarget(
string memory _name
)
public
view
returns (
bool _hasTarget
)
{
return getTarget(_name) != address(0);
}
function hasTarget(
address _proxy
)
public
view
returns (
bool _hasTarget
)
{
return getTarget(_proxy) != address(0);
}
function isTarget(
address _target
)
public
view
returns (
bool _isTarget
)
{
return nameByTarget[_target] != bytes32('');
}
function _getNameHash(
string memory _name
)
internal
pure
returns (
bytes32 _hash
)
{
return keccak256(abi.encodePacked(_name));
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/* Proxy Imports */
import { Proxy_Manager } from "./Proxy_Manager.sol";
/**
* @title Proxy_Resolver
*/
contract Proxy_Resolver {
Proxy_Manager internal proxyManager;
constructor(
address _proxyManager
) {
proxyManager = Proxy_Manager(_proxyManager);
}
function resolve(
string memory _name
)
public
view
returns (
address _proxy
)
{
return proxyManager.getProxy(_name);
}
function resolveTarget(
string memory _name
)
public
view
returns (
address _target
)
{
return proxyManager.getTarget(_name);
}
}
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