mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[DEV-25] Modified accept.go to account for multiple previous hashes..
This commit is contained in:
parent
6917fac21e
commit
bc5edffc92
@ -24,61 +24,72 @@ import (
|
||||
func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) (bool, error) {
|
||||
// The height of this block is one more than the referenced previous
|
||||
// block.
|
||||
prevHash := &block.MsgBlock().Header.PrevBlock
|
||||
prevNode := b.index.LookupNode(prevHash)
|
||||
if prevNode == nil {
|
||||
str := fmt.Sprintf("previous block %s is unknown", prevHash)
|
||||
return false, ruleError(ErrPreviousBlockUnknown, str)
|
||||
} else if b.index.NodeStatus(prevNode).KnownInvalid() {
|
||||
str := fmt.Sprintf("previous block %s is known to be invalid", prevHash)
|
||||
return false, ruleError(ErrInvalidAncestorBlock, str)
|
||||
}
|
||||
prevHeader := &block.MsgBlock().Header
|
||||
numPrevHashes := prevHeader.NumPrevBlocks
|
||||
prevHashes := prevHeader.PrevBlocks
|
||||
|
||||
blockHeight := prevNode.height + 1
|
||||
block.SetHeight(blockHeight)
|
||||
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)
|
||||
} else if b.index.NodeStatus(node).KnownInvalid() {
|
||||
str := fmt.Sprintf("previous block %s is known to be invalid", prevHashes)
|
||||
return false, ruleError(ErrInvalidAncestorBlock, str)
|
||||
}
|
||||
|
||||
// The block must pass all of the validation rules which depend on the
|
||||
// position of the block within the block chain.
|
||||
err := b.checkBlockContext(block, prevNode, flags)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
blockHeight := node.height + 1
|
||||
block.SetHeight(blockHeight)
|
||||
|
||||
// Insert the block into the database if it's not already there. Even
|
||||
// though it is possible the block will ultimately fail to connect, it
|
||||
// has already passed all proof-of-work and validity tests which means
|
||||
// it would be prohibitively expensive for an attacker to fill up the
|
||||
// disk with a bunch of blocks that fail to connect. This is necessary
|
||||
// since it allows block download to be decoupled from the much more
|
||||
// expensive connection logic. It also has some other nice properties
|
||||
// such as making blocks that never become part of the main chain or
|
||||
// blocks that fail to connect available for further analysis.
|
||||
err = b.db.Update(func(dbTx database.Tx) error {
|
||||
return dbStoreBlock(dbTx, block)
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// The block must pass all of the validation rules which depend on the
|
||||
// position of the block within the block chain.
|
||||
err := b.checkBlockContext(block, node, flags)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Create a new block node for the block and add it to the node index. Even
|
||||
// if the block ultimately gets connected to the main chain, it starts out
|
||||
// on a side chain.
|
||||
blockHeader := &block.MsgBlock().Header
|
||||
newNode := newBlockNode(blockHeader, prevNode)
|
||||
newNode.status = statusDataStored
|
||||
// Insert the block into the database if it's not already there. Even
|
||||
// though it is possible the block will ultimately fail to connect, it
|
||||
// has already passed all proof-of-work and validity tests which means
|
||||
// it would be prohibitively expensive for an attacker to fill up the
|
||||
// disk with a bunch of blocks that fail to connect. This is necessary
|
||||
// since it allows block download to be decoupled from the much more
|
||||
// expensive connection logic. It also has some other nice properties
|
||||
// such as making blocks that never become part of the main chain or
|
||||
// blocks that fail to connect available for further analysis.
|
||||
err = b.db.Update(func(dbTx database.Tx) error {
|
||||
return dbStoreBlock(dbTx, block)
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
b.index.AddNode(newNode)
|
||||
err = b.index.flushToDB()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Create a new block node for the block and add it to the node index. Even
|
||||
// if the block ultimately gets connected to the main chain, it starts out
|
||||
// on a side chain.
|
||||
blockHeader := &block.MsgBlock().Header
|
||||
newNode := newBlockNode(blockHeader, node)
|
||||
newNode.status = statusDataStored
|
||||
|
||||
// Connect the passed block to the chain while respecting proper chain
|
||||
// selection according to the chain with the most proof of work. This
|
||||
// also handles validation of the transaction scripts.
|
||||
isMainChain, err := b.connectBestChain(newNode, block, flags)
|
||||
if err != nil {
|
||||
return false, err
|
||||
b.index.AddNode(newNode)
|
||||
err = b.index.flushToDB()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Connect the passed block to the chain while respecting proper chain
|
||||
// selection according to the chain with the most proof of work. This
|
||||
// also handles validation of the transaction scripts.
|
||||
isMainChain, err := b.connectBestChain(newNode, block, flags)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !isMainChain {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the caller that the new block was accepted into the block
|
||||
|
Loading…
x
Reference in New Issue
Block a user