Commit 2758b354 authored by Karl Floersch's avatar Karl Floersch

Finish optimizing tx submission

parent f86b7237
...@@ -32,10 +32,11 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba ...@@ -32,10 +32,11 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba
uint256 constant public MAX_ROLLUP_TX_SIZE = 10000; uint256 constant public MAX_ROLLUP_TX_SIZE = 10000;
uint256 constant public L2_GAS_DISCOUNT_DIVISOR = 10; uint256 constant public L2_GAS_DISCOUNT_DIVISOR = 10;
// Encoding Constants // Encoding Constants
uint256 constant public BATCH_CONTEXT_SIZE = 16; uint256 constant internal BATCH_CONTEXT_SIZE = 16;
uint256 constant public BATCH_CONTEXT_LENGTH_POS = 12; uint256 constant internal BATCH_CONTEXT_LENGTH_POS = 12;
uint256 constant public BATCH_CONTEXT_START_POS = 15; uint256 constant internal BATCH_CONTEXT_START_POS = 15;
uint256 constant public TX_DATA_HEADER_SIZE = 3; uint256 constant internal TX_DATA_HEADER_SIZE = 3;
uint256 constant internal BYTES_TILL_TX_DATA = 66;
/************* /*************
...@@ -271,6 +272,13 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba ...@@ -271,6 +272,13 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba
uint32 transactionIndex = 0; uint32 transactionIndex = 0;
uint32 numSequencerTransactionsProcessed = 0; uint32 numSequencerTransactionsProcessed = 0;
uint32 nextSequencerTransactionPosition = uint32(BATCH_CONTEXT_START_POS + BATCH_CONTEXT_SIZE * _contextsLength); uint32 nextSequencerTransactionPosition = uint32(BATCH_CONTEXT_START_POS + BATCH_CONTEXT_SIZE * _contextsLength);
uint theCalldataSize;
assembly {
theCalldataSize := calldatasize()
}
require(theCalldataSize >= nextSequencerTransactionPosition, "Not enough BatchContexts provided.");
(, uint32 nextQueueIndex) = _getLatestBatchContext(); (, uint32 nextQueueIndex) = _getLatestBatchContext();
for (uint32 i = 0; i < _contextsLength; i++) { for (uint32 i = 0; i < _contextsLength; i++) {
...@@ -278,11 +286,29 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba ...@@ -278,11 +286,29 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba
_validateBatchContext(context, nextQueueIndex); _validateBatchContext(context, nextQueueIndex);
for (uint32 j = 0; j < context.numSequencedTransactions; j++) { for (uint32 j = 0; j < context.numSequencedTransactions; j++) {
(bytes32 leafHash, uint txDataLength) = _getSequencerChainElementLeafHash( uint256 txDataLength;
nextSequencerTransactionPosition, assembly {
context.timestamp, // 3 byte txDataLength
context.blockNumber txDataLength := shr(232, calldataload(nextSequencerTransactionPosition))
); }
bytes memory _chainElement = new bytes(BYTES_TILL_TX_DATA + txDataLength);
bytes32 leafHash;
uint _timestamp = context.timestamp;
uint _blockNumber = context.blockNumber;
assembly {
let chainElementStart := add(_chainElement, 0x20)
mstore8(chainElementStart, 1)
mstore8(add(chainElementStart, 1), 0)
mstore(add(chainElementStart, 2), _timestamp)
mstore(add(chainElementStart, 34), _blockNumber)
// Store the rest of the transaction
calldatacopy(add(chainElementStart, BYTES_TILL_TX_DATA), add(nextSequencerTransactionPosition, 3), txDataLength)
// Calculate the hash
leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, txDataLength))
}
leaves[transactionIndex] = leafHash; leaves[transactionIndex] = leafHash;
nextSequencerTransactionPosition += uint32(TX_DATA_HEADER_SIZE + txDataLength); nextSequencerTransactionPosition += uint32(TX_DATA_HEADER_SIZE + txDataLength);
numSequencerTransactionsProcessed++; numSequencerTransactionsProcessed++;
...@@ -358,57 +384,6 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba ...@@ -358,57 +384,6 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, OVM_Ba
}); });
} }
// /**
// * Returns the transaction data located at a particular start position in calldata.
// * @param _startPosition Start position in calldata (represented in bytes).
// * @return _transactionData The transaction data for this particular element.
// */
uint constant BYTES_TILL_TX_DATA = 66;
function _getSequencerChainElementLeafHash(
uint256 _startPosition,
uint256 _timestamp,
uint256 _blockNumber
)
internal
view
returns (
bytes32 _leafHash,
uint _txDataLength
)
{
uint256 transactionSize;
assembly {
// 3 byte transactionSize
transactionSize := shr(232, calldataload(_startPosition))
}
bytes memory _chainElement = new bytes(BYTES_TILL_TX_DATA + transactionSize);
assembly {
let chainElementStart := add(_chainElement, 0x20)
mstore8(chainElementStart, 1)
mstore8(add(chainElementStart, 1), 0)
mstore(add(chainElementStart, 2), _timestamp)
mstore(add(chainElementStart, 34), _blockNumber)
// Store the rest of the transaction
calldatacopy(add(chainElementStart, BYTES_TILL_TX_DATA), add(_startPosition, 3), transactionSize)
// Calculate the hash
_leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, transactionSize))
}
// console.log("Verifying that this worked!");
// console.logBytes(_chainElement);
// console.log("Hash:");
// console.logBytes32(_leafHash);
// console.log("TxSize:");
// console.log("transactionSize");
// console.log("~~~~~~~~");
return (
_leafHash,
transactionSize
);
}
/** /**
* Parses the batch context from the extra data. * Parses the batch context from the extra data.
* @return _totalElements Total number of elements submitted. * @return _totalElements Total number of elements submitted.
......
...@@ -150,7 +150,7 @@ const encodeBatchContext = (context: BatchContext): string => { ...@@ -150,7 +150,7 @@ const encodeBatchContext = (context: BatchContext): string => {
) )
} }
describe.only('OVM_CanonicalTransactionChain', () => { describe('OVM_CanonicalTransactionChain', () => {
let signer: Signer let signer: Signer
let sequencer: Signer let sequencer: Signer
before(async () => { before(async () => {
...@@ -488,7 +488,7 @@ describe.only('OVM_CanonicalTransactionChain', () => { ...@@ -488,7 +488,7 @@ describe.only('OVM_CanonicalTransactionChain', () => {
) )
}) })
it.only('should revert if expected start does not match current total batches', async () => { it.skip('should allow for a lower bound per-tx gas usage of <400 gas [GAS BENCHMARK]', async () => {
const timestamp = (await getEthTime(ethers.provider)) - 100 const timestamp = (await getEthTime(ethers.provider)) - 100
const blockNumber = (await getNextBlockNumber(ethers.provider)) + 100 const blockNumber = (await getNextBlockNumber(ethers.provider)) + 100
...@@ -523,10 +523,8 @@ describe.only('OVM_CanonicalTransactionChain', () => { ...@@ -523,10 +523,8 @@ describe.only('OVM_CanonicalTransactionChain', () => {
console.log('\n~~~~ BEGINNGING TRASACTION IN QUESTION ~~~~') console.log('\n~~~~ BEGINNGING TRASACTION IN QUESTION ~~~~')
const transactions = [] const transactions = []
const numTxs = 200 const numTxs = 200
// const numTxs = 20
for (let i = 0; i < numTxs; i++) { for (let i = 0; i < numTxs; i++) {
transactions.push('0x' + '1080111111111111111111111111111111111111111111111111111111111111') transactions.push('0x' + '1080111111111111111111111111111111111111111111'.repeat(20))
// transactions.push('0x' + '10801111')
} }
const res = await appendSequencerBatch(OVM_CanonicalTransactionChain, { const res = await appendSequencerBatch(OVM_CanonicalTransactionChain, {
shouldStartAtBatch: 2, shouldStartAtBatch: 2,
...@@ -542,8 +540,7 @@ describe.only('OVM_CanonicalTransactionChain', () => { ...@@ -542,8 +540,7 @@ describe.only('OVM_CanonicalTransactionChain', () => {
transactions, transactions,
}) })
const receipt = await res.wait() const receipt = await res.wait()
console.log(res) console.log("Benchmark complete. Gas used:", receipt.gasUsed)
console.log(receipt)
}).timeout(100000000) }).timeout(100000000)
it('should revert if expected start does not match current total batches', async () => { it('should revert if expected start does not match current total batches', async () => {
......
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