From 95a7b396a82be22c398b06497ac09467bd182964 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Thu, 20 Feb 2025 19:31:10 -0500 Subject: [PATCH] Fixed backward compatibility ordinals wrongly re-ordered in Firehose At some point in the Firehose 2.x release lifecycle, a bug was introduced that caused ordinals within the block to be broken. The problem was that system calls and block level balance changes were done using a block level ordinals and transactions were done using their own level ordinals. Then in the console reader, the ordinals were re-ordered correctly. While block level balance changes were re-ordered correctly, the system calls were not. Here, we re-apply the same bug to the transactions to ensure that the Firehose 3.x release lifecycle. First, we are going to reset the ordinal once we detect this is the first transaction. Then in the end block, we are going to fix balance & code changes ordinals. --- eth/tracers/firehose.go | 45 ++++++++++++++++ .../testdata/TestEIP7702/block.1.golden.json | 52 +++++++++---------- .../testdata/TestEIP7702/block.2.golden.json | 40 +++++++------- .../testdata/TestEIP7702/block.3.golden.json | 28 +++++----- 4 files changed, 105 insertions(+), 60 deletions(-) diff --git a/eth/tracers/firehose.go b/eth/tracers/firehose.go index c81d4beb4d..4038bdd1a3 100644 --- a/eth/tracers/firehose.go +++ b/eth/tracers/firehose.go @@ -421,6 +421,13 @@ func (f *Firehose) OnBlockEnd(err error) { f.reorderIsolatedTransactionsAndOrdinals() } + if *f.applyBackwardCompatibility && len(f.block.SystemCalls) > 0 && len(f.block.TransactionTraces) > 0 { + // Known Firehose issue: Wrong ordinals re-ordering in presence of system calls. + // + // See comment ref 5b4ef712dd18 within this file for more details. + f.fixOrdinalsForEndOfBlockChanges() + } + f.ensureInBlockAndNotInTrx() f.printBlockToFirehose(f.block, f.blockFinality) } else { @@ -434,6 +441,25 @@ func (f *Firehose) OnBlockEnd(err error) { firehoseInfo("block end") } +func (f *Firehose) fixOrdinalsForEndOfBlockChanges() { + lastSystemCallOrdinal := f.block.SystemCalls[len(f.block.SystemCalls)-1].EndOrdinal + lastTransactionOrdinal := uint64(0) + lastTransactionOrdinal = f.block.TransactionTraces[len(f.block.TransactionTraces)-1].EndOrdinal + + // Change balance changes and code changes that happened after the last transaction + for _, ch := range f.block.BalanceChanges { + if ch.Ordinal >= lastTransactionOrdinal { + ch.Ordinal += lastSystemCallOrdinal + } + } + + for _, ch := range f.block.CodeChanges { + if ch.Ordinal >= lastTransactionOrdinal { + ch.Ordinal += lastSystemCallOrdinal + } + } +} + // reorderIsolatedTransactionsAndOrdinals is called right after all transactions have completed execution. It will sort transactions // according to their index. // @@ -551,6 +577,25 @@ func (f *Firehose) OnTxStart(evm *tracing.VMContext, tx *types.Transaction, from to = *tx.To() } + if *f.applyBackwardCompatibility { + // Known Firehose issue: At some point in the Firehose 2.x release lifecycle, a bug was introduced that caused + // ordinals within the block to be broken. The problem was that system calls and block level balance changes + // were done using a block level ordinals and transactions were done using their own level ordinals. + // + // Then in the console reader, the ordinals were re-ordered correctly. While block level balance changes + // were re-ordered correctly, the system calls were not. + // + // Here, we re-apply the same bug to the transactions to ensure that the Firehose 3.x release lifecycle. + // First, we are going to reset the ordinal once we detect this is the first transaction. + // + // Then in the end block, we are going to fix balance & code changes ordinals. + // + // See comment ref 5b4ef712dd18 within this file for more details. + if len(f.block.TransactionTraces) == 0 && len(f.block.SystemCalls) > 0 { + f.blockOrdinal.Reset() + } + } + f.onTxStart(tx, tx.Hash(), from, to) } diff --git a/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.1.golden.json b/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.1.golden.json index a4b28ae124..99802d4832 100644 --- a/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.1.golden.json +++ b/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.1.golden.json @@ -51,26 +51,26 @@ }, { "address": "AAAJYe9IDrVegNGa2DV5pkwAcAI=", - "beginOrdinal": "28", + "beginOrdinal": "24", "callType": "CALL", "caller": "//////////////////////////4=", - "endOrdinal": "29", + "endOrdinal": "25", "gasLimit": "30000000", "index": 1 }, { "address": "AAC73cfOSIZC+1efiwDzpZAAclE=", - "beginOrdinal": "30", + "beginOrdinal": "26", "callType": "CALL", "caller": "//////////////////////////4=", - "endOrdinal": "31", + "endOrdinal": "27", "gasLimit": "30000000", "index": 1 } ], "transactionTraces": [ { - "beginOrdinal": "5", + "beginOrdinal": "1", "calls": [ { "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", @@ -84,7 +84,7 @@ "oldValue": { "bytes": "DeC2s6dkAAA=" }, - "ordinal": "6", + "ordinal": "2", "reason": "REASON_GAS_BUY" }, { @@ -95,7 +95,7 @@ "oldValue": { "bytes": "Dd8ozD895b8=" }, - "ordinal": "25", + "ordinal": "21", "reason": "REASON_GAS_REFUND" }, { @@ -103,7 +103,7 @@ "newValue": { "bytes": "BFWK" }, - "ordinal": "26", + "ordinal": "22", "reason": "REASON_REWARD_TRANSACTION_FEE" } ], @@ -115,14 +115,14 @@ "newCode": "7wEAAAAAAAAAAAAAAAAAAAAAAAAAqqo=", "newHash": "6BOVhfT5ksAf8bXRTf8FXcJyKhFA0Cb18MtIsAn1Z9o=", "oldHash": "xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", - "ordinal": "10" + "ordinal": "6" }, { "address": "cDxLK9cMFp9XFxAcruVDKZ/JRsc=", "newCode": "7wEAAAAAAAAAAAAAAAAAAAAAAAAAzMw=", "newHash": "2nRj6FdgztYMKwAqS2x5e7pQdCMd4bTSeffx8pbIFmU=", "oldHash": "xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", - "ordinal": "12" + "ordinal": "8" }, { "address": "cDxLK9cMFp9XFxAcruVDKZ/JRsc=", @@ -130,33 +130,33 @@ "newHash": "0mhxQ0BYDv3haWHrT7NIuLWUSlfUHjFwuLM/8Jt1SXA=", "oldCode": "7wEAAAAAAAAAAAAAAAAAAAAAAAAAzMw=", "oldHash": "2nRj6FdgztYMKwAqS2x5e7pQdCMd4bTSeffx8pbIFmU=", - "ordinal": "14" + "ordinal": "10" } ], - "endOrdinal": "24", + "endOrdinal": "20", "gasChanges": [ { "newValue": "354000", "oldValue": "500000", - "ordinal": "7", + "ordinal": "3", "reason": "REASON_INTRINSIC_GAS" }, { "newValue": "351280", "oldValue": "353880", - "ordinal": "16", + "ordinal": "12", "reason": "REASON_STATE_COLD_ACCESS" }, { "newValue": "5348", "oldValue": "353980", - "ordinal": "17", + "ordinal": "13", "reason": "REASON_CALL" }, { "newValue": "322474", "oldValue": "5348", - "ordinal": "23", + "ordinal": "19", "reason": "REASON_REFUND_AFTER_EXECUTION" } ], @@ -167,24 +167,24 @@ { "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "newValue": "1", - "ordinal": "8" + "ordinal": "4" }, { "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "newValue": "2", "oldValue": "1", - "ordinal": "9" + "ordinal": "5" }, { "address": "cDxLK9cMFp9XFxAcruVDKZ/JRsc=", "newValue": "1", - "ordinal": "11" + "ordinal": "7" }, { "address": "cDxLK9cMFp9XFxAcruVDKZ/JRsc=", "newValue": "2", "oldValue": "1", - "ordinal": "13" + "ordinal": "9" } ] }, @@ -200,7 +200,7 @@ "oldValue": { "bytes": "Dd8ozD895cA=" }, - "ordinal": "19", + "ordinal": "15", "reason": "REASON_TRANSFER" }, { @@ -211,15 +211,15 @@ "oldValue": { "bytes": "DeC2s6dkAAA=" }, - "ordinal": "20", + "ordinal": "16", "reason": "REASON_TRANSFER" } ], - "beginOrdinal": "18", + "beginOrdinal": "14", "callType": "CALL", "caller": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "depth": 1, - "endOrdinal": "22", + "endOrdinal": "18", "gasConsumed": "22106", "gasLimit": "339232", "index": 2, @@ -230,7 +230,7 @@ "key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI=", "newValue": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI=", "oldValue": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "ordinal": "21" + "ordinal": "17" } ], "value": { @@ -238,7 +238,7 @@ } } ], - "endOrdinal": "27", + "endOrdinal": "23", "from": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "gasLimit": "500000", "gasPrice": { diff --git a/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.2.golden.json b/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.2.golden.json index 7915908262..746c77050b 100644 --- a/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.2.golden.json +++ b/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.2.golden.json @@ -51,26 +51,26 @@ }, { "address": "AAAJYe9IDrVegNGa2DV5pkwAcAI=", - "beginOrdinal": "22", + "beginOrdinal": "18", "callType": "CALL", "caller": "//////////////////////////4=", - "endOrdinal": "23", + "endOrdinal": "19", "gasLimit": "30000000", "index": 1 }, { "address": "AAC73cfOSIZC+1efiwDzpZAAclE=", - "beginOrdinal": "24", + "beginOrdinal": "20", "callType": "CALL", "caller": "//////////////////////////4=", - "endOrdinal": "25", + "endOrdinal": "21", "gasLimit": "30000000", "index": 1 } ], "transactionTraces": [ { - "beginOrdinal": "5", + "beginOrdinal": "1", "calls": [ { "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", @@ -84,7 +84,7 @@ "oldValue": { "bytes": "DeBFrisGZrU=" }, - "ordinal": "6", + "ordinal": "2", "reason": "REASON_GAS_BUY" }, { @@ -95,7 +95,7 @@ "oldValue": { "bytes": "CmgYAUEtZrQ=" }, - "ordinal": "19", + "ordinal": "15", "reason": "REASON_GAS_REFUND" }, { @@ -106,42 +106,42 @@ "oldValue": { "bytes": "BFWK" }, - "ordinal": "20", + "ordinal": "16", "reason": "REASON_REWARD_TRANSACTION_FEE" } ], "callType": "CALL", "caller": "cVYrcZmYc9tbKG35V68ZnslGF/c=", - "endOrdinal": "18", + "endOrdinal": "14", "gasChanges": [ { "newValue": "479000", "oldValue": "500000", - "ordinal": "7", + "ordinal": "3", "reason": "REASON_INTRINSIC_GAS" }, { "newValue": "476380", "oldValue": "478880", - "ordinal": "10", + "ordinal": "6", "reason": "REASON_STATE_COLD_ACCESS" }, { "newValue": "473780", "oldValue": "476380", - "ordinal": "11", + "ordinal": "7", "reason": "REASON_STATE_COLD_ACCESS" }, { "newValue": "7262", "oldValue": "478980", - "ordinal": "12", + "ordinal": "8", "reason": "REASON_CALL" }, { "newValue": "464874", "oldValue": "7262", - "ordinal": "17", + "ordinal": "13", "reason": "REASON_REFUND_AFTER_EXECUTION" } ], @@ -153,7 +153,7 @@ "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "newValue": "3", "oldValue": "2", - "ordinal": "8" + "ordinal": "4" } ] }, @@ -169,7 +169,7 @@ "oldValue": { "bytes": "CmgYAUEtZrU=" }, - "ordinal": "14", + "ordinal": "10", "reason": "REASON_TRANSFER" }, { @@ -180,15 +180,15 @@ "oldValue": { "bytes": "DeC2s6dkAAE=" }, - "ordinal": "15", + "ordinal": "11", "reason": "REASON_TRANSFER" } ], - "beginOrdinal": "13", + "beginOrdinal": "9", "callType": "CALL", "caller": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "depth": 1, - "endOrdinal": "16", + "endOrdinal": "12", "gasConsumed": "2206", "gasLimit": "459818", "index": 2, @@ -198,7 +198,7 @@ } } ], - "endOrdinal": "21", + "endOrdinal": "17", "from": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "gasLimit": "500000", "gasPrice": { diff --git a/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.3.golden.json b/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.3.golden.json index f227eb9aae..57e67b4969 100644 --- a/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.3.golden.json +++ b/eth/tracers/internal/tracetest/firehose/testdata/TestEIP7702/block.3.golden.json @@ -51,26 +51,26 @@ }, { "address": "AAAJYe9IDrVegNGa2DV5pkwAcAI=", - "beginOrdinal": "16", + "beginOrdinal": "12", "callType": "CALL", "caller": "//////////////////////////4=", - "endOrdinal": "17", + "endOrdinal": "13", "gasLimit": "30000000", "index": 1 }, { "address": "AAC73cfOSIZC+1efiwDzpZAAclE=", - "beginOrdinal": "18", + "beginOrdinal": "14", "callType": "CALL", "caller": "//////////////////////////4=", - "endOrdinal": "19", + "endOrdinal": "15", "gasLimit": "30000000", "index": 1 } ], "transactionTraces": [ { - "beginOrdinal": "5", + "beginOrdinal": "1", "calls": [ { "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", @@ -83,7 +83,7 @@ "oldValue": { "bytes": "DaHgOZLVtrQ=" }, - "ordinal": "6", + "ordinal": "2", "reason": "REASON_GAS_BUY" }, { @@ -94,7 +94,7 @@ "oldValue": { "bytes": "DaCsTVRHwNQ=" }, - "ordinal": "13", + "ordinal": "9", "reason": "REASON_GAS_REFUND" }, { @@ -105,7 +105,7 @@ "oldValue": { "bytes": "PkzJFSq+Qg==" }, - "ordinal": "14", + "ordinal": "10", "reason": "REASON_REWARD_TRANSACTION_FEE" } ], @@ -117,15 +117,15 @@ "newHash": "xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", "oldCode": "7wEAAAAAAAAAAAAAAAAAAAAAAAAAqqo=", "oldHash": "6BOVhfT5ksAf8bXRTf8FXcJyKhFA0Cb18MtIsAn1Z9o=", - "ordinal": "10" + "ordinal": "6" } ], - "endOrdinal": "12", + "endOrdinal": "8", "gasChanges": [ { "newValue": "454000", "oldValue": "500000", - "ordinal": "7", + "ordinal": "3", "reason": "REASON_INTRINSIC_GAS" } ], @@ -136,18 +136,18 @@ "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "newValue": "4", "oldValue": "3", - "ordinal": "8" + "ordinal": "4" }, { "address": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "newValue": "5", "oldValue": "4", - "ordinal": "9" + "ordinal": "5" } ] } ], - "endOrdinal": "15", + "endOrdinal": "11", "from": "cVYrcZmYc9tbKG35V68ZnslGF/c=", "gasLimit": "500000", "gasPrice": {