func (sm *ShardStateManager) Finalize(finalizedHash chainhash.Hash, finalizedSlot uint64) error {
	sm.stateLock.Lock()
	defer sm.stateLock.Unlock()

	if sm.finalizedDB.hash.IsEqual(&finalizedHash) {
		return nil
	}

	logrus.WithField("block hash", finalizedHash).WithField("shard", sm.shardInfo.ShardID).Debug("finalize block action")

	// first, let's start at the tip and commit everything
	finalizeNode, found := sm.stateMap[finalizedHash]
	if !found {
		return fmt.Errorf("could not find block to finalize %s on slot %d %d", finalizedHash, finalizedSlot, sm.shardInfo.ShardID)
	}

	// start at the finalized node
	flushingNode := finalizeNode

	// while the flushing database is a cache
	memCache, isCache := flushingNode.db.(*csmt.TreeMemoryCache)
	for isCache {
		if err := memCache.Flush(); err != nil {
			return err
		}
		// go to previous block
		prevBlock := flushingNode.parent

		// if this is null, that means something went wrong because there is no underlying store.
		memCache, isCache = prevBlock.db.(*csmt.TreeMemoryCache)

		flushingNode = prevBlock
	}


	diskCache := flushingNode.db
	finalizeNode.db = diskCache

	// after we've flushed all of that, we should clean up any states with slots before that.
	for k, node := range sm.stateMap {
		if node.slot > finalizedSlot {
			continue
		}
		if k.IsEqual(&finalizedHash) {
			continue
		}
		if node.slot < finalizedSlot {
			delete(sm.stateMap, k)
		}
		if node.slot == finalizedSlot && !k.IsEqual(&finalizedHash) {
			delete(sm.stateMap, k)
		}
		if node.parent == finalizeNode {
			// if the parent is a tree cache, let's update the underlying store if needed
			childCache, isCache := node.db.(*csmt.TreeMemoryCache)
			if isCache {
				if err := childCache.UpdateUnderlying(diskCache); err != nil {
					return err
				}
			}
		}
	}

	sm.finalizedDB = sm.stateMap[finalizedHash]

	return nil
}
// Finalize removes unnecessary state from the state map.
Finalize removes unnecessary state from the state map.
// Finalize removes unnecessary state from the state map .
func (sm *ShardStateManager) Finalize(finalizedHash chainhash.Hash, finalizedSlot uint64) error {
	sm.stateLock.Lock()
	defer sm.stateLock.Unlock()
	if sm.finalizedDB.hash.IsEqual(&finalizedHash) {
		return nil
	}
	logrus.WithField("block hash", finalizedHash).WithField("shard", sm.shardInfo.ShardID).Debug("finalize block action")
	finalizeNode, found := sm.stateMap[finalizedHash]
	if !found {
		return fmt.Errorf("could not find block to finalize %s on slot %d %d", finalizedHash, finalizedSlot, sm.shardInfo.ShardID)
	}
	flushingNode := finalizeNode
	memCache, isCache := flushingNode.db.(*csmt.TreeMemoryCache)
	for isCache {
		if err := memCache.Flush(); err != nil {
			return err
		}
		prevBlock := flushingNode.parent
		memCache, isCache = prevBlock.db.(*csmt.TreeMemoryCache)
		flushingNode = prevBlock
	}
	diskCache := flushingNode.db
	finalizeNode.db = diskCache
	for k, node := range sm.stateMap {
		if node.slot > finalizedSlot {
			continue
		}
		if k.IsEqual(&finalizedHash) {
			continue
		}
		if node.slot < finalizedSlot {
			delete(sm.stateMap, k)
		}
		if node.slot == finalizedSlot && !k.IsEqual(&finalizedHash) {
			delete(sm.stateMap, k)
		}
		if node.parent == finalizeNode {
			childCache, isCache := node.db.(*csmt.TreeMemoryCache)
			if isCache {
				if err := childCache.UpdateUnderlying(diskCache); err != nil {
					return err
				}
			}
		}
	}
	sm.finalizedDB = sm.stateMap[finalizedHash]
	return nil
}
func ( sm * ShardStateManager ) Finalize ( finalizedHash chainhash . Hash , finalizedSlot uint64 ) error { sm . stateLock . Lock ( ) defer sm . stateLock . Unlock ( ) if sm . finalizedDB . hash . IsEqual ( & finalizedHash ) { return nil } logrus . WithField ( " " , finalizedHash ) . WithField ( " " , sm . shardInfo . ShardID ) . Debug ( " " ) finalizeNode , found := sm . stateMap [ finalizedHash ] if ! found { return fmt . Errorf ( " " , finalizedHash , finalizedSlot , sm . shardInfo . ShardID ) } flushingNode := finalizeNode memCache , isCache := flushingNode . db . ( * csmt . TreeMemoryCache ) for isCache { if err := memCache . Flush ( ) ; err != nil { return err } prevBlock := flushingNode . parent memCache , isCache = prevBlock . db . ( * csmt . TreeMemoryCache ) flushingNode = prevBlock } diskCache := flushingNode . db finalizeNode . db = diskCache for k , node := range sm . stateMap { if node . slot > finalizedSlot { continue } if k . IsEqual ( & finalizedHash ) { continue } if node . slot < finalizedSlot { delete ( sm . stateMap , k ) } if node . slot == finalizedSlot && ! k . IsEqual ( & finalizedHash ) { delete ( sm . stateMap , k ) } if node . parent == finalizeNode { childCache , isCache := node . db . ( * csmt . TreeMemoryCache ) if isCache { if err := childCache . UpdateUnderlying ( diskCache ) ; err != nil { return err } } } } sm . finalizedDB = sm . stateMap [ finalizedHash ] return nil }
Finalize removes unnecessary state from the state map.
Finalize removes unnecessary state from the state map .
// first, let's start at the tip and commit everything // start at the finalized node // while the flushing database is a cache // go to previous block // if this is null, that means something went wrong because there is no underlying store. // after we've flushed all of that, we should clean up any states with slots before that. // if the parent is a tree cache, let's update the underlying store if needed