@@ -41,18 +41,16 @@ var (
41
41
42
42
type (
43
43
fileDAOv2 struct {
44
- compressor string
45
- storeBatch uint64 // number of blocks to be stored together as a unit
46
- bottomHeight uint64 // height of first block in this DB file
47
- header * FileHeader
48
- cfg config.DB
49
- blkBuffer * stagingBuffer
50
- blkCache * cache.ThreadSafeLruCache
51
- kvStore db.KVStore
52
- batch batch.KVStoreBatch
53
- hashStore db.CountingIndex // store block hash
54
- blkStore db.CountingIndex // store raw blocks
55
- sysStore db.CountingIndex // store transaction log
44
+ header * FileHeader
45
+ tip * FileTip
46
+ cfg config.DB
47
+ blkBuffer * stagingBuffer
48
+ blkCache * cache.ThreadSafeLruCache
49
+ kvStore db.KVStore
50
+ batch batch.KVStoreBatch
51
+ hashStore db.CountingIndex // store block hash
52
+ blkStore db.CountingIndex // store raw blocks
53
+ sysStore db.CountingIndex // store transaction log
56
54
}
57
55
)
58
56
@@ -63,52 +61,58 @@ func NewFileDAOv2(kvStore db.KVStore, bottom uint64, cfg config.DB) (FileDAO, er
63
61
}
64
62
65
63
fd := fileDAOv2 {
66
- compressor : cfg .Compressor ,
67
- storeBatch : uint64 (cfg .BlockStoreBatchSize ),
68
- bottomHeight : bottom ,
69
- cfg : cfg ,
70
- blkCache : cache .NewThreadSafeLruCache (16 ),
71
- kvStore : kvStore ,
72
- batch : batch .NewBatch (),
64
+ header : & FileHeader {
65
+ Version : FileV2 ,
66
+ Compressor : cfg .Compressor ,
67
+ BlockStoreSize : uint64 (cfg .BlockStoreBatchSize ),
68
+ Start : bottom ,
69
+ },
70
+ tip : & FileTip {
71
+ Height : bottom - 1 ,
72
+ },
73
+ cfg : cfg ,
74
+ blkCache : cache .NewThreadSafeLruCache (16 ),
75
+ kvStore : kvStore ,
76
+ batch : batch .NewBatch (),
73
77
}
74
78
return & fd , nil
75
79
}
76
80
77
81
// openFileDAOv2 opens an existing v2 file
78
82
func openFileDAOv2 (kvStore db.KVStore , cfg config.DB ) (FileDAO , error ) {
79
83
fd := fileDAOv2 {
80
- compressor : cfg .Compressor ,
81
- cfg : cfg ,
82
- blkCache : cache .NewThreadSafeLruCache (16 ),
83
- kvStore : kvStore ,
84
- batch : batch .NewBatch (),
84
+ cfg : cfg ,
85
+ blkCache : cache .NewThreadSafeLruCache (16 ),
86
+ kvStore : kvStore ,
87
+ batch : batch .NewBatch (),
85
88
}
86
89
return & fd , nil
87
90
}
88
91
89
92
func (fd * fileDAOv2 ) Start (ctx context.Context ) error {
90
- var err error
91
- if err = fd .kvStore .Start (ctx ); err != nil {
93
+ if err := fd .kvStore .Start (ctx ); err != nil {
92
94
return err
93
95
}
94
96
95
97
// check file header
96
- fd . header , err = ReadFileHeader (fd .kvStore , headerDataNs , fileHeaderKey )
98
+ header , err := ReadHeader (fd .kvStore , headerDataNs , fileHeaderKey )
97
99
if err != nil {
98
100
if errors .Cause (err ) != db .ErrBucketNotExist && errors .Cause (err ) != db .ErrNotExist {
99
101
return errors .Wrap (err , "failed to get file header" )
100
102
}
101
- // write file header
102
- fd .header = & FileHeader {
103
- Version : FileV2 ,
104
- Compressor : fd .cfg .Compressor ,
105
- BlockStoreSize : fd .storeBatch ,
106
- Start : fd .bottomHeight ,
107
- End : fd .bottomHeight - 1 ,
108
- }
103
+ // write file header and tip
109
104
if err = WriteHeader (fd .kvStore , headerDataNs , fileHeaderKey , fd .header ); err != nil {
110
105
return err
111
106
}
107
+ if err = WriteTip (fd .kvStore , headerDataNs , topHeightKey , fd .tip ); err != nil {
108
+ return err
109
+ }
110
+ } else {
111
+ fd .header = header
112
+ // read file tip
113
+ if fd .tip , err = ReadTip (fd .kvStore , headerDataNs , topHeightKey ); err != nil {
114
+ return err
115
+ }
112
116
}
113
117
114
118
// create counting index for hash, blk, and transaction log
@@ -134,19 +138,20 @@ func (fd *fileDAOv2) Stop(ctx context.Context) error {
134
138
}
135
139
136
140
func (fd * fileDAOv2 ) Height () (uint64 , error ) {
137
- h , err := ReadFileHeader (fd .kvStore , headerDataNs , fileHeaderKey )
141
+ var err error
142
+ fd .tip , err = ReadTip (fd .kvStore , headerDataNs , topHeightKey )
138
143
if err != nil {
139
144
return 0 , errors .Wrap (err , "failed to get top height" )
140
145
}
141
- return h . End , nil
146
+ return fd . tip . Height , nil
142
147
}
143
148
144
149
func (fd * fileDAOv2 ) Bottom () (uint64 , error ) {
145
150
return fd .header .Start , nil
146
151
}
147
152
148
153
func (fd * fileDAOv2 ) ContainsHeight (height uint64 ) bool {
149
- return fd .header .Start <= height && height <= fd .header . End
154
+ return fd .header .Start <= height && height <= fd .tip . Height
150
155
}
151
156
152
157
func (fd * fileDAOv2 ) GetBlockHash (height uint64 ) (hash.Hash256 , error ) {
@@ -208,15 +213,15 @@ func (fd *fileDAOv2) TransactionLogs(height uint64) (*iotextypes.TransactionLogs
208
213
if err != nil {
209
214
return nil , errors .Wrapf (err , "failed to get transaction log at height %d" , height )
210
215
}
211
- value , err = decompBytes (value , fd .compressor )
216
+ value , err = decompBytes (value , fd .header . Compressor )
212
217
if err != nil {
213
218
return nil , errors .Wrapf (err , "failed to get transaction log at height %d" , height )
214
219
}
215
220
return block .DeserializeSystemLogPb (value )
216
221
}
217
222
218
223
func (fd * fileDAOv2 ) PutBlock (_ context.Context , blk * block.Block ) error {
219
- if blk .Height () != fd .header . End + 1 {
224
+ if blk .Height () != fd .tip . Height + 1 {
220
225
return ErrInvalidTipHeight
221
226
}
222
227
@@ -238,7 +243,7 @@ func (fd *fileDAOv2) PutBlock(_ context.Context, blk *block.Block) error {
238
243
if err := fd .kvStore .WriteBatch (fd .batch ); err != nil {
239
244
return errors .Wrapf (err , "failed to put block at height %d" , blk .Height ())
240
245
}
241
- fd .header . End = blk .Height ()
246
+ fd .tip . Height = blk .Height ()
242
247
return nil
243
248
}
244
249
@@ -269,11 +274,11 @@ func (fd *fileDAOv2) DeleteTipBlock() error {
269
274
}
270
275
271
276
// delete hash -> height mapping
272
- header , err := ReadFileHeader (fd .kvStore , headerDataNs , fileHeaderKey )
277
+ fd . tip , err = ReadTip (fd .kvStore , headerDataNs , topHeightKey )
273
278
if err != nil {
274
279
return err
275
280
}
276
- fd .batch .Delete (blockHashHeightMappingNS , hashKey (header . TopHash ), "failed to delete hash -> height mapping" )
281
+ fd .batch .Delete (blockHashHeightMappingNS , hashKey (fd . tip . Hash ), "failed to delete hash -> height mapping" )
277
282
278
283
// update file header
279
284
h := hash .ZeroHash256
@@ -283,15 +288,15 @@ func (fd *fileDAOv2) DeleteTipBlock() error {
283
288
return err
284
289
}
285
290
}
286
- ser , err := fd . header . createHeaderBytes ( height - 1 , h )
291
+ ser , err := ( & FileTip { Height : height - 1 , Hash : h }). Serialize ( )
287
292
if err != nil {
288
293
return err
289
294
}
290
- fd .batch .Put (headerDataNs , fileHeaderKey , ser , "failed to put file header " )
295
+ fd .batch .Put (headerDataNs , topHeightKey , ser , "failed to put file tip " )
291
296
292
297
if err := fd .kvStore .WriteBatch (fd .batch ); err != nil {
293
298
return err
294
299
}
295
- fd .header . End = height - 1
300
+ fd .tip . Height = height - 1
296
301
return nil
297
302
}
0 commit comments