Fix potential issue with dependent orphans.
This commit modifies the main processing loop for orphan dependencies (orphans that are processed due to their parents showing up) to use an index based for loop over range. Since the Go range statement does not reevaluate on every iteration, it was previously possible under certain circumstances for the slice to be changed out from under the range statement while processing the orphan blocks.
This commit is contained in:
parent
c88338d227
commit
b7b9823f6c
1 changed files with 14 additions and 2 deletions
16
process.go
16
process.go
|
@ -53,13 +53,25 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error {
|
|||
// accepted. This will typically only be one, but it could
|
||||
// be multiple if multiple blocks are mined and broadcast
|
||||
// around the same time. The one with the most proof of work
|
||||
// will eventually win out.
|
||||
for _, orphan := range b.prevOrphans[*processHash] {
|
||||
// will eventually win out. An indexing for loop is
|
||||
// intentionally used over a range here as range does not
|
||||
// reevaluate the slice on each iteration nor does it adjust the
|
||||
// index for the modified slice.
|
||||
for i := 0; i < len(b.prevOrphans[*processHash]); i++ {
|
||||
orphan := b.prevOrphans[*processHash][i]
|
||||
if orphan == nil {
|
||||
log.Warnf("Found a nil entry at index %d in the "+
|
||||
"orphan dependency list for block %v", i,
|
||||
processHash)
|
||||
continue
|
||||
}
|
||||
|
||||
// Remove the orphan from the orphan pool.
|
||||
// It's safe to ignore the error on Sha since the hash
|
||||
// is already cached.
|
||||
orphanHash, _ := orphan.block.Sha()
|
||||
b.removeOrphanBlock(orphan)
|
||||
i--
|
||||
|
||||
// Potentially accept the block into the block chain.
|
||||
err := b.maybeAcceptBlock(orphan.block)
|
||||
|
|
Loading…
Add table
Reference in a new issue