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 {
* @return _totalElements Total submitted elements.
*/
function getTotalElements()
override
virtual
override
public
view
returns (
......
......@@ -2,6 +2,9 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
/* Interface Imports */
import { iOVM_BaseChain } from "./iOVM_BaseChain.sol";
......@@ -10,11 +13,90 @@ import { iOVM_BaseChain } from "./iOVM_BaseChain.sol";
*/
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
}
function enqueue(address _target, uint256 _gasLimit, bytes memory _data) external;
function appendQueueBatch() external;
function appendSequencerBatch(bytes[] calldata _batch, uint256 _timestamp) external;
/********************
* 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;
/**
* Allows the sequencer to append a batch of transactions.
* @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'
import {
NON_NULL_BYTES32,
makeHexString,
increaseEthTime
increaseEthTime,
} from '../../../helpers'
const numToBytes32 = (num: Number): string => {
if (num < 0 || num > 255) {
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
}
......@@ -29,8 +29,14 @@ describe('Lib_TimeboundRingBuffer', () => {
let Lib_TimeboundRingBuffer: Contract
const NON_NULL_BYTES28 = makeHexString('01', 28)
const pushNum = (num: Number) => Lib_TimeboundRingBuffer.push(numToBytes32(num), NON_NULL_BYTES28)
const push2Nums = (num1: Number, num2: Number) => Lib_TimeboundRingBuffer.push2(numToBytes32(num1), numToBytes32(num2), NON_NULL_BYTES28)
const pushNum = (num: Number) =>
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', () => {
beforeEach(async () => {
......@@ -69,11 +75,15 @@ describe('Lib_TimeboundRingBuffer', () => {
})
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 () => {
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', () => {
}
})
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 () => {
await pushNum(2)
......@@ -151,7 +162,9 @@ describe('Lib_TimeboundRingBuffer', () => {
it('should return the expected extra data', async () => {
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', () => {
it('should disallow deletions which are too old', async () => {
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 () => {
pushNum(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)
await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith("Index too old & has been overridden.")
await expect(Lib_TimeboundRingBuffer.get(4)).to.be.revertedWith("Index too large.")
await expect(Lib_TimeboundRingBuffer.get(0)).to.be.revertedWith(
'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(3)).to.equal(numToBytes32(3))
})
......
......@@ -24,3 +24,7 @@ export const getBlockTime = async (
await provider.send('evm_mine', [])
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 @@
},
"linterOptions": {
"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