Commit 3b132974 authored by Karl Floersch's avatar Karl Floersch

fix: estimate gas when pending tx in mempool

style: address pr feedback
parent 6702ce41
---
'@eth-optimism/batch-submitter': patch
---
Fix tx resubmission estimateGas bug in batch submitter
......@@ -159,14 +159,14 @@ export class StateBatchSubmitter extends BatchSubmitter {
endBlock: number
): Promise<TransactionReceipt> {
const batch = await this._generateStateCommitmentBatch(startBlock, endBlock)
const tx = this.chainContract.interface.encodeFunctionData(
const calldata = this.chainContract.interface.encodeFunctionData(
'appendStateBatch',
[batch, startBlock]
)
const batchSizeInBytes = remove0x(tx).length / 2
const batchSizeInBytes = remove0x(calldata).length / 2
this.logger.debug('State batch generated', {
batchSizeInBytes,
tx,
calldata,
})
if (!this._shouldSubmitBatch(batchSizeInBytes)) {
......@@ -174,29 +174,31 @@ export class StateBatchSubmitter extends BatchSubmitter {
}
const offsetStartsAtIndex = startBlock - this.blockOffset
this.logger.debug('Submitting batch.', { tx })
this.logger.debug('Submitting batch.', { calldata })
const nonce = await this.signer.getTransactionCount()
// Generate the transaction we will repeatedly submit
const tx = await this.chainContract.populateTransaction.appendStateBatch(
batch,
offsetStartsAtIndex
)
const contractFunction = async (gasPrice): Promise<TransactionReceipt> => {
this.logger.info('Submitting appendStateBatch transaction', {
gasPrice,
nonce,
contractAddr: this.chainContract.address,
})
const contractTx = await this.chainContract.appendStateBatch(
batch,
offsetStartsAtIndex,
{ nonce, gasPrice }
)
const txResponse = await this.signer.sendTransaction({
...tx,
gasPrice,
})
this.logger.info('Submitted appendStateBatch transaction', {
txHash: contractTx.hash,
from: contractTx.from,
txHash: txResponse.hash,
from: txResponse.from,
})
this.logger.debug('appendStateBatch transaction data', {
data: contractTx.data,
data: txResponse.data,
})
return this.signer.provider.waitForTransaction(
contractTx.hash,
txResponse.hash,
this.numConfirmations
)
}
......
......@@ -140,28 +140,32 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
)
if (!this.disableQueueBatchAppend) {
const nonce = await this.signer.getTransactionCount()
// Generate the transaction we will repeatedly submit
const tx = await this.chainContract.populateTransaction.appendQueueBatch(
ethers.constants.MaxUint256 // Completely empty the queue by appending (up to) an enormous number of queue elements.
)
const contractFunction = async (
gasPrice
): Promise<TransactionReceipt> => {
this.logger.info('Submitting appendQueueBatch transaction', {
gasPrice,
nonce,
contractAddr: this.chainContract.address,
})
const tx = await this.chainContract.appendQueueBatch(99999999, {
nonce,
gasPrice,
})
const txResponse = await this.chainContract.appendQueueBatch(
ethers.constants.MaxUint256, // Completely empty the queue by appending (up to) an enormous number of queue elements.
{
gasPrice,
}
)
this.logger.info('Submitted appendQueueBatch transaction', {
txHash: tx.hash,
from: tx.from,
txHash: txResponse.hash,
from: txResponse.from,
})
this.logger.debug('appendQueueBatch transaction data', {
data: tx.data,
data: txResponse.data,
})
return this.signer.provider.waitForTransaction(
tx.hash,
txResponse.hash,
this.numConfirmations
)
}
......@@ -250,26 +254,28 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
l1tipHeight,
})
const nonce = await this.signer.getTransactionCount()
// Generate the transaction we will repeatedly submit
const tx = await this.chainContract.customPopulateTransaction.appendSequencerBatch(
batchParams
)
const contractFunction = async (gasPrice): Promise<TransactionReceipt> => {
this.logger.info('Submitting appendSequencerBatch transaction', {
gasPrice,
nonce,
contractAddr: this.chainContract.address,
})
const tx = await this.chainContract.appendSequencerBatch(batchParams, {
nonce,
const txResponse = await this.signer.sendTransaction({
...tx,
gasPrice,
})
this.logger.info('Submitted appendSequencerBatch transaction', {
txHash: tx.hash,
from: tx.from,
txHash: txResponse.hash,
from: txResponse.from,
})
this.logger.debug('appendSequencerBatch transaction data', {
data: tx.data,
data: txResponse.data,
})
return this.signer.provider.waitForTransaction(
tx.hash,
txResponse.hash,
this.numConfirmations
)
}
......
/* External Imports */
import { Contract, BigNumber } from 'ethers'
import { Contract, BigNumber, ethers } from 'ethers'
import {
TransactionResponse,
TransactionRequest,
} from '@ethersproject/abstract-provider'
import { JsonRpcProvider } from '@ethersproject/providers'
import { keccak256 } from 'ethers/lib/utils'
import {
AppendSequencerBatchParams,
BatchContext,
encodeAppendSequencerBatch,
encodeHex,
remove0x,
} from '@eth-optimism/core-utils'
export { encodeAppendSequencerBatch, BatchContext, AppendSequencerBatchParams }
......@@ -19,6 +21,28 @@ export { encodeAppendSequencerBatch, BatchContext, AppendSequencerBatchParams }
* where the `appendSequencerBatch(...)` function uses a specialized encoding for improved efficiency.
*/
export class CanonicalTransactionChainContract extends Contract {
public customPopulateTransaction = {
appendSequencerBatch: async (
batch: AppendSequencerBatchParams
): Promise<ethers.PopulatedTransaction> => {
const nonce = await this.signer.getTransactionCount()
const to = this.address
const data = getEncodedCalldata(batch)
const gasLimit = await this.signer.provider.estimateGas({
to,
from: await this.signer.getAddress(),
data,
})
const value = 0
return {
nonce,
to,
data,
gasLimit,
}
},
}
public async appendSequencerBatch(
batch: AppendSequencerBatchParams,
options?: TransactionRequest
......@@ -38,17 +62,21 @@ const appendSequencerBatch = async (
batch: AppendSequencerBatchParams,
options?: TransactionRequest
): Promise<TransactionResponse> => {
const methodId = keccak256(
Buffer.from(APPEND_SEQUENCER_BATCH_METHOD_ID)
).slice(2, 10)
const calldata = encodeAppendSequencerBatch(batch)
return OVM_CanonicalTransactionChain.signer.sendTransaction({
to: OVM_CanonicalTransactionChain.address,
data: '0x' + methodId + calldata,
data: getEncodedCalldata(batch),
...options,
})
}
const getEncodedCalldata = (batch: AppendSequencerBatchParams): string => {
const methodId = keccak256(
Buffer.from(APPEND_SEQUENCER_BATCH_METHOD_ID)
).slice(2, 10)
const calldata = encodeAppendSequencerBatch(batch)
return '0x' + remove0x(methodId) + remove0x(calldata)
}
const encodeBatchContext = (context: BatchContext): string => {
return (
encodeHex(context.numSequencedTransactions, 6) +
......
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