@@ -35,26 +35,37 @@ pub const DEFAULT_ACCOUNT_PRESET: usize = 1000000;
35
35
36
36
pub const ACCOUNT_BLOOM_HASHCOUNT_KEY : & ' static [ u8 ] = b"account_hash_count" ;
37
37
38
+ /// Shared canonical state cache.
38
39
struct AccountCache {
39
40
/// DB Account cache. `None` indicates that account is known to be missing.
40
41
accounts : LruCache < Address , Option < Account > > ,
41
- /// Accounts changed in recent blocks. Ordered by block number.
42
+ /// Accounts changed in recently committed blocks. Ordered by block number.
42
43
modifications : VecDeque < BlockChanges > ,
43
44
}
44
45
46
+ /// Pending account cache item.
45
47
struct CacheQueueItem {
48
+ /// Account address.
46
49
address : Address ,
50
+ /// Acccount data or `None` if account does not exist.
47
51
account : Option < Account > ,
52
+ /// Indicates that the account was modified before being
53
+ /// added to the cache.
48
54
modified : bool ,
49
55
}
50
56
51
57
#[ derive( Debug ) ]
52
- // Accumulates a list of accounts changed in a block.
58
+ /// Accumulates a list of accounts changed in a block.
53
59
struct BlockChanges {
60
+ /// Block number.
54
61
number : BlockNumber ,
62
+ /// Block hash.
55
63
hash : H256 ,
64
+ /// Parent block hash.
56
65
parent : H256 ,
66
+ /// A set of modified account addresses.
57
67
accounts : HashSet < Address > ,
68
+ /// Block is part of the canonical chain.
58
69
is_canon : bool ,
59
70
}
60
71
@@ -65,19 +76,20 @@ struct BlockChanges {
65
76
/// on commit.
66
77
/// For non-canonical clones cache is cleared on commit.
67
78
pub struct StateDB {
68
- // Backing database.
79
+ /// Backing database.
69
80
db : Box < JournalDB > ,
70
- // Shared canonical state cache.
81
+ /// Shared canonical state cache.
71
82
account_cache : Arc < Mutex < AccountCache > > ,
72
- // Local pending cache changes.
73
- cache_overlay : Vec < CacheQueueItem > ,
74
- // Shared account bloom. Does not handle chain reorganizations.
83
+ /// Local pending cache changes.
84
+ pending_cache : Vec < CacheQueueItem > ,
85
+ /// Shared account bloom. Does not handle chain reorganizations.
75
86
account_bloom : Arc < Mutex < Bloom > > ,
76
- // Hash of the block on top of which this instance was created
87
+ /// Hash of the block on top of which this instance was created or
88
+ /// `None` if cache is disabled
77
89
parent_hash : Option < H256 > ,
78
- // Hash of the committing block
90
+ /// Hash of the committing block or `None` if not committed yet.
79
91
commit_hash : Option < H256 > ,
80
- // Number of the committing block
92
+ /// Number of the committing block or `None` if not committed yet.
81
93
commit_number : Option < BlockNumber > ,
82
94
}
83
95
@@ -118,7 +130,7 @@ impl StateDB {
118
130
accounts : LruCache :: new ( STATE_CACHE_ITEMS ) ,
119
131
modifications : VecDeque :: new ( ) ,
120
132
} ) ) ,
121
- cache_overlay : Vec :: new ( ) ,
133
+ pending_cache : Vec :: new ( ) ,
122
134
account_bloom : Arc :: new ( Mutex :: new ( bloom) ) ,
123
135
parent_hash : None ,
124
136
commit_hash : None ,
@@ -165,11 +177,14 @@ impl StateDB {
165
177
Ok ( records)
166
178
}
167
179
168
- /// Update canonical cache. This should be called after the block has been commited and the
169
- /// blockchain route has ben calculated.
170
- /// `retracted` is the list of the retracted block hashes.
171
- pub fn update_cache ( & mut self , enacted : & [ H256 ] , retracted : & [ H256 ] , is_best : bool ) {
172
- trace ! ( "commit id = (#{:?}, {:?}), parent={:?}, best={}" , self . commit_number, self . commit_hash, self . parent_hash, is_best) ;
180
+ /// Apply pending cache changes and synchronize canonical
181
+ /// state cache with the best block state.
182
+ /// This function updates the cache by removing entries that are
183
+ /// invalidated by chain reorganization. `update_cache` should be
184
+ /// called after the block has been commited and the blockchain
185
+ /// route has ben calculated.
186
+ pub fn sync_cache ( & mut self , enacted : & [ H256 ] , retracted : & [ H256 ] , is_best : bool ) {
187
+ trace ! ( "sync_cache id = (#{:?}, {:?}), parent={:?}, best={}" , self . commit_number, self . commit_hash, self . parent_hash, is_best) ;
173
188
let mut cache = self . account_cache . lock ( ) ;
174
189
let mut cache = & mut * cache;
175
190
@@ -178,10 +193,10 @@ impl StateDB {
178
193
for block in enacted. iter ( ) . filter ( |h| self . commit_hash . as_ref ( ) . map_or ( false , |p| * h != p) ) {
179
194
clear = clear || {
180
195
if let Some ( ref mut m) = cache. modifications . iter_mut ( ) . find ( |ref m| & m. hash == block) {
181
- trace ! ( "reverting enacted block {:?}" , block) ;
196
+ trace ! ( "Reverting enacted block {:?}" , block) ;
182
197
m. is_canon = true ;
183
198
for a in & m. accounts {
184
- trace ! ( "reverting enacted address {:?}" , a) ;
199
+ trace ! ( "Reverting enacted address {:?}" , a) ;
185
200
cache. accounts . remove ( a) ;
186
201
}
187
202
false
@@ -194,10 +209,10 @@ impl StateDB {
194
209
for block in retracted {
195
210
clear = clear || {
196
211
if let Some ( ref mut m) = cache. modifications . iter_mut ( ) . find ( |ref m| & m. hash == block) {
197
- trace ! ( "retracting block {:?}" , block) ;
212
+ trace ! ( "Retracting block {:?}" , block) ;
198
213
m. is_canon = false ;
199
214
for a in & m. accounts {
200
- trace ! ( "retracted address {:?}" , a) ;
215
+ trace ! ( "Retracted address {:?}" , a) ;
201
216
cache. accounts . remove ( a) ;
202
217
}
203
218
false
@@ -208,7 +223,7 @@ impl StateDB {
208
223
}
209
224
if clear {
210
225
// We don't know anything about the block; clear everything
211
- trace ! ( "wiping cache" ) ;
226
+ trace ! ( "Wiping cache" ) ;
212
227
cache. accounts . clear ( ) ;
213
228
cache. modifications . clear ( ) ;
214
229
}
@@ -221,8 +236,8 @@ impl StateDB {
221
236
cache. modifications . pop_back ( ) ;
222
237
}
223
238
let mut modifications = HashSet :: new ( ) ;
224
- trace ! ( "committing {} cache entries" , self . cache_overlay . len( ) ) ;
225
- for account in self . cache_overlay . drain ( ..) {
239
+ trace ! ( "committing {} cache entries" , self . pending_cache . len( ) ) ;
240
+ for account in self . pending_cache . drain ( ..) {
226
241
if account. modified {
227
242
modifications. insert ( account. address . clone ( ) ) ;
228
243
}
@@ -272,7 +287,7 @@ impl StateDB {
272
287
StateDB {
273
288
db : self . db . boxed_clone ( ) ,
274
289
account_cache : self . account_cache . clone ( ) ,
275
- cache_overlay : Vec :: new ( ) ,
290
+ pending_cache : Vec :: new ( ) ,
276
291
account_bloom : self . account_bloom . clone ( ) ,
277
292
parent_hash : None ,
278
293
commit_hash : None ,
@@ -285,7 +300,7 @@ impl StateDB {
285
300
StateDB {
286
301
db : self . db . boxed_clone ( ) ,
287
302
account_cache : self . account_cache . clone ( ) ,
288
- cache_overlay : Vec :: new ( ) ,
303
+ pending_cache : Vec :: new ( ) ,
289
304
account_bloom : self . account_bloom . clone ( ) ,
290
305
parent_hash : Some ( parent. clone ( ) ) ,
291
306
commit_hash : None ,
@@ -308,26 +323,18 @@ impl StateDB {
308
323
& * self . db
309
324
}
310
325
311
- /// Enqueue cache change.
312
- pub fn cache_account ( & mut self , addr : Address , data : Option < Account > , modified : bool ) {
313
- self . cache_overlay . push ( CacheQueueItem {
326
+ /// Add pending cache change.
327
+ /// The change is queued to be applied in `commit`.
328
+ pub fn add_to_account_cache ( & mut self , addr : Address , data : Option < Account > , modified : bool ) {
329
+ self . pending_cache . push ( CacheQueueItem {
314
330
address : addr,
315
331
account : data,
316
332
modified : modified,
317
333
} )
318
334
}
319
335
320
- /// Clear the cache.
321
- pub fn clear_cache ( & mut self ) {
322
- trace ! ( "Clearing cache" ) ;
323
- self . cache_overlay . clear ( ) ;
324
- let mut cache = self . account_cache . lock ( ) ;
325
- cache. accounts . clear ( ) ;
326
- }
327
-
328
336
/// Get basic copy of the cached account. Does not include storage.
329
- /// Returns 'None' if the state is non-canonical and cache is disabled
330
- /// or if the account is not cached.
337
+ /// Returns 'None' if cache is disabled or if the account is not cached.
331
338
pub fn get_cached_account ( & self , addr : & Address ) -> Option < Option < Account > > {
332
339
let mut cache = self . account_cache . lock ( ) ;
333
340
if !Self :: is_allowed ( addr, & self . parent_hash , & cache. modifications ) {
@@ -337,8 +344,7 @@ impl StateDB {
337
344
}
338
345
339
346
/// Get value from a cached account.
340
- /// Returns 'None' if the state is non-canonical and cache is disabled
341
- /// or if the account is not cached.
347
+ /// Returns 'None' if cache is disabled or if the account is not cached.
342
348
pub fn get_cached < F , U > ( & self , a : & Address , f : F ) -> Option < U >
343
349
where F : FnOnce ( Option < & mut Account > ) -> U {
344
350
let mut cache = self . account_cache . lock ( ) ;
@@ -348,12 +354,12 @@ impl StateDB {
348
354
cache. accounts . get_mut ( a) . map ( |c| f ( c. as_mut ( ) ) )
349
355
}
350
356
351
- // Check if the account can be returned from cache by matching current block parent hash against canonical
352
- // state and filtering out account modified in later blocks.
357
+ /// Check if the account can be returned from cache by matching current block parent hash against canonical
358
+ /// state and filtering out account modified in later blocks.
353
359
fn is_allowed ( addr : & Address , parent_hash : & Option < H256 > , modifications : & VecDeque < BlockChanges > ) -> bool {
354
360
let mut parent = match * parent_hash {
355
361
None => {
356
- trace ! ( "cache lookup skipped for {:?}: no parent hash" , addr) ;
362
+ trace ! ( "Cache lookup skipped for {:?}: no parent hash" , addr) ;
357
363
return false ;
358
364
}
359
365
Some ( ref parent) => parent,
@@ -375,11 +381,11 @@ impl StateDB {
375
381
parent = & m. parent ;
376
382
}
377
383
if m. accounts . contains ( addr) {
378
- trace ! ( "cache lookup skipped for {:?}: modified in a later block" , addr) ;
384
+ trace ! ( "Cache lookup skipped for {:?}: modified in a later block" , addr) ;
379
385
return false ;
380
386
}
381
387
}
382
- trace ! ( "cache lookup skipped for {:?}: parent hash is unknown" , addr) ;
388
+ trace ! ( "Cache lookup skipped for {:?}: parent hash is unknown" , addr) ;
383
389
return false ;
384
390
}
385
391
}
0 commit comments