Commit db369be9 authored by Karl Floersch's avatar Karl Floersch

Add appendQueueBatch(..)

parent 48cfb704
......@@ -46,6 +46,7 @@ contract OVM_BaseChain is iOVM_BaseChain {
*/
function getTotalElements()
override
virtual
public
view
returns (
......@@ -190,11 +191,6 @@ contract OVM_BaseChain is iOVM_BaseChain {
batches.deleteElementsAfter(uint32(_batchHeader.batchIndex - 1), bytes28(uint224(totalElements)));
}
/*********************
* Private Functions *
*********************/
/**
* Calculates a hash for a given batch header.
* @param _batchHeader Header to hash.
......@@ -203,7 +199,7 @@ contract OVM_BaseChain is iOVM_BaseChain {
function _hashBatchHeader(
Lib_OVMCodec.ChainBatchHeader memory _batchHeader
)
private
internal
pure
returns (
bytes32 _hash
......
......@@ -29,6 +29,7 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
using Lib_TimeboundRingBuffer for TimeboundRingBuffer;
TimeboundRingBuffer internal queue;
TimeboundRingBuffer internal chain;
struct MultiBatchContext {
uint numSequencedTransactions;
......@@ -111,7 +112,8 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
i++; // TODO: Replace this dumb work with minting gas token. (not today)
}
bytes32 batchRoot = keccak256(abi.encode(
bytes32 queueRoot = keccak256(abi.encode(
msg.sender,
_target,
_gasLimit,
_data
......@@ -119,28 +121,90 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
// bytes is left aligned, uint is right aligned - use this to encode them together
bytes32 timestampAndBlockNumber = bytes32(bytes4(uint32(block.number))) | bytes32(uint256(uint40(block.timestamp)));
// bytes32 timestampAndBlockNumber = bytes32(bytes4(uint32(999))) | bytes32(uint256(uint40(777)));
queue.push2(batchRoot, timestampAndBlockNumber, bytes28(0));
queue.push2(queueRoot, timestampAndBlockNumber, bytes28(0));
}
function getQueueElement(uint queueIndex) public view returns(Lib_OVMCodec.QueueElement memory) {
uint32 trueIndex = uint32(queueIndex * 2);
bytes32 batchRoot = queue.get(trueIndex);
bytes32 queueRoot = queue.get(trueIndex);
bytes32 timestampAndBlockNumber = queue.get(trueIndex + 1);
uint40 timestamp = uint40(uint256(timestampAndBlockNumber & 0x000000000000000000000000000000000000000000000000000000ffffffffff));
uint32 blockNumber = uint32(bytes4(timestampAndBlockNumber & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000));
return Lib_OVMCodec.QueueElement({
batchRoot: batchRoot,
queueRoot: queueRoot,
timestamp: timestamp,
blockNumber: blockNumber
});
}
function getLatestBatchContext() public view returns(uint40 totalElements, uint32 nextQueueIndex) {
bytes28 extraData = batches.getExtraData();
totalElements = uint40(uint256(uint224(extraData & 0x0000000000000000000000000000000000000000000000ffffffffff)));
nextQueueIndex = uint32(bytes4(extraData & 0xffffffffffffffffffffffffffffffffffffffffffffff0000000000));
return (totalElements, nextQueueIndex);
}
function makeLatestBatchContext(uint40 totalElements, uint32 nextQueueIndex) public view returns(bytes28) {
bytes28 totalElementsAndNextQueueIndex = bytes28(bytes4(uint32(nextQueueIndex))) | bytes28(uint224(uint40(totalElements)));
return totalElementsAndNextQueueIndex;
}
/****************************************
* Public Functions: Batch Manipulation *
****************************************/
// TODO: allow the sequencer/users to append queue batches independently
function appendQueueTransaction()
public
{
(uint40 totalElements, uint32 nextQueueIndex) = getLatestBatchContext();
Lib_OVMCodec.QueueElement memory nextQueueElement = getQueueElement(nextQueueIndex);
require(
nextQueueElement.timestamp + forceInclusionPeriodSeconds <= block.timestamp || msg.sender == sequencerAddress,
"Message sender does not have permission to append this batch"
);
_appendQueueBatch();
}
function _appendQueueBatch()
internal
{
(uint40 totalElements, uint32 nextQueueIndex) = getLatestBatchContext();
// TODO: Improve this require statement (the `nextQueueIndex*2` is ugly)
require(nextQueueIndex*2 != queue.getLength(), "No more queue elements to append!");
TransactionChainElement memory element = TransactionChainElement({
isSequenced: false,
queueIndex: nextQueueIndex,
timestamp: 0,
blocknumber: 0,
txData: hex""
});
bytes32 batchRoot = _hashTransactionChainElement(element);
bytes32 batchHeaderHash = _hashBatchHeader(Lib_OVMCodec.ChainBatchHeader({
batchIndex: batches.getLength(),
batchRoot: batchRoot,
batchSize: 1,
prevTotalElements: totalElements,
extraData: hex""
}));
bytes28 latestBatchContext = makeLatestBatchContext(totalElements + 1, nextQueueIndex + 1);
batches.push(batchHeaderHash, latestBatchContext);
}
function getTotalElements()
override
public
view
returns (
uint256 _totalElements
)
{
(uint40 totalElements, uint32 nextQueueIndex) = getLatestBatchContext();
return uint256(totalElements);
}
/**
......
......@@ -81,7 +81,7 @@ library Lib_OVMCodec {
}
struct QueueElement {
bytes32 batchRoot;
bytes32 queueRoot;
uint40 timestamp;
uint32 blockNumber;
}
......
......@@ -10,8 +10,7 @@ import {
makeAddressManager,
setProxyTarget,
FORCE_INCLUSION_PERIOD_SECONDS,
// getEthTime,
// setEthTime,
increaseEthTime,
// NON_NULL_BYTES32,
// ZERO_ADDRESS,
} from '../../../helpers'
......@@ -63,11 +62,22 @@ describe('OVM_CanonicalTransactionChain', () => {
)
})
describe('enqueue', () => {
it.only('should store queued elements correctly', async () => {
describe.only('enqueue', () => {
it('should store queued elements correctly', async () => {
await OVM_CanonicalTransactionChain.enqueue('0x' + '01'.repeat(20), 25000, '0x1234')
const firstQueuedElement = await OVM_CanonicalTransactionChain.getQueueElement(0)
console.log(firstQueuedElement)
// Sanity check that the blockNumber is non-zero
expect(firstQueuedElement.blockNumber).to.not.equal(0)
})
it('should append queued elements correctly', async () => {
await OVM_CanonicalTransactionChain.enqueue('0x' + '01'.repeat(20), 25000, '0x1234')
const firstQueuedElement = await OVM_CanonicalTransactionChain.getQueueElement(0)
// Increase the time to ensure we can append the queued tx
await increaseEthTime(ethers.provider, 100000000)
await OVM_CanonicalTransactionChain.appendQueueTransaction()
// Sanity check that the batch was appended
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(1)
})
})
......
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