Export GetOrphanRoot.
This commit exposes GetOrphanRoot to callers. It also modifies the code to allow the function to be called in a concurrent safe manner. This allows the information to be safely obtained from multiple goroutines.
This commit is contained in:
parent
f4bae7dc41
commit
9d5f855580
2 changed files with 22 additions and 3 deletions
23
chain.go
23
chain.go
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/conformal/btcwire"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -152,6 +153,7 @@ type BlockChain struct {
|
|||
orphans map[btcwire.ShaHash]*orphanBlock
|
||||
prevOrphans map[btcwire.ShaHash][]*orphanBlock
|
||||
oldestOrphan *orphanBlock
|
||||
orphanLock sync.RWMutex
|
||||
blockCache map[btcwire.ShaHash]*btcutil.Block
|
||||
noVerify bool
|
||||
noCheckpoints bool
|
||||
|
@ -166,9 +168,16 @@ func (b *BlockChain) DisableVerify(disable bool) {
|
|||
b.noVerify = disable
|
||||
}
|
||||
|
||||
// getOrphanRoot returns the head of the chain for the provided hash from the
|
||||
// GetOrphanRoot returns the head of the chain for the provided hash from the
|
||||
// map of orphan blocks.
|
||||
func (b *BlockChain) getOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash {
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (b *BlockChain) GetOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash {
|
||||
// Protect concurrent access. Using a read lock only so multiple
|
||||
// readers can query without blocking each other.
|
||||
b.orphanLock.RLock()
|
||||
defer b.orphanLock.RUnlock()
|
||||
|
||||
// Keep looping while the parent of each orphaned block is
|
||||
// known and is an orphan itself.
|
||||
orphanRoot := hash
|
||||
|
@ -188,6 +197,10 @@ func (b *BlockChain) getOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash {
|
|||
// removeOrphanBlock removes the passed orphan block from the orphan pool and
|
||||
// previous orphan index.
|
||||
func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) {
|
||||
// Protect concurrent access.
|
||||
b.orphanLock.Lock()
|
||||
defer b.orphanLock.Unlock()
|
||||
|
||||
// Remove the orphan block from the orphan pool. It's safe to ignore
|
||||
// the error on Sha since it's cached.
|
||||
orphanHash, _ := orphan.block.Sha()
|
||||
|
@ -249,6 +262,12 @@ func (b *BlockChain) addOrphanBlock(block *btcutil.Block) {
|
|||
// errors would've been caught prior to calling this function.
|
||||
blockSha, _ := block.Sha()
|
||||
|
||||
// Protect concurrent access. This is intentionally done here instead
|
||||
// of near the top since removeOrphanBlock does its own locking and
|
||||
// the range iterator is not invalidated by removing map entries.
|
||||
b.orphanLock.Lock()
|
||||
b.orphanLock.Unlock()
|
||||
|
||||
// Insert the block into the orphan map with an expiration time
|
||||
// 1 hour from now.
|
||||
expiration := time.Now().Add(time.Hour)
|
||||
|
|
|
@ -151,7 +151,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error {
|
|||
// Get the hash for the head of the orphaned block chain for
|
||||
// this block and notify the caller so it can request missing
|
||||
// blocks.
|
||||
orphanRoot := b.getOrphanRoot(blockHash)
|
||||
orphanRoot := b.GetOrphanRoot(blockHash)
|
||||
b.sendNotification(NTOrphanBlock, orphanRoot)
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue