mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-300] If node has invalid ancestor set the according status in blockindex (#386)
* [NOD-300] If node has invalid ancestor set the according status in blockindex * [NOD-300] Test that status is also updated for grand child of an invalid block * [NOD-300] change make(blockSet) to newSet()
This commit is contained in:
parent
b07a118431
commit
f0c80905eb
@ -6,11 +6,18 @@ package blockdag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/daglabs/btcd/database"
|
||||
"github.com/daglabs/btcd/util"
|
||||
)
|
||||
|
||||
func (dag *BlockDAG) addNodeToIndexWithInvalidAncestor(block *util.Block) error {
|
||||
blockHeader := &block.MsgBlock().Header
|
||||
newNode := newBlockNode(blockHeader, newSet(), dag.dagParams.K)
|
||||
newNode.status = statusInvalidAncestor
|
||||
dag.index.AddNode(newNode)
|
||||
return dag.index.flushToDB()
|
||||
}
|
||||
|
||||
// maybeAcceptBlock potentially accepts a block into the block DAG. It
|
||||
// performs several validation checks which depend on its position within
|
||||
// the block DAG before adding it. The block is expected to have already
|
||||
@ -21,10 +28,14 @@ import (
|
||||
//
|
||||
// This function MUST be called with the dagLock held (for writes).
|
||||
func (dag *BlockDAG) maybeAcceptBlock(block *util.Block, flags BehaviorFlags) error {
|
||||
// The height of this block is one more than the referenced previous
|
||||
// block.
|
||||
parents, err := lookupParentNodes(block, dag)
|
||||
if err != nil {
|
||||
if rErr, ok := err.(RuleError); ok && rErr.ErrorCode == ErrInvalidAncestorBlock {
|
||||
err := dag.addNodeToIndexWithInvalidAncestor(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1281,3 +1281,106 @@ func testFinalizeNodesBelowFinalityPoint(t *testing.T, deleteDiffData bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDAGIndexFailedStatus(t *testing.T) {
|
||||
params := dagconfig.SimNetParams
|
||||
dag, teardownFunc, err := DAGSetup("TestDAGIndexFailedStatus", Config{
|
||||
DAGParams: ¶ms,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to setup DAG instance: %v", err)
|
||||
}
|
||||
defer teardownFunc()
|
||||
|
||||
invalidCbTx := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{}, []*wire.TxOut{}, subnetworkid.SubnetworkIDCoinbase, 0, []byte{})
|
||||
txs := []*util.Tx{util.NewTx(invalidCbTx)}
|
||||
hashMerkleRoot := BuildHashMerkleTreeStore(txs).Root()
|
||||
invalidMsgBlock := wire.NewMsgBlock(
|
||||
wire.NewBlockHeader(
|
||||
1,
|
||||
[]*daghash.Hash{params.GenesisHash}, hashMerkleRoot,
|
||||
&daghash.Hash{},
|
||||
&daghash.Hash{},
|
||||
dag.genesis.bits,
|
||||
0),
|
||||
)
|
||||
invalidMsgBlock.AddTransaction(invalidCbTx)
|
||||
invalidBlock := util.NewBlock(invalidMsgBlock)
|
||||
isOrphan, delay, err := dag.ProcessBlock(invalidBlock, BFNoPoWCheck)
|
||||
|
||||
if _, ok := err.(RuleError); !ok {
|
||||
t.Fatalf("ProcessBlock: expected a rule error but got %s instead", err)
|
||||
}
|
||||
if delay != 0 {
|
||||
t.Fatalf("ProcessBlock: invalidBlock " +
|
||||
"is too far in the future")
|
||||
}
|
||||
if isOrphan {
|
||||
t.Fatalf("ProcessBlock incorrectly returned invalidBlock " +
|
||||
"is an orphan\n")
|
||||
}
|
||||
|
||||
invalidBlockNode := dag.index.LookupNode(invalidBlock.Hash())
|
||||
if invalidBlockNode == nil {
|
||||
t.Fatalf("invalidBlockNode wasn't added to the block index as expected")
|
||||
}
|
||||
if invalidBlockNode.status&statusValidateFailed != statusValidateFailed {
|
||||
t.Fatalf("invalidBlockNode status to have %b flags raised (got: %b)", statusValidateFailed, invalidBlockNode.status)
|
||||
}
|
||||
|
||||
invalidMsgBlockChild := wire.NewMsgBlock(
|
||||
wire.NewBlockHeader(1, []*daghash.Hash{
|
||||
invalidBlock.Hash(),
|
||||
}, hashMerkleRoot, &daghash.Hash{}, &daghash.Hash{}, dag.genesis.bits, 0),
|
||||
)
|
||||
invalidMsgBlockChild.AddTransaction(invalidCbTx)
|
||||
invalidBlockChild := util.NewBlock(invalidMsgBlockChild)
|
||||
|
||||
isOrphan, delay, err = dag.ProcessBlock(invalidBlockChild, BFNoPoWCheck)
|
||||
if rErr, ok := err.(RuleError); !ok || rErr.ErrorCode != ErrInvalidAncestorBlock {
|
||||
t.Fatalf("ProcessBlock: expected a rule error but got %s instead", err)
|
||||
}
|
||||
if delay != 0 {
|
||||
t.Fatalf("ProcessBlock: invalidBlockChild " +
|
||||
"is too far in the future")
|
||||
}
|
||||
if isOrphan {
|
||||
t.Fatalf("ProcessBlock incorrectly returned invalidBlockChild " +
|
||||
"is an orphan\n")
|
||||
}
|
||||
invalidBlockChildNode := dag.index.LookupNode(invalidBlockChild.Hash())
|
||||
if invalidBlockChildNode == nil {
|
||||
t.Fatalf("invalidBlockChild wasn't added to the block index as expected")
|
||||
}
|
||||
if invalidBlockChildNode.status&statusInvalidAncestor != statusInvalidAncestor {
|
||||
t.Fatalf("invalidBlockNode status to have %b flags raised (got %b)", statusInvalidAncestor, invalidBlockChildNode.status)
|
||||
}
|
||||
|
||||
invalidMsgBlockGrandChild := wire.NewMsgBlock(
|
||||
wire.NewBlockHeader(1, []*daghash.Hash{
|
||||
invalidBlockChild.Hash(),
|
||||
}, hashMerkleRoot, &daghash.Hash{}, &daghash.Hash{}, dag.genesis.bits, 0),
|
||||
)
|
||||
invalidMsgBlockGrandChild.AddTransaction(invalidCbTx)
|
||||
invalidBlockGrandChild := util.NewBlock(invalidMsgBlockGrandChild)
|
||||
|
||||
isOrphan, delay, err = dag.ProcessBlock(invalidBlockGrandChild, BFNoPoWCheck)
|
||||
if rErr, ok := err.(RuleError); !ok || rErr.ErrorCode != ErrInvalidAncestorBlock {
|
||||
t.Fatalf("ProcessBlock: expected a rule error but got %s instead", err)
|
||||
}
|
||||
if delay != 0 {
|
||||
t.Fatalf("ProcessBlock: invalidBlockGrandChild " +
|
||||
"is too far in the future")
|
||||
}
|
||||
if isOrphan {
|
||||
t.Fatalf("ProcessBlock incorrectly returned invalidBlockGrandChild " +
|
||||
"is an orphan\n")
|
||||
}
|
||||
invalidBlockGrandChildNode := dag.index.LookupNode(invalidBlockGrandChild.Hash())
|
||||
if invalidBlockGrandChildNode == nil {
|
||||
t.Fatalf("invalidBlockGrandChild wasn't added to the block index as expected")
|
||||
}
|
||||
if invalidBlockGrandChildNode.status&statusInvalidAncestor != statusInvalidAncestor {
|
||||
t.Fatalf("invalidBlockGrandChildNode status to have %b flags raised (got %b)", statusInvalidAncestor, invalidBlockGrandChildNode.status)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user