code: func (b *BlockChain) addOrphanBlock(block *btcutil.Block) {
  	// Remove expired orphan blocks.
  	for _, oBlock := range b.orphans {
  		if time.Now().After(oBlock.expiration) {
  			b.removeOrphanBlock(oBlock)
  			continue
  		}
  
  		// Update the oldest orphan block pointer so it can be discarded
  		// in case the orphan pool fills up.
  		if b.oldestOrphan == nil || oBlock.expiration.Before(b.oldestOrphan.expiration) {
  			b.oldestOrphan = oBlock
  		}
  	}
  
  	// Limit orphan blocks to prevent memory exhaustion.
  	if len(b.orphans)+1 > maxOrphanBlocks {
  		// Remove the oldest orphan to make room for the new one.
  		b.removeOrphanBlock(b.oldestOrphan)
  		b.oldestOrphan = nil
  	}
  
  	// 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()
  	defer b.orphanLock.Unlock()
  
  	// Insert the block into the orphan map with an expiration time
  	// 1 hour from now.
  	expiration := time.Now().Add(time.Hour)
  	oBlock := &orphanBlock{
  		block:      block,
  		expiration: expiration,
  	}
  	b.orphans[*block.Hash()] = oBlock
  
  	// Add to previous hash lookup index for faster dependency lookups.
  	prevHash := &block.MsgBlock().Header.PrevBlock
  	b.prevOrphans[*prevHash] = append(b.prevOrphans[*prevHash], oBlock)
  }
docs: // addOrphanBlock adds the passed block (which is already determined to be
  // an orphan prior calling this function) to the orphan pool.  It lazily cleans
  // up any expired blocks so a separate cleanup poller doesn't need to be run.
  // It also imposes a maximum limit on the number of outstanding orphan
  // blocks and will remove the oldest received orphan block if the limit is
  // exceeded.