Commit 41cfbd16 authored by Georgios Konstantopoulos's avatar Georgios Konstantopoulos Committed by GitHub

chore: update to latest master part 2 (#53)

* feat(hardhat-ovm): allow ignoring libraries when compiling

https://github.com/ethereum-optimism/plugins/pull/39

* feat(batch-submitter): add logs

https://github.com/ethereum-optimism/batch-submitter/pull/75
https://github.com/ethereum-optimism/batch-submitter/pull/73

* chore: build contracts sequentially

this worsens our compilation times but ensures that the runs are not flaky
parent 0f8bac35
......@@ -69,6 +69,10 @@ export abstract class BatchSubmitter {
}
await this._updateChainInfo()
await this._checkBalance()
this.log.info('Readying to submit next batch...', {
l2ChainId: this.l2ChainId,
batchSubmitterAddress: await this.signer.getAddress(),
})
if (this.syncing === true) {
this.log.info(
......@@ -225,7 +229,7 @@ export abstract class BatchSubmitter {
this.log
)
this.log.debug('Transaction receipt:', { receipt })
this.log.info('Received transaction receipt', { receipt })
this.log.info(successMessage)
return receipt
}
......
......@@ -3,7 +3,7 @@ import { Promise as bPromise } from 'bluebird'
import { Contract, Signer } from 'ethers'
import { TransactionReceipt } from '@ethersproject/abstract-provider'
import { getContractFactory } from '@eth-optimism/contracts'
import { Logger, Bytes32 } from '@eth-optimism/core-utils'
import { Logger, Bytes32, remove0x } from '@eth-optimism/core-utils'
import { OptimismProvider } from '@eth-optimism/provider'
/* Internal Imports */
......@@ -82,6 +82,10 @@ export class StateBatchSubmitter extends BatchSubmitter {
sccAddress === this.chainContract.address &&
ctcAddress === this.ctcContract.address
) {
this.log.debug('Chain contract already initialized', {
sccAddress,
ctcAddress,
})
return
}
......@@ -105,12 +109,21 @@ export class StateBatchSubmitter extends BatchSubmitter {
}
public async _getBatchStartAndEnd(): Promise<Range> {
this.log.info('Getting batch start and end for state batch submitter...')
// TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis
const startBlock: number =
(await this.chainContract.getTotalElements()).toNumber() + BLOCK_OFFSET
this.log.info('Retrieved start block number from SCC', {
startBlock,
})
// We will submit state roots for txs which have been in the tx chain for a while.
const totalElements: number =
(await this.ctcContract.getTotalElements()).toNumber() + BLOCK_OFFSET
this.log.info('Retrieved total elements from CTC', {
totalElements,
})
const endBlock: number = Math.min(
startBlock + this.maxBatchSize,
totalElements
......@@ -142,7 +155,13 @@ export class StateBatchSubmitter extends BatchSubmitter {
'appendStateBatch',
[batch, startBlock]
)
if (!this._shouldSubmitBatch(tx.length / 2)) {
const batchSizeInBytes = remove0x(tx).length / 2
this.log.debug('State batch generated', {
batchSizeInBytes,
tx,
})
if (!this._shouldSubmitBatch(batchSizeInBytes)) {
return
}
......@@ -156,6 +175,13 @@ export class StateBatchSubmitter extends BatchSubmitter {
offsetStartsAtIndex,
{ nonce, gasPrice }
)
this.log.info('Submitted appendStateBatch transaction', {
nonce,
txHash: contractTx.hash,
contractAddr: this.chainContract.address,
from: contractTx.from,
data: contractTx.data,
})
return this.signer.provider.waitForTransaction(
contractTx.hash,
this.numConfirmations
......@@ -180,7 +206,12 @@ export class StateBatchSubmitter extends BatchSubmitter {
const block = (await this.l2Provider.getBlockWithTransactions(
startBlock + i
)) as L2Block
if (block.transactions[0].from === this.fraudSubmissionAddress) {
const blockTx = block.transactions[0]
if (blockTx.from === this.fraudSubmissionAddress) {
this.log.warn('Found transaction from fraud submission address', {
txHash: blockTx.hash,
fraudSubmissionAddress: this.fraudSubmissionAddress,
})
this.fraudSubmissionAddress = 'no fraud'
return '0xbad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1'
}
......@@ -193,14 +224,20 @@ export class StateBatchSubmitter extends BatchSubmitter {
'appendStateBatch',
[batch, startBlock]
)
while (tx.length > this.maxTxSize) {
while (remove0x(tx).length / 2 > this.maxTxSize) {
batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
this.log.debug('Splicing batch...', {
batchSizeInBytes: tx.length / 2,
})
tx = this.chainContract.interface.encodeFunctionData('appendStateBatch', [
batch,
startBlock,
])
}
this.log.info('Generated state commitment batch', {
batch, // list of stateRoots
})
return batch
}
}
......@@ -114,6 +114,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
typeof this.chainContract !== 'undefined' &&
ctcAddress === this.chainContract.address
) {
this.log.debug('Chain contract already initialized', {
ctcAddress,
})
return
}
......@@ -134,6 +137,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
public async _onSync(): Promise<TransactionReceipt> {
const pendingQueueElements = await this.chainContract.getNumPendingQueueElements()
this.log.debug('Got number of pending queue elements', {
pendingQueueElements,
})
if (pendingQueueElements !== 0) {
this.log.info(
......@@ -150,6 +156,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
nonce,
gasPrice,
})
this.log.info('Submitted appendQueueBatch transaction', {
nonce,
txHash: tx.hash,
contractAddr: this.chainContract.address,
from: tx.from,
data: tx.data,
})
return this.signer.provider.waitForTransaction(
tx.hash,
this.numConfirmations
......@@ -166,6 +179,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
// TODO: Remove this function and use geth for lastL1BlockNumber!
private async _updateLastL1BlockNumber() {
this.log.warn('Calling _updateLastL1BlockNumber...')
const pendingQueueElements = await this.chainContract.getNumPendingQueueElements()
if (pendingQueueElements !== 0) {
......@@ -187,17 +201,32 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
}
}
}
this.log.debug('Set lastL1BlockNumber', {
lastL1BlockNumber: this.lastL1BlockNumber,
})
}
public async _getBatchStartAndEnd(): Promise<Range> {
this.log.info(
'Getting batch start and end for transaction batch submitter...'
)
// TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis
const startBlock =
(await this.chainContract.getTotalElements()).toNumber() + BLOCK_OFFSET
this.log.info('Retrieved start block number from CTC', {
startBlock,
})
const endBlock =
Math.min(
startBlock + this.maxBatchSize,
await this.l2Provider.getBlockNumber()
) + 1 // +1 because the `endBlock` is *exclusive*
this.log.info('Retrieved end block number from L2 sequencer', {
endBlock,
})
if (startBlock >= endBlock) {
if (startBlock > endBlock) {
this.log
......@@ -224,7 +253,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
)
if (gasPriceInGwei > this.gasThresholdInGwei) {
this.log.warn(
'Gas price is higher than gras price threshold; aborting batch submission',
'Gas price is higher than gas price threshold; aborting batch submission',
{
gasPriceInGwei,
gasThresholdInGwei: this.gasThresholdInGwei,
......@@ -238,6 +267,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
wasBatchTruncated,
] = await this._generateSequencerBatchParams(startBlock, endBlock)
const batchSizeInBytes = encodeAppendSequencerBatch(batchParams).length / 2
this.log.debug('Sequencer batch generated', {
batchSizeInBytes,
})
// Only submit batch if one of the following is true:
// 1. it was truncated
......@@ -256,6 +288,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
nonce,
gasPrice,
})
this.log.info('Submitted appendSequencerBatch transaction', {
nonce,
txHash: tx.hash,
contractAddr: this.chainContract.address,
from: tx.from,
data: tx.data,
})
return this.signer.provider.waitForTransaction(
tx.hash,
this.numConfirmations
......@@ -299,6 +338,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
let wasBatchTruncated = false
let encoded = encodeAppendSequencerBatch(sequencerBatchParams)
while (encoded.length / 2 > this.maxTxSize) {
this.log.debug('Splicing batch...', {
batchSizeInBytes: encoded.length / 2,
})
batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
sequencerBatchParams = await this._getSequencerBatchParams(
startBlock,
......@@ -310,6 +352,12 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
// In this case, we want to submit regardless of the batch's size.
wasBatchTruncated = true
}
this.log.info('Generated sequencer batch params', {
contexts: sequencerBatchParams.contexts,
transactions: sequencerBatchParams.transactions,
wasBatchTruncated,
})
return [sequencerBatchParams, wasBatchTruncated]
}
......@@ -421,6 +469,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
// TODO: Remove this super complex logic and rely on Geth to actually supply correct block data.
const fixMonotonicity = async (b: Batch): Promise<Batch> => {
this.log.debug('Fixing monotonicity...')
// The earliest allowed timestamp/blockNumber is the last timestamp submitted on chain.
const {
lastTimestamp,
......@@ -428,6 +477,10 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
} = await this._getLastTimestampAndBlockNumber()
let earliestTimestamp = lastTimestamp
let earliestBlockNumber = lastBlockNumber
this.log.debug('Determined earliest timestamp and blockNumber', {
earliestTimestamp,
earliestBlockNumber,
})
// The latest allowed timestamp/blockNumber is the next queue element!
let nextQueueIndex = await this.chainContract.getNextQueueIndex()
......@@ -457,6 +510,10 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
}
// Actually update the latest timestamp and block number
await updateLatestTimestampAndBlockNumber()
this.log.debug('Determined latest timestamp and blockNumber', {
latestTimestamp,
latestBlockNumber,
})
// Now go through our batch and fix the timestamps and block numbers
// to automatically enforce monotonicity.
......@@ -573,7 +630,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
blockNumber > queueElement.blockNumber
) {
this.log.warn(
'Double deposit detected!!! Fixing by skipping the deposit & replacing with a dummy tx.'
'Double deposit detected. Fixing by skipping the deposit & replacing with a dummy tx.',
{
timestamp,
blockNumber,
queueElementTimestamp: queueElement.timestamp,
queueElementBlockNumber: queueElement.blockNumber,
}
)
// This implies that we've double played a deposit.
// We can correct this by instead submitting a dummy sequencer tx
......@@ -712,6 +775,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
private async _getL2BatchElement(blockNumber: number): Promise<BatchElement> {
const block = await this._getBlock(blockNumber)
this.log.debug('Fetched L2 block', {
block,
})
const txType = block.transactions[0].txType
if (this._isSequencerTx(block)) {
......@@ -744,6 +810,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
if (!block.transactions[0].l1BlockNumber) {
block.transactions[0].l1BlockNumber = this.lastL1BlockNumber
}
return block
}
......
......@@ -201,9 +201,12 @@ export const run = async () => {
value: 0,
nonce: i,
})
log.info('Submitting empty transaction', {
log.info('Submitted empty transaction', {
nonce: i,
txHash: response.hash,
to: response.to,
from: response.from,
data: response.data,
})
await sequencerSigner.provider.waitForTransaction(
response.hash,
......
export * from './batch-submitter'
export * from './utils'
export * from './transaction-chain-contract'
export * from './types'
......@@ -5,11 +5,11 @@ import {
TransactionRequest,
} from '@ethersproject/abstract-provider'
import { keccak256 } from 'ethers/lib/utils'
import { remove0x, encodeHex } from './utils'
import {
AppendSequencerBatchParams,
BatchContext,
encodeAppendSequencerBatch,
encodeHex,
} from '@eth-optimism/core-utils'
export { encodeAppendSequencerBatch, BatchContext, AppendSequencerBatchParams }
......
yarn run build:typescript & yarn run build:contracts & yarn run build:contracts:ovm
yarn run build:typescript & yarn run build:contracts
yarn run build:contracts:ovm
yarn run build:copy:artifacts & yarn run build:copy:artifacts:ovm & yarn run build:copy:contracts
......@@ -75,7 +75,19 @@ const getOvmSolcPath = async (version: string): Promise<string> => {
subtask(
TASK_COMPILE_SOLIDITY_RUN_SOLC,
async (args: { input: any; solcPath: string }, hre, runSuper) => {
const ignoreRxList = hre.network.config.ignoreRxList || [];
const ignore = (filename: string) => ignoreRxList.reduce((ignored: boolean, rx: string | RegExp) => ignored || new RegExp(rx).test(filename), false);
if (hre.network.ovm !== true) {
// Separate the EVM and OVM inputs.
for (const file of Object.keys(args.input.sources)) {
// Ignore any contract that has this tag or in ignore list
if (args.input.sources[file].content.includes('// @unsupported: evm') || ignore(file)) {
delete args.input.sources[file];
}
else {
//console.log(file + ' included');
}
}
return runSuper(args)
}
......@@ -101,8 +113,8 @@ subtask(
// Separate the EVM and OVM inputs.
for (const file of Object.keys(args.input.sources)) {
// Ignore any contract that has this tag.
if (!args.input.sources[file].content.includes('// @unsupported: ovm')) {
// Ignore any contract that has this tag or in ignore list
if (!args.input.sources[file].content.includes('// @unsupported: ovm') && !ignore(file)) {
ovmInput.sources[file] = args.input.sources[file]
}
}
......@@ -141,8 +153,8 @@ extendEnvironment((hre) => {
}
// Forcibly update the artifacts object.
hre.config.paths.artifacts = artifactsPath
hre.config.paths.cache = cachePath
;(hre as any).artifacts = new Artifacts(artifactsPath)
hre.config.paths.artifacts = artifactsPath;
hre.config.paths.cache = cachePath;
(hre as any).artifacts = new Artifacts(artifactsPath);
}
})
......@@ -14,24 +14,31 @@ declare module 'hardhat/types/config' {
}
interface HardhatNetworkUserConfig {
ovm?: boolean
ovm?: boolean;
ignoreRxList?: string[];
}
interface HttpNetworkUserConfig {
ovm?: boolean
ovm?: boolean;
ignoreRxList?: string[];
}
interface HardhatNetworkConfig {
ovm: boolean
ovm: boolean;
ignoreRxList: string[];
}
interface HttpNetworkConfig {
ovm: boolean
ovm: boolean;
ignoreRxList: string[];
}
}
declare module 'hardhat/types/runtime' {
interface Network {
ovm: boolean
ovm: boolean;
ignoreRxList: string[];
}
}
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