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
faa0086a
Commit
faa0086a
authored
Oct 12, 2020
by
Karl Floersch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove old L1ToL2 queue
parent
a71ff5bd
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
19 additions
and
1102 deletions
+19
-1102
OVM_L1CrossDomainMessenger.sol
...mistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol
+4
-4
NEW_OVM_CanonicalTransactionChain.sol
...-ethereum/OVM/chain/NEW_OVM_CanonicalTransactionChain.sol
+12
-16
OVM_CanonicalTransactionChain.sol
...stic-ethereum/OVM/chain/OVM_CanonicalTransactionChain.sol
+0
-155
OVM_BaseQueue.sol
...contracts/optimistic-ethereum/OVM/queue/OVM_BaseQueue.sol
+0
-108
OVM_L1ToL2TransactionQueue.sol
...imistic-ethereum/OVM/queue/OVM_L1ToL2TransactionQueue.sol
+0
-124
iOVM_CanonicalTransactionChain.sol
...ic-ethereum/iOVM/chain/iOVM_CanonicalTransactionChain.sol
+1
-0
iOVM_BaseQueue.sol
...ntracts/optimistic-ethereum/iOVM/queue/iOVM_BaseQueue.sol
+0
-19
iOVM_L1ToL2TransactionQueue.sol
...istic-ethereum/iOVM/queue/iOVM_L1ToL2TransactionQueue.sol
+0
-22
Lib_OVMCodec.sol
...acts/optimistic-ethereum/libraries/codec/Lib_OVMCodec.sol
+2
-2
OVM_CanonicalTransactionChain.spec.ts
...contracts/OVM/chain/OVM_CanonicalTransactionChain.spec.ts
+0
-368
OVM_L1ToL2TransactionQueue.spec.ts
...st/contracts/OVM/queue/OVM_L1ToL2TransactionQueue.spec.ts
+0
-284
No files found.
packages/contracts/contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol
View file @
faa0086a
...
...
@@ -10,7 +10,7 @@ import { Lib_BytesUtils } from "../../libraries/utils/Lib_BytesUtils.sol";
/* Interface Imports */
import { iOVM_L1CrossDomainMessenger } from "../../iOVM/bridge/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_
L1ToL2TransactionQueue } from "../../iOVM/queue/iOVM_L1ToL2TransactionQueue
.sol";
import { iOVM_
CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain
.sol";
import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol";
/* Contract Imports */
...
...
@@ -25,7 +25,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
* Contract Variables: Contract References *
*******************************************/
iOVM_
L1ToL2TransactionQueue internal ovmL1ToL2TransactionQueue
;
iOVM_
CanonicalTransactionChain internal ovmCanonicalTransactionChain
;
iOVM_StateCommitmentChain internal ovmStateCommitmentChain;
...
...
@@ -41,7 +41,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
)
Lib_AddressResolver(_libAddressManager)
{
ovm
L1ToL2TransactionQueue = iOVM_L1ToL2TransactionQueue(resolve("OVM_L1ToL2TransactionQueue
"));
ovm
CanonicalTransactionChain = iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain
"));
ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
}
...
...
@@ -235,7 +235,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
override
internal
{
ovm
L1ToL2TransactionQueue
.enqueue(
ovm
CanonicalTransactionChain
.enqueue(
targetMessengerAddress,
_gasLimit,
_message
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/chain/NEW_OVM_CanonicalTransactionChain.sol
View file @
faa0086a
...
...
@@ -11,7 +11,6 @@ import { console } from "@nomiclabs/buidler/console.sol";
/* Interface Imports */
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_L1ToL2TransactionQueue } from "../../iOVM/queue/iOVM_L1ToL2TransactionQueue.sol";
/* Contract Imports */
import { OVM_BaseChain } from "./OVM_BaseChain.sol";
...
...
@@ -50,8 +49,6 @@ contract NEW_OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver
* Contract Variables: Contract References *
*******************************************/
iOVM_L1ToL2TransactionQueue internal ovmL1ToL2TransactionQueue;
/*******************************************
* Contract Variables: Internal Accounting *
...
...
@@ -76,7 +73,6 @@ contract NEW_OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver
)
Lib_AddressResolver(_libAddressManager)
{
ovmL1ToL2TransactionQueue = iOVM_L1ToL2TransactionQueue(resolve("OVM_L1ToL2TransactionQueue"));
sequencerAddress = resolve("OVM_Sequencer");
forceInclusionPeriodSeconds = _forceInclusionPeriodSeconds;
queue.init(100, 50, 0); // TODO: Update once we have arbitrary condition
...
...
@@ -106,7 +102,7 @@ contract NEW_OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver
);
require(_gasLimit >= 20000, "Gas limit too low.");
// Consume l1 gas
to pay for l2 gas on l1
// Consume l1 gas
rate limit queued transactions
uint gasToConsume = _gasLimit/L2_GAS_DISCOUNT_DIVISOR;
uint startingGas = gasleft();
uint i;
...
...
@@ -115,13 +111,13 @@ contract NEW_OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver
}
Lib_OVMCodec.QueueElement memory element = Lib_OVMCodec.QueueElement({
timestamp: block.timestamp,
timestamp: uint40(block.timestamp),
blockNumber: uint32(block.number),
batchRoot: keccak256(abi.encodePacked(
_target,
_gasLimit,
_data
)),
isL1ToL2Batch: true
))
});
// bytes32 extraData = timestamp + blockNumber
...
...
@@ -159,12 +155,11 @@ contract NEW_OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver
"Function can only be called by the Sequencer."
);
if (ovmL1ToL2TransactionQueue.size() > 0) {
require(
block.timestamp < ovmL1ToL2TransactionQueue.peek().timestamp + forceInclusionPeriodSeconds,
"Older queue batches must be processed before a new sequencer batch."
);
}
// TODO: Verify that there are no outstanding queue transactions which need to be processed
// require(
// block.timestamp < queue.get(lastQueueIndex).timestamp + forceInclusionPeriodSeconds,
// "Older queue batches must be processed before a new sequencer batch."
// );
// Initialize an array which will contain the leaves of the merkle tree commitment
bytes32[] memory leaves = new bytes32[](_totalElementsToAppend);
...
...
@@ -196,14 +191,15 @@ contract NEW_OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver
for (uint queueTxIndex = 0; queueTxIndex < numQueuedTransactions; queueTxIndex++) {
TransactionChainElement memory element = TransactionChainElement({
isSequenced: false,
queueIndex:
ovmL1ToL2TransactionQueue.size
(),
queueIndex:
queue.getLength
(),
timestamp: 0,
blocknumber: 0,
txData: hex""
});
leaves[transactionIndex] = _hashTransactionChainElement(element);
transactionIndex++;
ovmL1ToL2TransactionQueue.dequeue();
// TODO: Increment our lastQueueIndex
// lastQueueIndex++;
}
}
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_CanonicalTransactionChain.sol
deleted
100644 → 0
View file @
a71ff5bd
// 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_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_MerkleUtils } from "../../libraries/utils/Lib_MerkleUtils.sol";
/* Interface Imports */
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_L1ToL2TransactionQueue } from "../../iOVM/queue/iOVM_L1ToL2TransactionQueue.sol";
/* Contract Imports */
import { OVM_BaseChain } from "./OVM_BaseChain.sol";
/**
* @title OVM_CanonicalTransactionChain
*/
contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_BaseChain, Lib_AddressResolver {
/*******************************************
* Contract Variables: Contract References *
*******************************************/
iOVM_L1ToL2TransactionQueue internal ovmL1ToL2TransactionQueue;
/*******************************************
* Contract Variables: Internal Accounting *
*******************************************/
uint256 internal forceInclusionPeriodSeconds;
uint256 internal lastOVMTimestamp;
/***************
* Constructor *
***************/
/**
* @param _libAddressManager Address of the Address Manager.
* @param _forceInclusionPeriodSeconds Period during which only the sequencer can submit.
*/
constructor(
address _libAddressManager,
uint256 _forceInclusionPeriodSeconds
)
Lib_AddressResolver(_libAddressManager)
{
ovmL1ToL2TransactionQueue = iOVM_L1ToL2TransactionQueue(resolve("OVM_L1ToL2TransactionQueue"));
forceInclusionPeriodSeconds = _forceInclusionPeriodSeconds;
}
/****************************************
* Public Functions: Batch Manipulation *
****************************************/
/**
* Appends a batch from the L1ToL2TransactionQueue.
*/
function appendQueueBatch()
override
public
{
require(
ovmL1ToL2TransactionQueue.size() > 0,
"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();
}
/**
* Appends a sequencer batch.
* @param _batch Batch of transactions to append.
* @param _timestamp Timestamp for the provided batch.
*/
function appendSequencerBatch(
bytes[] memory _batch,
uint256 _timestamp
)
override
public
{
require(
msg.sender == resolve("Sequencer"),
"Function can only be called by the Sequencer."
);
require(
_batch.length > 0,
"Cannot submit an empty batch."
);
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);
}
/******************************************
* Internal Functions: Batch Manipulation *
******************************************/
/**
* Appends a queue batch to the chain.
* @param _queueElement Queue element to append.
* @param _batchSize Number of elements in the batch.
*/
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/queue/OVM_BaseQueue.sol
deleted
100644 → 0
View file @
a71ff5bd
// 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_BaseQueue } from "../../iOVM/queue/iOVM_BaseQueue.sol";
/**
* @title OVM_BaseQueue
*/
contract OVM_BaseQueue is iOVM_BaseQueue {
/****************************************
* Contract Variables: Internal Storage *
****************************************/
Lib_OVMCodec.QueueElement[] internal queue;
uint256 internal front;
/**********************
* Function Modifiers *
**********************/
/**
* Asserts that the queue is not empty.
*/
modifier notEmpty() {
require(
size() > 0,
"Queue is empty."
);
_;
}
/**********************************
* Public Functions: Queue Access *
**********************************/
/**
* Gets the size of the queue.
* @return _size Number of elements in the queue.
*/
function size()
override
public
view
returns (
uint256 _size
)
{
return front >= queue.length ? 0 : queue.length - front;
}
/**
* Gets the top element of the queue.
* @return _element First element in the queue.
*/
function peek()
override
public
view
notEmpty
returns (
Lib_OVMCodec.QueueElement memory _element
)
{
return queue[front];
}
/******************************************
* Internal Functions: Queue Manipulation *
******************************************/
/**
* Adds an element to the queue.
* @param _element Queue element to add to the queue.
*/
function _enqueue(
Lib_OVMCodec.QueueElement memory _element
)
internal
{
queue.push(_element);
}
/**
* Pops an element from the queue.
* @return _element Queue element popped from the queue.
*/
function _dequeue()
internal
notEmpty
returns (
Lib_OVMCodec.QueueElement memory _element
)
{
_element = queue[front];
delete queue[front];
front += 1;
return _element;
}
}
packages/contracts/contracts/optimistic-ethereum/OVM/queue/OVM_L1ToL2TransactionQueue.sol
deleted
100644 → 0
View file @
a71ff5bd
// 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_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
/* Interface Imports */
import { iOVM_L1ToL2TransactionQueue } from "../../iOVM/queue/iOVM_L1ToL2TransactionQueue.sol";
/* Contract Imports */
import { OVM_BaseQueue } from "./OVM_BaseQueue.sol";
/**
* @title OVM_L1ToL2TransactionQueue
*/
contract OVM_L1ToL2TransactionQueue is iOVM_L1ToL2TransactionQueue, OVM_BaseQueue, Lib_AddressResolver {
/*************************************************
* Contract Variables: Transaction Restrinctions *
*************************************************/
uint constant MAX_ROLLUP_TX_SIZE = 10000;
uint constant L2_GAS_DISCOUNT_DIVISOR = 10;
/*******************************************
* Contract Variables: Contract References *
*******************************************/
address internal ovmCanonicalTransactionChain;
/***************
* Constructor *
***************/
/**
* @param _libAddressManager Address of the Address Manager.
*/
constructor(
address _libAddressManager
)
Lib_AddressResolver(_libAddressManager)
{
ovmCanonicalTransactionChain = resolve("OVM_CanonicalTransactionChain");
}
/****************************************
* Public Functions: Queue Manipulation *
****************************************/
/**
* Adds a transaction to the queue.
* @param _target Target contract to send the transaction to.
* @param _gasLimit Gas limit for the given transaction.
* @param _data Transaction data.
*/
function enqueue(
address _target,
uint256 _gasLimit,
bytes memory _data
)
override
public
{
require(
_data.length <= MAX_ROLLUP_TX_SIZE,
"Transaction exceeds maximum rollup data size."
);
require(_gasLimit >= 20000, "Gas limit too low.");
consumeGas(_gasLimit/L2_GAS_DISCOUNT_DIVISOR);
Lib_OVMCodec.QueueElement memory element = Lib_OVMCodec.QueueElement({
timestamp: block.timestamp,
batchRoot: keccak256(abi.encodePacked(
_target,
_gasLimit,
_data
)),
isL1ToL2Batch: true
});
_enqueue(element);
}
/**
* Pops an element from the queue.
*/
function dequeue()
override
public
{
require(
msg.sender == ovmCanonicalTransactionChain,
"Sender is not allowed to dequeue."
);
_dequeue();
}
/***************************************
* External Functions: Gas Consumption *
***************************************/
/**
* Consumes all gas provided.
*/
function consumeGas
(
uint gasToConsume
)
internal
{
uint startingGas = gasleft();
uint i;
while(startingGas - gasleft() > gasToConsume) {
i++; // TODO: Replace this dumb work with minting gas token.
}
}
}
packages/contracts/contracts/optimistic-ethereum/iOVM/chain/iOVM_CanonicalTransactionChain.sol
View file @
faa0086a
...
...
@@ -14,6 +14,7 @@ interface iOVM_CanonicalTransactionChain is iOVM_BaseChain {
* Public Functions: Batch Manipulation *
****************************************/
function enqueue(address _target, uint256 _gasLimit, bytes memory _data) external;
function appendQueueBatch() external;
function appendSequencerBatch(bytes[] calldata _batch, uint256 _timestamp) external;
}
packages/contracts/contracts/optimistic-ethereum/iOVM/queue/iOVM_BaseQueue.sol
deleted
100644 → 0
View file @
a71ff5bd
// 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_BaseQueue
*/
interface iOVM_BaseQueue {
/**********************************
* Public Functions: Queue Access *
**********************************/
function size() external view returns (uint256 _size);
function peek() external view returns (Lib_OVMCodec.QueueElement memory _element);
}
packages/contracts/contracts/optimistic-ethereum/iOVM/queue/iOVM_L1ToL2TransactionQueue.sol
deleted
100644 → 0
View file @
a71ff5bd
// 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_BaseQueue } from "./iOVM_BaseQueue.sol";
/**
* @title iOVM_L1ToL2TransactionQueue
*/
interface iOVM_L1ToL2TransactionQueue is iOVM_BaseQueue {
/****************************************
* Public Functions: Queue Manipulation *
****************************************/
function enqueue(address _target, uint256 _gasLimit, bytes memory _data) external;
function dequeue() external;
}
packages/contracts/contracts/optimistic-ethereum/libraries/codec/Lib_OVMCodec.sol
View file @
faa0086a
...
...
@@ -82,8 +82,8 @@ library Lib_OVMCodec {
struct QueueElement {
bytes32 batchRoot;
uint
256 timestamp; // TODO: make smaller so it gets back and update L1toL2queue to truncate
bool isL1ToL2Batch
;
uint
40 timestamp;
uint32 blockNumber
;
}
struct EOATransaction {
...
...
packages/contracts/test/contracts/OVM/chain/OVM_CanonicalTransactionChain.spec.ts
deleted
100644 → 0
View file @
a71ff5bd
import
{
expect
}
from
'
../../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Signer
,
ContractFactory
,
Contract
}
from
'
ethers
'
import
{
smockit
,
MockContract
}
from
'
@eth-optimism/smock
'
/* Internal Imports */
import
{
makeAddressManager
,
setProxyTarget
,
getEthTime
,
setEthTime
,
NON_NULL_BYTES32
,
FORCE_INCLUSION_PERIOD_SECONDS
,
ZERO_ADDRESS
,
}
from
'
../../../helpers
'
describe
(
'
OVM_CanonicalTransactionChain
'
,
()
=>
{
let
signer
:
Signer
before
(
async
()
=>
{
;[
signer
]
=
await
ethers
.
getSigners
()
})
let
AddressManager
:
Contract
before
(
async
()
=>
{
AddressManager
=
await
makeAddressManager
()
})
let
Mock__OVM_L1ToL2TransactionQueue
:
MockContract
before
(
async
()
=>
{
Mock__OVM_L1ToL2TransactionQueue
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_L1ToL2TransactionQueue
'
)
)
await
setProxyTarget
(
AddressManager
,
'
OVM_L1ToL2TransactionQueue
'
,
Mock__OVM_L1ToL2TransactionQueue
)
})
let
Factory__OVM_CanonicalTransactionChain
:
ContractFactory
before
(
async
()
=>
{
Factory__OVM_CanonicalTransactionChain
=
await
ethers
.
getContractFactory
(
'
OVM_CanonicalTransactionChain
'
)
})
let
OVM_CanonicalTransactionChain
:
Contract
beforeEach
(
async
()
=>
{
OVM_CanonicalTransactionChain
=
await
Factory__OVM_CanonicalTransactionChain
.
deploy
(
AddressManager
.
address
,
FORCE_INCLUSION_PERIOD_SECONDS
)
})
describe
(
'
appendQueueBatch()
'
,
()
=>
{
describe
(
'
when the L1ToL2TransactionQueue queue is empty
'
,
()
=>
{
before
(()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
})
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendQueueBatch
()
).
to
.
be
.
revertedWith
(
'
No batches are currently queued to be appended.
'
)
})
})
describe
(
'
when the L1ToL2TransactionQueue queue is not empty
'
,
()
=>
{
before
(()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
1
)
})
describe
(
'
when the inclusion delay period has not elapsed
'
,
()
=>
{
beforeEach
(
async
()
=>
{
const
timestamp
=
await
getEthTime
(
ethers
.
provider
)
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
peek
.
will
.
return
.
with
([
{
timestamp
,
batchRoot
:
NON_NULL_BYTES32
,
isL1ToL2Batch
:
true
,
},
])
await
setEthTime
(
ethers
.
provider
,
timestamp
+
FORCE_INCLUSION_PERIOD_SECONDS
/
2
)
})
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendQueueBatch
()
).
to
.
be
.
revertedWith
(
'
Cannot append until the inclusion delay period has elapsed.
'
)
})
})
describe
(
'
when the inclusion delay period has elapsed
'
,
()
=>
{
beforeEach
(
async
()
=>
{
const
timestamp
=
await
getEthTime
(
ethers
.
provider
)
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
dequeue
.
will
.
return
()
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
peek
.
will
.
return
.
with
([
{
timestamp
,
batchRoot
:
NON_NULL_BYTES32
,
isL1ToL2Batch
:
true
,
},
])
await
setEthTime
(
ethers
.
provider
,
timestamp
+
FORCE_INCLUSION_PERIOD_SECONDS
)
})
it
(
'
should append the top element of the queue and attempt to dequeue
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendQueueBatch
()).
to
.
not
.
be
.
reverted
// TODO: Check that the batch root was inserted.
expect
(
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
dequeue
.
calls
.
length
).
to
.
equal
(
1
)
})
})
})
})
describe
(
'
appendSequencerBatch()
'
,
()
=>
{
describe
(
'
when the sender is not the sequencer
'
,
()
=>
{
before
(
async
()
=>
{
await
AddressManager
.
setAddress
(
'
Sequencer
'
,
ZERO_ADDRESS
)
})
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendSequencerBatch
([],
0
)
).
to
.
be
.
revertedWith
(
'
Function can only be called by the Sequencer.
'
)
})
})
describe
(
'
when the sender is the sequencer
'
,
()
=>
{
before
(
async
()
=>
{
await
AddressManager
.
setAddress
(
'
Sequencer
'
,
await
signer
.
getAddress
())
})
describe
(
'
when the given batch is empty
'
,
()
=>
{
const
batch
=
[]
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
0
)
).
to
.
be
.
revertedWith
(
'
Cannot submit an empty batch.
'
)
})
})
describe
(
'
when the given batch is not empty
'
,
()
=>
{
const
batch
=
[
NON_NULL_BYTES32
]
describe
(
'
when the timestamp is not greater than the previous OVM timestamp
'
,
()
=>
{
const
timestamp
=
0
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
timestamp
)
).
to
.
be
.
revertedWith
(
'
Batch timestamp must be later than the last OVM timestamp.
'
)
})
})
describe
(
'
when the timestamp is greater than the previous OVM timestamp
'
,
()
=>
{
const
timestamp
=
1000
describe
(
'
when the queue is not empty
'
,
()
=>
{
before
(()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
1
)
})
describe
(
'
when the first element in the queue is older than the provided batch
'
,
()
=>
{
before
(()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
peek
.
will
.
return
.
with
([
{
timestamp
:
timestamp
/
2
,
batchRoot
:
NON_NULL_BYTES32
,
isL1ToL2Batch
:
true
,
},
])
})
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
timestamp
)
).
to
.
be
.
revertedWith
(
'
Older queue batches must be processed before a newer sequencer batch.
'
)
})
})
describe
(
'
when the first element in the queue is not older than the provided batch
'
,
()
=>
{
before
(()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
peek
.
will
.
return
.
with
([
{
timestamp
,
batchRoot
:
NON_NULL_BYTES32
,
isL1ToL2Batch
:
true
,
},
])
})
it
(
'
should insert the sequencer batch
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
timestamp
)
).
to
.
not
.
be
.
reverted
// TODO: Check that the batch was inserted correctly.
})
})
})
describe
(
'
when the queue is empty
'
,
async
()
=>
{
before
(()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
})
it
(
'
should insert the sequencer batch
'
,
async
()
=>
{
await
expect
(
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
timestamp
)
).
to
.
not
.
be
.
reverted
// TODO: Check that the batch was inserted correctly.
})
})
})
})
})
})
describe
(
'
getTotalElements()
'
,
()
=>
{
describe
(
'
when no batch elements have been inserted
'
,
()
=>
{
it
(
'
should return zero
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalElements
()).
to
.
equal
(
0
)
})
})
describe
(
'
when one batch element has been inserted
'
,
()
=>
{
beforeEach
(
async
()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
await
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
[
NON_NULL_BYTES32
],
1000
)
})
it
(
'
should return the number of inserted batch elements
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalElements
()).
to
.
equal
(
1
)
})
})
describe
(
'
when 64 batch elements have been inserted in one batch
'
,
()
=>
{
const
batch
=
Array
(
64
).
fill
(
NON_NULL_BYTES32
)
beforeEach
(
async
()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
await
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
1000
)
})
it
(
'
should return the number of inserted batch elements
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalElements
()).
to
.
equal
(
64
)
})
})
describe
(
'
when 32 batch elements have been inserted in each of two batches
'
,
()
=>
{
const
batch
=
Array
(
32
).
fill
(
NON_NULL_BYTES32
)
beforeEach
(
async
()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
await
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
1000
)
await
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
batch
,
2000
)
})
it
(
'
should return the number of inserted batch elements
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalElements
()).
to
.
equal
(
64
)
})
})
})
describe
(
'
getTotalBatches()
'
,
()
=>
{
describe
(
'
when no batches have been inserted
'
,
()
=>
{
it
(
'
should return zero
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalBatches
()).
to
.
equal
(
0
)
})
})
describe
(
'
when one batch has been inserted
'
,
()
=>
{
beforeEach
(
async
()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
await
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
[
NON_NULL_BYTES32
],
1000
)
})
it
(
'
should return the number of inserted batch elements
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalBatches
()).
to
.
equal
(
1
)
})
})
describe
(
'
when 8 batches have been inserted
'
,
()
=>
{
beforeEach
(
async
()
=>
{
Mock__OVM_L1ToL2TransactionQueue
.
smocked
.
size
.
will
.
return
.
with
(
0
)
for
(
let
i
=
0
;
i
<
8
;
i
++
)
{
await
OVM_CanonicalTransactionChain
.
appendSequencerBatch
(
[
NON_NULL_BYTES32
],
1000
*
(
i
+
1
)
)
}
})
it
(
'
should return the number of inserted batch elements
'
,
async
()
=>
{
expect
(
await
OVM_CanonicalTransactionChain
.
getTotalBatches
()).
to
.
equal
(
8
)
})
})
})
describe
(
'
verifyElement()
'
,
()
=>
{
it
(
'
should revert when given an invalid batch header
'
,
async
()
=>
{
// TODO
})
it
(
'
should revert when given an invalid inclusion proof
'
,
async
()
=>
{
// TODO
})
it
(
'
should return true when given a valid proof
'
,
async
()
=>
{
// TODO
})
})
})
packages/contracts/test/contracts/OVM/queue/OVM_L1ToL2TransactionQueue.spec.ts
deleted
100644 → 0
View file @
a71ff5bd
import
{
expect
}
from
'
../../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Contract
,
ContractFactory
,
Signer
,
BigNumber
}
from
'
ethers
'
import
{
keccak256
}
from
'
ethers/lib/utils
'
import
_
from
'
lodash
'
/* Internal Imports */
import
{
ZERO_ADDRESS
,
NON_ZERO_ADDRESS
,
DUMMY_BYTES32
,
remove0x
,
getBlockTime
,
makeAddressManager
,
}
from
'
../../../helpers
'
const
calcBatchRoot
=
(
element
:
any
):
string
=>
{
return
keccak256
(
element
.
target
+
remove0x
(
BigNumber
.
from
(
element
.
gasLimit
).
toHexString
()).
padStart
(
64
,
'
0
'
)
+
remove0x
(
element
.
data
)
)
}
const
makeQueueElements
=
(
count
:
number
):
any
=>
{
return
[...
Array
(
count
)].
map
((
el
,
idx
)
=>
{
return
{
target
:
NON_ZERO_ADDRESS
,
gasLimit
:
idx
+
30
_000
,
data
:
DUMMY_BYTES32
[
0
],
}
})
}
describe
.
only
(
'
OVM_L1ToL2TransactionQueue
'
,
()
=>
{
let
signer
:
Signer
before
(
async
()
=>
{
;[
signer
]
=
await
ethers
.
getSigners
()
})
let
AddressManager
:
Contract
before
(
async
()
=>
{
AddressManager
=
await
makeAddressManager
()
})
let
Factory__OVM_L1ToL2TransactionQueue
:
ContractFactory
before
(
async
()
=>
{
Factory__OVM_L1ToL2TransactionQueue
=
await
ethers
.
getContractFactory
(
'
OVM_L1ToL2TransactionQueue
'
)
})
let
OVM_L1ToL2TransactionQueue
:
Contract
beforeEach
(
async
()
=>
{
OVM_L1ToL2TransactionQueue
=
await
Factory__OVM_L1ToL2TransactionQueue
.
deploy
(
AddressManager
.
address
)
})
describe
(
'
enqueue()
'
,
()
=>
{
it
(
'
should allow users to enqueue an element
'
,
async
()
=>
{
const
[
element
]
=
makeQueueElements
(
1
)
await
expect
(
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
).
to
.
not
.
be
.
reverted
})
it
(
'
should allow users to enqueue more than one element
'
,
async
()
=>
{
for
(
const
element
of
makeQueueElements
(
10
))
{
await
expect
(
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
).
to
.
not
.
be
.
reverted
}
})
})
describe
(
'
dequeue()
'
,
()
=>
{
describe
(
'
when the sender is not the OVM_CanonicalTransactionChain
'
,
()
=>
{
before
(
async
()
=>
{
await
AddressManager
.
setAddress
(
'
OVM_CanonicalTransactionChain
'
,
ZERO_ADDRESS
)
})
it
(
'
should revert
'
,
async
()
=>
{
await
expect
(
OVM_L1ToL2TransactionQueue
.
dequeue
()).
to
.
be
.
revertedWith
(
'
Sender is not allowed to dequeue.
'
)
})
})
describe
(
'
when the sender is the OVM_CanonicalTransactionChain
'
,
()
=>
{
before
(
async
()
=>
{
await
AddressManager
.
setAddress
(
'
OVM_CanonicalTransactionChain
'
,
await
signer
.
getAddress
()
)
})
it
(
'
should revert if the queue is empty
'
,
async
()
=>
{
await
expect
(
OVM_L1ToL2TransactionQueue
.
dequeue
()).
to
.
be
.
revertedWith
(
'
Queue is empty.
'
)
})
it
(
'
should allow users to dequeue an element
'
,
async
()
=>
{
const
[
element
]
=
makeQueueElements
(
1
)
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
await
expect
(
OVM_L1ToL2TransactionQueue
.
dequeue
()).
to
.
not
.
be
.
reverted
})
it
(
'
should allow users to dequeue more than one element
'
,
async
()
=>
{
const
elements
=
makeQueueElements
(
10
)
for
(
const
element
of
elements
)
{
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
}
for
(
const
element
of
elements
)
{
await
expect
(
OVM_L1ToL2TransactionQueue
.
dequeue
()).
to
.
not
.
be
.
reverted
}
})
})
})
describe
(
'
size()
'
,
()
=>
{
before
(
async
()
=>
{
await
AddressManager
.
setAddress
(
'
OVM_CanonicalTransactionChain
'
,
await
signer
.
getAddress
()
)
})
it
(
'
should return zero when no elements are in the queue
'
,
async
()
=>
{
const
size
=
await
OVM_L1ToL2TransactionQueue
.
size
()
expect
(
size
).
to
.
equal
(
0
)
})
it
(
'
should increase when new elements are enqueued
'
,
async
()
=>
{
const
elements
=
makeQueueElements
(
10
)
for
(
let
i
=
0
;
i
<
elements
.
length
;
i
++
)
{
const
element
=
elements
[
i
]
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
const
size
=
await
OVM_L1ToL2TransactionQueue
.
size
()
expect
(
size
).
to
.
equal
(
i
+
1
)
}
})
it
(
'
should decrease when elements are dequeued
'
,
async
()
=>
{
const
elements
=
makeQueueElements
(
10
)
for
(
const
element
of
elements
)
{
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
}
for
(
let
i
=
0
;
i
<
elements
.
length
;
i
++
)
{
await
OVM_L1ToL2TransactionQueue
.
dequeue
()
const
size
=
await
OVM_L1ToL2TransactionQueue
.
size
()
expect
(
size
).
to
.
equal
(
elements
.
length
-
i
-
1
)
}
})
})
describe
(
'
peek()
'
,
()
=>
{
before
(
async
()
=>
{
await
AddressManager
.
setAddress
(
'
OVM_CanonicalTransactionChain
'
,
await
signer
.
getAddress
()
)
})
it
(
'
should revert when the queue is empty
'
,
async
()
=>
{
await
expect
(
OVM_L1ToL2TransactionQueue
.
peek
()).
to
.
be
.
revertedWith
(
'
Queue is empty.
'
)
})
it
(
'
should return the front element if only one exists
'
,
async
()
=>
{
const
[
element
]
=
makeQueueElements
(
1
)
const
result
=
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
const
timestamp
=
BigNumber
.
from
(
await
getBlockTime
(
ethers
.
provider
,
result
.
blockNumber
)
)
expect
(
_
.
toPlainObject
(
await
OVM_L1ToL2TransactionQueue
.
peek
())
).
to
.
deep
.
include
({
timestamp
,
batchRoot
:
calcBatchRoot
(
element
),
isL1ToL2Batch
:
true
,
})
})
it
(
'
should return the front if more than one exists
'
,
async
()
=>
{
const
elements
=
makeQueueElements
(
10
)
const
result
=
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
elements
[
0
].
target
,
elements
[
0
].
gasLimit
,
elements
[
0
].
data
)
const
timestamp
=
BigNumber
.
from
(
await
getBlockTime
(
ethers
.
provider
,
result
.
blockNumber
)
)
for
(
const
element
of
elements
.
slice
(
1
))
{
expect
(
_
.
toPlainObject
(
await
OVM_L1ToL2TransactionQueue
.
peek
())
).
to
.
deep
.
include
({
timestamp
,
batchRoot
:
calcBatchRoot
(
elements
[
0
]),
isL1ToL2Batch
:
true
,
})
}
})
it
(
'
should return the new front when elements are dequeued
'
,
async
()
=>
{
const
elements
=
makeQueueElements
(
10
)
const
timestamps
:
BigNumber
[]
=
[]
for
(
const
element
of
elements
)
{
const
result
=
await
OVM_L1ToL2TransactionQueue
.
enqueue
(
element
.
target
,
element
.
gasLimit
,
element
.
data
)
timestamps
.
push
(
BigNumber
.
from
(
await
getBlockTime
(
ethers
.
provider
,
result
.
blockNumber
)
)
)
}
for
(
let
i
=
0
;
i
<
elements
.
length
-
1
;
i
++
)
{
expect
(
_
.
toPlainObject
(
await
OVM_L1ToL2TransactionQueue
.
peek
())
).
to
.
deep
.
include
({
timestamp
:
timestamps
[
i
],
batchRoot
:
calcBatchRoot
(
elements
[
i
]),
isL1ToL2Batch
:
true
,
})
await
OVM_L1ToL2TransactionQueue
.
dequeue
()
}
})
})
})
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