From acbfd6709b79e0341f644a611a0b647a37a4d374 Mon Sep 17 00:00:00 2001 From: Longs Pemun Gotar Date: Tue, 16 Dec 2025 13:07:21 +0100 Subject: [PATCH] core/rawdb: change tx index from uint64 to uint32 --- core/rawdb/accessors_indexes.go | 34 ++++++++++++++-------------- core/rawdb/accessors_indexes_test.go | 14 ++++++------ core/rawdb/chain_iterator.go | 4 ++-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 7373703bd9..75b263f60e 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -35,11 +35,11 @@ import ( // DecodeTxLookupEntry decodes the supplied tx lookup data. It returns the block // number and optionally the transaction index within the block. The transaction // index is only available in database v7+ format; for older formats it returns nil. -func DecodeTxLookupEntry(data []byte, db ethdb.Reader) (*uint64, *uint64) { - // Database v7 tx lookup stores block number (8 bytes) + tx index (8 bytes) = 16 bytes - if len(data) == 16 { +func DecodeTxLookupEntry(data []byte, db ethdb.Reader) (*uint64, *uint32) { + // Database v7 tx lookup stores block number (8 bytes) + tx index (4 bytes) = 12 bytes + if len(data) == 12 { number := binary.BigEndian.Uint64(data[:8]) - txIndex := binary.BigEndian.Uint64(data[8:16]) + txIndex := binary.BigEndian.Uint32(data[8:12]) return &number, &txIndex } // Database v6 tx lookup just stores the block number @@ -68,7 +68,7 @@ func DecodeTxLookupEntry(data []byte, db ethdb.Reader) (*uint64, *uint64) { // hash to allow retrieving the transaction or receipt by hash. It returns the block // number and optionally the transaction index within the block (if available in the // database format). -func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) (*uint64, *uint64) { +func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) (*uint64, *uint32) { data, _ := db.Get(txLookupKey(hash)) if len(data) == 0 { return nil, nil @@ -78,10 +78,10 @@ func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) (*uint64, *uint64) { // writeTxLookupEntryV7 stores a positional metadata for a transaction in database // v7 format, which includes both the block number and transaction index. -func writeTxLookupEntryV7(db ethdb.KeyValueWriter, hash common.Hash, blockNumber uint64, txIndex uint64) { - var data [16]byte +func writeTxLookupEntryV7(db ethdb.KeyValueWriter, hash common.Hash, blockNumber uint64, txIndex uint32) { + var data [12]byte binary.BigEndian.PutUint64(data[:8], blockNumber) - binary.BigEndian.PutUint64(data[8:16], txIndex) + binary.BigEndian.PutUint32(data[8:12], txIndex) if err := db.Put(txLookupKey(hash), data[:]); err != nil { log.Crit("Failed to store transaction lookup entry", "err", err) } @@ -91,7 +91,7 @@ func writeTxLookupEntryV7(db ethdb.KeyValueWriter, hash common.Hash, blockNumber // hashes list, using the new database v7 format that includes transaction indices. func WriteTxLookupEntries(db ethdb.KeyValueWriter, number uint64, hashes []common.Hash) { for i, hash := range hashes { - writeTxLookupEntryV7(db, hash, number, uint64(i)) + writeTxLookupEntryV7(db, hash, number, uint32(i)) } } @@ -100,7 +100,7 @@ func WriteTxLookupEntries(db ethdb.KeyValueWriter, number uint64, hashes []commo func WriteTxLookupEntriesByBlock(db ethdb.KeyValueWriter, block *types.Block) { number := block.Number().Uint64() for i, tx := range block.Transactions() { - writeTxLookupEntryV7(db, tx.Hash(), number, uint64(i)) + writeTxLookupEntryV7(db, tx.Hash(), number, uint32(i)) } } @@ -149,7 +149,7 @@ func DeleteAllTxLookupEntries(db ethdb.KeyValueStore, condition func(common.Hash // extractTransactionAtIndex extracts a single transaction from the RLP-encoded // block body at the specified index. This is more efficient than findTxInBlockBody // when the transaction index is known, as it avoids hashing all transactions. -func extractTransactionAtIndex(blockbody rlp.RawValue, targetIndex uint64) (*types.Transaction, error) { +func extractTransactionAtIndex(blockbody rlp.RawValue, targetIndex uint32) (*types.Transaction, error) { txnListRLP, _, err := rlp.SplitList(blockbody) if err != nil { return nil, err @@ -158,7 +158,7 @@ func extractTransactionAtIndex(blockbody rlp.RawValue, targetIndex uint64) (*typ if err != nil { return nil, err } - for i := uint64(0); i < targetIndex; i++ { + for i := uint32(0); i < targetIndex; i++ { if !iter.Next() { return nil, fmt.Errorf("transaction index %d out of bounds", targetIndex) } @@ -190,7 +190,7 @@ func findTxInBlockBody(blockbody rlp.RawValue, target common.Hash) (*types.Trans if err != nil { return nil, 0, err } - txIndex := uint64(0) + txIndex := uint32(0) for iter.Next() { if iter.Err() != nil { return nil, 0, iter.Err() @@ -212,7 +212,7 @@ func findTxInBlockBody(blockbody rlp.RawValue, target common.Hash) (*types.Trans if err := rlp.DecodeBytes(txRLP, &tx); err != nil { return nil, 0, err } - return &tx, txIndex, nil + return &tx, uint64(txIndex), nil } txIndex++ } @@ -242,7 +242,7 @@ func ReadCanonicalTransaction(db ethdb.Reader, hash common.Hash) (*types.Transac log.Error("Transaction not found at index", "number", *blockNumber, "hash", blockHash, "txhash", hash, "index", *txIndex, "err", err) return nil, common.Hash{}, 0, 0 } - return tx, blockHash, *blockNumber, *txIndex + return tx, blockHash, *blockNumber, uint64(*txIndex) } tx, foundIndex, err := findTxInBlockBody(bodyRLP, hash) if err != nil { @@ -271,8 +271,8 @@ func ReadCanonicalReceipt(db ethdb.Reader, hash common.Hash, config *params.Chai } if txIndex != nil { receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config) - if *txIndex < uint64(len(receipts)) { - return receipts[*txIndex], blockHash, *blockNumber, *txIndex + if uint64(*txIndex) < uint64(len(receipts)) { + return receipts[*txIndex], blockHash, *blockNumber, uint64(*txIndex) } log.Error("Receipt index out of bounds", "number", *blockNumber, "hash", blockHash, "txhash", hash, "index", *txIndex) return nil, common.Hash{}, 0, 0 diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go index c7b3546f7d..243bb6a08d 100644 --- a/core/rawdb/accessors_indexes_test.go +++ b/core/rawdb/accessors_indexes_test.go @@ -347,7 +347,7 @@ func TestExtractTransactionAtIndex(t *testing.T) { bodyRLP := ReadBodyRLP(db, block.Hash(), block.NumberU64()) for i, expectedTx := range txs { - extractedTx, err := extractTransactionAtIndex(bodyRLP, uint64(i)) + extractedTx, err := extractTransactionAtIndex(bodyRLP, uint32(i)) if err != nil { t.Fatalf("Failed to extract transaction at index %d: %v", i, err) } @@ -356,7 +356,7 @@ func TestExtractTransactionAtIndex(t *testing.T) { } } - _, err := extractTransactionAtIndex(bodyRLP, uint64(len(txs))) + _, err := extractTransactionAtIndex(bodyRLP, uint32(len(txs))) if err == nil { t.Fatal("Expected error for out of bounds index, got nil") } @@ -381,14 +381,14 @@ func TestTxLookupV7Encoding(t *testing.T) { testCases := []struct { blockNumber uint64 - txIndex uint64 + txIndex uint32 txHash common.Hash }{ {0, 0, common.BytesToHash([]byte{0x01})}, {1, 0, common.BytesToHash([]byte{0x02})}, {100, 5, common.BytesToHash([]byte{0x03})}, {999999, 199, common.BytesToHash([]byte{0x04})}, - {18446744073709551615, 255, common.BytesToHash([]byte{0x05})}, // max uint64 + {18446744073709551615, 4294967295, common.BytesToHash([]byte{0x05})}, // max uint32 } for _, tc := range testCases { @@ -417,7 +417,7 @@ func TestTxLookupBackwardCompatibility(t *testing.T) { tx := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11}) txHash := tx.Hash() blockNumber := uint64(314) - txIndex := uint64(2) + txIndex := uint32(2) writeTxLookupEntryV7(db, txHash, blockNumber, txIndex) num, idx := ReadTxLookupEntry(db, txHash) @@ -455,7 +455,7 @@ func TestTxLookupBackwardCompatibility(t *testing.T) { entry := LegacyTxLookupEntry{ BlockHash: blockHash, BlockIndex: blockNumber, - Index: txIndex, + Index: uint64(txIndex), } data, _ := rlp.EncodeToBytes(entry) db.Put(txLookupKey(v3Hash), data) @@ -589,7 +589,7 @@ func BenchmarkExtractTransactionAtIndex(b *testing.B) { WriteBlock(db, block) bodyRLP := ReadBodyRLP(db, block.Hash(), block.NumberU64()) - targetIndex := uint64(size - 1) + targetIndex := uint32(size - 1) b.ResetTimer() b.ReportAllocs() diff --git a/core/rawdb/chain_iterator.go b/core/rawdb/chain_iterator.go index 0a92f7770e..50c70bfa54 100644 --- a/core/rawdb/chain_iterator.go +++ b/core/rawdb/chain_iterator.go @@ -379,8 +379,8 @@ func PruneTransactionIndex(db ethdb.Database, pruneBlock uint64) { log.Info("Pruning tx index", "count", count, "removed", removed) } var bn uint64 - // Database v7: block number (8 bytes) + tx index (8 bytes) = 16 bytes - if len(v) == 16 { + // Database v7: block number (8 bytes) + tx index (4 bytes) = 12 bytes + if len(v) == 12 { bn = binary.BigEndian.Uint64(v[:8]) } else if len(v) <= 8 { // Database v6 or earlier