Commit dcfd3df9 authored by Kelvin Fichter's avatar Kelvin Fichter

Cleaned up CTC and added some tests

parent fba4de0d
...@@ -45,8 +45,8 @@ contract OVM_BaseChain is iOVM_BaseChain { ...@@ -45,8 +45,8 @@ contract OVM_BaseChain is iOVM_BaseChain {
* @return _totalElements Total submitted elements. * @return _totalElements Total submitted elements.
*/ */
function getTotalElements() function getTotalElements()
override
virtual virtual
override
public public
view view
returns ( returns (
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
pragma solidity ^0.7.0; pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
/* Interface Imports */ /* Interface Imports */
import { iOVM_BaseChain } from "./iOVM_BaseChain.sol"; import { iOVM_BaseChain } from "./iOVM_BaseChain.sol";
...@@ -10,11 +13,90 @@ import { iOVM_BaseChain } from "./iOVM_BaseChain.sol"; ...@@ -10,11 +13,90 @@ import { iOVM_BaseChain } from "./iOVM_BaseChain.sol";
*/ */
interface iOVM_CanonicalTransactionChain is iOVM_BaseChain { interface iOVM_CanonicalTransactionChain is iOVM_BaseChain {
/**************************************** /**********
* Public Functions: Batch Manipulation * * Events *
****************************************/ **********/
event QueueTransactionAppended(
bytes _transaction,
bytes32 _timestampAndBlockNumber
);
event ChainBatchAppended(
uint256 _startingQueueIndex,
uint256 _numQueueElements
);
/***********
* Structs *
***********/
struct BatchContext {
uint256 numSequencedTransactions;
uint256 numSubsequentQueueTransactions;
uint256 timestamp;
uint256 blockNumber;
}
struct TransactionChainElement {
bool isSequenced;
uint256 queueIndex; // QUEUED TX ONLY
uint256 timestamp; // SEQUENCER TX ONLY
uint256 blockNumber; // SEQUENCER TX ONLY
bytes txData; // SEQUENCER TX ONLY
}
/********************
* Public Functions *
********************/
/**
* Gets the queue element at a particular index.
* @param _index Index of the queue element to access.
* @return _element Queue element at the given index.
*/
function getQueueElement(
uint256 _index
)
external
view
returns (
Lib_OVMCodec.QueueElement memory _element
);
/**
* 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
) external;
/**
* Appends a given number of queued transactions as a single batch.
* @param _numQueuedTransactions Number of transactions to append.
*/
function appendQueueBatch(
uint256 _numQueuedTransactions
) external;
function enqueue(address _target, uint256 _gasLimit, bytes memory _data) external; /**
function appendQueueBatch() external; * Allows the sequencer to append a batch of transactions.
function appendSequencerBatch(bytes[] calldata _batch, uint256 _timestamp) external; * @param _transactions Array of raw transaction data.
* @param _contexts Array of batch contexts.
* @param _shouldStartAtBatch Specific batch we expect to start appending to.
* @param _totalElementsToAppend Total number of batch elements we expect to append.
*/
function appendSequencerBatch(
bytes[] memory _transactions,
BatchContext[] memory _contexts,
uint256 _shouldStartAtBatch,
uint _totalElementsToAppend
) external;
} }
...@@ -9,14 +9,14 @@ import { Contract, Signer } from 'ethers' ...@@ -9,14 +9,14 @@ import { Contract, Signer } from 'ethers'
import { import {
NON_NULL_BYTES32, NON_NULL_BYTES32,
makeHexString, makeHexString,
increaseEthTime increaseEthTime,
} from '../../../helpers' } from '../../../helpers'
const numToBytes32 = (num: Number): string => { const numToBytes32 = (num: Number): string => {
if (num < 0 || num > 255) { if (num < 0 || num > 255) {
throw new Error('Unsupported number.') throw new Error('Unsupported number.')
} }
const strNum = (num < 16) ? '0' + num.toString(16) : num.toString(16) const strNum = num < 16 ? '0' + num.toString(16) : num.toString(16)
return '0x' + '00'.repeat(31) + strNum return '0x' + '00'.repeat(31) + strNum
} }
...@@ -29,8 +29,14 @@ describe('Lib_TimeboundRingBuffer', () => { ...@@ -29,8 +29,14 @@ describe('Lib_TimeboundRingBuffer', () => {
let Lib_TimeboundRingBuffer: Contract let Lib_TimeboundRingBuffer: Contract
const NON_NULL_BYTES28 = makeHexString('01', 28) const NON_NULL_BYTES28 = makeHexString('01', 28)
const pushNum = (num: Number) => Lib_TimeboundRingBuffer.push(numToBytes32(num), NON_NULL_BYTES28) const pushNum = (num: Number) =>
const push2Nums = (num1: Number, num2: Number) => Lib_TimeboundRingBuffer.push2(numToBytes32(num1), numToBytes32(num2), NON_NULL_BYTES28) Lib_TimeboundRingBuffer.push(numToBytes32(num), NON_NULL_BYTES28)
const push2Nums = (num1: Number, num2: Number) =>
Lib_TimeboundRingBuffer.push2(
numToBytes32(num1),
numToBytes32(num2),
NON_NULL_BYTES28
)
describe('push with no timeout', () => { describe('push with no timeout', () => {
beforeEach(async () => { beforeEach(async () => {
...@@ -69,11 +75,15 @@ describe('Lib_TimeboundRingBuffer', () => { ...@@ -69,11 +75,15 @@ describe('Lib_TimeboundRingBuffer', () => {
}) })
it('should revert if index is too old', async () => { it('should revert if index is too old', async () => {
await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith("Index too old & has been overridden.") await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith(
'Index too old & has been overridden.'
)
}) })
it('should revert if index is greater than length', async () => { it('should revert if index is greater than length', async () => {
await expect(Lib_TimeboundRingBuffer.get(5)).to.be.revertedWith("Index too large.") await expect(Lib_TimeboundRingBuffer.get(5)).to.be.revertedWith(
'Index too large.'
)
}) })
}) })
...@@ -89,7 +99,8 @@ describe('Lib_TimeboundRingBuffer', () => { ...@@ -89,7 +99,8 @@ describe('Lib_TimeboundRingBuffer', () => {
} }
}) })
const pushJunk = () => Lib_TimeboundRingBuffer.push(NON_NULL_BYTES32, NON_NULL_BYTES28) const pushJunk = () =>
Lib_TimeboundRingBuffer.push(NON_NULL_BYTES32, NON_NULL_BYTES28)
it('should push a single value which extends the array', async () => { it('should push a single value which extends the array', async () => {
await pushNum(2) await pushNum(2)
...@@ -151,7 +162,9 @@ describe('Lib_TimeboundRingBuffer', () => { ...@@ -151,7 +162,9 @@ describe('Lib_TimeboundRingBuffer', () => {
it('should return the expected extra data', async () => { it('should return the expected extra data', async () => {
await Lib_TimeboundRingBuffer.push(NON_NULL_BYTES32, NON_NULL_BYTES28) await Lib_TimeboundRingBuffer.push(NON_NULL_BYTES32, NON_NULL_BYTES28)
expect(await Lib_TimeboundRingBuffer.getExtraData()).to.equal(NON_NULL_BYTES28) expect(await Lib_TimeboundRingBuffer.getExtraData()).to.equal(
NON_NULL_BYTES28
)
}) })
}) })
...@@ -168,17 +181,25 @@ describe('Lib_TimeboundRingBuffer', () => { ...@@ -168,17 +181,25 @@ describe('Lib_TimeboundRingBuffer', () => {
it('should disallow deletions which are too old', async () => { it('should disallow deletions which are too old', async () => {
push2Nums(4, 5) push2Nums(4, 5)
await expect(Lib_TimeboundRingBuffer.deleteElementsAfter(0, NON_NULL_BYTES28)).to.be.revertedWith("Attempting to delete too many elements.") await expect(
Lib_TimeboundRingBuffer.deleteElementsAfter(0, NON_NULL_BYTES28)
).to.be.revertedWith('Attempting to delete too many elements.')
}) })
it('should not allow get to be called on an old value even after deletion', async () => { it('should not allow get to be called on an old value even after deletion', async () => {
pushNum(4) pushNum(4)
expect(await Lib_TimeboundRingBuffer.getMaxSize()).to.equal(4) expect(await Lib_TimeboundRingBuffer.getMaxSize()).to.equal(4)
await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith("Index too old & has been overridden.") await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith(
'Index too old & has been overridden.'
)
Lib_TimeboundRingBuffer.deleteElementsAfter(3, NON_NULL_BYTES28) Lib_TimeboundRingBuffer.deleteElementsAfter(3, NON_NULL_BYTES28)
await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith("Index too old & has been overridden.") await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith(
await expect(Lib_TimeboundRingBuffer.get(4)).to.be.revertedWith("Index too large.") 'Index too old & has been overridden.'
)
await expect(Lib_TimeboundRingBuffer.get(4)).to.be.revertedWith(
'Index too large.'
)
expect(await Lib_TimeboundRingBuffer.get(1)).to.equal(numToBytes32(1)) expect(await Lib_TimeboundRingBuffer.get(1)).to.equal(numToBytes32(1))
expect(await Lib_TimeboundRingBuffer.get(3)).to.equal(numToBytes32(3)) expect(await Lib_TimeboundRingBuffer.get(3)).to.equal(numToBytes32(3))
}) })
...@@ -192,4 +213,4 @@ describe('Lib_TimeboundRingBuffer', () => { ...@@ -192,4 +213,4 @@ describe('Lib_TimeboundRingBuffer', () => {
expect(await Lib_TimeboundRingBuffer.get(1)).to.equal(numToBytes32(1)) expect(await Lib_TimeboundRingBuffer.get(1)).to.equal(numToBytes32(1))
}) })
}) })
}) })
\ No newline at end of file
...@@ -24,3 +24,7 @@ export const getBlockTime = async ( ...@@ -24,3 +24,7 @@ export const getBlockTime = async (
await provider.send('evm_mine', []) await provider.send('evm_mine', [])
return (await provider.getBlock(block)).timestamp return (await provider.getBlock(block)).timestamp
} }
export const getNextBlockNumber = async (provider: any): Promise<number> => {
return (await provider.getBlock('latest')).number + 1
}
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
}, },
"linterOptions": { "linterOptions": {
"exclude": [ "exclude": [
"**/node_modules/**/*" "**/node_modules/**/*",
"bin/**/*"
] ]
} }
} }
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