@@ -25,6 +25,7 @@ import (
25
25
26
26
"github.com/ethereum/go-ethereum/common"
27
27
"github.com/ethereum/go-ethereum/core/types"
28
+ "github.com/ethereum/go-ethereum/ethdb"
28
29
)
29
30
30
31
func TestChainIterator (t * testing.T ) {
@@ -102,19 +103,18 @@ func TestChainIterator(t *testing.T) {
102
103
}
103
104
}
104
105
105
- func TestIndexTransactions (t * testing.T ) {
106
- // Construct test chain db
107
- chainDb := NewMemoryDatabase ()
108
-
109
- var block * types.Block
106
+ func initDatabaseWithTransactions (db ethdb.Database ) ([]* types.Block , []* types.Transaction ) {
107
+ var blocks []* types.Block
110
108
var txs []* types.Transaction
111
109
to := common .BytesToAddress ([]byte {0x11 })
112
110
113
111
// Write empty genesis block
114
- block = types .NewBlock (& types.Header {Number : big .NewInt (int64 (0 ))}, nil , nil , newTestHasher ())
115
- WriteBlock (chainDb , block )
116
- WriteCanonicalHash (chainDb , block .Hash (), block .NumberU64 ())
112
+ block := types .NewBlock (& types.Header {Number : big .NewInt (int64 (0 ))}, nil , nil , newTestHasher ())
113
+ WriteBlock (db , block )
114
+ WriteCanonicalHash (db , block .Hash (), block .NumberU64 ())
115
+ blocks = append (blocks , block )
117
116
117
+ // Create transactions.
118
118
for i := uint64 (1 ); i <= 10 ; i ++ {
119
119
var tx * types.Transaction
120
120
if i % 2 == 0 {
@@ -138,48 +138,59 @@ func TestIndexTransactions(t *testing.T) {
138
138
})
139
139
}
140
140
txs = append (txs , tx )
141
- block = types .NewBlock (& types.Header {Number : big .NewInt (int64 (i ))}, & types.Body {Transactions : types.Transactions {tx }}, nil , newTestHasher ())
142
- WriteBlock (chainDb , block )
143
- WriteCanonicalHash (chainDb , block .Hash (), block .NumberU64 ())
141
+ block := types .NewBlock (& types.Header {Number : big .NewInt (int64 (i ))}, & types.Body {Transactions : types.Transactions {tx }}, nil , newTestHasher ())
142
+ WriteBlock (db , block )
143
+ WriteCanonicalHash (db , block .Hash (), block .NumberU64 ())
144
+ blocks = append (blocks , block )
144
145
}
146
+
147
+ return blocks , txs
148
+ }
149
+
150
+ func TestIndexTransactions (t * testing.T ) {
151
+ // Construct test chain db
152
+ chainDB := NewMemoryDatabase ()
153
+
154
+ _ , txs := initDatabaseWithTransactions (chainDB )
155
+
145
156
// verify checks whether the tx indices in the range [from, to)
146
157
// is expected.
147
158
verify := func (from , to int , exist bool , tail uint64 ) {
148
159
for i := from ; i < to ; i ++ {
149
160
if i == 0 {
150
161
continue
151
162
}
152
- number := ReadTxLookupEntry (chainDb , txs [i - 1 ].Hash ())
163
+ number := ReadTxLookupEntry (chainDB , txs [i - 1 ].Hash ())
153
164
if exist && number == nil {
154
165
t .Fatalf ("Transaction index %d missing" , i )
155
166
}
156
167
if ! exist && number != nil {
157
168
t .Fatalf ("Transaction index %d is not deleted" , i )
158
169
}
159
170
}
160
- number := ReadTxIndexTail (chainDb )
171
+ number := ReadTxIndexTail (chainDB )
161
172
if number == nil || * number != tail {
162
173
t .Fatalf ("Transaction tail mismatch" )
163
174
}
164
175
}
165
- IndexTransactions (chainDb , 5 , 11 , nil , false )
176
+ IndexTransactions (chainDB , 5 , 11 , nil , false )
166
177
verify (5 , 11 , true , 5 )
167
178
verify (0 , 5 , false , 5 )
168
179
169
- IndexTransactions (chainDb , 0 , 5 , nil , false )
180
+ IndexTransactions (chainDB , 0 , 5 , nil , false )
170
181
verify (0 , 11 , true , 0 )
171
182
172
- UnindexTransactions (chainDb , 0 , 5 , nil , false )
183
+ UnindexTransactions (chainDB , 0 , 5 , nil , false )
173
184
verify (5 , 11 , true , 5 )
174
185
verify (0 , 5 , false , 5 )
175
186
176
- UnindexTransactions (chainDb , 5 , 11 , nil , false )
187
+ UnindexTransactions (chainDB , 5 , 11 , nil , false )
177
188
verify (0 , 11 , false , 11 )
178
189
179
190
// Testing corner cases
180
191
signal := make (chan struct {})
181
192
var once sync.Once
182
- indexTransactionsForTesting (chainDb , 5 , 11 , signal , func (n uint64 ) bool {
193
+ indexTransactionsForTesting (chainDB , 5 , 11 , signal , func (n uint64 ) bool {
183
194
if n <= 8 {
184
195
once .Do (func () {
185
196
close (signal )
@@ -190,11 +201,11 @@ func TestIndexTransactions(t *testing.T) {
190
201
})
191
202
verify (9 , 11 , true , 9 )
192
203
verify (0 , 9 , false , 9 )
193
- IndexTransactions (chainDb , 0 , 9 , nil , false )
204
+ IndexTransactions (chainDB , 0 , 9 , nil , false )
194
205
195
206
signal = make (chan struct {})
196
207
var once2 sync.Once
197
- unindexTransactionsForTesting (chainDb , 0 , 11 , signal , func (n uint64 ) bool {
208
+ unindexTransactionsForTesting (chainDB , 0 , 11 , signal , func (n uint64 ) bool {
198
209
if n >= 8 {
199
210
once2 .Do (func () {
200
211
close (signal )
@@ -206,3 +217,37 @@ func TestIndexTransactions(t *testing.T) {
206
217
verify (8 , 11 , true , 8 )
207
218
verify (0 , 8 , false , 8 )
208
219
}
220
+
221
+ func TestPruneTransactionIndex (t * testing.T ) {
222
+ chainDB := NewMemoryDatabase ()
223
+ blocks , _ := initDatabaseWithTransactions (chainDB )
224
+ lastBlock := blocks [len (blocks )- 1 ].NumberU64 ()
225
+ pruneBlock := lastBlock - 3
226
+
227
+ IndexTransactions (chainDB , 0 , lastBlock + 1 , nil , false )
228
+
229
+ // Check all transactions are in index.
230
+ for _ , block := range blocks {
231
+ for _ , tx := range block .Transactions () {
232
+ num := ReadTxLookupEntry (chainDB , tx .Hash ())
233
+ if num == nil || * num != block .NumberU64 () {
234
+ t .Fatalf ("wrong TxLookup entry: %x -> %v" , tx .Hash (), num )
235
+ }
236
+ }
237
+ }
238
+
239
+ PruneTransactionIndex (chainDB , pruneBlock )
240
+
241
+ // Check transactions from old blocks not included.
242
+ for _ , block := range blocks {
243
+ for _ , tx := range block .Transactions () {
244
+ num := ReadTxLookupEntry (chainDB , tx .Hash ())
245
+ if block .NumberU64 () < pruneBlock && num != nil {
246
+ t .Fatalf ("TxLookup entry not removed: %x -> %v" , tx .Hash (), num )
247
+ }
248
+ if block .NumberU64 () >= pruneBlock && (num == nil || * num != block .NumberU64 ()) {
249
+ t .Fatalf ("wrong TxLookup entry after pruning: %x -> %v" , tx .Hash (), num )
250
+ }
251
+ }
252
+ }
253
+ }
0 commit comments