diff --git a/domain/consensus/processes/blockprocessor/validateblock.go b/domain/consensus/processes/blockprocessor/validateblock.go index 11ce29a80..9d1d6ff52 100644 --- a/domain/consensus/processes/blockprocessor/validateblock.go +++ b/domain/consensus/processes/blockprocessor/validateblock.go @@ -53,12 +53,19 @@ func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock, isPrunin err = bp.validatePostProofOfWork(block, isPruningPoint) if err != nil { if errors.As(err, &ruleerrors.RuleError{}) { - // If we got ErrMissingParents the block shouldn't be considered as invalid - // because it could be added later on when its parents are present, and if - // we get ErrBadMerkleRoot we shouldn't mark the block as invalid because - // later on we can get the block with transactions that fits the merkle - // root. - if !errors.As(err, &ruleerrors.ErrMissingParents{}) && !errors.Is(err, ruleerrors.ErrBadMerkleRoot) { + // We mark invalid blocks with status externalapi.StatusInvalid except in the + // case of the following errors: + // ErrMissingParents - If we got ErrMissingParents the block shouldn't be + // considered as invalid because it could be added later on when its + // parents are present. + // ErrBadMerkleRoot - if we get ErrBadMerkleRoot we shouldn't mark the + // block as invalid because later on we can get the block with + // transactions that fits the merkle root. + // ErrPrunedBlock - ErrPrunedBlock is an error that rejects a block body and + // not the block as a whole, so we shouldn't mark it as invalid. + if !errors.As(err, &ruleerrors.ErrMissingParents{}) && + !errors.Is(err, ruleerrors.ErrBadMerkleRoot) && + !errors.Is(err, ruleerrors.ErrPrunedBlock) { // Discard all changes so we save only the block status bp.discardAllChanges() hash := consensushashing.BlockHash(block) diff --git a/domain/consensus/processes/blockvalidator/block_body_in_context_test.go b/domain/consensus/processes/blockvalidator/block_body_in_context_test.go index f25339966..c6ac81de2 100644 --- a/domain/consensus/processes/blockvalidator/block_body_in_context_test.go +++ b/domain/consensus/processes/blockvalidator/block_body_in_context_test.go @@ -5,6 +5,7 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/ruleerrors" + "github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing" "github.com/kaspanet/kaspad/domain/consensus/utils/constants" "github.com/kaspanet/kaspad/domain/consensus/utils/testutils" "github.com/kaspanet/kaspad/domain/dagconfig" @@ -58,6 +59,17 @@ func TestCheckBlockIsNotPruned(t *testing.T) { if !errors.Is(err, ruleerrors.ErrPrunedBlock) { t.Fatalf("Unexpected error: %+v", err) } + + beforePruningBlockBlockStatus, err := tc.BlockStatusStore().Get(tc.DatabaseContext(), + consensushashing.BlockHash(beforePruningBlock)) + if err != nil { + t.Fatalf("BlockStatusStore().Get: %+v", err) + } + + // Check that the block still has header only status although it got rejected. + if beforePruningBlockBlockStatus != externalapi.StatusHeaderOnly { + t.Fatalf("Unexpected status %s", beforePruningBlockBlockStatus) + } }) }