From a0a00525d4e6bfdd6fd577be5bba59dc521016d7 Mon Sep 17 00:00:00 2001 From: Mark Tyneway <mark.tyneway@gmail.com> Date: Wed, 5 May 2021 15:43:45 -0700 Subject: [PATCH] fix: backport value fixes (#766) * dtl: index the value field (#686) * chore: add changeset * chore: add changeset * dtl: pass through value field * core-utils: update and test toRpcString * lint: fix * l2geth: parse value fields * chore: add changeset * dtl: prevent null reference in L1 handler (#757) * dtl: prevent reference of null value * chore: add changeset * dtl: propagate value * lint: fix --- .changeset/beige-keys-hammer.md | 5 ++++ .changeset/brown-bananas-deny.md | 5 ++++ .changeset/tough-lamps-hammer.md | 5 ++++ .changeset/violet-comics-reflect.md | 5 ++++ l2geth/rollup/client.go | 8 +++++-- packages/core-utils/src/common/hex-strings.ts | 15 ++++++++---- .../core-utils/test/common/hex-utils.spec.ts | 24 ++++++++++++++++++- .../handlers/sequencer-batch-appended.ts | 5 ++++ .../l2-ingestion/handlers/transaction.ts | 2 ++ .../src/types/database-types.ts | 2 ++ 10 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 .changeset/beige-keys-hammer.md create mode 100644 .changeset/brown-bananas-deny.md create mode 100644 .changeset/tough-lamps-hammer.md create mode 100644 .changeset/violet-comics-reflect.md diff --git a/.changeset/beige-keys-hammer.md b/.changeset/beige-keys-hammer.md new file mode 100644 index 000000000..c7f737b87 --- /dev/null +++ b/.changeset/beige-keys-hammer.md @@ -0,0 +1,5 @@ +--- +"@eth-optimism/data-transport-layer": patch +--- + +Parse and index the value field in the data transport layer diff --git a/.changeset/brown-bananas-deny.md b/.changeset/brown-bananas-deny.md new file mode 100644 index 000000000..0f8c2ca18 --- /dev/null +++ b/.changeset/brown-bananas-deny.md @@ -0,0 +1,5 @@ +--- +"@eth-optimism/l2geth": patch +--- + +Add value parsing to the rollup client diff --git a/.changeset/tough-lamps-hammer.md b/.changeset/tough-lamps-hammer.md new file mode 100644 index 000000000..204262b71 --- /dev/null +++ b/.changeset/tough-lamps-hammer.md @@ -0,0 +1,5 @@ +--- +"@eth-optimism/core-utils": patch +--- + +Update toRpcHexString to accept ethers.BigNumber and add tests diff --git a/.changeset/violet-comics-reflect.md b/.changeset/violet-comics-reflect.md new file mode 100644 index 000000000..8f52dda5c --- /dev/null +++ b/.changeset/violet-comics-reflect.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/data-transport-layer': patch +--- + +Prevent access of null value in L1 transaction deserialization diff --git a/l2geth/rollup/client.go b/l2geth/rollup/client.go index 0e55550e4..795c8d394 100644 --- a/l2geth/rollup/client.go +++ b/l2geth/rollup/client.go @@ -70,6 +70,7 @@ type transaction struct { BatchIndex uint64 `json:"batchIndex"` BlockNumber uint64 `json:"blockNumber"` Timestamp uint64 `json:"timestamp"` + Value hexutil.Uint64 `json:"value"` GasLimit uint64 `json:"gasLimit"` Target common.Address `json:"target"` Origin *common.Address `json:"origin"` @@ -104,6 +105,7 @@ type signature struct { // it means that the decoding failed. type decoded struct { Signature signature `json:"sig"` + Value hexutil.Uint64 `json:"value"` GasLimit uint64 `json:"gasLimit"` GasPrice uint64 `json:"gasPrice"` Nonce uint64 `json:"nonce"` @@ -228,6 +230,7 @@ func enqueueToTransaction(enqueue *Enqueue) (*types.Transaction, error) { } data := *enqueue.Data + // enqueue transactions have no value value := big.NewInt(0) tx := types.NewTransaction(nonce, target, value, gasLimit, big.NewInt(0), data) @@ -303,7 +306,7 @@ func batchedTransactionToTransaction(res *transaction, signer *types.OVMSigner) if res.Decoded != nil { nonce := res.Decoded.Nonce to := res.Decoded.Target - value := new(big.Int) + value := new(big.Int).SetUint64(uint64(res.Decoded.Value)) // Note: there are two gas limits, one top level and // another on the raw transaction itself. Maybe maxGasLimit // for the top level? @@ -357,7 +360,8 @@ func batchedTransactionToTransaction(res *transaction, signer *types.OVMSigner) gasLimit := res.GasLimit data := res.Data origin := res.Origin - tx := types.NewTransaction(nonce, target, big.NewInt(0), gasLimit, big.NewInt(0), data) + value := new(big.Int).SetUint64(uint64(res.Value)) + tx := types.NewTransaction(nonce, target, value, gasLimit, big.NewInt(0), data) txMeta := types.NewTransactionMeta( new(big.Int).SetUint64(res.BlockNumber), res.Timestamp, diff --git a/packages/core-utils/src/common/hex-strings.ts b/packages/core-utils/src/common/hex-strings.ts index d87c3673f..71b412c76 100644 --- a/packages/core-utils/src/common/hex-strings.ts +++ b/packages/core-utils/src/common/hex-strings.ts @@ -60,11 +60,18 @@ export const toHexString = (inp: Buffer | string | number | null): string => { } } -export const toRpcHexString = (n: number): string => { - if (n === 0) { - return '0x0' +export const toRpcHexString = (n: number | BigNumber): string => { + let num + if (typeof n === 'number') { + num = '0x' + n.toString(16) } else { - return '0x' + toHexString(n).slice(2).replace(/^0+/, '') + num = n.toHexString() + } + + if (num === '0x0') { + return num + } else { + return num.replace(/^0x0/, '0x') } } diff --git a/packages/core-utils/test/common/hex-utils.spec.ts b/packages/core-utils/test/common/hex-utils.spec.ts index 7bb26b70d..c91ceca9f 100644 --- a/packages/core-utils/test/common/hex-utils.spec.ts +++ b/packages/core-utils/test/common/hex-utils.spec.ts @@ -1,7 +1,8 @@ import { expect } from '../setup' +import { BigNumber } from 'ethers' /* Imports: Internal */ -import { getRandomHexString } from '../../src' +import { getRandomHexString, toRpcHexString } from '../../src' describe('getRandomHexString', () => { const random = global.Math.random @@ -18,3 +19,24 @@ describe('getRandomHexString', () => { expect(getRandomHexString(8)).to.equal('0x' + '88'.repeat(8)) }) }) + +describe('toRpcHexString', () => { + it('should parse 0', () => { + expect(toRpcHexString(0)).to.deep.equal('0x0') + expect(toRpcHexString(BigNumber.from(0))).to.deep.equal('0x0') + }) + + it('should parse non 0', () => { + const cases = [ + { input: 2, output: '0x2' }, + { input: BigNumber.from(2), output: '0x2' }, + { input: 100, output: '0x64' }, + { input: BigNumber.from(100), output: '0x64' }, + { input: 300, output: '0x12c' }, + { input: BigNumber.from(300), output: '0x12c' }, + ] + for (const test of cases) { + expect(toRpcHexString(test.input)).to.deep.equal(test.output) + } + }) +}) diff --git a/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts b/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts index 5ecf06fdc..c162994a7 100644 --- a/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts +++ b/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts @@ -5,6 +5,7 @@ import { ctcCoder, fromHexString, toHexString, + toRpcHexString, TxType, EventArgsSequencerBatchAppended, } from '@eth-optimism/core-utils' @@ -120,6 +121,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet< data: toHexString(sequencerTransaction), queueOrigin: 'sequencer', type, + value: decoded ? decoded.value : '0x0', queueIndex: null, decoded, confirmed: true, @@ -152,6 +154,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet< data: '0x', queueOrigin: 'l1', type: 'EIP155', + value: '0x0', queueIndex: queueIndex.toNumber(), decoded: null, confirmed: true, @@ -254,6 +257,8 @@ const maybeDecodeSequencerBatchTransaction = ( } else { throw new Error(`Unknown sequencer transaction type.`) } + // Temporary fix to propagate the value + decoded.value = '0x0' // Validate the transaction if (!validateBatchTransaction(type, decoded)) { decoded = null diff --git a/packages/data-transport-layer/src/services/l2-ingestion/handlers/transaction.ts b/packages/data-transport-layer/src/services/l2-ingestion/handlers/transaction.ts index b4199ba53..176900422 100644 --- a/packages/data-transport-layer/src/services/l2-ingestion/handlers/transaction.ts +++ b/packages/data-transport-layer/src/services/l2-ingestion/handlers/transaction.ts @@ -32,6 +32,7 @@ export const handleSequencerBlock = { let transactionEntry: Partial<TransactionEntry> = { // Legacy support. index: transactionIndex, + value: transaction.value, batchIndex: null, blockNumber: BigNumber.from(transaction.l1BlockNumber).toNumber(), timestamp: BigNumber.from(transaction.l1Timestamp).toNumber(), @@ -47,6 +48,7 @@ export const handleSequencerBlock = { r: padHexString(transaction.r, 32), s: padHexString(transaction.s, 32), }, + value: transaction.value, gasLimit: BigNumber.from(transaction.gas).toNumber(), gasPrice: BigNumber.from(transaction.gasPrice).toNumber(), // ? nonce: BigNumber.from(transaction.nonce).toNumber(), diff --git a/packages/data-transport-layer/src/types/database-types.ts b/packages/data-transport-layer/src/types/database-types.ts index 42074ee45..f477f5a37 100644 --- a/packages/data-transport-layer/src/types/database-types.ts +++ b/packages/data-transport-layer/src/types/database-types.ts @@ -4,6 +4,7 @@ export interface DecodedSequencerBatchTransaction { s: string v: number } + value: string gasLimit: number gasPrice: number nonce: number @@ -31,6 +32,7 @@ export interface TransactionEntry { gasLimit: number target: string origin: string + value: string queueOrigin: 'sequencer' | 'l1' queueIndex: number | null type: 'EIP155' | 'ETH_SIGN' | null -- 2.23.0