@@ -131,11 +131,12 @@ public long GetScriptSize
131131 private readonly IBlockStore blockStore ;
132132 private readonly CancellationTokenSource cancellationToken ;
133133 private readonly ConsensusSettings consensusSettings ;
134+ private readonly ChainIndexer chainIndexer ;
134135 private CachePerformanceSnapshot latestPerformanceSnapShot ;
135136
136137 private readonly Random random ;
137138
138- public CachedCoinView ( Network network , ICoindb coindb , IDateTimeProvider dateTimeProvider , ILoggerFactory loggerFactory , INodeStats nodeStats , ConsensusSettings consensusSettings ,
139+ public CachedCoinView ( Network network , ICoindb coindb , IDateTimeProvider dateTimeProvider , ILoggerFactory loggerFactory , INodeStats nodeStats , ConsensusSettings consensusSettings , ChainIndexer chainIndexer ,
139140 StakeChainStore stakeChainStore = null , IRewindDataIndexCache rewindDataIndexCache = null , IBlockStore blockStore = null , INodeLifetime nodeLifetime = null )
140141 {
141142 Guard . NotNull ( coindb , nameof ( CachedCoinView . coindb ) ) ;
@@ -145,6 +146,7 @@ public CachedCoinView(Network network, ICoindb coindb, IDateTimeProvider dateTim
145146 this . network = network ;
146147 this . dateTimeProvider = dateTimeProvider ;
147148 this . consensusSettings = consensusSettings ;
149+ this . chainIndexer = chainIndexer ;
148150 this . stakeChainStore = stakeChainStore ;
149151 this . rewindDataIndexCache = rewindDataIndexCache ;
150152 this . blockStore = blockStore ;
@@ -166,22 +168,22 @@ public CachedCoinView(Network network, ICoindb coindb, IDateTimeProvider dateTim
166168 /// <summary>
167169 /// Remain on-chain.
168170 /// </summary>
169- public void Sync ( ChainIndexer chainIndexer )
171+ public void Sync ( )
170172 {
171173 lock ( this . lockobj )
172174 {
173175 HashHeightPair coinViewTip = this . GetTipHash ( ) ;
174- if ( coinViewTip . Hash == chainIndexer . Tip . HashBlock )
176+ if ( coinViewTip . Hash == this . chainIndexer . Tip . HashBlock )
175177 return ;
176178
177179 Flush ( ) ;
178180
179- ChainedHeader fork = chainIndexer [ coinViewTip . Hash ] ;
181+ ChainedHeader fork = this . chainIndexer [ coinViewTip . Hash ] ;
180182 if ( fork == null )
181183 {
182184 // Determine the last usable height.
183- int height = BinarySearch . BinaryFindFirst ( h => ( h > chainIndexer . Height ) || this . GetRewindData ( h ) . PreviousBlockHash . Hash != chainIndexer [ h ] . Previous . HashBlock , 0 , coinViewTip . Height + 1 ) - 1 ;
184- fork = chainIndexer [ ( height < 0 ) ? coinViewTip . Height : height ] ;
185+ int height = BinarySearch . BinaryFindFirst ( h => ( h > this . chainIndexer . Height ) || this . GetRewindData ( h ) . PreviousBlockHash . Hash != this . chainIndexer [ h ] . Previous . HashBlock , 0 , coinViewTip . Height + 1 ) - 1 ;
186+ fork = this . chainIndexer [ ( height < 0 ) ? coinViewTip . Height : height ] ;
185187 }
186188
187189 while ( coinViewTip . Height != fork . Height )
@@ -196,11 +198,13 @@ public void Sync(ChainIndexer chainIndexer)
196198 }
197199 }
198200
199- public void Initialize ( ChainedHeader chainTip , ChainIndexer chainIndexer , IConsensusRuleEngine consensusRuleEngine )
201+ public void Initialize ( IConsensusManager consensusManager )
200202 {
203+ ChainedHeader chainTip = this . chainIndexer . Tip ;
204+
201205 this . coindb . Initialize ( ) ;
202206
203- Sync ( chainIndexer ) ;
207+ Sync ( ) ;
204208
205209 HashHeightPair coinViewTip = this . coindb . GetTipHash ( ) ;
206210
@@ -209,12 +213,14 @@ public void Initialize(ChainedHeader chainTip, ChainIndexer chainIndexer, IConse
209213 {
210214 try
211215 {
216+ IConsensusRuleEngine consensusRuleEngine = consensusManager . ConsensusRules ;
217+
212218 var loadCoinViewRule = consensusRuleEngine . GetRule < LoadCoinviewRule > ( ) ;
213219 var saveCoinViewRule = consensusRuleEngine . GetRule < SaveCoinviewRule > ( ) ;
214220 var coinViewRule = consensusRuleEngine . GetRule < CoinViewRule > ( ) ;
215221 var deploymentsRule = consensusRuleEngine . GetRule < SetActivationDeploymentsFullValidationRule > ( ) ;
216222
217- foreach ( ( ChainedHeader chainedHeader , Block block ) in this . blockStore . BatchBlocksFrom ( chainIndexer [ coinViewTip . Hash ] , chainIndexer , this . cancellationToken , batchSize : 1000 ) )
223+ foreach ( ( ChainedHeader chainedHeader , Block block ) in this . blockStore . BatchBlocksFrom ( this . chainIndexer [ coinViewTip . Hash ] , this . chainIndexer , this . cancellationToken , batchSize : 1000 ) )
218224 {
219225 if ( block == null )
220226 break ;
@@ -258,15 +264,18 @@ public void Initialize(ChainedHeader chainTip, ChainIndexer chainIndexer, IConse
258264
259265 public HashHeightPair GetTipHash ( )
260266 {
261- if ( this . blockHash == null )
267+ lock ( this . lockobj )
262268 {
263- HashHeightPair response = this . coindb . GetTipHash ( ) ;
269+ if ( this . blockHash == null )
270+ {
271+ HashHeightPair response = this . coindb . GetTipHash ( ) ;
264272
265- this . innerBlockHash = response ;
266- this . blockHash = this . innerBlockHash ;
267- }
273+ this . innerBlockHash = response ;
274+ this . blockHash = this . innerBlockHash ;
275+ }
268276
269- return this . blockHash ;
277+ return this . blockHash ;
278+ }
270279 }
271280
272281 /// <inheritdoc />
@@ -412,44 +421,44 @@ private void TryEvictCacheLocked()
412421 /// </remarks>
413422 public void Flush ( bool force = true )
414423 {
415- if ( ! force )
424+ lock ( this . lockobj )
416425 {
417- // Check if periodic flush is required.
418- // Ideally this will flush less frequent and always be behind
419- // blockstore which is currently set to 17 sec.
426+ if ( ! force )
427+ {
428+ // Check if periodic flush is required.
429+ // Ideally this will flush less frequent and always be behind
430+ // blockstore which is currently set to 17 sec.
420431
421- DateTime now = this . dateTimeProvider . GetUtcNow ( ) ;
422- bool flushTimeLimit = ( now - this . lastCacheFlushTime ) . TotalSeconds >= this . CacheFlushTimeIntervalSeconds ;
432+ DateTime now = this . dateTimeProvider . GetUtcNow ( ) ;
433+ bool flushTimeLimit = ( now - this . lastCacheFlushTime ) . TotalSeconds >= this . CacheFlushTimeIntervalSeconds ;
423434
424- // The size of the cache was reached and most likely TryEvictCacheLocked didn't work
425- // so the cahces is pulledted with flushable items, then we flush anyway.
435+ // The size of the cache was reached and most likely TryEvictCacheLocked didn't work
436+ // so the cahces is pulledted with flushable items, then we flush anyway.
426437
427- long totalBytes = this . cacheSizeBytes + this . rewindDataSizeBytes ;
428- bool flushSizeLimit = totalBytes > this . MaxCacheSizeBytes ;
438+ long totalBytes = this . cacheSizeBytes + this . rewindDataSizeBytes ;
439+ bool flushSizeLimit = totalBytes > this . MaxCacheSizeBytes ;
429440
430- if ( ! flushTimeLimit && ! flushSizeLimit )
431- {
432- return ;
433- }
441+ if ( ! flushTimeLimit && ! flushSizeLimit )
442+ {
443+ return ;
444+ }
434445
435- this . logger . LogDebug ( "Flushing, reasons flushTimeLimit={0} flushSizeLimit={1}." , flushTimeLimit , flushSizeLimit ) ;
436- }
446+ this . logger . LogDebug ( "Flushing, reasons flushTimeLimit={0} flushSizeLimit={1}." , flushTimeLimit , flushSizeLimit ) ;
447+ }
437448
438- // Before flushing the coinview persist the stake store
439- // the stake store depends on the last block hash
440- // to be stored after the stake store is persisted.
441- if ( this . stakeChainStore != null )
442- this . stakeChainStore . Flush ( true ) ;
449+ // Before flushing the coinview persist the stake store
450+ // the stake store depends on the last block hash
451+ // to be stored after the stake store is persisted.
452+ if ( this . stakeChainStore != null )
453+ this . stakeChainStore . Flush ( true ) ;
443454
444- // Before flushing the coinview persist the rewind data index store as well.
445- if ( this . rewindDataIndexCache != null )
446- this . rewindDataIndexCache . SaveAndEvict ( this . blockHash . Height , null ) ;
455+ // Before flushing the coinview persist the rewind data index store as well.
456+ if ( this . rewindDataIndexCache != null )
457+ this . rewindDataIndexCache . SaveAndEvict ( this . blockHash . Height , null ) ;
447458
448- if ( this . innerBlockHash == null )
449- this . innerBlockHash = this . coindb . GetTipHash ( ) ;
459+ if ( this . innerBlockHash == null )
460+ this . innerBlockHash = this . coindb . GetTipHash ( ) ;
450461
451- lock ( this . lockobj )
452- {
453462 if ( this . innerBlockHash == null )
454463 {
455464 this . logger . LogTrace ( "(-)[NULL_INNER_TIP]" ) ;
@@ -476,10 +485,9 @@ public void Flush(bool force = true)
476485 this . cachedRewindData . Clear ( ) ;
477486 this . rewindDataSizeBytes = 0 ;
478487 this . dirtyCacheCount = 0 ;
479- this . innerBlockHash = this . blockHash ;
488+ this . innerBlockHash = this . blockHash ;
489+ this . lastCacheFlushTime = this . dateTimeProvider . GetUtcNow ( ) ;
480490 }
481-
482- this . lastCacheFlushTime = this . dateTimeProvider . GetUtcNow ( ) ;
483491 }
484492
485493 /// <inheritdoc />
@@ -668,16 +676,16 @@ public void SaveChanges(IList<UnspentOutput> outputs, HashHeightPair oldBlockHas
668676
669677 public HashHeightPair Rewind ( HashHeightPair target = null )
670678 {
671- if ( this . innerBlockHash == null )
679+ lock ( this . lockobj )
672680 {
673- this . innerBlockHash = this . coindb . GetTipHash ( ) ;
674- }
681+ if ( this . innerBlockHash == null )
682+ {
683+ this . innerBlockHash = this . coindb . GetTipHash ( ) ;
684+ }
675685
676- // Flush the entire cache before rewinding
677- this . Flush ( true ) ;
686+ // Flush the entire cache before rewinding
687+ this . Flush ( true ) ;
678688
679- lock ( this . lockobj )
680- {
681689 HashHeightPair hash = this . coindb . Rewind ( target ) ;
682690
683691 foreach ( KeyValuePair < OutPoint , CacheItem > cachedUtxoItem in this . cachedUtxoItems )
@@ -707,10 +715,13 @@ public HashHeightPair Rewind(HashHeightPair target = null)
707715 /// <inheritdoc />
708716 public RewindData GetRewindData ( int height )
709717 {
710- if ( this . cachedRewindData . TryGetValue ( height , out RewindData existingRewindData ) )
711- return existingRewindData ;
718+ lock ( this . lockobj )
719+ {
720+ if ( this . cachedRewindData . TryGetValue ( height , out RewindData existingRewindData ) )
721+ return existingRewindData ;
712722
713- return this . coindb . GetRewindData ( height ) ;
723+ return this . coindb . GetRewindData ( height ) ;
724+ }
714725 }
715726
716727 [ NoTrace ]
0 commit comments