Skip to content

Commit fc9bac6

Browse files
BrannonKingroylee17
authored andcommitted
fix crash on unlock generate/invalidate loop
1 parent 61ad706 commit fc9bac6

3 files changed

Lines changed: 19 additions & 6 deletions

File tree

blockchain/accept.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags)
8484
// Notify the caller that the new block was accepted into the block
8585
// chain. The caller would typically want to react by relaying the
8686
// inventory to other peers.
87+
b.notificationSendLock.Lock()
88+
defer b.notificationSendLock.Unlock()
8789
b.chainLock.Unlock()
90+
defer b.chainLock.Lock()
8891
b.sendNotification(NTBlockAccepted, block)
89-
b.chainLock.Lock()
9092

9193
return isMainChain, nil
9294
}

blockchain/chain.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ type BlockChain struct {
116116
// fields in this struct below this point.
117117
chainLock sync.RWMutex
118118

119+
// notificationSendLock helps us only process one block at a time.
120+
// It's definitely a hack. DCRD has much better structure in this regard.
121+
// Without this you will get an error if you invalidate a block and then generate more right after.
122+
// Taken from https://github.com/gcash/bchd/pull/308
123+
notificationSendLock sync.Mutex
124+
119125
// These fields are related to the memory block index. They both have
120126
// their own locks, however they are often also protected by the chain
121127
// lock to help prevent logic races when blocks are being processed.
@@ -683,9 +689,11 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block,
683689
// Notify the caller that the block was connected to the main chain.
684690
// The caller would typically want to react with actions such as
685691
// updating wallets.
692+
b.notificationSendLock.Lock()
693+
defer b.notificationSendLock.Unlock()
686694
b.chainLock.Unlock()
695+
defer b.chainLock.Lock()
687696
b.sendNotification(NTBlockConnected, block)
688-
b.chainLock.Lock()
689697

690698
return nil
691699
}
@@ -808,9 +816,11 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view
808816
// Notify the caller that the block was disconnected from the main
809817
// chain. The caller would typically want to react with actions such as
810818
// updating wallets.
819+
b.notificationSendLock.Lock()
820+
defer b.notificationSendLock.Unlock()
811821
b.chainLock.Unlock()
822+
defer b.chainLock.Lock()
812823
b.sendNotification(NTBlockDisconnected, block)
813-
b.chainLock.Lock()
814824

815825
return nil
816826
}
@@ -1646,6 +1656,8 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has
16461656
//
16471657
// This function is safe for concurrent access.
16481658
func (b *BlockChain) InvalidateBlock(hash *chainhash.Hash) error {
1659+
b.chainLock.Lock()
1660+
defer b.chainLock.Unlock()
16491661
return b.invalidateBlock(hash)
16501662
}
16511663

@@ -1671,8 +1683,6 @@ func (b *BlockChain) invalidateBlock(hash *chainhash.Hash) error {
16711683
b.index.SetStatusFlags(node, statusValidateFailed)
16721684
b.index.UnsetStatusFlags(node, statusValid)
16731685

1674-
b.chainLock.Lock()
1675-
defer b.chainLock.Unlock()
16761686
detachNodes, attachNodes := b.getReorganizeNodes(node.parent)
16771687

16781688
err := b.reorganizeChain(detachNodes, attachNodes)
@@ -1727,6 +1737,7 @@ func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error {
17271737
firstNode = n
17281738
}
17291739

1740+
// do we need an rlock on chainstate for this section?
17301741
var blk *btcutil.Block
17311742
err := b.db.View(func(dbTx database.Tx) error {
17321743
var err error

mempool/estimatefee.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ func (ef *FeeEstimator) RegisterBlock(block *btcutil.Block) error {
275275

276276
// This shouldn't happen but check just in case to avoid
277277
// an out-of-bounds array index later.
278-
if blocksToConfirm >= estimateFeeDepth {
278+
if blocksToConfirm >= estimateFeeDepth || blocksToConfirm < 0 {
279279
continue
280280
}
281281

0 commit comments

Comments
 (0)