From 96d9e5800fba31a18f72344068783105b39b3afa Mon Sep 17 00:00:00 2001 From: Ori Newman Date: Mon, 23 Nov 2020 08:27:44 -0800 Subject: [PATCH] [NOD-1561] Add TestCheckParentsIncest and fix validation order (#1143) --- .../blockvalidator/block_header_in_context.go | 5 -- .../block_header_in_context_test.go | 70 +++++++++++++++++++ .../processes/blockvalidator/proof_of_work.go | 9 ++- 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/domain/consensus/processes/blockvalidator/block_header_in_context.go b/domain/consensus/processes/blockvalidator/block_header_in_context.go index ae52d147a..1d76108ed 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_context.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_context.go @@ -16,11 +16,6 @@ func (v *blockValidator) ValidateHeaderInContext(blockHash *externalapi.DomainHa return err } - err = v.checkParentsIncest(header) - if err != nil { - return err - } - isHeadersOnlyBlock, err := v.isHeadersOnlyBlock(blockHash) if err != nil { return err diff --git a/domain/consensus/processes/blockvalidator/block_header_in_context_test.go b/domain/consensus/processes/blockvalidator/block_header_in_context_test.go index eea7db5b2..781a15e26 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_context_test.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_context_test.go @@ -81,3 +81,73 @@ func TestValidateMedianTime(t *testing.T) { addBlock(pastMedianTime(tipHash)-1, []*externalapi.DomainHash{tipHash}, ruleerrors.ErrTimeTooOld) }) } + +func TestCheckParentsIncest(t *testing.T) { + testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) { + factory := consensus.NewFactory() + tc, teardown, err := factory.NewTestConsensus(params, "TestCheckParentsIncest") + if err != nil { + t.Fatalf("Error setting up consensus: %+v", err) + } + defer teardown() + + a, err := tc.AddBlock([]*externalapi.DomainHash{params.GenesisHash}, nil, nil) + if err != nil { + t.Fatalf("AddBlock: %+v", err) + } + + b, err := tc.AddBlock([]*externalapi.DomainHash{a}, nil, nil) + if err != nil { + t.Fatalf("AddBlock: %+v", err) + } + + c, err := tc.AddBlock([]*externalapi.DomainHash{params.GenesisHash}, nil, nil) + if err != nil { + t.Fatalf("AddBlock: %+v", err) + } + + directParentsRelationBlock := &externalapi.DomainBlock{ + Header: &externalapi.DomainBlockHeader{ + Version: 0, + ParentHashes: []*externalapi.DomainHash{a, b}, + HashMerkleRoot: externalapi.DomainHash{}, + AcceptedIDMerkleRoot: externalapi.DomainHash{}, + UTXOCommitment: externalapi.DomainHash{}, + TimeInMilliseconds: 0, + Bits: 0, + Nonce: 0, + }, + Transactions: nil, + } + + err = tc.ValidateAndInsertBlock(directParentsRelationBlock) + if !errors.Is(err, ruleerrors.ErrInvalidParentsRelation) { + t.Fatalf("unexpected error %+v", err) + } + + indirectParentsRelationBlock := &externalapi.DomainBlock{ + Header: &externalapi.DomainBlockHeader{ + Version: 0, + ParentHashes: []*externalapi.DomainHash{params.GenesisHash, b}, + HashMerkleRoot: externalapi.DomainHash{}, + AcceptedIDMerkleRoot: externalapi.DomainHash{}, + UTXOCommitment: externalapi.DomainHash{}, + TimeInMilliseconds: 0, + Bits: 0, + Nonce: 0, + }, + Transactions: nil, + } + + err = tc.ValidateAndInsertBlock(indirectParentsRelationBlock) + if !errors.Is(err, ruleerrors.ErrInvalidParentsRelation) { + t.Fatalf("unexpected error %+v", err) + } + + // Try to add block with unrelated parents + _, err = tc.AddBlock([]*externalapi.DomainHash{b, c}, nil, nil) + if err != nil { + t.Fatalf("AddBlock: %s", err) + } + }) +} diff --git a/domain/consensus/processes/blockvalidator/proof_of_work.go b/domain/consensus/processes/blockvalidator/proof_of_work.go index 49175ffb5..6014a0282 100644 --- a/domain/consensus/processes/blockvalidator/proof_of_work.go +++ b/domain/consensus/processes/blockvalidator/proof_of_work.go @@ -15,12 +15,17 @@ func (v *blockValidator) ValidateProofOfWorkAndDifficulty(blockHash *externalapi return err } - err = v.checkProofOfWork(header) + err = v.checkParentsExist(header) if err != nil { return err } - err = v.checkParentsExist(header) + err = v.checkParentsIncest(header) + if err != nil { + return err + } + + err = v.checkProofOfWork(header) if err != nil { return err }