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,
......
......@@ -234,13 +234,13 @@ library Lib_MerkleTrie {
// Included leaf nodes should have no key remainder, values should match.
return (
keyRemainder.length == 0 &&
libByteUtils.equal(getNodeValue(proof[pathLength - 1]), _value)
Lib_ByteUtils.equal(getNodeValue(proof[pathLength - 1]), _value)
);
} else {
// If there's no key remainder then a leaf with the given key exists and the value should differ.
// Otherwise, we need to make sure that we've hit a dead end.
return (
(keyRemainder.length == 0 && !libByteUtils.equal(getNodeValue(proof[pathLength - 1]), _value)) ||
(keyRemainder.length == 0 && !Lib_ByteUtils.equal(getNodeValue(proof[pathLength - 1]), _value)) ||
(keyRemainder.length != 0 && isFinalNode)
);
}
......@@ -271,7 +271,7 @@ library Lib_MerkleTrie {
)
{
uint256 pathLength = 0;
bytes memory key = libByteUtils.toNibbles(_key);
bytes memory key = Lib_ByteUtils.toNibbles(_key);
bytes32 currentNodeID = _root;
uint256 currentKeyIndex = 0;
......@@ -302,7 +302,7 @@ library Lib_MerkleTrie {
} else {
// Nodes smaller than 31 bytes aren't hashed.
require(
libByteUtils.toBytes32(currentNode.encoded) == currentNodeID,
Lib_ByteUtils.toBytes32(currentNode.encoded) == currentNodeID,
"Invalid internal node hash"
);
}
......@@ -324,8 +324,8 @@ library Lib_MerkleTrie {
bytes memory path = getNodePath(currentNode);
uint8 prefix = uint8(path[0]);
uint8 offset = 2 - prefix % 2;
bytes memory pathRemainder = libByteUtils.slice(path, offset);
bytes memory keyRemainder = libByteUtils.slice(key, currentKeyIndex);
bytes memory pathRemainder = Lib_ByteUtils.slice(path, offset);
bytes memory keyRemainder = Lib_ByteUtils.slice(key, currentKeyIndex);
uint256 sharedNibbleLength = getSharedNibbleLength(pathRemainder, keyRemainder);
if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {
......@@ -360,7 +360,7 @@ library Lib_MerkleTrie {
// If our node ID is NULL, then we're at a dead end.
bool isFinalNode = currentNodeID == bytes32(RLP_NULL);
return (pathLength, libByteUtils.slice(key, currentKeyIndex), isFinalNode);
return (pathLength, Lib_ByteUtils.slice(key, currentKeyIndex), isFinalNode);
}
/**
......@@ -418,7 +418,7 @@ library Lib_MerkleTrie {
totalNewNodes += 1;
// Create a new leaf node, slicing our remainder since the first byte points
// to our branch node.
newNodes[totalNewNodes] = makeLeafNode(libByteUtils.slice(keyRemainder, 1), _value);
newNodes[totalNewNodes] = makeLeafNode(Lib_ByteUtils.slice(keyRemainder, 1), _value);
totalNewNodes += 1;
}
} else {
......@@ -429,13 +429,13 @@ library Lib_MerkleTrie {
if (sharedNibbleLength != 0) {
// We've got some shared nibbles between the last node and our key remainder.
// We'll need to insert an extension node that covers these shared nibbles.
bytes memory nextNodeKey = libByteUtils.slice(lastNodeKey, 0, sharedNibbleLength);
bytes memory nextNodeKey = Lib_ByteUtils.slice(lastNodeKey, 0, sharedNibbleLength);
newNodes[totalNewNodes] = makeExtensionNode(nextNodeKey, getNodeHash(_value));
totalNewNodes += 1;
// Cut down the keys since we've just covered these shared nibbles.
lastNodeKey = libByteUtils.slice(lastNodeKey, sharedNibbleLength);
keyRemainder = libByteUtils.slice(keyRemainder, sharedNibbleLength);
lastNodeKey = Lib_ByteUtils.slice(lastNodeKey, sharedNibbleLength);
keyRemainder = Lib_ByteUtils.slice(keyRemainder, sharedNibbleLength);
}
// Create an empty branch to fill in.
......@@ -451,7 +451,7 @@ library Lib_MerkleTrie {
// We're going to modify some index of our branch.
uint8 branchKey = uint8(lastNodeKey[0]);
// Move on to the next nibble.
lastNodeKey = libByteUtils.slice(lastNodeKey, 1);
lastNodeKey = Lib_ByteUtils.slice(lastNodeKey, 1);
if (lastNodeType == NodeType.LeafNode) {
// We're dealing with a leaf node.
......@@ -482,7 +482,7 @@ library Lib_MerkleTrie {
// We've got some key remainder to work with.
// We'll be inserting a leaf node into the trie.
// First, move on to the next nibble.
keyRemainder = libByteUtils.slice(keyRemainder, 1);
keyRemainder = Lib_ByteUtils.slice(keyRemainder, 1);
// Push the branch into the list of new nodes.
newNodes[totalNewNodes] = newBranch;
totalNewNodes += 1;
......@@ -513,7 +513,7 @@ library Lib_MerkleTrie {
bytes32
)
{
bytes memory key = libByteUtils.toNibbles(_key);
bytes memory key = Lib_ByteUtils.toNibbles(_key);
// Some variables to keep track of during iteration.
TrieNode memory currentNode;
......@@ -530,11 +530,11 @@ library Lib_MerkleTrie {
// Leaf nodes are already correctly encoded.
// Shift the key over to account for the nodes key.
bytes memory nodeKey = getNodeKey(currentNode);
key = libByteUtils.slice(key, 0, key.length - nodeKey.length);
key = Lib_ByteUtils.slice(key, 0, key.length - nodeKey.length);
} else if (currentNodeType == NodeType.ExtensionNode) {
// Shift the key over to account for the nodes key.
bytes memory nodeKey = getNodeKey(currentNode);
key = libByteUtils.slice(key, 0, key.length - nodeKey.length);
key = Lib_ByteUtils.slice(key, 0, key.length - nodeKey.length);
// If this node is the last element in the path, it'll be correctly encoded
// and we can skip this part.
......@@ -548,7 +548,7 @@ library Lib_MerkleTrie {
if (previousNodeHash.length > 0) {
// Re-encode the node based on the previous node.
uint8 branchKey = uint8(key[key.length - 1]);
key = libByteUtils.slice(key, 0, key.length - 1);
key = Lib_ByteUtils.slice(key, 0, key.length - 1);
currentNode = editBranchIndex(currentNode, branchKey, previousNodeHash);
}
}
......@@ -576,14 +576,14 @@ library Lib_MerkleTrie {
TrieNode[] memory
)
{
Lib_RLPReader.RLPItem[] memory nodes = libRLPReader.toList(libRLPReader.toRlpItem(_proof));
Lib_RLPReader.RLPItem[] memory nodes = Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(_proof));
TrieNode[] memory proof = new TrieNode[](nodes.length);
for (uint256 i = 0; i < nodes.length; i++) {
bytes memory encoded = libRLPReader.toBytes(nodes[i]);
bytes memory encoded = Lib_RLPReader.toBytes(nodes[i]);
proof[i] = TrieNode({
encoded: encoded,
decoded: libRLPReader.toList(libRLPReader.toRlpItem(encoded))
decoded: Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(encoded))
});
}
......@@ -610,13 +610,13 @@ library Lib_MerkleTrie {
if (_node.len < 32) {
// Nodes smaller than 32 bytes are RLP encoded.
nodeID = libRLPReader.toRlpBytes(_node);
nodeID = Lib_RLPReader.toRlpBytes(_node);
} else {
// Nodes 32 bytes or larger are hashed.
nodeID = libRLPReader.toBytes(_node);
nodeID = Lib_RLPReader.toBytes(_node);
}
return libByteUtils.toBytes32(nodeID);
return Lib_ByteUtils.toBytes32(nodeID);
}
/**
......@@ -633,7 +633,7 @@ library Lib_MerkleTrie {
bytes memory
)
{
return libByteUtils.toNibbles(libRLPReader.toBytes(_node.decoded[0]));
return Lib_ByteUtils.toNibbles(Lib_RLPReader.toBytes(_node.decoded[0]));
}
/**
......@@ -668,7 +668,7 @@ library Lib_MerkleTrie {
bytes memory
)
{
return libRLPReader.toBytes(_node.decoded[_node.decoded.length - 1]);
return Lib_RLPReader.toBytes(_node.decoded[_node.decoded.length - 1]);
}
/**
......@@ -761,11 +761,11 @@ library Lib_MerkleTrie {
TrieNode memory
)
{
bytes memory encoded = libRLPWriter.encodeList(_raw);
bytes memory encoded = Lib_RLPWriter.encodeList(_raw);
return TrieNode({
encoded: encoded,
decoded: libRLPReader.toList(libRLPReader.toRlpItem(encoded))
decoded: Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(encoded))
});
}
......@@ -785,7 +785,7 @@ library Lib_MerkleTrie {
{
bytes[] memory raw = new bytes[](_items.length);
for (uint256 i = 0; i < _items.length; i++) {
raw[i] = libRLPReader.toRlpBytes(_items[i]);
raw[i] = Lib_RLPReader.toRlpBytes(_items[i]);
}
return makeNode(raw);
}
......@@ -808,8 +808,8 @@ library Lib_MerkleTrie {
{
bytes[] memory raw = new bytes[](2);
bytes memory key = addHexPrefix(_key, false);
raw[0] = libRLPWriter.encodeBytes(libByteUtils.fromNibbles(key));
raw[1] = libRLPWriter.encodeBytes(_value);
raw[0] = Lib_RLPWriter.encodeBytes(Lib_ByteUtils.fromNibbles(key));
raw[1] = Lib_RLPWriter.encodeBytes(_value);
return makeNode(raw);
}
......@@ -834,8 +834,8 @@ library Lib_MerkleTrie {
{
bytes[] memory raw = new bytes[](2);
bytes memory key = addHexPrefix(_key, true);
raw[0] = libRLPWriter.encodeBytes(libByteUtils.fromNibbles(key));
raw[1] = libRLPWriter.encodeBytes(_value);
raw[0] = Lib_RLPWriter.encodeBytes(Lib_ByteUtils.fromNibbles(key));
raw[1] = Lib_RLPWriter.encodeBytes(_value);
return makeNode(raw);
}
......@@ -873,8 +873,8 @@ library Lib_MerkleTrie {
TrieNode memory
)
{
bytes memory encoded = libRLPWriter.encodeBytes(_value);
_branch.decoded[_branch.decoded.length - 1] = libRLPReader.toRlpItem(encoded);
bytes memory encoded = Lib_RLPWriter.encodeBytes(_value);
_branch.decoded[_branch.decoded.length - 1] = Lib_RLPReader.toRlpItem(encoded);
return makeNode(_branch.decoded);
}
......@@ -896,8 +896,8 @@ library Lib_MerkleTrie {
TrieNode memory
)
{
bytes memory encoded = _value.length < 32 ? _value : libRLPWriter.encodeBytes(_value);
_branch.decoded[_index] = libRLPReader.toRlpItem(encoded);
bytes memory encoded = _value.length < 32 ? _value : Lib_RLPWriter.encodeBytes(_value);
_branch.decoded[_index] = Lib_RLPReader.toRlpItem(encoded);
return makeNode(_branch.decoded);
}
......@@ -921,7 +921,7 @@ library Lib_MerkleTrie {
uint8 offset = uint8(_key.length % 2);
bytes memory prefixed = new bytes(2 - offset);
prefixed[0] = bytes1(prefix + offset);
return libByteUtils.concat(prefixed, _key);
return Lib_ByteUtils.concat(prefixed, _key);
}
/**
......@@ -939,9 +939,9 @@ library Lib_MerkleTrie {
)
{
if (uint8(_path[0]) % 2 == 0) {
return libByteUtils.slice(_path, 2);
return Lib_ByteUtils.slice(_path, 2);
} else {
return libByteUtils.slice(_path, 1);
return Lib_ByteUtils.slice(_path, 1);
}
}
......
// 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