diff --git a/domain/consensus/processes/blockvalidator/proof_of_work_test.go b/domain/consensus/processes/blockvalidator/proof_of_work_test.go new file mode 100644 index 000000000..451e5e06b --- /dev/null +++ b/domain/consensus/processes/blockvalidator/proof_of_work_test.go @@ -0,0 +1,70 @@ +package blockvalidator_test + +import ( + "github.com/kaspanet/kaspad/domain/consensus/model/pow" + "github.com/kaspanet/kaspad/domain/consensus/ruleerrors" + "github.com/kaspanet/kaspad/domain/consensus/utils/mining" + "github.com/kaspanet/kaspad/util" + "math" + "math/rand" + + "testing" + + "github.com/kaspanet/kaspad/domain/consensus" + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "github.com/kaspanet/kaspad/domain/consensus/utils/testutils" + "github.com/kaspanet/kaspad/domain/dagconfig" + "github.com/pkg/errors" +) + +// TestPOW tests the validation of the block's POW. +func TestPOW(t *testing.T) { + // We set the flag "skip pow" to be false (second argument in the function) for not skipping the check of POW and validate its correctness. + testutils.ForAllNets(t, false, func(t *testing.T, params *dagconfig.Params) { + factory := consensus.NewFactory() + tc, teardown, err := factory.NewTestConsensus(params, false, "TestPOW") + if err != nil { + t.Fatalf("Error setting up consensus: %+v", err) + } + defer teardown(false) + + // Builds and checks block with invalid POW. + invalidBlockWrongPOW, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, nil, nil) + if err != nil { + t.Fatal(err) + } + invalidBlockWrongPOW = solveBlockWithWrongPOW(invalidBlockWrongPOW) + _, err = tc.ValidateAndInsertBlock(invalidBlockWrongPOW) + if !errors.Is(err, ruleerrors.ErrInvalidPoW) { + t.Fatalf("Expected block to be invalid with err: %v, instead found: %v", ruleerrors.ErrInvalidPoW, err) + } + + // test on a valid block. + validBlock, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, nil, nil) + if err != nil { + t.Fatal(err) + } + random := rand.New(rand.NewSource(0)) + mining.SolveBlock(validBlock, random) + _, err = tc.ValidateAndInsertBlock(validBlock) + if err != nil { + t.Fatal(err) + } + }) +} + +// solveBlockWithWrongPOW increments the given block's nonce until it gets wrong POW (for test!). +func solveBlockWithWrongPOW(block *externalapi.DomainBlock) *externalapi.DomainBlock { + targetDifficulty := util.CompactToBig(block.Header.Bits()) + headerForMining := block.Header.ToMutable() + initialNonce := uint64(0) + for i := initialNonce; i < math.MaxUint64; i++ { + headerForMining.SetNonce(i) + if !pow.CheckProofOfWorkWithTarget(headerForMining, targetDifficulty) { + block.Header = headerForMining.ToImmutable() + return block + } + } + + panic("Failed to solve block! cannot find a invalid POW for the test") +} diff --git a/domain/consensus/processes/dagtraversalmanager/window_test.go b/domain/consensus/processes/dagtraversalmanager/window_test.go index 0d0016aee..e62c52e61 100644 --- a/domain/consensus/processes/dagtraversalmanager/window_test.go +++ b/domain/consensus/processes/dagtraversalmanager/window_test.go @@ -130,37 +130,37 @@ func TestBlueBlockWindow(t *testing.T) { { parents: []string{"H", "F"}, id: "I", - expectedWindowWithGenesisPadding: []string{"F", "C", "H", "D", "G", "B", "A", "A", "A", "A"}, + expectedWindowWithGenesisPadding: []string{"F", "H", "C", "D", "B", "G", "A", "A", "A", "A"}, }, { parents: []string{"I"}, id: "J", - expectedWindowWithGenesisPadding: []string{"I", "F", "C", "H", "D", "G", "B", "A", "A", "A"}, + expectedWindowWithGenesisPadding: []string{"I", "F", "H", "C", "D", "B", "G", "A", "A", "A"}, }, { parents: []string{"J"}, id: "K", - expectedWindowWithGenesisPadding: []string{"J", "I", "F", "C", "H", "D", "G", "B", "A", "A"}, + expectedWindowWithGenesisPadding: []string{"J", "I", "F", "H", "C", "D", "B", "G", "A", "A"}, }, { parents: []string{"K"}, id: "L", - expectedWindowWithGenesisPadding: []string{"K", "J", "I", "F", "C", "H", "D", "G", "B", "A"}, + expectedWindowWithGenesisPadding: []string{"K", "J", "I", "F", "H", "C", "D", "B", "G", "A"}, }, { parents: []string{"L"}, id: "M", - expectedWindowWithGenesisPadding: []string{"L", "K", "J", "I", "F", "C", "H", "D", "G", "B"}, + expectedWindowWithGenesisPadding: []string{"L", "K", "J", "I", "F", "H", "C", "D", "B", "G"}, }, { parents: []string{"M"}, id: "N", - expectedWindowWithGenesisPadding: []string{"M", "L", "K", "J", "I", "F", "C", "H", "D", "G"}, + expectedWindowWithGenesisPadding: []string{"M", "L", "K", "J", "I", "F", "H", "C", "D", "B"}, }, { parents: []string{"N"}, id: "O", - expectedWindowWithGenesisPadding: []string{"N", "M", "L", "K", "J", "I", "F", "C", "H", "D"}, + expectedWindowWithGenesisPadding: []string{"N", "M", "L", "K", "J", "I", "F", "H", "C", "D"}, }, }, "kaspa-devnet": { diff --git a/domain/consensus/processes/pruningmanager/pruning_test.go b/domain/consensus/processes/pruningmanager/pruning_test.go index 99770c47a..94071618a 100644 --- a/domain/consensus/processes/pruningmanager/pruning_test.go +++ b/domain/consensus/processes/pruningmanager/pruning_test.go @@ -33,10 +33,10 @@ func TestPruning(t *testing.T) { "kaspa-testnet": "1582", }, "dag-for-test-pruning.json": { - "kaspa-mainnet": "502", + "kaspa-mainnet": "503", "kaspa-simnet": "502", "kaspa-devnet": "503", - "kaspa-testnet": "502", + "kaspa-testnet": "503", }, } diff --git a/domain/dagconfig/genesis.go b/domain/dagconfig/genesis.go index b27189c00..d91ad274c 100644 --- a/domain/dagconfig/genesis.go +++ b/domain/dagconfig/genesis.go @@ -30,10 +30,10 @@ var genesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0, []*externa // genesisHash is the hash of the first block in the block DAG for the main // network (genesis block). var genesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ - 0xbf, 0x07, 0x16, 0x75, 0x1e, 0x62, 0x3b, 0xbe, - 0x18, 0xab, 0x1e, 0x79, 0x09, 0xe6, 0x48, 0x5c, - 0x1b, 0xaf, 0x03, 0x08, 0x25, 0x3c, 0xb9, 0xf5, - 0x22, 0xd2, 0x9d, 0xa6, 0x4d, 0xd1, 0x01, 0xc0, + 0x92, 0x29, 0x3c, 0xbd, 0x65, 0xa8, 0x6d, 0x9c, + 0xc1, 0xb2, 0x8f, 0x63, 0xc9, 0x2a, 0x50, 0x90, + 0x28, 0xe7, 0x45, 0x57, 0x1d, 0xdc, 0xc2, 0xcd, + 0xdd, 0x9b, 0x99, 0x4c, 0x22, 0xc6, 0x21, 0x89, }) // genesisMerkleRoot is the hash of the first transaction in the genesis block @@ -54,9 +54,9 @@ var genesisBlock = externalapi.DomainBlock{ genesisMerkleRoot, &externalapi.DomainHash{}, &externalapi.DomainHash{}, - 0x176c86a5bac, + 0x176eb9ddaf4, 0x207fffff, - 0x3, + 0x0, ), Transactions: []*externalapi.DomainTransaction{genesisCoinbaseTx}, } @@ -182,10 +182,10 @@ var testnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0, // testnetGenesisHash is the hash of the first block in the block DAG for the test // network (genesis block). var testnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ - 0x5a, 0x22, 0xf5, 0x2e, 0x87, 0x5b, 0xc2, 0xf2, - 0x9d, 0xbb, 0xa7, 0xc1, 0xf6, 0x0a, 0x81, 0xde, - 0xfa, 0x1e, 0xbc, 0x87, 0x8a, 0x37, 0x20, 0xac, - 0xc6, 0x6d, 0x1f, 0x49, 0x9b, 0x0b, 0xe7, 0xe0, + 0x5d, 0xb7, 0x49, 0xc1, 0x6e, 0xfb, 0x4e, 0x7a, + 0x0c, 0x9f, 0xd1, 0x80, 0x74, 0x91, 0x60, 0xd0, + 0x1b, 0x84, 0xc7, 0x92, 0xa8, 0x5f, 0xcf, 0x9b, + 0x1d, 0x8c, 0x8c, 0x34, 0xa9, 0x41, 0x5f, 0xa5, }) // testnetGenesisMerkleRoot is the hash of the first transaction in the genesis block @@ -206,9 +206,9 @@ var testnetGenesisBlock = externalapi.DomainBlock{ testnetGenesisMerkleRoot, &externalapi.DomainHash{}, &externalapi.DomainHash{}, - 0x176c86a5c26, + 0x176eb9ddb6d, 0x1e7fffff, - 0x18cbd, + 0x5dba6, ), Transactions: []*externalapi.DomainTransaction{testnetGenesisCoinbaseTx}, }