mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-20 14:59:26 +00:00
core/rawdb: change tx index from uint64 to uint32
This commit is contained in:
parent
50c75a9a4c
commit
acbfd6709b
3 changed files with 26 additions and 26 deletions
|
|
@ -35,11 +35,11 @@ import (
|
||||||
// DecodeTxLookupEntry decodes the supplied tx lookup data. It returns the block
|
// DecodeTxLookupEntry decodes the supplied tx lookup data. It returns the block
|
||||||
// number and optionally the transaction index within the block. The transaction
|
// 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.
|
// index is only available in database v7+ format; for older formats it returns nil.
|
||||||
func DecodeTxLookupEntry(data []byte, db ethdb.Reader) (*uint64, *uint64) {
|
func DecodeTxLookupEntry(data []byte, db ethdb.Reader) (*uint64, *uint32) {
|
||||||
// Database v7 tx lookup stores block number (8 bytes) + tx index (8 bytes) = 16 bytes
|
// Database v7 tx lookup stores block number (8 bytes) + tx index (4 bytes) = 12 bytes
|
||||||
if len(data) == 16 {
|
if len(data) == 12 {
|
||||||
number := binary.BigEndian.Uint64(data[:8])
|
number := binary.BigEndian.Uint64(data[:8])
|
||||||
txIndex := binary.BigEndian.Uint64(data[8:16])
|
txIndex := binary.BigEndian.Uint32(data[8:12])
|
||||||
return &number, &txIndex
|
return &number, &txIndex
|
||||||
}
|
}
|
||||||
// Database v6 tx lookup just stores the block number
|
// 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
|
// 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
|
// number and optionally the transaction index within the block (if available in the
|
||||||
// database format).
|
// 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))
|
data, _ := db.Get(txLookupKey(hash))
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, nil
|
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
|
// writeTxLookupEntryV7 stores a positional metadata for a transaction in database
|
||||||
// v7 format, which includes both the block number and transaction index.
|
// v7 format, which includes both the block number and transaction index.
|
||||||
func writeTxLookupEntryV7(db ethdb.KeyValueWriter, hash common.Hash, blockNumber uint64, txIndex uint64) {
|
func writeTxLookupEntryV7(db ethdb.KeyValueWriter, hash common.Hash, blockNumber uint64, txIndex uint32) {
|
||||||
var data [16]byte
|
var data [12]byte
|
||||||
binary.BigEndian.PutUint64(data[:8], blockNumber)
|
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 {
|
if err := db.Put(txLookupKey(hash), data[:]); err != nil {
|
||||||
log.Crit("Failed to store transaction lookup entry", "err", err)
|
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.
|
// hashes list, using the new database v7 format that includes transaction indices.
|
||||||
func WriteTxLookupEntries(db ethdb.KeyValueWriter, number uint64, hashes []common.Hash) {
|
func WriteTxLookupEntries(db ethdb.KeyValueWriter, number uint64, hashes []common.Hash) {
|
||||||
for i, hash := range hashes {
|
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) {
|
func WriteTxLookupEntriesByBlock(db ethdb.KeyValueWriter, block *types.Block) {
|
||||||
number := block.Number().Uint64()
|
number := block.Number().Uint64()
|
||||||
for i, tx := range block.Transactions() {
|
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
|
// extractTransactionAtIndex extracts a single transaction from the RLP-encoded
|
||||||
// block body at the specified index. This is more efficient than findTxInBlockBody
|
// block body at the specified index. This is more efficient than findTxInBlockBody
|
||||||
// when the transaction index is known, as it avoids hashing all transactions.
|
// 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)
|
txnListRLP, _, err := rlp.SplitList(blockbody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -158,7 +158,7 @@ func extractTransactionAtIndex(blockbody rlp.RawValue, targetIndex uint64) (*typ
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for i := uint64(0); i < targetIndex; i++ {
|
for i := uint32(0); i < targetIndex; i++ {
|
||||||
if !iter.Next() {
|
if !iter.Next() {
|
||||||
return nil, fmt.Errorf("transaction index %d out of bounds", targetIndex)
|
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 {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
txIndex := uint64(0)
|
txIndex := uint32(0)
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
if iter.Err() != nil {
|
if iter.Err() != nil {
|
||||||
return nil, 0, iter.Err()
|
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 {
|
if err := rlp.DecodeBytes(txRLP, &tx); err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
return &tx, txIndex, nil
|
return &tx, uint64(txIndex), nil
|
||||||
}
|
}
|
||||||
txIndex++
|
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)
|
log.Error("Transaction not found at index", "number", *blockNumber, "hash", blockHash, "txhash", hash, "index", *txIndex, "err", err)
|
||||||
return nil, common.Hash{}, 0, 0
|
return nil, common.Hash{}, 0, 0
|
||||||
}
|
}
|
||||||
return tx, blockHash, *blockNumber, *txIndex
|
return tx, blockHash, *blockNumber, uint64(*txIndex)
|
||||||
}
|
}
|
||||||
tx, foundIndex, err := findTxInBlockBody(bodyRLP, hash)
|
tx, foundIndex, err := findTxInBlockBody(bodyRLP, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -271,8 +271,8 @@ func ReadCanonicalReceipt(db ethdb.Reader, hash common.Hash, config *params.Chai
|
||||||
}
|
}
|
||||||
if txIndex != nil {
|
if txIndex != nil {
|
||||||
receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config)
|
receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config)
|
||||||
if *txIndex < uint64(len(receipts)) {
|
if uint64(*txIndex) < uint64(len(receipts)) {
|
||||||
return receipts[*txIndex], blockHash, *blockNumber, *txIndex
|
return receipts[*txIndex], blockHash, *blockNumber, uint64(*txIndex)
|
||||||
}
|
}
|
||||||
log.Error("Receipt index out of bounds", "number", *blockNumber, "hash", blockHash, "txhash", hash, "index", *txIndex)
|
log.Error("Receipt index out of bounds", "number", *blockNumber, "hash", blockHash, "txhash", hash, "index", *txIndex)
|
||||||
return nil, common.Hash{}, 0, 0
|
return nil, common.Hash{}, 0, 0
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,7 @@ func TestExtractTransactionAtIndex(t *testing.T) {
|
||||||
bodyRLP := ReadBodyRLP(db, block.Hash(), block.NumberU64())
|
bodyRLP := ReadBodyRLP(db, block.Hash(), block.NumberU64())
|
||||||
|
|
||||||
for i, expectedTx := range txs {
|
for i, expectedTx := range txs {
|
||||||
extractedTx, err := extractTransactionAtIndex(bodyRLP, uint64(i))
|
extractedTx, err := extractTransactionAtIndex(bodyRLP, uint32(i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to extract transaction at index %d: %v", i, err)
|
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 {
|
if err == nil {
|
||||||
t.Fatal("Expected error for out of bounds index, got nil")
|
t.Fatal("Expected error for out of bounds index, got nil")
|
||||||
}
|
}
|
||||||
|
|
@ -381,14 +381,14 @@ func TestTxLookupV7Encoding(t *testing.T) {
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
blockNumber uint64
|
blockNumber uint64
|
||||||
txIndex uint64
|
txIndex uint32
|
||||||
txHash common.Hash
|
txHash common.Hash
|
||||||
}{
|
}{
|
||||||
{0, 0, common.BytesToHash([]byte{0x01})},
|
{0, 0, common.BytesToHash([]byte{0x01})},
|
||||||
{1, 0, common.BytesToHash([]byte{0x02})},
|
{1, 0, common.BytesToHash([]byte{0x02})},
|
||||||
{100, 5, common.BytesToHash([]byte{0x03})},
|
{100, 5, common.BytesToHash([]byte{0x03})},
|
||||||
{999999, 199, common.BytesToHash([]byte{0x04})},
|
{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 {
|
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})
|
tx := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11})
|
||||||
txHash := tx.Hash()
|
txHash := tx.Hash()
|
||||||
blockNumber := uint64(314)
|
blockNumber := uint64(314)
|
||||||
txIndex := uint64(2)
|
txIndex := uint32(2)
|
||||||
|
|
||||||
writeTxLookupEntryV7(db, txHash, blockNumber, txIndex)
|
writeTxLookupEntryV7(db, txHash, blockNumber, txIndex)
|
||||||
num, idx := ReadTxLookupEntry(db, txHash)
|
num, idx := ReadTxLookupEntry(db, txHash)
|
||||||
|
|
@ -455,7 +455,7 @@ func TestTxLookupBackwardCompatibility(t *testing.T) {
|
||||||
entry := LegacyTxLookupEntry{
|
entry := LegacyTxLookupEntry{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
BlockIndex: blockNumber,
|
BlockIndex: blockNumber,
|
||||||
Index: txIndex,
|
Index: uint64(txIndex),
|
||||||
}
|
}
|
||||||
data, _ := rlp.EncodeToBytes(entry)
|
data, _ := rlp.EncodeToBytes(entry)
|
||||||
db.Put(txLookupKey(v3Hash), data)
|
db.Put(txLookupKey(v3Hash), data)
|
||||||
|
|
@ -589,7 +589,7 @@ func BenchmarkExtractTransactionAtIndex(b *testing.B) {
|
||||||
WriteBlock(db, block)
|
WriteBlock(db, block)
|
||||||
bodyRLP := ReadBodyRLP(db, block.Hash(), block.NumberU64())
|
bodyRLP := ReadBodyRLP(db, block.Hash(), block.NumberU64())
|
||||||
|
|
||||||
targetIndex := uint64(size - 1)
|
targetIndex := uint32(size - 1)
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|
|
||||||
|
|
@ -379,8 +379,8 @@ func PruneTransactionIndex(db ethdb.Database, pruneBlock uint64) {
|
||||||
log.Info("Pruning tx index", "count", count, "removed", removed)
|
log.Info("Pruning tx index", "count", count, "removed", removed)
|
||||||
}
|
}
|
||||||
var bn uint64
|
var bn uint64
|
||||||
// Database v7: block number (8 bytes) + tx index (8 bytes) = 16 bytes
|
// Database v7: block number (8 bytes) + tx index (4 bytes) = 12 bytes
|
||||||
if len(v) == 16 {
|
if len(v) == 12 {
|
||||||
bn = binary.BigEndian.Uint64(v[:8])
|
bn = binary.BigEndian.Uint64(v[:8])
|
||||||
} else if len(v) <= 8 {
|
} else if len(v) <= 8 {
|
||||||
// Database v6 or earlier
|
// Database v6 or earlier
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue