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

Use rollup_getInfo endpoint for ctc address & more #339

Merged
merged 5 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
70 changes: 64 additions & 6 deletions packages/batch-submitter/src/batch-submitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
} from '@ethersproject/abstract-provider'
import { getLogger } from '@eth-optimism/core-utils'
import { OptimismProvider } from '@eth-optimism/provider'
import {
getContractInterface,
getContractFactory,
} from '@eth-optimism/contracts'

const log = getLogger('oe:batch-submitter:core')

Expand All @@ -22,21 +26,40 @@ import {
TxType,
ctcCoder,
EthSignTxData,
Address,
Bytes32,
} from './coders'
import { L2Block, BatchElement, Batch, QueueOrigin } from '.'

export interface RollupInfo {
signer: Address
mode: 'sequencer' | 'verifier'
syncing: boolean
l1BlockHash: Bytes32
l1BlockHeight: number
addresses: {
canonicalTransactionChain: Address
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like its unused, so no big deal

addressResolver: Address
l1ToL2TransactionQueue: Address
sequencerDecompression: Address
}
}

export class BatchSubmitter {
private txChain: CanonicalTransactionChainContract
private l2ChainId: number

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

public async submitNextBatch(): Promise<TransactionReceipt> {
await this._updateL2ChainInfo()

const startBlock = parseInt(await this.txChain.getTotalElements(), 16) + 1 // +1 to skip L2 genesis block
const endBlock = Math.min(
startBlock + this.maxBatchSize,
Expand Down Expand Up @@ -66,7 +89,34 @@ export class BatchSubmitter {
return receipt
}

public async _generateSequencerBatchParams(
private async _updateL2ChainInfo(): Promise<void> {
if (typeof this.l2ChainId === 'undefined') {
this.l2ChainId = await this._getL2ChainId()
}

const info: RollupInfo = await this._getRollupInfo()
const ctcAddress = info.addresses.canonicalTransactionChain

if (
typeof this.txChain !== 'undefined' &&
ctcAddress === this.txChain.address
) {
return
}

const unwrapped_OVM_CanonicalTransactionChain = (
await getContractFactory('OVM_CanonicalTransactionChain', this.signer)
).attach(ctcAddress)

this.txChain = new CanonicalTransactionChainContract(
unwrapped_OVM_CanonicalTransactionChain.address,
getContractInterface('OVM_CanonicalTransactionChain'),
this.signer
)
log.info(`Initialized new CTC with address: ${this.txChain.address}`)
}

private async _generateSequencerBatchParams(
startBlock: number,
endBlock: number
): Promise<AppendSequencerBatchParams> {
Expand All @@ -91,7 +141,7 @@ export class BatchSubmitter {
return sequencerBatchParams
}

public async _getSequencerBatchParams(
private async _getSequencerBatchParams(
shouldStartAtIndex: number,
blocks: Batch
): Promise<AppendSequencerBatchParams> {
Expand Down Expand Up @@ -162,7 +212,7 @@ export class BatchSubmitter {
}
}

public async _getL2BatchElement(blockNumber: number): Promise<BatchElement> {
private async _getL2BatchElement(blockNumber: number): Promise<BatchElement> {
const block = (await this.l2Provider.getBlockWithTransactions(
blockNumber
)) as L2Block
Expand Down Expand Up @@ -226,7 +276,15 @@ export class BatchSubmitter {
}
}

public _isSequencerTx(block: L2Block): boolean {
private _isSequencerTx(block: L2Block): boolean {
return block.transactions[0].meta.queueOrigin === QueueOrigin.Sequencer
}

private async _getRollupInfo(): Promise<RollupInfo> {
return this.l2Provider.send('rollup_getInfo', [])
}

private async _getL2ChainId(): Promise<number> {
return this.l2Provider.send('eth_chainId', [])
}
}
36 changes: 0 additions & 36 deletions packages/batch-submitter/src/exec/run-batch-submitter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/* External Imports */
import { getLogger } from '@eth-optimism/core-utils'
import { exit } from 'process'
import {
getContractInterface,
getContractFactory,
} from '@eth-optimism/contracts'
import { Signer, Wallet } from 'ethers'
import { Provider, JsonRpcProvider } from '@ethersproject/providers'
import { OptimismProvider } from '@eth-optimism/provider'
Expand All @@ -16,41 +12,26 @@ import { BatchSubmitter, CanonicalTransactionChainContract } from '..'
const log = getLogger('oe:batch-submitter:init')

interface RequiredEnvVars {
ADDRESS_MANAGER_ADDRESS: 'ADDRESS_MANAGER_ADDRESS'
SEQUENCER_PRIVATE_KEY: 'SEQUENCER_PRIVATE_KEY'
INFURA_NETWORK: 'INFURA_NETWORK'
INFURA_PROJECT_ID: 'INFURA_PROJECT_ID'
L2_WEB3_URL: 'L2_WEB3_URL'
L2_CHAIN_ID: 'L2_CHAIN_ID'
MAX_TX_SIZE: 'MAX_TX_SIZE'
POLL_INTERVAL: 'POLL_INTERVAL'
DEFAULT_BATCH_SIZE: 'DEFAULT_BATCH_SIZE'
NUM_CONFIRMATIONS: 'NUM_CONFIRMATIONS'
}
const requiredEnvVars: RequiredEnvVars = {
ADDRESS_MANAGER_ADDRESS: 'ADDRESS_MANAGER_ADDRESS',
SEQUENCER_PRIVATE_KEY: 'SEQUENCER_PRIVATE_KEY',
INFURA_NETWORK: 'INFURA_NETWORK',
INFURA_PROJECT_ID: 'INFURA_PROJECT_ID',
L2_WEB3_URL: 'L2_WEB3_URL',
L2_CHAIN_ID: 'L2_CHAIN_ID',
MAX_TX_SIZE: 'MAX_TX_SIZE',
POLL_INTERVAL: 'POLL_INTERVAL',
DEFAULT_BATCH_SIZE: 'DEFAULT_BATCH_SIZE',
NUM_CONFIRMATIONS: 'NUM_CONFIRMATIONS',
}

const getAddressFromResolver = async (
addressResolverAddress: string,
contractToResolve: string,
signer: Signer
): Promise<string> => {
const Lib_AddressResolver = (
await getContractFactory('Lib_AddressResolver', signer)
).attach(addressResolverAddress)
return Lib_AddressResolver.resolve('OVM_CanonicalTransactionChain')
}

export const run = async () => {
log.info('Starting batch submitter...')

Expand All @@ -73,26 +54,9 @@ export const run = async () => {
l1Provider
)

const ctcAddress = await getAddressFromResolver(
requiredEnvVars.ADDRESS_MANAGER_ADDRESS,
'OVM_CanonicalTransactionChain',
sequencerSigner
)
const unwrapped_OVM_CanonicalTransactionChain = (
await getContractFactory('OVM_CanonicalTransactionChain', sequencerSigner)
).attach(ctcAddress)

const OVM_CanonicalTransactionChain = new CanonicalTransactionChainContract(
unwrapped_OVM_CanonicalTransactionChain.address,
getContractInterface('OVM_CanonicalTransactionChain'),
sequencerSigner
)

const batchSubmitter = new BatchSubmitter(
OVM_CanonicalTransactionChain,
sequencerSigner,
l2Provider,
parseInt(requiredEnvVars.L2_CHAIN_ID, 10),
parseInt(requiredEnvVars.MAX_TX_SIZE, 10),
parseInt(requiredEnvVars.DEFAULT_BATCH_SIZE, 10),
parseInt(requiredEnvVars.NUM_CONFIRMATIONS, 10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe('BatchSubmitter', () => {
getContractInterface('OVM_CanonicalTransactionChain'),
sequencer
)
l2Provider = new MockchainProvider()
l2Provider = new MockchainProvider(OVM_CanonicalTransactionChain.address)
})

describe('Submit', () => {
Expand All @@ -125,6 +125,7 @@ describe('BatchSubmitter', () => {
timestamp: number
}> = []

let batchSubmitter
beforeEach(async () => {
for (let i = 1; i < 15; i++) {
await OVM_CanonicalTransactionChain.enqueue(
Expand All @@ -136,18 +137,16 @@ describe('BatchSubmitter', () => {
}
)
}
})

it('should submit a sequencer batch correctly', async () => {
const batchSubmitter = new BatchSubmitter(
OVM_CanonicalTransactionChain,
batchSubmitter = new BatchSubmitter(
sequencer,
l2Provider as any,
l2Provider.chainId(),
MAX_TX_SIZE,
10,
1
)
})

it('should submit a sequencer batch correctly', async () => {
l2Provider.setNumBlocksToReturn(5)
const nextQueueElement = await getQueueElement(
OVM_CanonicalTransactionChain
Expand Down Expand Up @@ -181,15 +180,6 @@ describe('BatchSubmitter', () => {
})

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: {
Expand All @@ -209,15 +199,6 @@ describe('BatchSubmitter', () => {
})

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: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '@ethersproject/abstract-provider'

/* Internal Imports */
import { L2Transaction, L2Block } from '../../src'
import { L2Transaction, L2Block, RollupInfo } from '../../src'

/**
* Unformatted Transaction & Blocks. This exists because Geth currently
Expand All @@ -31,8 +31,9 @@ export class MockchainProvider extends OptimismProvider {
public mockBlockNumber: number = 1
public numBlocksToReturn: number = 2
public mockBlocks: L2Block[] = []
public ctcAddr: string

constructor() {
constructor(ctcAddr: string) {
super('https://optimism.io')
for (const block of BLOCKS) {
if (block.number === 0) {
Expand All @@ -41,6 +42,7 @@ export class MockchainProvider extends OptimismProvider {
continue
}
this.mockBlocks.push(this._toL2Block(block))
this.ctcAddr = ctcAddr
}
}

Expand All @@ -57,6 +59,29 @@ export class MockchainProvider extends OptimismProvider {
return this.mockBlockNumber
}

public async send(endpoint: string, params: []): Promise<any> {
if (endpoint === 'eth_chainId') {
return this.chainId()
}
if (endpoint === 'rollup_getInfo') {
const info: RollupInfo = {
signer: '0x' + '99'.repeat(20),
mode: 'sequencer',
syncing: false,
l1BlockHash: '0x' + '99'.repeat(32),
l1BlockHeight: 1,
addresses: {
canonicalTransactionChain: this.ctcAddr,
addressResolver: '0x' + '99'.repeat(20),
l1ToL2TransactionQueue: '0x' + '99'.repeat(20),
sequencerDecompression: '0x' + '99'.repeat(20),
},
}
return info
}
throw new Error('Unsupported endpoint!')
}

public setNumBlocksToReturn(numBlocks: number): void {
this.numBlocksToReturn = numBlocks
}
Expand Down