[DEV-25] Modified accept.go to account for multiple previous hashes..

This commit is contained in:
Stas Boutenko 2018-06-20 13:49:43 +03:00
parent 6917fac21e
commit bc5edffc92

View File

@ -24,22 +24,28 @@ import (
func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) (bool, error) { func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) (bool, error) {
// The height of this block is one more than the referenced previous // The height of this block is one more than the referenced previous
// block. // block.
prevHash := &block.MsgBlock().Header.PrevBlock prevHeader := &block.MsgBlock().Header
prevNode := b.index.LookupNode(prevHash) numPrevHashes := prevHeader.NumPrevBlocks
if prevNode == nil { prevHashes := prevHeader.PrevBlocks
str := fmt.Sprintf("previous block %s is unknown", prevHash)
var isMainChain bool
for i := byte(0); i < numPrevHashes; i++ {
prevHash := prevHashes[i]
node := b.index.LookupNode(&prevHash)
if node == nil {
str := fmt.Sprintf("previous block %s is unknown", prevHashes)
return false, ruleError(ErrPreviousBlockUnknown, str) return false, ruleError(ErrPreviousBlockUnknown, str)
} else if b.index.NodeStatus(prevNode).KnownInvalid() { } else if b.index.NodeStatus(node).KnownInvalid() {
str := fmt.Sprintf("previous block %s is known to be invalid", prevHash) str := fmt.Sprintf("previous block %s is known to be invalid", prevHashes)
return false, ruleError(ErrInvalidAncestorBlock, str) return false, ruleError(ErrInvalidAncestorBlock, str)
} }
blockHeight := prevNode.height + 1 blockHeight := node.height + 1
block.SetHeight(blockHeight) block.SetHeight(blockHeight)
// The block must pass all of the validation rules which depend on the // The block must pass all of the validation rules which depend on the
// position of the block within the block chain. // position of the block within the block chain.
err := b.checkBlockContext(block, prevNode, flags) err := b.checkBlockContext(block, node, flags)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -64,7 +70,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags)
// if the block ultimately gets connected to the main chain, it starts out // if the block ultimately gets connected to the main chain, it starts out
// on a side chain. // on a side chain.
blockHeader := &block.MsgBlock().Header blockHeader := &block.MsgBlock().Header
newNode := newBlockNode(blockHeader, prevNode) newNode := newBlockNode(blockHeader, node)
newNode.status = statusDataStored newNode.status = statusDataStored
b.index.AddNode(newNode) b.index.AddNode(newNode)
@ -81,6 +87,11 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags)
return false, err return false, err
} }
if !isMainChain {
break
}
}
// Notify the caller that the new block was accepted into the block // Notify the caller that the new block was accepted into the block
// chain. The caller would typically want to react by relaying the // chain. The caller would typically want to react by relaying the
// inventory to other peers. // inventory to other peers.