Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
4b241fdb
Commit
4b241fdb
authored
Sep 17, 2020
by
Kelvin Fichter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Started adding chain contracts
parent
9b464f1d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
539 additions
and
0 deletions
+539
-0
OVM_BaseChain.sol
...contracts/optimistic-ethereum/OVM/chain/OVM_BaseChain.sol
+170
-0
OVM_CanonicalTransactionChain.sol
...stic-ethereum/OVM/chain/OVM_CanonicalTransactionChain.sol
+110
-0
OVM_StateCommitmentChain.sol
...ptimistic-ethereum/OVM/chain/OVM_StateCommitmentChain.sol
+67
-0
iOVM_BaseChain.sol
...ntracts/optimistic-ethereum/iOVM/chain/iOVM_BaseChain.sol
+30
-0
iOVM_CanonicalTransactionChain.sol
...ic-ethereum/iOVM/chain/iOVM_CanonicalTransactionChain.sol
+11
-0
iOVM_StateCommitmentChain.sol
...imistic-ethereum/iOVM/chain/iOVM_StateCommitmentChain.sol
+14
-0
Lib_MerkleUtils.sol
...s/optimistic-ethereum/libraries/utils/Lib_MerkleUtils.sol
+137
-0
No files found.
packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_BaseChain.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_BaseChain } from "../../iOVM/chain/iOVM_BaseChain.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_MerkleUtils } from "../../../libraries/utils/Lib_MerkleUtils.sol";
/**
* @title OVM_BaseChain
*/
contract OVM_BaseChain is iOVM_BaseChain {
/*******************************
* Contract Variables: Batches *
*******************************/
bytes32[] internal batches;
uint256 internal totalBatches;
uint256 internal totalElements;
/*************************************
* Public Functions: Batch Retrieval *
*************************************/
function getTotalElements()
override
public
view
returns (
uint256 _totalElements
)
{
return totalElements;
}
function getTotalBatches()
override
public
view
returns (
uint256 _totalBatches
)
{
return totalBatches;
}
/****************************************
* Public Functions: Batch Verification *
****************************************/
function verifyElement(
bytes calldata _element,
Lib_OVMDataTypes.OVMChainBatchHeader memory _batchHeader,
Lib_OVMDataTypes.OVMChainInclusionProof memory _proof
)
override
public
view
returns (
bool _verified
)
{
require(
_hashBatchHeader(_batchHeader) == batches[_batchHeader.batchIndex],
"Invalid batch header."
);
require(
libMerkleUtils.verify(
_batchHeader.batchRoot,
_element,
_proof.index,
_proof.siblings
),
"Invalid inclusion proof."
);
return true;
}
/******************************************
* Internal Functions: Batch Modification *
******************************************/
function _appendBatch(
Lib_OVMDataTypes.OVMChainBatchHeader memory _batchHeader
)
internal
{
bytes32 batchHeaderHash = _hashBatchHeader(_batchHeader);
batches.push(batchHeaderHash);
totalBatches += 1;
totalElements += _batchHeader.batchSize;
}
function _appendBatch(
bytes[] memory _elements,
bytes memory _extraData
)
internal
{
Lib_OVMDataTypes.OVMChainBatchHeader memory batchHeader = Lib_OVMDataTypes.OVMChainBatchHeader({
batchIndex: batches.length,
batchRoot: libMerkleUtils.getMerkleRoot(_elements),
batchSize: _elements.length,
prevTotalElements: totalElements,
extraData: _extraData
});
appendBatch(batchHeader);
}
function _appendBatch(
bytes[] memory _elements
)
internal
{
appendBatch(
_elements,
bytes('')
);
}
function _deleteBatch(
Lib_OVMDataTypes.OVMChainBatchHeader memory _batchHeader
)
internal
{
require(
_batchHeader.batchIndex < batches.length,
"Invalid batch index."
);
require(
_hashBatchHeader(_batchHeader) == batches[_batchHeader.batchIndex],
"Invalid batch header."
);
totalBatches = _batchHeader.batchIndex;
totalElements = _batchHeader.prevTotalElements;
}
/*********************
* Private Functions *
*********************/
function _hashBatchHeader(
Lib_OVMDataTypes.OVMChainBatchHeader memory _batchHeader
)
internal
returns (
bytes32 _hash
)
{
return keccak256(abi.encodePacked(
_batchHeader.batchRoot,
_batchHeader.batchSize,
_batchHeader.prevTotalElements,
_batchHeader.extraData
));
}
}
packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_CanonicalTransactionChain.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_MerkleUtils } from "../../../libraries/utils/Lib_MerkleUtils.sol";
/* Interface Imports */
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_BaseQueue } from "../../iOVM/queue/iOVM_BaseQueue.sol";
/* Contract Imports */
import { OVM_BaseChain } from "./OVM_BaseChain.sol";
contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_BaseChain {
iOVM_BaseQueue internal ovmL1ToL2TransactionQueue;
address internal sequencer;
uint256 internal forceInclusionPeriodSeconds;
uint256 internal lastOVMTimestamp;
constructor(
address _ovmL1ToL2TransactionQueue,
address _sequencer,
uint256 _forceInclusionPeriodSeconds,
)
Lib_ContractProxyResolver(_libContractProxyManager)
{
ovmL1ToL2TransactionQueue = iOVM_BaseQueue(_ovmL1ToL2TransactionQueue);
sequencer = _sequencer;
forceInclusionPeriodSeconds = _forceInclusionPeriodSeconds;
}
modifier onlySequencer() {
require(
msg.sender == sequencer,
"Function can only be called by the sequencer."
);
_;
}
function appendQueueBatch()
override
public
{
require(
ovmL1ToL2TransactionQueue.size() > 0 == true,
"No batches are currently queued to be appended."
);
Lib_OVMCodec.QueueElement memory queueElement = ovmL1ToL2TransactionQueue.peek();
require(
queueElement.timestamp + forceInclusionPeriodSeconds <= block.timestamp,
"Cannot append until the inclusion delay period has elapsed."
);
_appendQueueBatch(queueElement, 1);
ovmL1ToL2TransactionQueue.dequeue();
}
function appendSequencerBatch(
bytes[] memory _batch,
uint256 _timestamp
)
override
public
onlySequencer
{
require(
_timestamp >= lastOVMTimestamp,
"Batch timestamp must be later than the last OVM timestamp."
);
if (ovmL1ToL2TransactionQueue.size() > 0) {
require(
_timestamp <= ovmL1ToL2TransactionQueue.peek().timestamp,
"Older queue batches must be processed before a newer sequencer batch."
);
}
Lib_OVMCodec.QueueElement memory queueElement = Lib_OVMCodec.QueueElement({
timestamp: _timestamp,
batchRoot: Lib_MerkleUtils.getMerkleRoot(_batch),
isL1ToL2Batch: false
});
_appendQueueBatch(queueElement, _batch.length);
}
function _appendQueueBatch(
Lib_OVMCodec.QueueElement memory _queueElement,
uint256 _batchSize
)
internal
{
Lib_OVMCodec.ChainBatchHeader memory batchHeader = Lib_OVMCodec.ChainBatchHeader({
batchIndex: getTotalBatches(),
batchRoot: _queueElement.batchRoot,
batchSize: _batchSize,
prevTotalElements: getTotalElements(),
extraData: abi.encodePacked(
_queueElement.timestamp,
_queueElement.isL1ToL2Batch
)
});
_appendBatch(batchHeader);
lastOVMTimestamp = _queueElement.timestamp;
}
}
packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_StateCommitmentChain.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
/* Interface Imports */
import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol";
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_FraudVerifier } from "../../iOVM/execution/iOVM_FraudVerifier.sol";
/* Contract Imports */
import { OVM_BaseChain } from "./OVM_BaseChain.sol";
contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain {
iOVM_CanonicalTransactionChain internal ovmCanonicalTransactionChain;
iOVM_FraudVerifier internal ovmFraudVerifier;
constructor(
address _ovmCanonicalTransactionChain,
address _ovmFraudVerifier
)
Lib_ContractProxyResolver(_libContractProxyManager)
{
ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(_ovmCanonicalTransactionChain);
ovmFraudVerifier = iOVM_FraudVerifier(_ovmFraudVerifier);
}
function appendStateBatch(
bytes32[] memory _batch
)
override
public
{
require(
_batch.length > 0,
"Cannot submit an empty state batch."
);
require(
getTotalElements() + _batch.length <= ovmCanonicalTransactionChain.getTotalElements(),
"Number of state roots cannot exceed the number of canonical transactions."
);
bytes[] memory elements = new bytes[](_batch.length);
for (uint256 i = 0; i < _batch.length; i++) {
elements[i] = abi.encodePacked(_batch[i]);
}
_appendBatch(elements);
}
function deleteStateBatch(
Lib_OVMDataTypes.OVMChainBatchHeader memory _batchHeader
)
override
public
{
require(
msg.sender == address(ovmFraudVerifier),
"State batches can only be deleted by the fraud verifier"
);
_deleteBatch(_batchHeader);
}
}
packages/contracts/contracts/optimistic-ethereum/iOVM/chain/iOVM_BaseChain.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
/**
* @title iOVM_BaseChain
*/
interface iOVM_BaseChain {
/*************************************
* Public Functions: Batch Retrieval *
*************************************/
function getTotalElements() external view returns (uint256 _totalElements);
function getTotalBatches() external view returns (uint256 _totalBatches);
/****************************************
* Public Functions: Batch Verification *
****************************************/
function verifyElement(
bytes calldata _element,
Lib_OVMCodec.ChainBatchHeader calldata _batchHeader,
Lib_OVMCodec.ChainInclusionProof calldata _proof
) external view returns (bool _verified);
}
packages/contracts/contracts/optimistic-ethereum/iOVM/chain/iOVM_CanonicalTransactionChain.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_BaseChain } from "./iOVM_BaseChain.sol";
interface iOVM_CanonicalTransactionChain is iOVM_BaseChain {
function appendQueueBatch() external;
function appendSequencerBatch(bytes[] calldata _batch, uint256 _timestamp) external;
}
packages/contracts/contracts/optimistic-ethereum/iOVM/chain/iOVM_StateCommitmentChain.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_BaseChain } from "./iOVM_BaseChain.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
interface iOVM_StateCommitmentChain is iOVM_BaseChain {
function appendStateBatch(bytes32[] calldata _batch) external;
function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external;
}
packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_MerkleUtils.sol
0 → 100644
View file @
4b241fdb
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title Lib_MerkleUtils
*/
library Lib_MerkleUtils {
function getMerkleRoot(
bytes32[] memory _hashes
)
public
view
returns (
bytes32 _root
)
{
if (_hashes.length == 1) {
return _hashes[0];
}
bytes32[] memory defaultHashes = _getDefaultHashes(_hashes.length);
bytes32[] memory nodes = _hashes;
if (_hashes.length % 2 == 1) {
nodes = new bytes32[](_hashes.length + 1);
for (uint256 i = 0; i < _hashes.length; i++) {
nodes[i] = _hashes[i];
}
}
uint256 currentLevel = 0;
uint256 nextLevelSize = _hashes.length;
if (nextLevelSize % 2 == 1) {
nodes[nextLevelSize] = defaultHashes[currentLevel];
nextLevelSize += 1;
}
while (nextLevelSize > 1) {
currentLevel += 1;
for (uint256 i = 0; i < nextLevelSize / 2; i++) {
nodes[i] = _getParentHash(
nodes[i*2],
nodes[i*2 + 1]
);
}
nextLevelSize = nextLevelSize / 2;
if (nextLevelSize % 2 == 1 && nextLevelSize != 1) {
nodes[nextLevelSize] = defaultHashes[currentLevel];
nextLevelSize += 1;
}
}
return nodes[0];
}
function getMerkleRoot(
bytes[] memory _elements
)
public
view
returns (
bytes32 _root
)
{
bytes32[] memory hashes = new bytes32[](_elements.length);
for (uint256 i = 0; i < _elements.length; i++) {
hashes[i] = keccak256(_elements[i]);
}
return getMerkleRoot(hashes);
}
function verify(
bytes32 _root,
bytes memory _leaf,
uint256 _path,
bytes32[] memory _siblings
)
public
pure
returns (
bool _verified
)
{
bytes32 computedRoot = keccak256(_leaf);
for (uint256 i = 0; i < _siblings.length; i++) {
bytes32 sibling = _siblings[i];
bool isRightSibling = uint8(_path >> i & 1) == 1;
if (isRightSibling) {
computedRoot = _getParentHash(computedRoot, sibling);
} else {
computedRoot = _getParentHash(sibling, computedRoot);
}
}
return computedRoot == _root;
}
function _getDefaultHashes(
uint256 _length
)
internal
pure
returns (
bytes32[] memory _defaultHashes
)
{
bytes32[] memory defaultHashes = new bytes32[](_length);
defaultHashes[0] = keccak256(abi.encodePacked(uint256(0)));
for (uint256 i = 1; i < defaultHashes.length; i++) {
defaultHashes[i] = keccak256(abi.encodePacked(defaultHashes[i-1]));
}
return defaultHashes;
}
function _getParentHash(
bytes32 _leftChildHash,
bytes32 _rightChildHash
)
internal
pure
returns (
bytes32 _hash
)
{
return keccak256(abi.encodePacked(_leftChildHash, _rightChildHash));
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment