Skip to content

Instantly share code, notes, and snippets.

@brunoerg
Last active February 17, 2025 14:08
Show Gist options
  • Select an option

  • Save brunoerg/a004553327efbf766b289154ae6d777a to your computer and use it in GitHub Desktop.

Select an option

Save brunoerg/a004553327efbf766b289154ae6d777a to your computer and use it in GitHub Desktop.
Mutation testing weekly setup

Introduction

Mutation testing is software testing technique that introduces bugs (mutations) on the source code and verify if the automated tests are able to catch these bugs. I created mutation-core (a mutation testing tool) to perform mutation testing on Bitcoin Core codebase. It does not spend time by creating invalid mutants and can deal with some nuances of Bitcoin Core.

However, mutation testing is expensive since we have to compile and run the tests for every single mutant. That is, running mutation testing for every PR may be extremely costly. Instead, we could perform mutation testing once a week based on master branch and make it available for developers to check and decide to write better and/or more tests. That said, I have been doing it and publishing the reports at https://bitcoincore.space.

At this moment, I perform mutation testing for the following critical/more important code: src/wallet/coinselection.cpp, src/script/interpreter.cpp, src/consensus/tx_verify.cpp, src/consensus/tx_check.cpp, src/consensus/tx_verify.cpp, src/consensus/merkle.cpp, src/pow.cpp and src/addrman.cpp.

Setup

First...

cmake -B build

Then we create the mutants (where -f is the file):

mutation-core mutate -f="src/wallet/coinselection.cpp"
mutation-core mutate -f="src/script/interpreter.cpp"
mutation-core mutate -f="src/consensus/tx_verify.cpp"
mutation-core mutate -f="src/consensus/tx_check.cpp"
mutation-core mutate -f="src/consensus/merkle.cpp"
mutation-core mutate -f="src/pow.cpp"
mutation-core mutate -f="src/addrman.cpp"

Now we can perform the analysis:

mutation-core analyze -f="muts-coinselection-cpp" -c="cmake --build build -j 5 && ./build/src/test/test_bitcoin --run_test=coinselector_tests && ./build/src/test/test_bitcoin --run_test=spend_tests && ./build/test/functional/rpc_psbt.py && ./build/test/functional/wallet_fundrawtransaction.py"
mutation-core analyze -f="muts-interpreter-cpp" -c="cmake --build build -j 5 && ./build/src/test/test_bitcoin --run_test=script_tests && ./build/src/test/test_bitcoin --run_test=scriptnum_tests && ./build/src/test/test_bitcoin --run_test=script_p2sh_tests && ./build/src/test/test_bitcoin --run_test=script_parse_tests && ./build/src/test/test_bitcoin --run_test=script_p2sh_tests && ./build/src/test/test_bitcoin --run_test=script_standard_tests && ./build/test/functional/feature_segwit.py && ./build/test/functional/feature_taproot.py"
mutation-core analyze -f="muts-tx_verify-cpp" -c="cmake --build build -j 5 && ./build/src/test/test_bitcoin --run_test=miner_tests && ./build/src/test/test_bitcoin --run_test=sigopcount_tests && ./build/src/test/test_bitcoin --run_test=validation_tests && ./build/src/test/test_bitcoin --run_test=mempool_tests && ./build/test/functional/feature_block.py && ./build/test/functional/mining_basic.py && /build/test/functional/mempool_accept.py && ./build/test/functional/mempool_compatibility.py"
mutation-core analyze -f="muts-tx_check-cpp" -c="cmake --build build -j 5 &&  ./build/src/test/test_bitcoin --run_test=sighash_tests && ./build/src/test/test_bitcoin --run_test=transaction_tests && ./build/src/test/test_bitcoin --run_test=validation_tests && ./build/src/test/test_bitcoin --run_test=mempool_tests && ./build/test/functional/feature_block.py && ./build/test/functional/mining_basic.py && /build/test/functional/mempool_accept.py && ./build/test/functional/mempool_compatibility.py"
mutation-core analyze -f="muts-merkle-cpp" -c="cmake --build build -j 5 && ./build/src/test/test_bitcoin --run_test=validation_tests && ./build/src/test/test_bitcoin --run_test=merkle_tests && ./build/src/test/test_bitcoin --run_test=blockencodings_tests && ./build/src/test/test_bitcoin --run_test=validation_block_tests && ./build/src/test/test_bitcoin --run_test=miner_tests && ./build/test/functional/feature_block.py"
mutation-core analyze -f="muts-pow-cpp" -c="cmake --build build -j 5 && ./build/src/test/test_bitcoin --run_test=pow_tests  && ./build/src/test/test_bitcoin --run_test=headers_sync_chainwork_tests && ./build/test/functional/feature_block.py"
mutation-core analyze -f="muts-addrman-cpp" -c="cmake --build build -j 5 && ./build/src/test/test_bitcoin --run_test=addrman_tests && ./build/test/functional/feature_addrman.py && ./build/test/functional/feature_asmap.py && ./build/test/functional/rpc_net.py"

At the end, it will create a json file with the unkilled mutants. e.g.:

[
    {
        "filename": "src/wallet/coinselection.cpp",
        "mutation_score": 0.9090909090909091,
        "date": "12/02/2025 14:25:19",
        "diffs": [
            "diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.14.cpp\nindex 6e6d7e053b..95fd8c07d1 100644\n--- a/src/wallet/coinselection.cpp\n+++ b/muts-coinselection-cpp/coinselection.mutant.14.cpp\n@@ -128,7 +128,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool\n             curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch\n             (curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing\n             backtrack = true;\n-        } else if (curr_selection_weight > max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs\n+                } else if (curr_selection_weight >= max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs\n             max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight\n             backtrack = true;\n         } else if (curr_value >= selection_target) {       // Selected value is within range\n",
            "diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.11.cpp\nindex 6e6d7e053b..afe60acf40 100644\n--- a/src/wallet/coinselection.cpp\n+++ b/muts-coinselection-cpp/coinselection.mutant.11.cpp\n@@ -117,7 +117,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool\n     std::vector<size_t> best_selection;\n     CAmount best_waste = MAX_MONEY;\n \n-    bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;\n+        bool is_feerate_high = utxo_pool.at(0).fee >= utxo_pool.at(0).long_term_fee;\n     bool max_tx_weight_exceeded = false;\n \n     // Depth First search loop for choosing the UTXOs\n",
            "diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.30.cpp\nindex 6e6d7e053b..688dc0b496 100644\n--- a/src/wallet/coinselection.cpp\n+++ b/muts-coinselection-cpp/coinselection.mutant.30.cpp\n@@ -118,7 +118,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool\n     CAmount best_waste = MAX_MONEY;\n \n     bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;\n-    bool max_tx_weight_exceeded = false;\n+        bool max_tx_weight_exceeded = true;\n \n     // Depth First search loop for choosing the UTXOs\n     for (size_t curr_try = 0, utxo_pool_index = 0; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {\n"
        ]
    },
    {
        "filename": "src/pow.cpp",
        "mutation_score": 0.5054945054945055,
        "date": "12/02/2025 14:35:46",
        "diffs": [
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.85.cpp\nindex 686b177fe3..353ed3b88d 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.85.cpp\n@@ -161,7 +161,7 @@ std::optional<arith_uint256> DeriveTarget(unsigned int nBits, const uint256 pow_\n bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params& params)\n {\n     auto bnTarget{DeriveTarget(nBits, params.powLimit)};\n-    if (!bnTarget) return false;\n+    \n \n     // Check proof of work matches claimed amount\n     if (UintToArith256(hash) > bnTarget)\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.46.cpp\nindex 686b177fe3..26bc9b1b7a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.46.cpp\n@@ -92,7 +92,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n \n     if (height % params.DifficultyAdjustmentInterval() == 0) {\n         int64_t smallest_timespan = params.nPowTargetTimespan/4;\n-        int64_t largest_timespan = params.nPowTargetTimespan*4;\n+                int64_t largest_timespan = (params.nPowTargetTimespan*4) + 1;\n \n         const arith_uint256 pow_limit = UintToArith256(params.powLimit);\n         arith_uint256 observed_new_target;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.52.cpp\nindex 686b177fe3..f397b8c331 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.52.cpp\n@@ -104,7 +104,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         largest_difficulty_target *= largest_timespan;\n         largest_difficulty_target /= params.nPowTargetTimespan;\n \n-        if (largest_difficulty_target > pow_limit) {\n+                if (1==0) {\n             largest_difficulty_target = pow_limit;\n         }\n \n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.47.cpp\nindex 686b177fe3..caeafbe1dc 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.47.cpp\n@@ -92,7 +92,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n \n     if (height % params.DifficultyAdjustmentInterval() == 0) {\n         int64_t smallest_timespan = params.nPowTargetTimespan/4;\n-        int64_t largest_timespan = params.nPowTargetTimespan*4;\n+                int64_t largest_timespan = (params.nPowTargetTimespan*4) - 1;\n \n         const arith_uint256 pow_limit = UintToArith256(params.powLimit);\n         arith_uint256 observed_new_target;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.90.cpp\nindex 686b177fe3..404fdf1f98 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.90.cpp\n@@ -167,5 +167,5 @@ bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Par\n     if (UintToArith256(hash) > bnTarget)\n         return false;\n \n-    return true;\n+        return false;\n }\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.84.cpp\nindex 686b177fe3..2894ed091b 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.84.cpp\n@@ -161,7 +161,7 @@ std::optional<arith_uint256> DeriveTarget(unsigned int nBits, const uint256 pow_\n bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params& params)\n {\n     auto bnTarget{DeriveTarget(nBits, params.powLimit)};\n-    if (!bnTarget) return false;\n+        if (1==0) return false;\n \n     // Check proof of work matches claimed amount\n     if (UintToArith256(hash) > bnTarget)\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.79.cpp\nindex 686b177fe3..c192483042 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.79.cpp\n@@ -152,7 +152,7 @@ std::optional<arith_uint256> DeriveTarget(unsigned int nBits, const uint256 pow_\n     bnTarget.SetCompact(nBits, &fNegative, &fOverflow);\n \n     // Check range\n-    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(pow_limit))\n+        if (fNegative || bnTarget == 0 || fOverflow || bnTarget >= UintToArith256(pow_limit))\n         return {};\n \n     return bnTarget;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.44.cpp\nindex 686b177fe3..b4fc7f9144 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.44.cpp\n@@ -91,7 +91,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n     if (params.fPowAllowMinDifficultyBlocks) return true;\n \n     if (height % params.DifficultyAdjustmentInterval() == 0) {\n-        int64_t smallest_timespan = params.nPowTargetTimespan/4;\n+                int64_t smallest_timespan = (params.nPowTargetTimespan/4) + 1;\n         int64_t largest_timespan = params.nPowTargetTimespan*4;\n \n         const arith_uint256 pow_limit = UintToArith256(params.powLimit);\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.87.cpp\nindex 686b177fe3..fbb50731b4 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.87.cpp\n@@ -164,7 +164,7 @@ bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Par\n     if (!bnTarget) return false;\n \n     // Check proof of work matches claimed amount\n-    if (UintToArith256(hash) > bnTarget)\n+        if (UintToArith256(hash) >= bnTarget)\n         return false;\n \n     return true;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.83.cpp\nindex 686b177fe3..561af1daec 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.83.cpp\n@@ -161,7 +161,7 @@ std::optional<arith_uint256> DeriveTarget(unsigned int nBits, const uint256 pow_\n bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params& params)\n {\n     auto bnTarget{DeriveTarget(nBits, params.powLimit)};\n-    if (!bnTarget) return false;\n+        if (1==1) return false;\n \n     // Check proof of work matches claimed amount\n     if (UintToArith256(hash) > bnTarget)\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.41.cpp\nindex 686b177fe3..6f36d561be 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.41.cpp\n@@ -88,7 +88,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n // or decrease beyond the permitted limits.\n bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t height, uint32_t old_nbits, uint32_t new_nbits)\n {\n-    if (params.fPowAllowMinDifficultyBlocks) return true;\n+        if (1==0) return true;\n \n     if (height % params.DifficultyAdjustmentInterval() == 0) {\n         int64_t smallest_timespan = params.nPowTargetTimespan/4;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.42.cpp\nindex 686b177fe3..b7f6b7a1d5 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.42.cpp\n@@ -88,7 +88,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n // or decrease beyond the permitted limits.\n bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t height, uint32_t old_nbits, uint32_t new_nbits)\n {\n-    if (params.fPowAllowMinDifficultyBlocks) return true;\n+    \n \n     if (height % params.DifficultyAdjustmentInterval() == 0) {\n         int64_t smallest_timespan = params.nPowTargetTimespan/4;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.19.cpp\nindex 686b177fe3..08f63dbe91 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.19.cpp\n@@ -53,7 +53,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n         return pindexLast->nBits;\n \n     // Limit adjustment step\n-    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;\n+        int64_t nActualTimespan = (pindexLast->GetBlockTime() - nFirstBlockTime) + 1;\n     if (nActualTimespan < params.nPowTargetTimespan/4)\n         nActualTimespan = params.nPowTargetTimespan/4;\n     if (nActualTimespan > params.nPowTargetTimespan*4)\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.32.cpp\nindex 686b177fe3..a2183ad502 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.32.cpp\n@@ -64,7 +64,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n     arith_uint256 bnNew;\n \n     // Special difficulty rule for Testnet4\n-    if (params.enforce_BIP94) {\n+        if (1==0) {\n         // Here we use the first block of the difficulty period. This way\n         // the real difficulty is always preserved in the first block as\n         // it is not allowed to use the min-difficulty exception.\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.27.cpp\nindex 686b177fe3..cca87f690e 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.27.cpp\n@@ -56,7 +56,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n     int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;\n     if (nActualTimespan < params.nPowTargetTimespan/4)\n         nActualTimespan = params.nPowTargetTimespan/4;\n-    if (nActualTimespan > params.nPowTargetTimespan*4)\n+        if (nActualTimespan >= params.nPowTargetTimespan*4)\n         nActualTimespan = params.nPowTargetTimespan*4;\n \n     // Retarget\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.33.cpp\nindex 686b177fe3..f88563349a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.33.cpp\n@@ -68,7 +68,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n         // Here we use the first block of the difficulty period. This way\n         // the real difficulty is always preserved in the first block as\n         // it is not allowed to use the min-difficulty exception.\n-        int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);\n+                int nHeightFirst = pindexLast->nHeight + (params.DifficultyAdjustmentInterval()-1);\n         const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);\n         bnNew.SetCompact(pindexFirst->nBits);\n     } else {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.8.cpp\nindex 686b177fe3..3b7a149047 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.8.cpp\n@@ -24,7 +24,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n             // then allow mining of a min-difficulty block.\n-            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n+                        if (pblock->GetBlockTime() <= pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n                 return nProofOfWorkLimit;\n             else\n             {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.22.cpp\nindex 686b177fe3..93e42279f2 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.22.cpp\n@@ -54,7 +54,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n \n     // Limit adjustment step\n     int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;\n-    if (nActualTimespan < params.nPowTargetTimespan/4)\n+        if (nActualTimespan <= params.nPowTargetTimespan/4)\n         nActualTimespan = params.nPowTargetTimespan/4;\n     if (nActualTimespan > params.nPowTargetTimespan*4)\n         nActualTimespan = params.nPowTargetTimespan*4;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.9.cpp\nindex 686b177fe3..42ea1cbce5 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.9.cpp\n@@ -24,7 +24,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n             // then allow mining of a min-difficulty block.\n-            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n+                        if (pblock->GetBlockTime() > pindexLast->GetBlockTime() - params.nPowTargetSpacing*2)\n                 return nProofOfWorkLimit;\n             else\n             {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.20.cpp\nindex 686b177fe3..a989866713 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.20.cpp\n@@ -53,7 +53,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n         return pindexLast->nBits;\n \n     // Limit adjustment step\n-    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;\n+        int64_t nActualTimespan = (pindexLast->GetBlockTime() - nFirstBlockTime) - 1;\n     if (nActualTimespan < params.nPowTargetTimespan/4)\n         nActualTimespan = params.nPowTargetTimespan/4;\n     if (nActualTimespan > params.nPowTargetTimespan*4)\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.35.cpp\nindex 686b177fe3..68afe8c6c7 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.35.cpp\n@@ -78,7 +78,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n     bnNew *= nActualTimespan;\n     bnNew /= params.nPowTargetTimespan;\n \n-    if (bnNew > bnPowLimit)\n+        if (bnNew >= bnPowLimit)\n         bnNew = bnPowLimit;\n \n     return bnNew.GetCompact();\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.7.cpp\nindex 686b177fe3..4e03a6e392 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.7.cpp\n@@ -24,7 +24,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n             // then allow mining of a min-difficulty block.\n-            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n+                        if (pblock->GetBlockTime() >= pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n                 return nProofOfWorkLimit;\n             else\n             {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.10.cpp\nindex 686b177fe3..65aa226e99 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.10.cpp\n@@ -24,7 +24,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n             // then allow mining of a min-difficulty block.\n-            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n+                        if (pblock->GetBlockTime() > pindexLast->GetBlockTime() * params.nPowTargetSpacing*2)\n                 return nProofOfWorkLimit;\n             else\n             {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.11.cpp\nindex 686b177fe3..4b1a75cdac 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.11.cpp\n@@ -24,7 +24,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n             // then allow mining of a min-difficulty block.\n-            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n+                        if (pblock->GetBlockTime() > pindexLast->GetBlockTime() / params.nPowTargetSpacing*2)\n                 return nProofOfWorkLimit;\n             else\n             {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.39.cpp\nindex 686b177fe3..c8cccf8938 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.39.cpp\n@@ -88,7 +88,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF\n // or decrease beyond the permitted limits.\n bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t height, uint32_t old_nbits, uint32_t new_nbits)\n {\n-    if (params.fPowAllowMinDifficultyBlocks) return true;\n+        if (params.fPowAllowMinDifficultyBlocks) return false;\n \n     if (height % params.DifficultyAdjustmentInterval() == 0) {\n         int64_t smallest_timespan = params.nPowTargetTimespan/4;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.6.cpp\nindex 686b177fe3..946babb8f2 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.6.cpp\n@@ -24,7 +24,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n             // then allow mining of a min-difficulty block.\n-            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n+                        if (pblock->GetBlockTime() < pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)\n                 return nProofOfWorkLimit;\n             else\n             {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.4.cpp\nindex 686b177fe3..05813fba8a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.4.cpp\n@@ -19,7 +19,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     // Only change once per difficulty adjustment interval\n     if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)\n     {\n-        if (params.fPowAllowMinDifficultyBlocks)\n+                if (1==1)\n         {\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.13.cpp\nindex 686b177fe3..92e9a92800 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.13.cpp\n@@ -30,7 +30,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             {\n                 // Return the last non-special-min-difficulty-rules-block\n                 const CBlockIndex* pindex = pindexLast;\n-                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)\n+                                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits != nProofOfWorkLimit)\n                     pindex = pindex->pprev;\n                 return pindex->nBits;\n             }\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.12.cpp\nindex 686b177fe3..b819b2ca54 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.12.cpp\n@@ -30,7 +30,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             {\n                 // Return the last non-special-min-difficulty-rules-block\n                 const CBlockIndex* pindex = pindexLast;\n-                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)\n+                                while (pindex->pprev || pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 || pindex->nBits == nProofOfWorkLimit)\n                     pindex = pindex->pprev;\n                 return pindex->nBits;\n             }\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.5.cpp\nindex 686b177fe3..94192bec71 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.5.cpp\n@@ -19,7 +19,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     // Only change once per difficulty adjustment interval\n     if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)\n     {\n-        if (params.fPowAllowMinDifficultyBlocks)\n+                if (1==0)\n         {\n             // Special difficulty rule for testnet:\n             // If the new block's timestamp is more than 2* 10 minutes\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.1.cpp\nindex 686b177fe3..00a11bbf3a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.1.cpp\n@@ -17,7 +17,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();\n \n     // Only change once per difficulty adjustment interval\n-    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)\n+        if ((pindexLast->nHeight-1) % params.DifficultyAdjustmentInterval() != 0)\n     {\n         if (params.fPowAllowMinDifficultyBlocks)\n         {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.17.cpp\nindex 686b177fe3..af077530a0 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.17.cpp\n@@ -49,7 +49,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n \n unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)\n {\n-    if (params.fPowNoRetargeting)\n+        if (1==0)\n         return pindexLast->nBits;\n \n     // Limit adjustment step\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.0.cpp\nindex 686b177fe3..1d5e0380b6 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.0.cpp\n@@ -17,7 +17,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();\n \n     // Only change once per difficulty adjustment interval\n-    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)\n+        if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() == 0)\n     {\n         if (params.fPowAllowMinDifficultyBlocks)\n         {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.2.cpp\nindex 686b177fe3..66433d1355 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.2.cpp\n@@ -17,7 +17,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();\n \n     // Only change once per difficulty adjustment interval\n-    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)\n+        if ((pindexLast->nHeight*1) % params.DifficultyAdjustmentInterval() != 0)\n     {\n         if (params.fPowAllowMinDifficultyBlocks)\n         {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.15.cpp\nindex 686b177fe3..f5a42b47fe 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.15.cpp\n@@ -39,7 +39,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     }\n \n     // Go back by what we want to be 14 days worth of blocks\n-    int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);\n+        int nHeightFirst = pindexLast->nHeight + (params.DifficultyAdjustmentInterval()-1);\n     assert(nHeightFirst >= 0);\n     const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);\n     assert(pindexFirst);\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.14.cpp\nindex 686b177fe3..d306dd7a4a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.14.cpp\n@@ -30,7 +30,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n             {\n                 // Return the last non-special-min-difficulty-rules-block\n                 const CBlockIndex* pindex = pindexLast;\n-                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)\n+                                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() == 0 && pindex->nBits == nProofOfWorkLimit)\n                     pindex = pindex->pprev;\n                 return pindex->nBits;\n             }\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.3.cpp\nindex 686b177fe3..6dd94f8650 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.3.cpp\n@@ -17,7 +17,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead\n     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();\n \n     // Only change once per difficulty adjustment interval\n-    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)\n+        if ((pindexLast->nHeight/1) % params.DifficultyAdjustmentInterval() != 0)\n     {\n         if (params.fPowAllowMinDifficultyBlocks)\n         {\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.73.cpp\nindex 686b177fe3..d7d93d95cf 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.73.cpp\n@@ -129,7 +129,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         arith_uint256 minimum_new_target;\n         minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact());\n         if (minimum_new_target > observed_new_target) return false;\n-    } else if (old_nbits != new_nbits) {\n+        } else if (1==1) {\n         return false;\n     }\n     return true;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.72.cpp\nindex 686b177fe3..b5e021f527 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.72.cpp\n@@ -129,7 +129,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         arith_uint256 minimum_new_target;\n         minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact());\n         if (minimum_new_target > observed_new_target) return false;\n-    } else if (old_nbits != new_nbits) {\n+        } else if (old_nbits == new_nbits) {\n         return false;\n     }\n     return true;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.64.cpp\nindex 686b177fe3..11dbf32fc8 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.64.cpp\n@@ -120,7 +120,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         smallest_difficulty_target *= smallest_timespan;\n         smallest_difficulty_target /= params.nPowTargetTimespan;\n \n-        if (smallest_difficulty_target > pow_limit) {\n+                if (1==0) {\n             smallest_difficulty_target = pow_limit;\n         }\n \n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.75.cpp\nindex 686b177fe3..1429707f57 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.75.cpp\n@@ -130,7 +130,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact());\n         if (minimum_new_target > observed_new_target) return false;\n     } else if (old_nbits != new_nbits) {\n-        return false;\n+                return true;\n     }\n     return true;\n }\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.61.cpp\nindex 686b177fe3..7d594f957a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.61.cpp\n@@ -120,7 +120,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         smallest_difficulty_target *= smallest_timespan;\n         smallest_difficulty_target /= params.nPowTargetTimespan;\n \n-        if (smallest_difficulty_target > pow_limit) {\n+                if (smallest_difficulty_target >= pow_limit) {\n             smallest_difficulty_target = pow_limit;\n         }\n \n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.49.cpp\nindex 686b177fe3..b695e0d71f 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.49.cpp\n@@ -104,7 +104,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         largest_difficulty_target *= largest_timespan;\n         largest_difficulty_target /= params.nPowTargetTimespan;\n \n-        if (largest_difficulty_target > pow_limit) {\n+                if (largest_difficulty_target >= pow_limit) {\n             largest_difficulty_target = pow_limit;\n         }\n \n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.74.cpp\nindex 686b177fe3..674dbe5e5a 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.74.cpp\n@@ -129,7 +129,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n         arith_uint256 minimum_new_target;\n         minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact());\n         if (minimum_new_target > observed_new_target) return false;\n-    } else if (old_nbits != new_nbits) {\n+        } else if (1==0) {\n         return false;\n     }\n     return true;\n",
            "diff --git a/src/pow.cpp b/muts-pow-cpp/pow.mutant.77.cpp\nindex 686b177fe3..167bf94467 100644\n--- a/src/pow.cpp\n+++ b/muts-pow-cpp/pow.mutant.77.cpp\n@@ -139,7 +139,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig\n // the most significant bit of the last byte of the hash is set.\n bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)\n {\n-    if constexpr (G_FUZZING) return (hash.data()[31] & 0x80) == 0;\n+        if constexpr (G_FUZZING) return (hash.data()[31] & 0x80) != 0;\n     return CheckProofOfWorkImpl(hash, nBits, params);\n }\n \n"
        ]
    },
    ...
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment