mutex.Lock during c.recoverFromCorruption()
This commit is contained in:
parent
1d11751e4e
commit
3873a4d895
|
@ -51,7 +51,12 @@ func (c *BlockCache) HashMismatch(prevhash []byte) bool {
|
|||
return c.latestHash != nil && !bytes.Equal(c.latestHash, prevhash)
|
||||
}
|
||||
|
||||
// Make the block at the given height the lowest height that we don't have.
|
||||
// In other words, wipe out this height and beyond.
|
||||
// This should never increase the size of the cache, only decrease.
|
||||
// Caller should hold c.mutex.Lock().
|
||||
func (c *BlockCache) setDbFiles(height int) {
|
||||
if height < c.nextBlock {
|
||||
index := height - c.firstBlock
|
||||
if err := c.lengthsFile.Truncate(int64(index * 4)); err != nil {
|
||||
Log.Fatal("truncate lengths file failed: ", err)
|
||||
|
@ -63,8 +68,10 @@ func (c *BlockCache) setDbFiles(height int) {
|
|||
c.starts = c.starts[:index+1]
|
||||
c.nextBlock = height
|
||||
c.setLatestHash()
|
||||
}
|
||||
}
|
||||
|
||||
// Caller should hold c.mutex.Lock().
|
||||
func (c *BlockCache) recoverFromCorruption(height int) {
|
||||
Log.Warning("CORRUPTION detected in db blocks-cache files, height ", height, " redownloading")
|
||||
c.setDbFiles(height)
|
||||
|
@ -86,6 +93,7 @@ func checksum(height int, b []byte) []byte {
|
|||
return cs.Sum(nil)
|
||||
}
|
||||
|
||||
// Caller should hold (at least) c.mutex.RLock().
|
||||
func (c *BlockCache) readBlock(height int) *walletrpc.CompactBlock {
|
||||
blockLen := c.blockLength(height)
|
||||
b := make([]byte, blockLen+8)
|
||||
|
@ -116,6 +124,7 @@ func (c *BlockCache) readBlock(height int) *walletrpc.CompactBlock {
|
|||
return block
|
||||
}
|
||||
|
||||
// Caller should hold c.mutex.Lock().
|
||||
func (c *BlockCache) setLatestHash() {
|
||||
c.latestHash = nil
|
||||
// There is at least one block; get the last block's hash
|
||||
|
@ -132,6 +141,7 @@ func (c *BlockCache) setLatestHash() {
|
|||
}
|
||||
|
||||
// NewBlockCache returns an instance of a block cache object.
|
||||
// (No locking here, we assume this is single-threaded.)
|
||||
func NewBlockCache(dbPath string, chainName string, startHeight int, redownload bool) *BlockCache {
|
||||
c := &BlockCache{}
|
||||
c.firstBlock = startHeight
|
||||
|
@ -298,7 +308,12 @@ func (c *BlockCache) Get(height int) *walletrpc.CompactBlock {
|
|||
}
|
||||
block := c.readBlock(height)
|
||||
if block == nil {
|
||||
go func() {
|
||||
// We hold only the read lock, need the exclusive lock.
|
||||
c.mutex.Lock()
|
||||
c.recoverFromCorruption(height)
|
||||
c.mutex.Unlock()
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
return block
|
||||
|
|
Loading…
Reference in New Issue