diff --git a/chain.go b/chain.go index ffe05ac82..0b979dcc1 100644 --- a/chain.go +++ b/chain.go @@ -175,8 +175,12 @@ func (b *BlockChain) DisableVerify(disable bool) { // be like part of the main chain, on a side chain, or in the orphan pool. // // This function is NOT safe for concurrent access. -func (b *BlockChain) HaveBlock(hash *btcwire.ShaHash) bool { - return b.IsKnownOrphan(hash) || b.blockExists(hash) +func (b *BlockChain) HaveBlock(hash *btcwire.ShaHash) (bool, error) { + exists, err := b.blockExists(hash) + if err != nil { + return false, err + } + return b.IsKnownOrphan(hash) || exists, nil } // IsKnownOrphan returns whether the passed hash is currently a known orphan. diff --git a/chain_test.go b/chain_test.go index 562eb7338..b1e4d72ee 100644 --- a/chain_test.go +++ b/chain_test.go @@ -97,7 +97,11 @@ func TestHaveBlock(t *testing.T) { continue } - result := chain.HaveBlock(hash) + result, err := chain.HaveBlock(hash) + if err != nil { + t.Errorf("HaveBlock #%d unexpected error: %v", i, err) + return + } if result != test.want { t.Errorf("HaveBlock #%d got %v want %v", i, result, test.want) diff --git a/checkpoints.go b/checkpoints.go index 6d02d6211..17417f116 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -103,7 +103,12 @@ func (b *BlockChain) findPreviousCheckpoint() (*btcutil.Block, error) { // that we already have. checkpointIndex := -1 for i := numCheckpoints - 1; i >= 0; i-- { - if b.db.ExistsSha(checkpoints[i].Hash) { + exists, err := b.db.ExistsSha(checkpoints[i].Hash) + if err != nil { + return nil, err + } + + if exists { checkpointIndex = i break } @@ -222,7 +227,11 @@ func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { } // A checkpoint must be in the main chain. - if !b.db.ExistsSha(blockHash) { + exists, err := b.db.ExistsSha(blockHash) + if err != nil { + return false, err + } + if !exists { return false, nil } diff --git a/process.go b/process.go index 4017a5524..e86103b1f 100644 --- a/process.go +++ b/process.go @@ -38,10 +38,10 @@ const ( // blockExists determines whether a block with the given hash exists either in // the main chain or any side chains. -func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { +func (b *BlockChain) blockExists(hash *btcwire.ShaHash) (bool, error) { // Check memory chain first (could be main chain or side chain blocks). if _, ok := b.index[*hash]; ok { - return true + return true, nil } // Check in database (rest of main chain not in memory). @@ -125,7 +125,11 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo log.Tracef("Processing block %v", blockHash) // The block must not already exist in the main chain or side chains. - if b.blockExists(blockHash) { + exists, err := b.blockExists(blockHash) + if err != nil { + return false, err + } + if exists { str := fmt.Sprintf("already have block %v", blockHash) return false, ruleError(ErrDuplicateBlock, str) } @@ -185,14 +189,20 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo // Handle orphan blocks. prevHash := &blockHeader.PrevBlock - if !prevHash.IsEqual(zeroHash) && !b.blockExists(prevHash) { - if !dryRun { - log.Infof("Adding orphan block %v with parent %v", - blockHash, prevHash) - b.addOrphanBlock(block) + if !prevHash.IsEqual(zeroHash) { + prevHashExists, err := b.blockExists(prevHash) + if err != nil { + return false, err } + if !prevHashExists { + if !dryRun { + log.Infof("Adding orphan block %v with parent %v", + blockHash, prevHash) + b.addOrphanBlock(block) + } - return true, nil + return true, nil + } } // The block has passed all context independent checks and appears sane