Skip to content

Instantly share code, notes, and snippets.

@brunoerg
Created September 17, 2024 18:20
Show Gist options
  • Select an option

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

Select an option

Save brunoerg/834063398d5002f738506d741513e310 to your computer and use it in GitHub Desktop.
Mutation testing for #29532

Mutation testing - #29532

  • 64 mutants were generated for the Branch and Bound function.
  • coinselector_tests mutation score: 84.37%
  • coinselection_tests mutation score: 84.37%

Mutants not killed by coinselection_tests:

diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.14.cpp
index cee558088f..947bf7b642 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.14.cpp
@@ -118,7 +118,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     CAmount best_waste = MAX_MONEY;
 
     bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
-    bool max_tx_weight_exceeded = false;
+    bool max_tx_weight_exceeded = true;
 
     // Depth First search loop for choosing the UTXOs
     for (size_t curr_try = 0, utxo_pool_index = 0; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.17.cpp
index cee558088f..b99220fd05 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.17.cpp
@@ -121,7 +121,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     bool max_tx_weight_exceeded = false;
 
     // Depth First search loop for choosing the UTXOs
-    for (size_t curr_try = 0, utxo_pool_index = 0; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
+    for (size_t curr_try = 0, utxo_pool_index = 0; curr_try <= TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
         // Conditions for starting a backtrack
         bool backtrack = false;
         if (curr_value + curr_available_value < selection_target || // Cannot possibly reach target with the amount remaining in the curr_available_value.
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.12.cpp
index cee558088f..a10f510bb3 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.12.cpp
@@ -117,7 +117,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     std::vector<size_t> best_selection;
     CAmount best_waste = MAX_MONEY;
 
-    bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
+    bool is_feerate_high = utxo_pool.at(0).fee >= utxo_pool.at(0).long_term_fee;
     bool max_tx_weight_exceeded = false;
 
     // Depth First search loop for choosing the UTXOs
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.39.cpp
index cee558088f..bbfdc23889 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.39.cpp
@@ -129,7 +129,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
             (curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
             backtrack = true;
         } else if (curr_selection_weight > max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
-            max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight
+            max_tx_weight_exceeded = false; // at least one selection attempt exceeded the max weight
             backtrack = true;
         } else if (curr_value >= selection_target) {       // Selected value is within range
             curr_waste += (curr_value - selection_target); // This is the excess value which is added to the waste for the below comparison
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.63.cpp
index cee558088f..d7f9b28d1d 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.63.cpp
@@ -180,7 +180,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
                 curr_selection.push_back(utxo_pool_index);
                 curr_value += utxo.GetSelectionAmount();
                 curr_waste += utxo.fee - utxo.long_term_fee;
-                curr_selection_weight += utxo.m_weight;
+                                curr_selection_weight -= utxo.m_weight;
             }
         }
     }
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.59.cpp
index cee558088f..e5c903aec8 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.59.cpp
@@ -174,7 +174,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
                 // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded.
                 // Since the ratio of fee to long term fee is the same, we only need to check if one of those values match in order to know that the waste is the same.
                 utxo.GetSelectionAmount() != utxo_pool.at(utxo_pool_index - 1).GetSelectionAmount() ||
-                utxo.fee != utxo_pool.at(utxo_pool_index - 1).fee)
+                                utxo.fee != utxo_pool.at(utxo_pool_index + 1).fee)
             {
                 // Inclusion branch first (Largest First Exploration)
                 curr_selection.push_back(utxo_pool_index);
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.40.cpp
index cee558088f..a6e1e5a834 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.40.cpp
@@ -130,7 +130,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
             backtrack = true;
         } else if (curr_selection_weight > max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
             max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight
-            backtrack = true;
+            backtrack = false;
         } else if (curr_value >= selection_target) {       // Selected value is within range
             curr_waste += (curr_value - selection_target); // This is the excess value which is added to the waste for the below comparison
             // Adding another UTXO after this check could bring the waste down if the long term fee is higher than the current fee.
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.2.cpp
index cee558088f..ac38003bc3 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.2.cpp
@@ -99,7 +99,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     int curr_selection_weight = 0; // sum of selected utxo weight
 
     // Calculate curr_available_value
-    CAmount curr_available_value = 0;
+    CAmount curr_available_value = 0 + 1;
     for (const OutputGroup& utxo : utxo_pool) {
         // Assert that this utxo is not negative. It should never be negative,
         // effective value calculation should have removed it
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.37.cpp
index cee558088f..9747cd26c9 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.37.cpp
@@ -128,7 +128,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
             curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch
             (curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
             backtrack = true;
-        } else if (curr_selection_weight > max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
+        } else if (curr_selection_weight >= max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
             max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight
             backtrack = true;
         } else if (curr_value >= selection_target) {       // Selected value is within range
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.32.cpp
index cee558088f..44d26c29f9 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.32.cpp
@@ -126,7 +126,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
         bool backtrack = false;
         if (curr_value + curr_available_value < selection_target || // Cannot possibly reach target with the amount remaining in the curr_available_value.
             curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch
-            (curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
+            (curr_waste >= best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
             backtrack = true;
         } else if (curr_selection_weight > max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
             max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight

Mutants not killed by coinselector_tests:

diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.14.cpp
index cee558088f..947bf7b642 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.14.cpp
@@ -118,7 +118,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     CAmount best_waste = MAX_MONEY;
 
     bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
-    bool max_tx_weight_exceeded = false;
+    bool max_tx_weight_exceeded = true;
 
     // Depth First search loop for choosing the UTXOs
     for (size_t curr_try = 0, utxo_pool_index = 0; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.17.cpp
index cee558088f..b99220fd05 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.17.cpp
@@ -121,7 +121,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     bool max_tx_weight_exceeded = false;
 
     // Depth First search loop for choosing the UTXOs
-    for (size_t curr_try = 0, utxo_pool_index = 0; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
+    for (size_t curr_try = 0, utxo_pool_index = 0; curr_try <= TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
         // Conditions for starting a backtrack
         bool backtrack = false;
         if (curr_value + curr_available_value < selection_target || // Cannot possibly reach target with the amount remaining in the curr_available_value.
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.12.cpp
index cee558088f..a10f510bb3 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.12.cpp
@@ -117,7 +117,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     std::vector<size_t> best_selection;
     CAmount best_waste = MAX_MONEY;
 
-    bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
+    bool is_feerate_high = utxo_pool.at(0).fee >= utxo_pool.at(0).long_term_fee;
     bool max_tx_weight_exceeded = false;
 
     // Depth First search loop for choosing the UTXOs
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.13.cpp
index cee558088f..3e679e6924 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.13.cpp
@@ -117,7 +117,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     std::vector<size_t> best_selection;
     CAmount best_waste = MAX_MONEY;
 
-    bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
+    bool is_feerate_high = utxo_pool.at(0).fee <= utxo_pool.at(0).long_term_fee;
     bool max_tx_weight_exceeded = false;
 
     // Depth First search loop for choosing the UTXOs
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.11.cpp
index cee558088f..9a9c85256c 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.11.cpp
@@ -117,7 +117,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
     std::vector<size_t> best_selection;
     CAmount best_waste = MAX_MONEY;
 
-    bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
+    bool is_feerate_high = utxo_pool.at(0).fee < utxo_pool.at(0).long_term_fee;
     bool max_tx_weight_exceeded = false;
 
     // Depth First search loop for choosing the UTXOs
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.58.cpp
index cee558088f..b1e9f5f7b9 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.58.cpp
@@ -174,7 +174,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
                 // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded.
                 // Since the ratio of fee to long term fee is the same, we only need to check if one of those values match in order to know that the waste is the same.
                 utxo.GetSelectionAmount() != utxo_pool.at(utxo_pool_index - 1).GetSelectionAmount() ||
-                utxo.fee != utxo_pool.at(utxo_pool_index - 1).fee)
+                utxo.fee == utxo_pool.at(utxo_pool_index - 1).fee)
             {
                 // Inclusion branch first (Largest First Exploration)
                 curr_selection.push_back(utxo_pool_index);
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.56.cpp
index cee558088f..3bbedea387 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.56.cpp
@@ -173,7 +173,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
                 (utxo_pool_index - 1) == curr_selection.back() ||
                 // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded.
                 // Since the ratio of fee to long term fee is the same, we only need to check if one of those values match in order to know that the waste is the same.
-                utxo.GetSelectionAmount() != utxo_pool.at(utxo_pool_index - 1).GetSelectionAmount() ||
+                utxo.GetSelectionAmount() == utxo_pool.at(utxo_pool_index - 1).GetSelectionAmount() ||
                 utxo.fee != utxo_pool.at(utxo_pool_index - 1).fee)
             {
                 // Inclusion branch first (Largest First Exploration)
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.55.cpp
index cee558088f..c93b930da6 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.55.cpp
@@ -170,7 +170,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
 
             if (curr_selection.empty() ||
                 // The previous index is included and therefore not relevant for exclusion shortcut
-                (utxo_pool_index - 1) == curr_selection.back() ||
+                (utxo_pool_index + 1) == curr_selection.back() ||
                 // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded.
                 // Since the ratio of fee to long term fee is the same, we only need to check if one of those values match in order to know that the waste is the same.
                 utxo.GetSelectionAmount() != utxo_pool.at(utxo_pool_index - 1).GetSelectionAmount() ||
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.54.cpp
index cee558088f..aef485be75 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.54.cpp
@@ -170,7 +170,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
 
             if (curr_selection.empty() ||
                 // The previous index is included and therefore not relevant for exclusion shortcut
-                (utxo_pool_index - 1) == curr_selection.back() ||
+                (utxo_pool_index - 1) != curr_selection.back() ||
                 // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded.
                 // Since the ratio of fee to long term fee is the same, we only need to check if one of those values match in order to know that the waste is the same.
                 utxo.GetSelectionAmount() != utxo_pool.at(utxo_pool_index - 1).GetSelectionAmount() ||
diff --git a/src/wallet/coinselection.cpp b/muts/coinselection.mutant.37.cpp
index cee558088f..9747cd26c9 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts/coinselection.mutant.37.cpp
@@ -128,7 +128,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
             curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch
             (curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
             backtrack = true;
-        } else if (curr_selection_weight > max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
+        } else if (curr_selection_weight >= max_selection_weight) { // Selected UTXOs weight exceeds the maximum weight allowed, cannot find more solutions by adding more inputs
             max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight
             backtrack = true;
         } else if (curr_value >= selection_target) {       // Selected value is within range
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment