Commit 0b6c2dd0 authored by Karl Floersch's avatar Karl Floersch

Finish appendSequencerBatch

parent 44c51b54
...@@ -35,14 +35,14 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { / ...@@ -35,14 +35,14 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
uint numSequencedTransactions; uint numSequencedTransactions;
uint numSubsequentQueueTransactions; uint numSubsequentQueueTransactions;
uint timestamp; uint timestamp;
uint blocknumber; uint blockNumber;
} }
struct TransactionChainElement { struct TransactionChainElement {
bool isSequenced; bool isSequenced;
uint queueIndex; // QUEUED TX ONLY uint queueIndex; // QUEUED TX ONLY
uint timestamp; // SEQUENCER TX ONLY uint timestamp; // SEQUENCER TX ONLY
uint blocknumber; // SEQUENCER TX ONLY uint blockNumber; // SEQUENCER TX ONLY
bytes txData; // SEQUENCER TX ONLY bytes txData; // SEQUENCER TX ONLY
} }
...@@ -189,7 +189,7 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { / ...@@ -189,7 +189,7 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
isSequenced: false, isSequenced: false,
queueIndex: queueIndex, queueIndex: queueIndex,
timestamp: 0, timestamp: 0,
blocknumber: 0, blockNumber: 0,
txData: hex"" txData: hex""
}); });
require( require(
...@@ -241,70 +241,70 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { / ...@@ -241,70 +241,70 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
_shouldStartAtBatch == getTotalBatches(), _shouldStartAtBatch == getTotalBatches(),
"Batch submission failed: chain length has become larger than expected" "Batch submission failed: chain length has become larger than expected"
); );
require( require(
msg.sender == sequencerAddress, msg.sender == sequencerAddress,
"Function can only be called by the Sequencer." "Function can only be called by the Sequencer."
); );
// TODO: Verify that there are no outstanding queue transactions which need to be processed
// require(
// block.timestamp < queue.getQueueElement(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 // Initialize an array which will contain the leaves of the merkle tree commitment
bytes32[] memory leaves = new bytes32[](_totalElementsToAppend); bytes32[] memory leaves = new bytes32[](_totalElementsToAppend);
uint numBatchContexts = _batchContexts.length; uint32 transactionIndex = 0;
uint transactionIndex = 0; uint32 numSequencerTransactionsProcessed = 0;
uint numSequencerTransactionsProcessed = 0; (, uint32 nextQueueIndex) = getLatestBatchContext();
for (uint batchContextIndex = 0; batchContextIndex < numBatchContexts; batchContextIndex++) { for (uint32 batchContextIndex = 0; batchContextIndex < _batchContexts.length; batchContextIndex++) {
//////////////////// Process Sequencer Transactions \\\\\\\\\\\\\\\\\\\\
// Process Sequencer Transactions
BatchContext memory curContext = _batchContexts[batchContextIndex]; BatchContext memory curContext = _batchContexts[batchContextIndex];
_validateBatchContext(curContext, nextQueueIndex);
uint numSequencedTransactions = curContext.numSequencedTransactions; uint numSequencedTransactions = curContext.numSequencedTransactions;
for (uint txIndex = 0; txIndex < numSequencedTransactions; txIndex++) { for (uint32 i = 0; i < numSequencedTransactions; i++) {
TransactionChainElement memory element = TransactionChainElement({ leaves[transactionIndex] = keccak256(abi.encode(
isSequenced: true, false,
queueIndex: 0, 0,
timestamp: curContext.timestamp, curContext.timestamp,
blocknumber: curContext.blocknumber, curContext.blockNumber,
txData: _rawTransactions[numSequencerTransactionsProcessed] _rawTransactions[numSequencerTransactionsProcessed]
}); ));
leaves[transactionIndex] = _hashTransactionChainElement(element);
numSequencerTransactionsProcessed++; numSequencerTransactionsProcessed++;
transactionIndex++; transactionIndex++;
console.log("Processed a sequencer transaction");
console.logBytes32(_hashTransactionChainElement(element));
} }
// Process Queue Transactions //////////////////// Process Queue Transactions \\\\\\\\\\\\\\\\\\\\
uint numQueuedTransactions = curContext.numSubsequentQueueTransactions; uint numQueuedTransactions = curContext.numSubsequentQueueTransactions;
for (uint queueTxIndex = 0; queueTxIndex < numQueuedTransactions; queueTxIndex++) { for (uint i = 0; i < numQueuedTransactions; i++) {
TransactionChainElement memory element = TransactionChainElement({ leaves[transactionIndex] = _getQueueLeafHash(nextQueueIndex);
isSequenced: false, nextQueueIndex++;
queueIndex: queue.getLength(),
timestamp: 0,
blocknumber: 0,
txData: hex""
});
leaves[transactionIndex] = _hashTransactionChainElement(element);
transactionIndex++; transactionIndex++;
// TODO: Increment our lastQueueIndex
// lastQueueIndex++;
} }
} }
console.log("We reached the end!");
bytes32 root;
// Make sure the correct number of leaves were calculated // Make sure the correct number of leaves were calculated
require(transactionIndex == _totalElementsToAppend, "Not enough transactions supplied!"); require(transactionIndex == _totalElementsToAppend, "Not enough transactions supplied!");
// TODO: get root from merkle utils on leaves bytes32 root = _getRoot(leaves);
// merklize(leaves); _appendBatch(
// _appendQueueTransaction(root, _batch.length); root,
_totalElementsToAppend,
_totalElementsToAppend - numSequencerTransactionsProcessed
);
}
function _validateBatchContext(BatchContext memory context, uint32 nextQueueIndex) internal {
if (nextQueueIndex == 0) {
return;
}
Lib_OVMCodec.QueueElement memory nextQueueElement = getQueueElement(nextQueueIndex);
require(
block.timestamp < nextQueueElement.timestamp + forceInclusionPeriodSeconds,
"Older queue batches must be processed before a new sequencer batch."
);
require(
context.timestamp <= nextQueueElement.timestamp,
"Sequencer transactions timestamp too high"
);
require(
context.blockNumber <= nextQueueElement.blockNumber,
"Sequencer transactions blockNumber too high"
);
} }
function getTotalElements() function getTotalElements()
...@@ -324,7 +324,6 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { / ...@@ -324,7 +324,6 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
* Internal Functions: Batch Manipulation * * Internal Functions: Batch Manipulation *
******************************************/ ******************************************/
// TODO docstring // TODO docstring
function _hashTransactionChainElement( function _hashTransactionChainElement(
TransactionChainElement memory _element TransactionChainElement memory _element
...@@ -337,7 +336,7 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { / ...@@ -337,7 +336,7 @@ contract OVM_CanonicalTransactionChain is OVM_BaseChain, Lib_AddressResolver { /
_element.isSequenced, _element.isSequenced,
_element.queueIndex, _element.queueIndex,
_element.timestamp, _element.timestamp,
_element.blocknumber, _element.blockNumber,
_element.txData _element.txData
)); ));
} }
......
...@@ -19,10 +19,10 @@ interface sequencerBatchContext { ...@@ -19,10 +19,10 @@ interface sequencerBatchContext {
numSequencedTransactions: Number numSequencedTransactions: Number
numSubsequentQueueTransactions: Number numSubsequentQueueTransactions: Number
timestamp: Number timestamp: Number
blocknumber: Number blockNumber: Number
} }
describe('OVM_CanonicalTransactionChain', () => { describe.only('OVM_CanonicalTransactionChain', () => {
let signer: Signer let signer: Signer
before(async () => { before(async () => {
;[signer] = await ethers.getSigners() ;[signer] = await ethers.getSigners()
...@@ -62,7 +62,7 @@ describe('OVM_CanonicalTransactionChain', () => { ...@@ -62,7 +62,7 @@ describe('OVM_CanonicalTransactionChain', () => {
) )
}) })
describe.only('enqueue', () => { describe('enqueue', () => {
it('should store queued elements correctly', async () => { it('should store queued elements correctly', async () => {
await OVM_CanonicalTransactionChain.enqueue('0x' + '01'.repeat(20), 25000, '0x1234') await OVM_CanonicalTransactionChain.enqueue('0x' + '01'.repeat(20), 25000, '0x1234')
const firstQueuedElement = await OVM_CanonicalTransactionChain.getQueueElement(0) const firstQueuedElement = await OVM_CanonicalTransactionChain.getQueueElement(0)
...@@ -90,22 +90,39 @@ describe('OVM_CanonicalTransactionChain', () => { ...@@ -90,22 +90,39 @@ describe('OVM_CanonicalTransactionChain', () => {
}) })
}) })
describe('appendSequencerMultiBatch', () => { describe('appendSequencerBatch', () => {
it('should append a multi-batch with just one batch', async () => { it('should append a batch with just one batch', async () => {
// Try out appending // Try out appending
const testBatchContext: sequencerBatchContext = { const testBatchContext: sequencerBatchContext = {
numSequencedTransactions: 1, numSequencedTransactions: 1,
numSubsequentQueueTransactions: 0, numSubsequentQueueTransactions: 0,
timestamp: 0, timestamp: 0,
blocknumber: 0 blockNumber: 0
} }
await OVM_CanonicalTransactionChain.appendSequencerMultiBatch( await OVM_CanonicalTransactionChain.appendSequencerBatch(
['0x1212'], ['0x1212'],
[testBatchContext], [testBatchContext],
0, 0,
1 1
) )
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(1)
})
it('should append a batch with 1 sequencer tx and a queue tx', async () => {
const testBatchContext: sequencerBatchContext = {
numSequencedTransactions: 1,
numSubsequentQueueTransactions: 1,
timestamp: 3,
blockNumber: 3
}
await OVM_CanonicalTransactionChain.enqueue('0x' + '01'.repeat(20), 25000, '0x1234')
await OVM_CanonicalTransactionChain.appendSequencerBatch(
['0x1212'],
[testBatchContext],
0,
2
)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(2)
}) })
}) })
}) })
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