Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add batch-submitter to CI, remove blockCache & improve tests #335

Merged
merged 5 commits into from
Oct 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/build-test-lint-batch-submitter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: CI - batch-submitter

on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
build-test-lint:
name: Run batch-submitter Test Suite on Node ${{matrix.node}}
runs-on: ubuntu-latest

strategy:
matrix:
node: [ '10' ]

steps:
- uses: actions/checkout@v2

- name: Setup node ${{ matrix.node }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}

# START DEPENDENCY CACHING
- name: Cache root deps
uses: actions/cache@v1
id: cache_base
with:
path: node_modules
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('package.json') }}

- name: Cache batch-submitter deps
uses: actions/cache@v1
id: cache_batch-submitter
with:
path: packages/batch-submitter/node_modules
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('packages/batch-submitter/package.json') }}

# END DEPENDENCY CACHING

- name: Install Dependencies
run: yarn install

- name: Lint
run: yarn lint
env:
PKGS: "batch-submitter"

- name: Build
run: |
yarn clean
yarn build
env:
PKGS: "batch-submitter"

- name: Test
run: yarn test
env:
PKGS: "batch-submitter"
2 changes: 1 addition & 1 deletion packages/batch-submitter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"url": "https://github.com/ethereum-optimism/optimism-monorepo.git"
},
"dependencies": {
"@eth-optimism/contracts": "^0.0.2-alpha.2",
"@eth-optimism/contracts": "^0.0.2-alpha.3",
"@eth-optimism/core-utils": "^0.0.1-alpha.30",
"@eth-optimism/provider": "^0.0.1-alpha.6",
"@ethersproject/abstract-provider": "^5.0.5",
Expand Down
26 changes: 10 additions & 16 deletions packages/batch-submitter/src/batch-submitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,20 @@ import {
import { L2Block, BatchElement, Batch, QueueOrigin } from '.'

export class BatchSubmitter {
public blockCache: {
[blockNumber: number]: BatchElement
} = {}

constructor(
readonly txChain: CanonicalTransactionChainContract,
readonly signer: Signer,
readonly l2Provider: OptimismProvider,
readonly l2ChainId: number,
readonly maxTxSize: number,
readonly defaultBatchSize: number,
readonly maxBatchSize: number,
readonly numConfirmations: number
) {}

public async submitNextBatch(): Promise<TransactionReceipt> {
const startBlock = parseInt(await this.txChain.getTotalElements(), 16) + 1
const endBlock = Math.min(
startBlock + this.defaultBatchSize,
startBlock + this.maxBatchSize,
await this.l2Provider.getBlockNumber()
)
log.info(
Expand All @@ -61,32 +57,30 @@ export class BatchSubmitter {
const txRes = await this.txChain.appendSequencerBatch(batchParams)
const receipt = await txRes.wait(this.numConfirmations)
log.info('Submitted batch!')
log.debug('Tx receipt:', receipt)
log.debug('Transaction Response:', txRes)
log.debug('Transaction receipt:', receipt)
return receipt
}

public async _generateSequencerBatchParams(
startBlock: number,
endBlock: number
): Promise<AppendSequencerBatchParams> {
// Get all L2Blocks between the given range
const blocks: Batch = []
// Get all L2 BatchElements for the given range
const batch: Batch = []
for (let i = startBlock; i < endBlock; i++) {
if (!this.blockCache.hasOwnProperty(i)) {
this.blockCache[i] = await this._getL2BatchElement(i)
}
blocks.push(this.blockCache[i])
batch.push(await this._getL2BatchElement(i))
}
let sequencerBatchParams = await this._getSequencerBatchParams(
startBlock,
blocks
batch
)
let encoded = encodeAppendSequencerBatch(sequencerBatchParams)
while (encoded.length / 2 > this.maxTxSize) {
blocks.splice(Math.ceil((blocks.length * 2) / 3)) // Delete 1/3rd of all of the blocks
batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
sequencerBatchParams = await this._getSequencerBatchParams(
startBlock,
blocks
batch
)
encoded = encodeAppendSequencerBatch(sequencerBatchParams)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ interface QueueElement {
timestamp: number
blockNumber: number
}
const getNextQueueElement = async (
ctcContract: Contract
const getQueueElement = async (
ctcContract: Contract,
nextQueueIndex?: number
): Promise<QueueElement> => {
const nextQueueIndex = await ctcContract.getNextQueueIndex()
if (!nextQueueIndex) {
nextQueueIndex = await ctcContract.getNextQueueIndex()
}
const nextQueueElement = await ctcContract.getQueueElement(nextQueueIndex)
return nextQueueElement
}
Expand All @@ -50,10 +53,8 @@ const DUMMY_SIG: Signature = {
describe('BatchSubmitter', () => {
let signer: Signer
let sequencer: Signer
let l2Provider: MockchainProvider
before(async () => {
;[signer, sequencer] = await ethers.getSigners()
l2Provider = new MockchainProvider()
})

let AddressManager: Contract
Expand Down Expand Up @@ -104,6 +105,7 @@ describe('BatchSubmitter', () => {
})

let OVM_CanonicalTransactionChain: CanonicalTransactionChainContract
let l2Provider: MockchainProvider
beforeEach(async () => {
const unwrapped_OVM_CanonicalTransactionChain = await Factory__OVM_CanonicalTransactionChain.deploy(
AddressManager.address,
Expand All @@ -114,6 +116,7 @@ describe('BatchSubmitter', () => {
getContractInterface('OVM_CanonicalTransactionChain'),
sequencer
)
l2Provider = new MockchainProvider()
})

describe('Submit', () => {
Expand All @@ -135,7 +138,7 @@ describe('BatchSubmitter', () => {
}
})

it('should execute without reverting', async () => {
it('should submit a sequencer batch correctly', async () => {
const batchSubmitter = new BatchSubmitter(
OVM_CanonicalTransactionChain,
sequencer,
Expand All @@ -146,7 +149,7 @@ describe('BatchSubmitter', () => {
1
)
l2Provider.setNumBlocksToReturn(5)
const nextQueueElement = await getNextQueueElement(
const nextQueueElement = await getQueueElement(
OVM_CanonicalTransactionChain
)
const data = ctcCoder.createEOATxData.encode({
Expand Down Expand Up @@ -176,5 +179,79 @@ describe('BatchSubmitter', () => {
expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(0) // _numQueueElements
expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(10) // _totalElements
})

it('should submit a queue batch correctly', async () => {
const batchSubmitter = new BatchSubmitter(
OVM_CanonicalTransactionChain,
sequencer,
l2Provider as any,
l2Provider.chainId(),
MAX_TX_SIZE,
10,
1
)
l2Provider.setNumBlocksToReturn(5)
l2Provider.setL2BlockData({
meta: {
queueOrigin: QueueOrigin.L1ToL2,
},
} as any)
let receipt = await batchSubmitter.submitNextBatch()
let logData = remove0x(receipt.logs[0].data)
expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(0) // _startingQueueIndex
expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(5) // _numQueueElements
expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(5) // _totalElements
receipt = await batchSubmitter.submitNextBatch()
logData = remove0x(receipt.logs[0].data)
expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(5) // _startingQueueIndex
expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(5) // _numQueueElements
expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(10) // _totalElements
})

it('should submit a batch with both queue and sequencer chain elements', async () => {
const batchSubmitter = new BatchSubmitter(
OVM_CanonicalTransactionChain,
sequencer,
l2Provider as any,
l2Provider.chainId(),
MAX_TX_SIZE,
10,
1
)
l2Provider.setNumBlocksToReturn(10) // For this batch we'll return 10 elements!
l2Provider.setL2BlockData({
meta: {
queueOrigin: QueueOrigin.L1ToL2,
},
} as any)
// Turn blocks 3-5 into sequencer txs
const nextQueueElement = await getQueueElement(
OVM_CanonicalTransactionChain,
2
)
const data = ctcCoder.createEOATxData.encode({
sig: DUMMY_SIG,
messageHash: '66'.repeat(32),
})
l2Provider.setL2BlockData(
{
data,
meta: {
l1BlockNumber: nextQueueElement.blockNumber - 1,
txType: TxType.createEOA,
queueOrigin: QueueOrigin.Sequencer,
l1TxOrigin: '0x' + '12'.repeat(20),
},
} as any,
nextQueueElement.timestamp - 1,
3,
6
)
const receipt = await batchSubmitter.submitNextBatch()
const logData = remove0x(receipt.logs[0].data)
expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(0) // _startingQueueIndex
expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(7) // _numQueueElements
expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(10) // _totalElements
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ export class MockchainProvider extends OptimismProvider {

public setL2BlockData(
tx: L2Transaction,
timestamp: number,
timestamp?: number,
start: number = 0,
end: number = this.mockBlocks.length
) {
for (let i = start; i < end; i++) {
this.mockBlocks[i].timestamp = timestamp
? timestamp
: this.mockBlocks[i].timestamp
this.mockBlocks[i].transactions[0] = {
...this.mockBlocks[i].transactions[0],
...tx,
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,20 @@
resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89"
integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==

"@eth-optimism/contracts@^0.0.2-alpha.1", "@eth-optimism/contracts@^0.0.2-alpha.2":
"@eth-optimism/contracts@^0.0.2-alpha.1":
version "0.0.2-alpha.2"
resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.0.2-alpha.2.tgz#3b69c4d4055d508f13c7c30c930a514a36215ce4"
integrity sha512-5L+owINbxyDIQUCZo+TSFriD4MjXNI6aniUS3TV2PkE4svPesCdKJiz2cV0P28+AIrMxQ+wa+KofTywyo+ZihA==
dependencies:
ethers "5.0.0"

"@eth-optimism/contracts@^0.0.2-alpha.3":
version "0.0.2-alpha.3"
resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.0.2-alpha.3.tgz#01cf0fe95389b84f98a8e57cc0b89097c8823241"
integrity sha512-ek7gOFX43monrv7GV4G61HXJ+GnjAWYdY4nHkUhPVid/2mlAVJ6fDJ4fP7XQdLJ4bqUGIBc34lAX2O5eDLbO+A==
dependencies:
ethers "5.0.0"

"@eth-optimism/[email protected]":
version "4.2.0-alpha.0"
resolved "https://registry.yarnpkg.com/@eth-optimism/ethereumjs-vm/-/ethereumjs-vm-4.2.0-alpha.0.tgz#58c8b84732568b73a7ba8105c30dc1513b331324"
Expand Down