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.
This commit is contained in:
Matthieu Vachon 2025-02-20 19:31:10 -05:00
parent 56ff050d95
commit 95a7b396a8
4 changed files with 105 additions and 60 deletions

View file

@ -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)
}

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {