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
5db50b3d
Unverified
Commit
5db50b3d
authored
Sep 30, 2021
by
Maurelian
Committed by
Kelvin Fichter
Nov 10, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor(contracts): Remove the queue storage container.
chore: add changeset
parent
d2eb8ae0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
45 additions
and
83 deletions
+45
-83
famous-pugs-prove.md
.changeset/famous-pugs-prove.md
+5
-0
CanonicalTransactionChain.sol
...ntracts/contracts/L1/rollup/CanonicalTransactionChain.sol
+32
-77
CanonicalTransactionChain.gas.spec.ts
...contracts/L1/rollup/CanonicalTransactionChain.gas.spec.ts
+5
-5
CanonicalTransactionChain.spec.ts
...est/contracts/L1/rollup/CanonicalTransactionChain.spec.ts
+3
-1
No files found.
.changeset/famous-pugs-prove.md
0 → 100644
View file @
5db50b3d
---
'
@eth-optimism/contracts'
:
minor
---
Replace the CTCs Queue storage container with a mapping
packages/contracts/contracts/L1/rollup/CanonicalTransactionChain.sol
View file @
5db50b3d
...
...
@@ -48,6 +48,14 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
uint256 public maxTransactionGasLimit;
/***************
* Queue State *
***************/
uint40 private nextQueueIndex; // index of the first queue element not yet included
Lib_OVMCodec.QueueElement[] queueElements;
/***************
* Constructor *
***************/
...
...
@@ -143,7 +151,6 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
uint40
)
{
(,uint40 nextQueueIndex,,) = _getBatchExtraData();
return nextQueueIndex;
}
...
...
@@ -192,8 +199,7 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
)
{
return _getQueueElement(
_index,
queue()
_index
);
}
...
...
@@ -223,9 +229,7 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
uint40
)
{
return _getQueueLength(
queue()
);
return uint40(transactionHashes.length);
}
/**
...
...
@@ -301,21 +305,14 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
)
);
bytes32 timestampAndBlockNumber;
assembly {
timestampAndBlockNumber := timestamp()
timestampAndBlockNumber := or(timestampAndBlockNumber, shl(40, number()))
}
IChainStorageContainer queueRef = queue();
queueRef.push(transactionHash);
queueRef.push(timestampAndBlockNumber);
// The underlying queue data structure stores 2 elements
// per insertion, so to get the real queue length we need
// to divide by 2 and subtract 1.
uint256 queueIndex = queueRef.length() / 2 - 1;
queueElements.push(
Lib_OVMCodec.QueueElement({
transactionHash: transactionHash,
timestamp: uint40(block.timestamp),
blockNumber: uint40(block.number)
})
);
uint256 queueIndex = queueElements.length - 1;
emit TransactionEnqueued(
sender,
_target,
...
...
@@ -365,18 +362,13 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
"Not enough BatchContexts provided."
);
// Take a reference to the queue and its length so we don't have to keep resolving it.
// Length isn't going to change during the course of execution, so it's fine to simply
// resolve this once at the start. Saves gas.
IChainStorageContainer queueRef = queue();
uint40 queueLength = _getQueueLength(queueRef);
// Counter for number of sequencer transactions appended so far.
uint32 numSequencerTransactions = 0;
// We will sequentially append leaves which are pointers to the queue.
// The initial queue index is what is currently in storage.
uint40 nextQueueIndex = getNextQueueIndex();
// Cache the nextQueueIndex.
// In order to be safe, nothing should read or write to the nextQueueIndex
// storage variable until it is updated with the value from nextQueueIndexCached.
uint40 nextQueueIndexCached = nextQueueIndex;
BatchContext memory curContext;
for (uint32 i = 0; i < numContexts; i++) {
...
...
@@ -389,11 +381,11 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
numSequencerTransactions += uint32(curContext.numSequencedTransactions);
// Now process any subsequent queue transactions.
nextQueueIndex += uint40(curContext.numSubsequentQueueTransactions);
nextQueueIndexCached += uint40(curContext.numSubsequentQueueTransactions);
}
require(
nextQueueIndex
<= queueL
ength,
nextQueueIndex
Cached <= queueElements.l
ength,
"Attempted to append more elements than are available in the queue."
);
...
...
@@ -413,8 +405,7 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
// least one queue element. We increment nextQueueIndex after processing each queue
// element, so the index of the last element we processed is nextQueueIndex - 1.
Lib_OVMCodec.QueueElement memory lastElement = _getQueueElement(
nextQueueIndex - 1,
queueRef
nextQueueIndexCached - 1
);
blockTimestamp = lastElement.timestamp;
...
...
@@ -431,10 +422,13 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
);
emit SequencerBatchAppended(
nextQueueIndex - numQueuedTransactions,
nextQueueIndex
Cached
- numQueuedTransactions,
numQueuedTransactions,
getTotalElements()
);
// Update the nextQueueIndex storage variable.
nextQueueIndex = nextQueueIndexCached;
}
/**********************
...
...
@@ -554,8 +548,7 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
* @return _element Queue element at the given index.
*/
function _getQueueElement(
uint256 _index,
IChainStorageContainer _queueRef
uint256 _index
)
internal
view
...
...
@@ -563,46 +556,8 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
Lib_OVMCodec.QueueElement memory _element
)
{
// The underlying queue data structure stores 2 elements
// per insertion, so to get the actual desired queue index
// we need to multiply by 2.
uint40 trueIndex = uint40(_index * 2);
bytes32 transactionHash = _queueRef.get(trueIndex);
bytes32 timestampAndBlockNumber = _queueRef.get(trueIndex + 1);
uint40 elementTimestamp;
uint40 elementBlockNumber;
// solhint-disable max-line-length
assembly {
elementTimestamp := and(timestampAndBlockNumber, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF)
elementBlockNumber := shr(40, and(timestampAndBlockNumber, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000))
}
// solhint-enable max-line-length
return Lib_OVMCodec.QueueElement({
transactionHash: transactionHash,
timestamp: elementTimestamp,
blockNumber: elementBlockNumber
});
}
/**
* Retrieves the length of the queue.
* @return Length of the queue.
*/
function _getQueueLength(
IChainStorageContainer _queueRef
)
internal
view
returns (
uint40
)
{
// The underlying queue data structure stores 2 elements
// per insertion, so to get the real queue length we need
// to divide by 2.
return uint40(_queueRef.length() / 2);
return queueElements[_index];
}
/**
...
...
packages/contracts/test/contracts/L1/rollup/CanonicalTransactionChain.gas.spec.ts
View file @
5db50b3d
...
...
@@ -218,7 +218,7 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain', () => {
'
Non-calldata overhead gas cost per transaction:
'
,
(
gasUsed
-
fixedCalldataCost
)
/
numTxs
)
expectApprox
(
gasUsed
,
1
_6
32_687
,
{
expectApprox
(
gasUsed
,
1
_6
17_381
,
{
absoluteUpperDeviation
:
1000
,
// Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your
// contracts are too efficient, consider updating the target value!
...
...
@@ -307,9 +307,9 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain', () => {
const
gasUsed
=
receipt
.
gasUsed
.
toNumber
()
console
.
log
(
'
Benchmark complete.
'
)
console
.
log
(
'
Gas used:
'
,
gasUsed
)
printGasSavings
(
gasUsed
,
237
_065
)
expectApprox
(
gasUsed
,
2
18
_203
,
{
expectApprox
(
gasUsed
,
2
06
_880
,
{
absoluteUpperDeviation
:
500
,
// Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your
// contracts are too efficient, consider updating the target value!
...
...
@@ -329,9 +329,9 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain', () => {
const
gasUsed
=
receipt
.
gasUsed
.
toNumber
()
console
.
log
(
'
Benchmark complete.
'
)
console
.
log
(
'
Gas used:
'
,
gasUsed
)
printGasSavings
(
gasUsed
,
196
_457
)
expectApprox
(
gasUsed
,
1
57
_822
,
{
expectApprox
(
gasUsed
,
1
46
_499
,
{
absoluteUpperDeviation
:
500
,
// Assert a lower bound of 1% reduction on gas cost. If your tests are breaking because your
// contracts are too efficient, consider updating the target value!
...
...
packages/contracts/test/contracts/L1/rollup/CanonicalTransactionChain.spec.ts
View file @
5db50b3d
...
...
@@ -261,7 +261,9 @@ describe('CanonicalTransactionChain', () => {
it
(
'
should revert when accessing a non-existent element
'
,
async
()
=>
{
await
expect
(
CanonicalTransactionChain
.
getQueueElement
(
0
)
).
to
.
be
.
revertedWith
(
'
Index out of bounds.
'
)
).
to
.
be
.
revertedWith
(
'
reverted with panic code 0x32 (Array accessed at an out-of-bounds or negative index)
'
)
})
describe
(
'
when the requested element exists
'
,
()
=>
{
...
...
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