Commit 7e38638b authored by Annie Ke's avatar Annie Ke Committed by GitHub

feat: add node_env to batch submitter (#678)

* add node_env to batch submitter

* rename log to logger for service consistency

* address review comments

* make ETH_NETWORK_NAME to disambiguate

* move tx data to debug
parent 7e6f3933
# Environment
NODE_ENV=development
# Leave blank during local development
ETH_NETWORK_NAME=
# Logging & monitoring # Logging & monitoring
DEBUG=info*,error*,warn*,debug* DEBUG=info*,error*,warn*,debug*
# Leave the SENTRY_DSN variable unset during local development # Leave the SENTRY_DSN variable unset during local development
SENTRY_DSN= SENTRY_DSN=
SENTRY_TRACE_RATE=
L1_NODE_WEB3_URL=http://localhost:9545 L1_NODE_WEB3_URL=http://localhost:9545
L2_NODE_WEB3_URL=http://localhost:8545 L2_NODE_WEB3_URL=http://localhost:8545
......
...@@ -40,7 +40,7 @@ export abstract class BatchSubmitter { ...@@ -40,7 +40,7 @@ export abstract class BatchSubmitter {
readonly maxGasPriceInGwei: number, readonly maxGasPriceInGwei: number,
readonly gasRetryIncrement: number, readonly gasRetryIncrement: number,
readonly gasThresholdInGwei: number, readonly gasThresholdInGwei: number,
readonly log: Logger, readonly logger: Logger,
readonly metrics: Metrics readonly metrics: Metrics
) {} ) {}
...@@ -58,13 +58,13 @@ export abstract class BatchSubmitter { ...@@ -58,13 +58,13 @@ export abstract class BatchSubmitter {
} }
await this._updateChainInfo() await this._updateChainInfo()
await this._checkBalance() await this._checkBalance()
this.log.info('Readying to submit next batch...', { this.logger.info('Readying to submit next batch...', {
l2ChainId: this.l2ChainId, l2ChainId: this.l2ChainId,
batchSubmitterAddress: await this.signer.getAddress(), batchSubmitterAddress: await this.signer.getAddress(),
}) })
if (this.syncing === true) { if (this.syncing === true) {
this.log.info( this.logger.info(
'Syncing mode enabled! Skipping batch submission and clearing queue...' 'Syncing mode enabled! Skipping batch submission and clearing queue...'
) )
return this._onSync() return this._onSync()
...@@ -83,13 +83,13 @@ export abstract class BatchSubmitter { ...@@ -83,13 +83,13 @@ export abstract class BatchSubmitter {
const ether = utils.formatEther(balance) const ether = utils.formatEther(balance)
const num = parseFloat(ether) const num = parseFloat(ether)
this.log.info('Checked balance', { this.logger.info('Checked balance', {
address, address,
ether, ether,
}) })
if (num < this.minBalanceEther) { if (num < this.minBalanceEther) {
this.log.fatal('Current balance lower than min safe balance', { this.logger.fatal('Current balance lower than min safe balance', {
current: num, current: num,
safeBalance: this.minBalanceEther, safeBalance: this.minBalanceEther,
}) })
...@@ -130,7 +130,7 @@ export abstract class BatchSubmitter { ...@@ -130,7 +130,7 @@ export abstract class BatchSubmitter {
currentTimestamp currentTimestamp
if (batchSizeInBytes < this.minTxSize) { if (batchSizeInBytes < this.minTxSize) {
if (!isTimeoutReached) { if (!isTimeoutReached) {
this.log.info( this.logger.info(
'Skipping batch submission. Batch too small & max submission timeout not reached.', 'Skipping batch submission. Batch too small & max submission timeout not reached.',
{ {
batchSizeInBytes, batchSizeInBytes,
...@@ -141,25 +141,28 @@ export abstract class BatchSubmitter { ...@@ -141,25 +141,28 @@ export abstract class BatchSubmitter {
) )
return false return false
} }
this.log.info('Timeout reached, proceeding with batch submission.', { this.logger.info('Timeout reached, proceeding with batch submission.', {
batchSizeInBytes, batchSizeInBytes,
lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp, lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp,
currentTimestamp, currentTimestamp,
}) })
return true return true
} }
this.log.info('Sufficient batch size, proceeding with batch submission.', { this.logger.info(
batchSizeInBytes, 'Sufficient batch size, proceeding with batch submission.',
lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp, {
currentTimestamp, batchSizeInBytes,
}) lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp,
currentTimestamp,
}
)
return true return true
} }
public static async getReceiptWithResubmission( public static async getReceiptWithResubmission(
txFunc: (gasPrice) => Promise<TransactionReceipt>, txFunc: (gasPrice) => Promise<TransactionReceipt>,
resubmissionConfig: ResubmissionConfig, resubmissionConfig: ResubmissionConfig,
log: Logger logger: Logger
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const { const {
resubmissionTimeout, resubmissionTimeout,
...@@ -176,7 +179,7 @@ export abstract class BatchSubmitter { ...@@ -176,7 +179,7 @@ export abstract class BatchSubmitter {
delay: resubmissionTimeout, delay: resubmissionTimeout,
}) })
log.debug('Resubmission tx receipt', { receipt }) logger.debug('Resubmission tx receipt', { receipt })
return receipt return receipt
} }
...@@ -190,7 +193,7 @@ export abstract class BatchSubmitter { ...@@ -190,7 +193,7 @@ export abstract class BatchSubmitter {
10 10
) )
if (minGasPriceInGwei > this.maxGasPriceInGwei) { if (minGasPriceInGwei > this.maxGasPriceInGwei) {
this.log.warn( this.logger.warn(
'Minimum gas price is higher than max! Ethereum must be congested...' 'Minimum gas price is higher than max! Ethereum must be congested...'
) )
minGasPriceInGwei = this.maxGasPriceInGwei minGasPriceInGwei = this.maxGasPriceInGwei
...@@ -203,7 +206,7 @@ export abstract class BatchSubmitter { ...@@ -203,7 +206,7 @@ export abstract class BatchSubmitter {
successMessage: string successMessage: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
this.lastBatchSubmissionTimestamp = Date.now() this.lastBatchSubmissionTimestamp = Date.now()
this.log.debug('Waiting for receipt...') this.logger.debug('Waiting for receipt...')
const resubmissionConfig: ResubmissionConfig = { const resubmissionConfig: ResubmissionConfig = {
resubmissionTimeout: this.resubmissionTimeout, resubmissionTimeout: this.resubmissionTimeout,
...@@ -215,11 +218,11 @@ export abstract class BatchSubmitter { ...@@ -215,11 +218,11 @@ export abstract class BatchSubmitter {
const receipt = await BatchSubmitter.getReceiptWithResubmission( const receipt = await BatchSubmitter.getReceiptWithResubmission(
txFunc, txFunc,
resubmissionConfig, resubmissionConfig,
this.log this.logger
) )
this.log.info('Received transaction receipt', { receipt }) this.logger.info('Received transaction receipt', { receipt })
this.log.info(successMessage) this.logger.info(successMessage)
return receipt return receipt
} }
} }
...@@ -40,7 +40,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -40,7 +40,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
maxGasPriceInGwei: number, maxGasPriceInGwei: number,
gasRetryIncrement: number, gasRetryIncrement: number,
gasThresholdInGwei: number, gasThresholdInGwei: number,
log: Logger, logger: Logger,
metrics: Metrics, metrics: Metrics,
fraudSubmissionAddress: string fraudSubmissionAddress: string
) { ) {
...@@ -60,7 +60,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -60,7 +60,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
maxGasPriceInGwei, maxGasPriceInGwei,
gasRetryIncrement, gasRetryIncrement,
gasThresholdInGwei, gasThresholdInGwei,
log, logger,
metrics metrics
) )
this.fraudSubmissionAddress = fraudSubmissionAddress this.fraudSubmissionAddress = fraudSubmissionAddress
...@@ -73,7 +73,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -73,7 +73,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
public async _updateChainInfo(): Promise<void> { public async _updateChainInfo(): Promise<void> {
const info: RollupInfo = await this._getRollupInfo() const info: RollupInfo = await this._getRollupInfo()
if (info.mode === 'verifier') { if (info.mode === 'verifier') {
this.log.error( this.logger.error(
'Verifier mode enabled! Batch submitter only compatible with sequencer mode' 'Verifier mode enabled! Batch submitter only compatible with sequencer mode'
) )
process.exit(1) process.exit(1)
...@@ -88,7 +88,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -88,7 +88,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
sccAddress === this.chainContract.address && sccAddress === this.chainContract.address &&
ctcAddress === this.ctcContract.address ctcAddress === this.ctcContract.address
) { ) {
this.log.debug('Chain contract already initialized', { this.logger.debug('Chain contract already initialized', {
sccAddress, sccAddress,
ctcAddress, ctcAddress,
}) })
...@@ -102,7 +102,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -102,7 +102,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
await getContractFactory('OVM_CanonicalTransactionChain', this.signer) await getContractFactory('OVM_CanonicalTransactionChain', this.signer)
).attach(ctcAddress) ).attach(ctcAddress)
this.log.info('Connected Optimism contracts', { this.logger.info('Connected Optimism contracts', {
stateCommitmentChain: this.chainContract.address, stateCommitmentChain: this.chainContract.address,
canonicalTransactionChain: this.ctcContract.address, canonicalTransactionChain: this.ctcContract.address,
}) })
...@@ -110,23 +110,23 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -110,23 +110,23 @@ export class StateBatchSubmitter extends BatchSubmitter {
} }
public async _onSync(): Promise<TransactionReceipt> { public async _onSync(): Promise<TransactionReceipt> {
this.log.info('Syncing mode enabled! Skipping state batch submission...') this.logger.info('Syncing mode enabled! Skipping state batch submission...')
return return
} }
public async _getBatchStartAndEnd(): Promise<Range> { public async _getBatchStartAndEnd(): Promise<Range> {
this.log.info('Getting batch start and end for state batch submitter...') this.logger.info('Getting batch start and end for state batch submitter...')
// TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis // TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis
const startBlock: number = const startBlock: number =
(await this.chainContract.getTotalElements()).toNumber() + BLOCK_OFFSET (await this.chainContract.getTotalElements()).toNumber() + BLOCK_OFFSET
this.log.info('Retrieved start block number from SCC', { this.logger.info('Retrieved start block number from SCC', {
startBlock, startBlock,
}) })
// We will submit state roots for txs which have been in the tx chain for a while. // We will submit state roots for txs which have been in the tx chain for a while.
const totalElements: number = const totalElements: number =
(await this.ctcContract.getTotalElements()).toNumber() + BLOCK_OFFSET (await this.ctcContract.getTotalElements()).toNumber() + BLOCK_OFFSET
this.log.info('Retrieved total elements from CTC', { this.logger.info('Retrieved total elements from CTC', {
totalElements, totalElements,
}) })
...@@ -137,11 +137,11 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -137,11 +137,11 @@ export class StateBatchSubmitter extends BatchSubmitter {
if (startBlock >= endBlock) { if (startBlock >= endBlock) {
if (startBlock > endBlock) { if (startBlock > endBlock) {
this.log.error( this.logger.error(
'State commitment chain is larger than transaction chain. This should never happen!' 'State commitment chain is larger than transaction chain. This should never happen!'
) )
} }
this.log.info( this.logger.info(
'No state commitments to submit. Skipping batch submission...' 'No state commitments to submit. Skipping batch submission...'
) )
return return
...@@ -162,7 +162,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -162,7 +162,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
[batch, startBlock] [batch, startBlock]
) )
const batchSizeInBytes = remove0x(tx).length / 2 const batchSizeInBytes = remove0x(tx).length / 2
this.log.debug('State batch generated', { this.logger.debug('State batch generated', {
batchSizeInBytes, batchSizeInBytes,
tx, tx,
}) })
...@@ -172,7 +172,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -172,7 +172,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
} }
const offsetStartsAtIndex = startBlock - BLOCK_OFFSET // TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis const offsetStartsAtIndex = startBlock - BLOCK_OFFSET // TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis
this.log.debug('Submitting batch.', { tx }) this.logger.debug('Submitting batch.', { tx })
const nonce = await this.signer.getTransactionCount() const nonce = await this.signer.getTransactionCount()
const contractFunction = async (gasPrice): Promise<TransactionReceipt> => { const contractFunction = async (gasPrice): Promise<TransactionReceipt> => {
...@@ -181,11 +181,13 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -181,11 +181,13 @@ export class StateBatchSubmitter extends BatchSubmitter {
offsetStartsAtIndex, offsetStartsAtIndex,
{ nonce, gasPrice } { nonce, gasPrice }
) )
this.log.info('Submitted appendStateBatch transaction', { this.logger.info('Submitted appendStateBatch transaction', {
nonce, nonce,
txHash: contractTx.hash, txHash: contractTx.hash,
contractAddr: this.chainContract.address, contractAddr: this.chainContract.address,
from: contractTx.from, from: contractTx.from,
})
this.logger.debug('appendStateBatch transaction data', {
data: contractTx.data, data: contractTx.data,
}) })
return this.signer.provider.waitForTransaction( return this.signer.provider.waitForTransaction(
...@@ -208,13 +210,15 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -208,13 +210,15 @@ export class StateBatchSubmitter extends BatchSubmitter {
const batch: Bytes32[] = await bPromise.map( const batch: Bytes32[] = await bPromise.map(
[...Array(blockRange).keys()], [...Array(blockRange).keys()],
async (i: number) => { async (i: number) => {
this.log.debug('Fetching L2BatchElement', { blockNo: startBlock + i }) this.logger.debug('Fetching L2BatchElement', {
blockNo: startBlock + i,
})
const block = (await this.l2Provider.getBlockWithTransactions( const block = (await this.l2Provider.getBlockWithTransactions(
startBlock + i startBlock + i
)) as L2Block )) as L2Block
const blockTx = block.transactions[0] const blockTx = block.transactions[0]
if (blockTx.from === this.fraudSubmissionAddress) { if (blockTx.from === this.fraudSubmissionAddress) {
this.log.warn('Found transaction from fraud submission address', { this.logger.warn('Found transaction from fraud submission address', {
txHash: blockTx.hash, txHash: blockTx.hash,
fraudSubmissionAddress: this.fraudSubmissionAddress, fraudSubmissionAddress: this.fraudSubmissionAddress,
}) })
...@@ -232,7 +236,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -232,7 +236,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
) )
while (remove0x(tx).length / 2 > 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 batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
this.log.debug('Splicing batch...', { this.logger.debug('Splicing batch...', {
batchSizeInBytes: tx.length / 2, batchSizeInBytes: tx.length / 2,
}) })
tx = this.chainContract.interface.encodeFunctionData('appendStateBatch', [ tx = this.chainContract.interface.encodeFunctionData('appendStateBatch', [
...@@ -241,7 +245,7 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -241,7 +245,7 @@ export class StateBatchSubmitter extends BatchSubmitter {
]) ])
} }
this.log.info('Generated state commitment batch', { this.logger.info('Generated state commitment batch', {
batch, // list of stateRoots batch, // list of stateRoots
}) })
return batch return batch
......
...@@ -50,7 +50,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -50,7 +50,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
maxGasPriceInGwei: number, maxGasPriceInGwei: number,
gasRetryIncrement: number, gasRetryIncrement: number,
gasThresholdInGwei: number, gasThresholdInGwei: number,
log: Logger, logger: Logger,
metrics: Metrics, metrics: Metrics,
disableQueueBatchAppend: boolean, disableQueueBatchAppend: boolean,
autoFixBatchOptions: AutoFixBatchOptions = { autoFixBatchOptions: AutoFixBatchOptions = {
...@@ -74,7 +74,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -74,7 +74,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
maxGasPriceInGwei, maxGasPriceInGwei,
gasRetryIncrement, gasRetryIncrement,
gasThresholdInGwei, gasThresholdInGwei,
log, logger,
metrics metrics
) )
this.disableQueueBatchAppend = disableQueueBatchAppend this.disableQueueBatchAppend = disableQueueBatchAppend
...@@ -88,7 +88,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -88,7 +88,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
public async _updateChainInfo(): Promise<void> { public async _updateChainInfo(): Promise<void> {
const info: RollupInfo = await this._getRollupInfo() const info: RollupInfo = await this._getRollupInfo()
if (info.mode === 'verifier') { if (info.mode === 'verifier') {
this.log.error( this.logger.error(
'Verifier mode enabled! Batch submitter only compatible with sequencer mode' 'Verifier mode enabled! Batch submitter only compatible with sequencer mode'
) )
process.exit(1) process.exit(1)
...@@ -101,7 +101,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -101,7 +101,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
typeof this.chainContract !== 'undefined' && typeof this.chainContract !== 'undefined' &&
ctcAddress === this.chainContract.address ctcAddress === this.chainContract.address
) { ) {
this.log.debug('Chain contract already initialized', { this.logger.debug('Chain contract already initialized', {
ctcAddress, ctcAddress,
}) })
return return
...@@ -116,7 +116,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -116,7 +116,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
getContractInterface('OVM_CanonicalTransactionChain'), getContractInterface('OVM_CanonicalTransactionChain'),
this.signer this.signer
) )
this.log.info('Initialized new CTC', { this.logger.info('Initialized new CTC', {
address: this.chainContract.address, address: this.chainContract.address,
}) })
return return
...@@ -124,12 +124,12 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -124,12 +124,12 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
public async _onSync(): Promise<TransactionReceipt> { public async _onSync(): Promise<TransactionReceipt> {
const pendingQueueElements = await this.chainContract.getNumPendingQueueElements() const pendingQueueElements = await this.chainContract.getNumPendingQueueElements()
this.log.debug('Got number of pending queue elements', { this.logger.debug('Got number of pending queue elements', {
pendingQueueElements, pendingQueueElements,
}) })
if (pendingQueueElements !== 0) { if (pendingQueueElements !== 0) {
this.log.info( this.logger.info(
'Syncing mode enabled! Skipping batch submission and clearing queue elements', 'Syncing mode enabled! Skipping batch submission and clearing queue elements',
{ pendingQueueElements } { pendingQueueElements }
) )
...@@ -143,11 +143,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -143,11 +143,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
nonce, nonce,
gasPrice, gasPrice,
}) })
this.log.info('Submitted appendQueueBatch transaction', { this.logger.info('Submitted appendQueueBatch transaction', {
nonce, nonce,
txHash: tx.hash, txHash: tx.hash,
contractAddr: this.chainContract.address, contractAddr: this.chainContract.address,
from: tx.from, from: tx.from,
})
this.logger.debug('appendQueueBatch transaction data', {
data: tx.data, data: tx.data,
}) })
return this.signer.provider.waitForTransaction( return this.signer.provider.waitForTransaction(
...@@ -160,18 +162,18 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -160,18 +162,18 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
return this._submitAndLogTx(contractFunction, 'Cleared queue!') return this._submitAndLogTx(contractFunction, 'Cleared queue!')
} }
} }
this.log.info('Syncing mode enabled but queue is empty. Skipping...') this.logger.info('Syncing mode enabled but queue is empty. Skipping...')
return return
} }
public async _getBatchStartAndEnd(): Promise<Range> { public async _getBatchStartAndEnd(): Promise<Range> {
this.log.info( this.logger.info(
'Getting batch start and end for transaction batch submitter...' 'Getting batch start and end for transaction batch submitter...'
) )
// TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis // TODO: Remove BLOCK_OFFSET by adding a tx to Geth's genesis
const startBlock = const startBlock =
(await this.chainContract.getTotalElements()).toNumber() + BLOCK_OFFSET (await this.chainContract.getTotalElements()).toNumber() + BLOCK_OFFSET
this.log.info('Retrieved start block number from CTC', { this.logger.info('Retrieved start block number from CTC', {
startBlock, startBlock,
}) })
...@@ -180,17 +182,17 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -180,17 +182,17 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
startBlock + this.maxBatchSize, startBlock + this.maxBatchSize,
await this.l2Provider.getBlockNumber() await this.l2Provider.getBlockNumber()
) + 1 // +1 because the `endBlock` is *exclusive* ) + 1 // +1 because the `endBlock` is *exclusive*
this.log.info('Retrieved end block number from L2 sequencer', { this.logger.info('Retrieved end block number from L2 sequencer', {
endBlock, endBlock,
}) })
if (startBlock >= endBlock) { if (startBlock >= endBlock) {
if (startBlock > endBlock) { if (startBlock > endBlock) {
this.log this.logger
.error(`More chain elements in L1 (${startBlock}) than in the L2 node (${endBlock}). .error(`More chain elements in L1 (${startBlock}) than in the L2 node (${endBlock}).
This shouldn't happen because we don't submit batches if the sequencer is syncing.`) This shouldn't happen because we don't submit batches if the sequencer is syncing.`)
} }
this.log.info('No txs to submit. Skipping batch submission...') this.logger.info('No txs to submit. Skipping batch submission...')
return return
} }
return { return {
...@@ -209,7 +211,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -209,7 +211,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
10 10
) )
if (gasPriceInGwei > this.gasThresholdInGwei) { if (gasPriceInGwei > this.gasThresholdInGwei) {
this.log.warn( this.logger.warn(
'Gas price is higher than gas price threshold; aborting batch submission', 'Gas price is higher than gas price threshold; aborting batch submission',
{ {
gasPriceInGwei, gasPriceInGwei,
...@@ -224,7 +226,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -224,7 +226,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
wasBatchTruncated, wasBatchTruncated,
] = await this._generateSequencerBatchParams(startBlock, endBlock) ] = await this._generateSequencerBatchParams(startBlock, endBlock)
const batchSizeInBytes = encodeAppendSequencerBatch(batchParams).length / 2 const batchSizeInBytes = encodeAppendSequencerBatch(batchParams).length / 2
this.log.debug('Sequencer batch generated', { this.logger.debug('Sequencer batch generated', {
batchSizeInBytes, batchSizeInBytes,
}) })
...@@ -236,7 +238,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -236,7 +238,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
return return
} }
const l1tipHeight = await this.signer.provider.getBlockNumber() const l1tipHeight = await this.signer.provider.getBlockNumber()
this.log.debug('Submitting batch.', { this.logger.debug('Submitting batch.', {
calldata: batchParams, calldata: batchParams,
l1tipHeight, l1tipHeight,
}) })
...@@ -247,11 +249,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -247,11 +249,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
nonce, nonce,
gasPrice, gasPrice,
}) })
this.log.info('Submitted appendSequencerBatch transaction', { this.logger.info('Submitted appendSequencerBatch transaction', {
nonce, nonce,
txHash: tx.hash, txHash: tx.hash,
contractAddr: this.chainContract.address, contractAddr: this.chainContract.address,
from: tx.from, from: tx.from,
})
this.logger.debug('appendSequencerBatch transaction data', {
data: tx.data, data: tx.data,
}) })
return this.signer.provider.waitForTransaction( return this.signer.provider.waitForTransaction(
...@@ -275,7 +279,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -275,7 +279,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
let batch: Batch = await bPromise.map( let batch: Batch = await bPromise.map(
[...Array(blockRange).keys()], [...Array(blockRange).keys()],
(i) => { (i) => {
this.log.debug('Fetching L2BatchElement', { blockNo: startBlock + i }) this.logger.debug('Fetching L2BatchElement', {
blockNo: startBlock + i,
})
return this._getL2BatchElement(startBlock + i) return this._getL2BatchElement(startBlock + i)
}, },
{ concurrency: 100 } { concurrency: 100 }
...@@ -284,7 +290,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -284,7 +290,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
// Fix our batches if we are configured to. TODO: Remove this. // Fix our batches if we are configured to. TODO: Remove this.
batch = await this._fixBatch(batch) batch = await this._fixBatch(batch)
if (!(await this._validateBatch(batch))) { if (!(await this._validateBatch(batch))) {
this.log.error('Batch is malformed! Cannot submit next batch!') this.logger.error('Batch is malformed! Cannot submit next batch!')
throw new Error('Batch is malformed! Cannot submit next batch!') throw new Error('Batch is malformed! Cannot submit next batch!')
} }
let sequencerBatchParams = await this._getSequencerBatchParams( let sequencerBatchParams = await this._getSequencerBatchParams(
...@@ -294,7 +300,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -294,7 +300,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
let wasBatchTruncated = false let wasBatchTruncated = false
let encoded = encodeAppendSequencerBatch(sequencerBatchParams) let encoded = encodeAppendSequencerBatch(sequencerBatchParams)
while (encoded.length / 2 > this.maxTxSize) { while (encoded.length / 2 > this.maxTxSize) {
this.log.debug('Splicing batch...', { this.logger.debug('Splicing batch...', {
batchSizeInBytes: encoded.length / 2, batchSizeInBytes: encoded.length / 2,
}) })
batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
...@@ -309,7 +315,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -309,7 +315,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
wasBatchTruncated = true wasBatchTruncated = true
} }
this.log.info('Generated sequencer batch params', { this.logger.info('Generated sequencer batch params', {
contexts: sequencerBatchParams.contexts, contexts: sequencerBatchParams.contexts,
transactions: sequencerBatchParams.transactions, transactions: sequencerBatchParams.transactions,
wasBatchTruncated, wasBatchTruncated,
...@@ -324,9 +330,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -324,9 +330,9 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
// Verify all of the queue elements are what we expect // Verify all of the queue elements are what we expect
let nextQueueIndex = await this.chainContract.getNextQueueIndex() let nextQueueIndex = await this.chainContract.getNextQueueIndex()
for (const ele of batch) { for (const ele of batch) {
this.log.debug('Verifying batch element', { ele }) this.logger.debug('Verifying batch element', { ele })
if (!ele.isSequencerTx) { if (!ele.isSequencerTx) {
this.log.debug('Checking queue equality against L1 queue index', { this.logger.debug('Checking queue equality against L1 queue index', {
nextQueueIndex, nextQueueIndex,
}) })
if (!(await this._doesQueueElementMatchL1(nextQueueIndex, ele))) { if (!(await this._doesQueueElementMatchL1(nextQueueIndex, ele))) {
...@@ -341,11 +347,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -341,11 +347,13 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
let lastBlockNumber: number let lastBlockNumber: number
for (const ele of batch) { for (const ele of batch) {
if (ele.timestamp < lastTimestamp) { if (ele.timestamp < lastTimestamp) {
this.log.error('Timestamp monotonicity violated! Element', { ele }) this.logger.error('Timestamp monotonicity violated! Element', { ele })
return false return false
} }
if (ele.blockNumber < lastBlockNumber) { if (ele.blockNumber < lastBlockNumber) {
this.log.error('Block Number monotonicity violated! Element', { ele }) this.logger.error('Block Number monotonicity violated! Element', {
ele,
})
return false return false
} }
lastTimestamp = ele.timestamp lastTimestamp = ele.timestamp
...@@ -359,7 +367,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -359,7 +367,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
queueElement: BatchElement queueElement: BatchElement
): Promise<boolean> { ): Promise<boolean> {
const logEqualityError = (name, index, expected, got) => { const logEqualityError = (name, index, expected, got) => {
this.log.error('Observed mismatched values', { this.logger.error('Observed mismatched values', {
index, index,
expected, expected,
got, got,
...@@ -410,7 +418,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -410,7 +418,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
for (const ele of b) { for (const ele of b) {
if (!ele.isSequencerTx) { if (!ele.isSequencerTx) {
if (!(await this._doesQueueElementMatchL1(nextQueueIndex, ele))) { if (!(await this._doesQueueElementMatchL1(nextQueueIndex, ele))) {
this.log.warn('Fixing double played queue element.', { this.logger.warn('Fixing double played queue element.', {
nextQueueIndex, nextQueueIndex,
}) })
fixedBatch.push(await this._fixQueueElement(nextQueueIndex, ele)) fixedBatch.push(await this._fixQueueElement(nextQueueIndex, ele))
...@@ -425,7 +433,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -425,7 +433,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
// TODO: Remove this super complex logic and rely on Geth to actually supply correct block data. // TODO: Remove this super complex logic and rely on Geth to actually supply correct block data.
const fixMonotonicity = async (b: Batch): Promise<Batch> => { const fixMonotonicity = async (b: Batch): Promise<Batch> => {
this.log.debug('Fixing monotonicity...') this.logger.debug('Fixing monotonicity...')
// The earliest allowed timestamp/blockNumber is the last timestamp submitted on chain. // The earliest allowed timestamp/blockNumber is the last timestamp submitted on chain.
const { const {
lastTimestamp, lastTimestamp,
...@@ -433,7 +441,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -433,7 +441,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
} = await this._getLastTimestampAndBlockNumber() } = await this._getLastTimestampAndBlockNumber()
let earliestTimestamp = lastTimestamp let earliestTimestamp = lastTimestamp
let earliestBlockNumber = lastBlockNumber let earliestBlockNumber = lastBlockNumber
this.log.debug('Determined earliest timestamp and blockNumber', { this.logger.debug('Determined earliest timestamp and blockNumber', {
earliestTimestamp, earliestTimestamp,
earliestBlockNumber, earliestBlockNumber,
}) })
...@@ -466,7 +474,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -466,7 +474,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
} }
// Actually update the latest timestamp and block number // Actually update the latest timestamp and block number
await updateLatestTimestampAndBlockNumber() await updateLatestTimestampAndBlockNumber()
this.log.debug('Determined latest timestamp and blockNumber', { this.logger.debug('Determined latest timestamp and blockNumber', {
latestTimestamp, latestTimestamp,
latestBlockNumber, latestBlockNumber,
}) })
...@@ -488,7 +496,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -488,7 +496,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
ele.timestamp < earliestTimestamp || ele.timestamp < earliestTimestamp ||
ele.blockNumber < earliestBlockNumber ele.blockNumber < earliestBlockNumber
) { ) {
this.log.error('Fixing timestamp/blockNumber too small', { this.logger.error('Fixing timestamp/blockNumber too small', {
oldTimestamp: ele.timestamp, oldTimestamp: ele.timestamp,
newTimestamp: earliestTimestamp, newTimestamp: earliestTimestamp,
oldBlockNumber: ele.blockNumber, oldBlockNumber: ele.blockNumber,
...@@ -506,7 +514,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -506,7 +514,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
ele.timestamp > latestTimestamp || ele.timestamp > latestTimestamp ||
ele.blockNumber > latestBlockNumber ele.blockNumber > latestBlockNumber
) { ) {
this.log.error('Fixing timestamp/blockNumber too large.', { this.logger.error('Fixing timestamp/blockNumber too large.', {
oldTimestamp: ele.timestamp, oldTimestamp: ele.timestamp,
newTimestamp: latestTimestamp, newTimestamp: latestTimestamp,
oldBlockNumber: ele.blockNumber, oldBlockNumber: ele.blockNumber,
...@@ -563,7 +571,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -563,7 +571,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
const nextQueueIndex = meta.slice(-20, -10) const nextQueueIndex = meta.slice(-20, -10)
const lastTimestamp = parseInt(meta.slice(-30, -20), 16) const lastTimestamp = parseInt(meta.slice(-30, -20), 16)
const lastBlockNumber = parseInt(meta.slice(-40, -30), 16) const lastBlockNumber = parseInt(meta.slice(-40, -30), 16)
this.log.debug('Retrieved timestamp and block number from CTC', { this.logger.debug('Retrieved timestamp and block number from CTC', {
lastTimestamp, lastTimestamp,
lastBlockNumber, lastBlockNumber,
}) })
...@@ -585,7 +593,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -585,7 +593,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
timestamp > queueElement.timestamp && timestamp > queueElement.timestamp &&
blockNumber > queueElement.blockNumber blockNumber > queueElement.blockNumber
) { ) {
this.log.warn( this.logger.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, timestamp,
...@@ -607,7 +615,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -607,7 +615,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
timestamp < queueElement.timestamp && timestamp < queueElement.timestamp &&
blockNumber < queueElement.blockNumber blockNumber < queueElement.blockNumber
) { ) {
this.log.error('A deposit seems to have been skipped!') this.logger.error('A deposit seems to have been skipped!')
throw new Error('Skipped deposit?!') throw new Error('Skipped deposit?!')
} }
throw new Error('Unable to fix queue element!') throw new Error('Unable to fix queue element!')
...@@ -691,7 +699,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -691,7 +699,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
private async _getL2BatchElement(blockNumber: number): Promise<BatchElement> { private async _getL2BatchElement(blockNumber: number): Promise<BatchElement> {
const block = await this._getBlock(blockNumber) const block = await this._getBlock(blockNumber)
this.log.debug('Fetched L2 block', { this.logger.debug('Fetched L2 block', {
block, block,
}) })
......
...@@ -16,19 +16,34 @@ import { ...@@ -16,19 +16,34 @@ import {
TX_BATCH_SUBMITTER_LOG_TAG, TX_BATCH_SUBMITTER_LOG_TAG,
} from '..' } from '..'
const environment = process.env.NODE_ENV
const network = process.env.ETH_NETWORK_NAME
const release = `batch-submitter@${process.env.npm_package_version}`
/* Logger */ /* Logger */
const name = 'oe:batch_submitter:init' const name = 'oe:batch_submitter:init'
const log = new Logger({ let logger
name,
sentryOptions: { if (network) {
release: `batch-submitter@${process.env.npm_package_version}`, // Initialize Sentry for Batch Submitter deployed to a network
dsn: process.env.SENTRY_DSN, logger = new Logger({
tracesSampleRate: 0.05, name,
}, sentryOptions: {
}) release,
dsn: process.env.SENTRY_DSN,
tracesSampleRate: parseInt(process.env.SENTRY_TRACE_RATE, 10) || 0.05,
environment: network, // separate our Sentry errors by network instead of node environment
},
})
} else {
// Skip initializing Sentry
logger = new Logger({ name })
}
/* Metrics */ /* Metrics */
const metrics = new Metrics({ const metrics = new Metrics({
prefix: name, prefix: name,
labels: { environment, release, network },
}) })
interface RequiredEnvVars { interface RequiredEnvVars {
...@@ -115,11 +130,11 @@ const autoFixBatchOptions: AutoFixBatchOptions = { ...@@ -115,11 +130,11 @@ const autoFixBatchOptions: AutoFixBatchOptions = {
} }
export const run = async () => { export const run = async () => {
log.info('Starting batch submitter...') logger.info('Starting batch submitter...')
for (const [i, val] of Object.entries(requiredEnvVars)) { for (const [i, val] of Object.entries(requiredEnvVars)) {
if (!process.env[val]) { if (!process.env[val]) {
log.warn('Missing environment variable', { logger.warn('Missing environment variable', {
varName: val, varName: val,
}) })
exit(1) exit(1)
...@@ -144,7 +159,7 @@ export const run = async () => { ...@@ -144,7 +159,7 @@ export const run = async () => {
} }
const address = await sequencerSigner.getAddress() const address = await sequencerSigner.getAddress()
log.info('Configured batch submitter addresses', { logger.info('Configured batch submitter addresses', {
batchSubmitterAddress: address, batchSubmitterAddress: address,
addressManagerAddress: requiredEnvVars.ADDRESS_MANAGER_ADDRESS, addressManagerAddress: requiredEnvVars.ADDRESS_MANAGER_ADDRESS,
}) })
...@@ -164,8 +179,11 @@ export const run = async () => { ...@@ -164,8 +179,11 @@ export const run = async () => {
MAX_GAS_PRICE_IN_GWEI, MAX_GAS_PRICE_IN_GWEI,
GAS_RETRY_INCREMENT, GAS_RETRY_INCREMENT,
GAS_THRESHOLD_IN_GWEI, GAS_THRESHOLD_IN_GWEI,
log.child({ name: TX_BATCH_SUBMITTER_LOG_TAG }), logger.child({ name: TX_BATCH_SUBMITTER_LOG_TAG }),
new Metrics({ prefix: TX_BATCH_SUBMITTER_LOG_TAG }), new Metrics({
prefix: TX_BATCH_SUBMITTER_LOG_TAG,
labels: { environment, release, network },
}),
DISABLE_QUEUE_BATCH_APPEND, DISABLE_QUEUE_BATCH_APPEND,
autoFixBatchOptions autoFixBatchOptions
) )
...@@ -186,8 +204,11 @@ export const run = async () => { ...@@ -186,8 +204,11 @@ export const run = async () => {
MAX_GAS_PRICE_IN_GWEI, MAX_GAS_PRICE_IN_GWEI,
GAS_RETRY_INCREMENT, GAS_RETRY_INCREMENT,
GAS_THRESHOLD_IN_GWEI, GAS_THRESHOLD_IN_GWEI,
log.child({ name: STATE_BATCH_SUBMITTER_LOG_TAG }), logger.child({ name: STATE_BATCH_SUBMITTER_LOG_TAG }),
new Metrics({ prefix: STATE_BATCH_SUBMITTER_LOG_TAG }), new Metrics({
prefix: STATE_BATCH_SUBMITTER_LOG_TAG,
labels: { environment, release, network },
}),
FRAUD_SUBMISSION_ADDRESS FRAUD_SUBMISSION_ADDRESS
) )
...@@ -201,18 +222,22 @@ export const run = async () => { ...@@ -201,18 +222,22 @@ export const run = async () => {
const pendingTxs = await sequencerSigner.getTransactionCount('pending') const pendingTxs = await sequencerSigner.getTransactionCount('pending')
const latestTxs = await sequencerSigner.getTransactionCount('latest') const latestTxs = await sequencerSigner.getTransactionCount('latest')
if (pendingTxs > latestTxs) { if (pendingTxs > latestTxs) {
log.info('Detected pending transactions. Clearing all transactions!') logger.info(
'Detected pending transactions. Clearing all transactions!'
)
for (let i = latestTxs; i < pendingTxs; i++) { for (let i = latestTxs; i < pendingTxs; i++) {
const response = await sequencerSigner.sendTransaction({ const response = await sequencerSigner.sendTransaction({
to: await sequencerSigner.getAddress(), to: await sequencerSigner.getAddress(),
value: 0, value: 0,
nonce: i, nonce: i,
}) })
log.info('Submitted empty transaction', { logger.info('Submitted empty transaction', {
nonce: i, nonce: i,
txHash: response.hash, txHash: response.hash,
to: response.to, to: response.to,
from: response.from, from: response.from,
})
logger.debug('empty transaction data', {
data: response.data, data: response.data,
}) })
await sequencerSigner.provider.waitForTransaction( await sequencerSigner.provider.waitForTransaction(
...@@ -222,7 +247,7 @@ export const run = async () => { ...@@ -222,7 +247,7 @@ export const run = async () => {
} }
} }
} catch (err) { } catch (err) {
log.error('Cannot clear transactions', { err }) logger.error('Cannot clear transactions', { err })
process.exit(1) process.exit(1)
} }
} }
...@@ -231,8 +256,8 @@ export const run = async () => { ...@@ -231,8 +256,8 @@ export const run = async () => {
try { try {
await func() await func()
} catch (err) { } catch (err) {
log.error('Error submitting batch', { err }) logger.error('Error submitting batch', { err })
log.info('Retrying...') logger.info('Retrying...')
} }
// Sleep // Sleep
await new Promise((r) => await new Promise((r) =>
......
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