mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
core/rawdb: add test for PruneTransactionIndex and fix bug
This commit is contained in:
parent
a223ee6c27
commit
45c8fe9f28
2 changed files with 67 additions and 24 deletions
|
|
@ -366,8 +366,8 @@ func unindexTransactionsForTesting(db ethdb.Database, from uint64, to uint64, in
|
||||||
|
|
||||||
// PruneTransactionIndex removes all tx index entries below a certain block number.
|
// PruneTransactionIndex removes all tx index entries below a certain block number.
|
||||||
func PruneTransactionIndex(db ethdb.Database, pruneBlock uint64) {
|
func PruneTransactionIndex(db ethdb.Database, pruneBlock uint64) {
|
||||||
index := NewTable(db, string(txLookupPrefix))
|
db = NewTable(db, string(txLookupPrefix))
|
||||||
iter := index.NewIterator(nil, nil)
|
iter := db.NewIterator(nil, nil)
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
|
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
|
|
@ -378,8 +378,7 @@ func PruneTransactionIndex(db ethdb.Database, pruneBlock uint64) {
|
||||||
}
|
}
|
||||||
bn := decodeNumber(v)
|
bn := decodeNumber(v)
|
||||||
if bn < pruneBlock {
|
if bn < pruneBlock {
|
||||||
fmt.Println("found entry", iter.Key())
|
db.Delete(iter.Key())
|
||||||
// db.Delete(iter.Key())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChainIterator(t *testing.T) {
|
func TestChainIterator(t *testing.T) {
|
||||||
|
|
@ -102,19 +103,18 @@ func TestChainIterator(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIndexTransactions(t *testing.T) {
|
func initDatabaseWithTransactions(db ethdb.Database) ([]*types.Block, []*types.Transaction) {
|
||||||
// Construct test chain db
|
var blocks []*types.Block
|
||||||
chainDb := NewMemoryDatabase()
|
|
||||||
|
|
||||||
var block *types.Block
|
|
||||||
var txs []*types.Transaction
|
var txs []*types.Transaction
|
||||||
to := common.BytesToAddress([]byte{0x11})
|
to := common.BytesToAddress([]byte{0x11})
|
||||||
|
|
||||||
// Write empty genesis block
|
// Write empty genesis block
|
||||||
block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher())
|
block := types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher())
|
||||||
WriteBlock(chainDb, block)
|
WriteBlock(db, block)
|
||||||
WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())
|
WriteCanonicalHash(db, block.Hash(), block.NumberU64())
|
||||||
|
blocks = append(blocks, block)
|
||||||
|
|
||||||
|
// Create transactions.
|
||||||
for i := uint64(1); i <= 10; i++ {
|
for i := uint64(1); i <= 10; i++ {
|
||||||
var tx *types.Transaction
|
var tx *types.Transaction
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
|
|
@ -138,10 +138,21 @@ func TestIndexTransactions(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
txs = append(txs, tx)
|
txs = append(txs, tx)
|
||||||
block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher())
|
block := types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher())
|
||||||
WriteBlock(chainDb, block)
|
WriteBlock(db, block)
|
||||||
WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())
|
WriteCanonicalHash(db, block.Hash(), block.NumberU64())
|
||||||
|
blocks = append(blocks, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return blocks, txs
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIndexTransactions(t *testing.T) {
|
||||||
|
// Construct test chain db
|
||||||
|
chainDB := NewMemoryDatabase()
|
||||||
|
|
||||||
|
_, txs := initDatabaseWithTransactions(chainDB)
|
||||||
|
|
||||||
// verify checks whether the tx indices in the range [from, to)
|
// verify checks whether the tx indices in the range [from, to)
|
||||||
// is expected.
|
// is expected.
|
||||||
verify := func(from, to int, exist bool, tail uint64) {
|
verify := func(from, to int, exist bool, tail uint64) {
|
||||||
|
|
@ -149,7 +160,7 @@ func TestIndexTransactions(t *testing.T) {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
number := ReadTxLookupEntry(chainDb, txs[i-1].Hash())
|
number := ReadTxLookupEntry(chainDB, txs[i-1].Hash())
|
||||||
if exist && number == nil {
|
if exist && number == nil {
|
||||||
t.Fatalf("Transaction index %d missing", i)
|
t.Fatalf("Transaction index %d missing", i)
|
||||||
}
|
}
|
||||||
|
|
@ -157,29 +168,29 @@ func TestIndexTransactions(t *testing.T) {
|
||||||
t.Fatalf("Transaction index %d is not deleted", i)
|
t.Fatalf("Transaction index %d is not deleted", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
number := ReadTxIndexTail(chainDb)
|
number := ReadTxIndexTail(chainDB)
|
||||||
if number == nil || *number != tail {
|
if number == nil || *number != tail {
|
||||||
t.Fatalf("Transaction tail mismatch")
|
t.Fatalf("Transaction tail mismatch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IndexTransactions(chainDb, 5, 11, nil, false)
|
IndexTransactions(chainDB, 5, 11, nil, false)
|
||||||
verify(5, 11, true, 5)
|
verify(5, 11, true, 5)
|
||||||
verify(0, 5, false, 5)
|
verify(0, 5, false, 5)
|
||||||
|
|
||||||
IndexTransactions(chainDb, 0, 5, nil, false)
|
IndexTransactions(chainDB, 0, 5, nil, false)
|
||||||
verify(0, 11, true, 0)
|
verify(0, 11, true, 0)
|
||||||
|
|
||||||
UnindexTransactions(chainDb, 0, 5, nil, false)
|
UnindexTransactions(chainDB, 0, 5, nil, false)
|
||||||
verify(5, 11, true, 5)
|
verify(5, 11, true, 5)
|
||||||
verify(0, 5, false, 5)
|
verify(0, 5, false, 5)
|
||||||
|
|
||||||
UnindexTransactions(chainDb, 5, 11, nil, false)
|
UnindexTransactions(chainDB, 5, 11, nil, false)
|
||||||
verify(0, 11, false, 11)
|
verify(0, 11, false, 11)
|
||||||
|
|
||||||
// Testing corner cases
|
// Testing corner cases
|
||||||
signal := make(chan struct{})
|
signal := make(chan struct{})
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
indexTransactionsForTesting(chainDb, 5, 11, signal, func(n uint64) bool {
|
indexTransactionsForTesting(chainDB, 5, 11, signal, func(n uint64) bool {
|
||||||
if n <= 8 {
|
if n <= 8 {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
close(signal)
|
close(signal)
|
||||||
|
|
@ -190,11 +201,11 @@ func TestIndexTransactions(t *testing.T) {
|
||||||
})
|
})
|
||||||
verify(9, 11, true, 9)
|
verify(9, 11, true, 9)
|
||||||
verify(0, 9, false, 9)
|
verify(0, 9, false, 9)
|
||||||
IndexTransactions(chainDb, 0, 9, nil, false)
|
IndexTransactions(chainDB, 0, 9, nil, false)
|
||||||
|
|
||||||
signal = make(chan struct{})
|
signal = make(chan struct{})
|
||||||
var once2 sync.Once
|
var once2 sync.Once
|
||||||
unindexTransactionsForTesting(chainDb, 0, 11, signal, func(n uint64) bool {
|
unindexTransactionsForTesting(chainDB, 0, 11, signal, func(n uint64) bool {
|
||||||
if n >= 8 {
|
if n >= 8 {
|
||||||
once2.Do(func() {
|
once2.Do(func() {
|
||||||
close(signal)
|
close(signal)
|
||||||
|
|
@ -206,3 +217,36 @@ func TestIndexTransactions(t *testing.T) {
|
||||||
verify(8, 11, true, 8)
|
verify(8, 11, true, 8)
|
||||||
verify(0, 8, false, 8)
|
verify(0, 8, false, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPruneTransactionIndex(t *testing.T) {
|
||||||
|
chainDB := NewMemoryDatabase()
|
||||||
|
blocks, _ := initDatabaseWithTransactions(chainDB)
|
||||||
|
lastBlock := blocks[len(blocks)-1].NumberU64()
|
||||||
|
pruneBlock := lastBlock - 3
|
||||||
|
|
||||||
|
IndexTransactions(chainDB, 0, lastBlock+1, nil, false)
|
||||||
|
|
||||||
|
// Check all transactions are in index.
|
||||||
|
for _, block := range blocks {
|
||||||
|
for _, tx := range block.Transactions() {
|
||||||
|
num := ReadTxLookupEntry(chainDB, tx.Hash())
|
||||||
|
if num == nil || *num != block.NumberU64() {
|
||||||
|
t.Fatalf("wrong TxLookup entry: %x -> %v", tx.Hash(), num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PruneTransactionIndex(chainDB, pruneBlock)
|
||||||
|
|
||||||
|
// Check transactions from old blocks not included.
|
||||||
|
for _, block := range blocks {
|
||||||
|
for _, tx := range block.Transactions() {
|
||||||
|
num := ReadTxLookupEntry(chainDB, tx.Hash())
|
||||||
|
if block.NumberU64() < pruneBlock {
|
||||||
|
if num != nil {
|
||||||
|
t.Fatalf("TxLookup entry not removed: %x -> %v", tx.Hash(), num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue