Commit 1741d884 authored by Mark Tyneway's avatar Mark Tyneway

fix(dtl): return enqueue tx timestamps

This commit makes sure that the DTL correctly returns timestamps using
the new scheme when the first batch submitter hardfork block is
activated. If the block is not activated, the DTL will operate as it
previously did.
parent 2e7f6a55
---
'@eth-optimism/data-transport-layer': patch
---
Updates DTL to correctly parse L1 to L2 tx timestamps after the first bss hardfork
...@@ -9,6 +9,7 @@ DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000 ...@@ -9,6 +9,7 @@ DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000
DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true
DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0 DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0
DATA_TRANSPORT_LAYER__L1_START_HEIGHT=1 DATA_TRANSPORT_LAYER__L1_START_HEIGHT=1
DATA_TRANSPORT_LAYER__BSS_HARDFORK_1_INDEX=0
DATA_TRANSPORT_LAYER__ADDRESS_MANAGER= DATA_TRANSPORT_LAYER__ADDRESS_MANAGER=
DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT= DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT=
......
...@@ -31,11 +31,17 @@ interface Indexed { ...@@ -31,11 +31,17 @@ interface Indexed {
index: number index: number
} }
interface ExtraTransportDBOptions {
bssHardfork1Index?: number
}
export class TransportDB { export class TransportDB {
public db: SimpleDB public db: SimpleDB
public opts: ExtraTransportDBOptions
constructor(leveldb: LevelUp) { constructor(leveldb: LevelUp, opts?: ExtraTransportDBOptions) {
this.db = new SimpleDB(leveldb) this.db = new SimpleDB(leveldb)
this.opts = opts || {}
} }
public async putEnqueueEntries(entries: EnqueueEntry[]): Promise<void> { public async putEnqueueEntries(entries: EnqueueEntry[]): Promise<void> {
...@@ -254,35 +260,7 @@ export class TransportDB { ...@@ -254,35 +260,7 @@ export class TransportDB {
return null return null
} }
if (transaction.queueOrigin === 'l1') { return this._makeFullTransaction(transaction)
const enqueue = await this.getEnqueueByIndex(transaction.queueIndex)
if (enqueue === null) {
return null
}
// handle backwards compatibility
let timestamp = enqueue.timestamp
if (transaction.timestamp !== 0) {
timestamp = transaction.timestamp
}
// TODO: compute the patch contexts
// else if tx in patchContexts
// timestamp = patchContexts[tx].timestamp
return {
...transaction,
...{
blockNumber: enqueue.blockNumber,
timestamp,
gasLimit: enqueue.gasLimit,
target: enqueue.target,
origin: enqueue.origin,
data: enqueue.data,
},
}
} else {
return transaction
}
} }
public async getLatestFullTransaction(): Promise<TransactionEntry> { public async getLatestFullTransaction(): Promise<TransactionEntry> {
...@@ -302,31 +280,46 @@ export class TransportDB { ...@@ -302,31 +280,46 @@ export class TransportDB {
const fullTransactions = [] const fullTransactions = []
for (const transaction of transactions) { for (const transaction of transactions) {
if (transaction.queueOrigin === 'l1') { fullTransactions.push(await this._makeFullTransaction(transaction))
const enqueue = await this.getEnqueueByIndex(transaction.queueIndex)
if (enqueue === null) {
return null
}
fullTransactions.push({
...transaction,
...{
blockNumber: enqueue.blockNumber,
timestamp: enqueue.timestamp,
gasLimit: enqueue.gasLimit,
target: enqueue.target,
origin: enqueue.origin,
data: enqueue.data,
},
})
} else {
fullTransactions.push(transaction)
}
} }
return fullTransactions return fullTransactions
} }
private async _makeFullTransaction(
transaction: TransactionEntry
): Promise<TransactionEntry> {
// We only need to do extra work for L1 to L2 transactions.
if (transaction.queueOrigin !== 'l1') {
return transaction
}
const enqueue = await this.getEnqueueByIndex(transaction.queueIndex)
if (enqueue === null) {
return null
}
let timestamp = enqueue.timestamp
if (
typeof this.opts.bssHardfork1Index === 'number' &&
transaction.index >= this.opts.bssHardfork1Index
) {
timestamp = transaction.timestamp
}
return {
...transaction,
...{
blockNumber: enqueue.blockNumber,
timestamp,
gasLimit: enqueue.gasLimit,
target: enqueue.target,
origin: enqueue.origin,
data: enqueue.data,
},
}
}
private async _getLatestEntryIndex(key: string): Promise<number> { private async _getLatestEntryIndex(key: string): Promise<number> {
return this.db.get<number>(`${key}:latest`, 0) || 0 return this.db.get<number>(`${key}:latest`, 0) || 0
} }
......
...@@ -104,7 +104,9 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> { ...@@ -104,7 +104,9 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
} = {} as any } = {} as any
protected async _init(): Promise<void> { protected async _init(): Promise<void> {
this.state.db = new TransportDB(this.options.db) this.state.db = new TransportDB(this.options.db, {
bssHardfork1Index: this.options.bssHardfork1Index,
})
this.l1IngestionMetrics = registerMetrics(this.metrics) this.l1IngestionMetrics = registerMetrics(this.metrics)
......
...@@ -84,7 +84,9 @@ export class L2IngestionService extends BaseService<L2IngestionServiceOptions> { ...@@ -84,7 +84,9 @@ export class L2IngestionService extends BaseService<L2IngestionServiceOptions> {
this.l2IngestionMetrics = registerMetrics(this.metrics) this.l2IngestionMetrics = registerMetrics(this.metrics)
this.state.db = new TransportDB(this.options.db) this.state.db = new TransportDB(this.options.db, {
bssHardfork1Index: this.options.bssHardfork1Index,
})
this.state.l2RpcProvider = this.state.l2RpcProvider =
typeof this.options.l2RpcProvider === 'string' typeof this.options.l2RpcProvider === 'string'
......
...@@ -36,6 +36,7 @@ export interface L1DataTransportServiceOptions { ...@@ -36,6 +36,7 @@ export interface L1DataTransportServiceOptions {
defaultBackend: string defaultBackend: string
l1GasPriceBackend: string l1GasPriceBackend: string
l1StartHeight?: number l1StartHeight?: number
bssHardfork1Index?: number
} }
const optionSettings = { const optionSettings = {
......
...@@ -51,6 +51,7 @@ type ethNetwork = 'mainnet' | 'kovan' | 'goerli' ...@@ -51,6 +51,7 @@ type ethNetwork = 'mainnet' | 'kovan' | 'goerli'
useSentry: config.bool('use-sentry', false), useSentry: config.bool('use-sentry', false),
sentryDsn: config.str('sentry-dsn'), sentryDsn: config.str('sentry-dsn'),
sentryTraceRate: config.ufloat('sentry-trace-rate', 0.05), sentryTraceRate: config.ufloat('sentry-trace-rate', 0.05),
bssHardfork1Index: config.uint('bss-hardfork-1-index', null),
}) })
const stop = async (signal) => { const stop = async (signal) => {
......
...@@ -87,7 +87,10 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { ...@@ -87,7 +87,10 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> {
await this.options.db.open() await this.options.db.open()
} }
this.state.db = new TransportDB(this.options.db) this.state.db = new TransportDB(this.options.db, {
bssHardfork1Index: this.options.bssHardfork1Index,
})
this.state.l1RpcProvider = this.state.l1RpcProvider =
typeof this.options.l1RpcProvider === 'string' typeof this.options.l1RpcProvider === 'string'
? new JsonRpcProvider(this.options.l1RpcProvider) ? new JsonRpcProvider(this.options.l1RpcProvider)
......
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