]> Untitled Git - bdk/commitdiff
Add unit test required not enough
authorTobin Harding <me@tobin.cc>
Fri, 23 Jul 2021 00:27:16 +0000 (10:27 +1000)
committerTobin Harding <me@tobin.cc>
Fri, 23 Jul 2021 00:27:16 +0000 (10:27 +1000)
Add a unit test that passes a required utxo to the coin selection
algorithm that is less than the required spend. This tests that we get
that utxo included as well as tests that the rest of the coin selection
algorithm code also executes (i.e., that we do not short circuit
incorrectly).

src/wallet/coin_selection.rs

index 1dcc2c9e85cdcefaa7821b941f353e8df79f4650..41e83da976115b81cd6ed084a7d575f4cdd0c7f2 100644 (file)
@@ -557,50 +557,31 @@ mod test {
 
     const FEE_AMOUNT: f32 = 50.0;
 
+    fn utxo(value: u64, index: u32) -> WeightedUtxo {
+        assert!(index < 10);
+        let outpoint = OutPoint::from_str(&format!(
+            "000000000000000000000000000000000000000000000000000000000000000{}:0",
+            index
+        ))
+        .unwrap();
+        WeightedUtxo {
+            satisfaction_weight: P2WPKH_WITNESS_SIZE,
+            utxo: Utxo::Local(LocalUtxo {
+                outpoint,
+                txout: TxOut {
+                    value,
+                    script_pubkey: Script::new(),
+                },
+                keychain: KeychainKind::External,
+            }),
+        }
+    }
+
     fn get_test_utxos() -> Vec<WeightedUtxo> {
         vec![
-            WeightedUtxo {
-                satisfaction_weight: P2WPKH_WITNESS_SIZE,
-                utxo: Utxo::Local(LocalUtxo {
-                    outpoint: OutPoint::from_str(
-                        "0000000000000000000000000000000000000000000000000000000000000000:0",
-                    )
-                    .unwrap(),
-                    txout: TxOut {
-                        value: 100_000,
-                        script_pubkey: Script::new(),
-                    },
-                    keychain: KeychainKind::External,
-                }),
-            },
-            WeightedUtxo {
-                satisfaction_weight: P2WPKH_WITNESS_SIZE,
-                utxo: Utxo::Local(LocalUtxo {
-                    outpoint: OutPoint::from_str(
-                        "0000000000000000000000000000000000000000000000000000000000000001:0",
-                    )
-                    .unwrap(),
-                    txout: TxOut {
-                        value: FEE_AMOUNT as u64 - 40,
-                        script_pubkey: Script::new(),
-                    },
-                    keychain: KeychainKind::External,
-                }),
-            },
-            WeightedUtxo {
-                satisfaction_weight: P2WPKH_WITNESS_SIZE,
-                utxo: Utxo::Local(LocalUtxo {
-                    outpoint: OutPoint::from_str(
-                        "0000000000000000000000000000000000000000000000000000000000000002:0",
-                    )
-                    .unwrap(),
-                    txout: TxOut {
-                        value: 200_000,
-                        script_pubkey: Script::new(),
-                    },
-                    keychain: KeychainKind::Internal,
-                }),
-            },
+            utxo(100_000, 0),
+            utxo(FEE_AMOUNT as u64 - 40, 1),
+            utxo(200_000, 2),
         ]
     }
 
@@ -817,6 +798,37 @@ mod test {
         assert!((result.fee_amount - 254.0).abs() < f32::EPSILON);
     }
 
+    #[test]
+    fn test_bnb_coin_selection_required_not_enough() {
+        let utxos = get_test_utxos();
+        let database = MemoryDatabase::default();
+
+        let required = vec![utxos[0].clone()];
+        let mut optional = utxos[1..].to_vec();
+        optional.push(utxo(500_000, 3));
+
+        // Defensive assertions, for sanity and in case someone changes the test utxos vector.
+        let amount: u64 = required.iter().map(|u| u.utxo.txout().value).sum();
+        assert_eq!(amount, 100_000);
+        let amount: u64 = optional.iter().map(|u| u.utxo.txout().value).sum();
+        assert!(amount > 150_000);
+
+        let result = BranchAndBoundCoinSelection::default()
+            .coin_select(
+                &database,
+                required,
+                optional,
+                FeeRate::from_sat_per_vb(1.0),
+                150_000,
+                FEE_AMOUNT,
+            )
+            .unwrap();
+
+        assert_eq!(result.selected.len(), 3);
+        assert_eq!(result.selected_amount(), 300_010);
+        assert!((result.fee_amount - 254.0).abs() < f32::EPSILON);
+    }
+
     #[test]
     #[should_panic(expected = "InsufficientFunds")]
     fn test_bnb_coin_selection_insufficient_funds() {