@@ -6,7 +6,6 @@ use bdk::wallet::coin_selection::LargestFirstCoinSelection;
66use  bdk:: wallet:: AddressIndex :: * ; 
77use  bdk:: wallet:: { AddressIndex ,  AddressInfo ,  Balance ,  Wallet } ; 
88use  bdk:: { Error ,  FeeRate ,  KeychainKind } ; 
9- use  bdk_chain:: tx_graph:: CalculateFeeError ; 
109use  bdk_chain:: COINBASE_MATURITY ; 
1110use  bdk_chain:: { BlockId ,  ConfirmationTime } ; 
1211use  bitcoin:: hashes:: Hash ; 
@@ -84,63 +83,60 @@ fn test_descriptor_checksum() {
8483#[ test]  
8584fn  test_get_funded_wallet_balance ( )  { 
8685    let  ( wallet,  _)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
87-     assert_eq ! ( wallet. get_balance( ) . confirmed,  50000 ) ; 
86+ 
87+     // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 
88+     // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 
89+     // sats are the transaction fee. 
90+     assert_eq ! ( wallet. get_balance( ) . confirmed,  50_000 ) ; 
8891} 
8992
9093#[ test]  
9194fn  test_get_funded_wallet_sent_and_received ( )  { 
92-     let  ( wallet,  _ )  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
93-      assert_eq ! ( wallet . get_balance ( ) . confirmed ,   50000 ) ; 
95+     let  ( wallet,  txid )  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
96+ 
9497    let  mut  tx_amounts:  Vec < ( Txid ,  ( u64 ,  u64 ) ) >  = wallet
9598        . transactions ( ) 
96-         . map ( |ct| ( ct. node . txid ,  wallet. sent_and_received ( ct. node . tx ) ) ) 
99+         . map ( |ct| ( ct. tx_node . txid ,  wallet. sent_and_received ( ct. tx_node . tx ) ) ) 
97100        . collect ( ) ; 
98101    tx_amounts. sort_by ( |a1,  a2| a1. 0 . cmp ( & a2. 0 ) ) ; 
99102
100-     assert_eq ! ( tx_amounts. len( ) ,  2 ) ; 
101-     assert_matches ! ( tx_amounts. get( 0 ) ,  Some ( ( _,  ( 76_000 ,  50_000 ) ) ) ) 
103+     let  tx = wallet. get_tx ( txid) . expect ( "transaction" ) . tx_node . tx ; 
104+     let  ( sent,  received)  = wallet. sent_and_received ( tx) ; 
105+ 
106+     // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 
107+     // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 
108+     // sats are the transaction fee. 
109+     assert_eq ! ( sent,  76_000 ) ; 
110+     assert_eq ! ( received,  50_000 ) ; 
102111} 
103112
104113#[ test]  
105114fn  test_get_funded_wallet_tx_fees ( )  { 
106-     let  ( wallet,  _)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
107-     assert_eq ! ( wallet. get_balance( ) . confirmed,  50000 ) ; 
108-     let  mut  tx_fee_amounts:  Vec < ( Txid ,  Result < u64 ,  CalculateFeeError > ) >  = wallet
109-         . transactions ( ) 
110-         . map ( |ct| { 
111-             let  fee = wallet. calculate_fee ( ct. node . tx ) ; 
112-             ( ct. node . txid ,  fee) 
113-         } ) 
114-         . collect ( ) ; 
115-     tx_fee_amounts. sort_by ( |a1,  a2| a1. 0 . cmp ( & a2. 0 ) ) ; 
115+     let  ( wallet,  txid)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
116116
117-     assert_eq ! ( tx_fee_amounts. len( ) ,  2 ) ; 
118-     assert_matches ! ( 
119-         tx_fee_amounts. get( 1 ) , 
120-         Some ( ( _,  Err ( CalculateFeeError :: MissingTxOut ( _) ) ) ) 
121-     ) ; 
122-     assert_matches ! ( tx_fee_amounts. get( 0 ) ,  Some ( ( _,  Ok ( 1000 ) ) ) ) 
117+     let  tx = wallet. get_tx ( txid) . expect ( "transaction" ) . tx_node . tx ; 
118+     let  tx_fee = wallet. calculate_fee ( tx) . expect ( "transaction fee" ) ; 
119+ 
120+     // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 
121+     // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 
122+     // sats are the transaction fee. 
123+     assert_eq ! ( tx_fee,  1000 ) 
123124} 
124125
125126#[ test]  
126127fn  test_get_funded_wallet_tx_fee_rate ( )  { 
127-     let  ( wallet,  _)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
128-     assert_eq ! ( wallet. get_balance( ) . confirmed,  50000 ) ; 
129-     let  mut  tx_fee_rates:  Vec < ( Txid ,  Result < FeeRate ,  CalculateFeeError > ) >  = wallet
130-         . transactions ( ) 
131-         . map ( |ct| { 
132-             let  fee_rate = wallet. calculate_fee_rate ( ct. node . tx ) ; 
133-             ( ct. node . txid ,  fee_rate) 
134-         } ) 
135-         . collect ( ) ; 
136-     tx_fee_rates. sort_by ( |a1,  a2| a1. 0 . cmp ( & a2. 0 ) ) ; 
128+     let  ( wallet,  txid)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
137129
138-     assert_eq ! ( tx_fee_rates. len( ) ,  2 ) ; 
139-     assert_matches ! ( 
140-         tx_fee_rates. get( 1 ) , 
141-         Some ( ( _,  Err ( CalculateFeeError :: MissingTxOut ( _) ) ) ) 
142-     ) ; 
143-     assert_matches ! ( tx_fee_rates. get( 0 ) ,  Some ( ( _,  Ok ( _) ) ) ) 
130+     let  tx = wallet. get_tx ( txid) . expect ( "transaction" ) . tx_node . tx ; 
131+     let  tx_fee_rate = wallet. calculate_fee_rate ( tx) . expect ( "transaction fee rate" ) ; 
132+ 
133+     // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 
134+     // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 
135+     // sats are the transaction fee. 
136+ 
137+     // tx weight = 452 bytes, as vbytes = (452+3)/4 = 113 
138+     // fee rate (sats per vbyte) = fee / vbytes = 1000 / 113 = 8.8495575221 rounded to 8.849558 
139+     assert_eq ! ( tx_fee_rate. as_sat_per_vb( ) ,  8.849558 ) ; 
144140} 
145141
146142macro_rules!  assert_fee_rate { 
@@ -1098,6 +1094,77 @@ fn test_add_foreign_utxo() {
10981094    assert ! ( finished,  "all the inputs should have been signed now" ) ; 
10991095} 
11001096
1097+ #[ test]  
1098+ #[ should_panic(  
1099+     expected = "MissingTxOut([OutPoint { txid: 0x21d7fb1bceda00ab4069fc52d06baa13470803e9050edd16f5736e5d8c4925fd, vout: 0 }])"  
1100+ ) ] 
1101+ fn  test_calculate_fee_with_missing_foreign_utxo ( )  { 
1102+     let  ( mut  wallet1,  _)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
1103+     let  ( wallet2,  _)  =
1104+         get_funded_wallet ( "wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)" ) ; 
1105+ 
1106+     let  addr = Address :: from_str ( "2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX" ) 
1107+         . unwrap ( ) 
1108+         . assume_checked ( ) ; 
1109+     let  utxo = wallet2. list_unspent ( ) . next ( ) . expect ( "must take!" ) ; 
1110+     #[ allow( deprecated) ]  
1111+     let  foreign_utxo_satisfaction = wallet2
1112+         . get_descriptor_for_keychain ( KeychainKind :: External ) 
1113+         . max_satisfaction_weight ( ) 
1114+         . unwrap ( ) ; 
1115+ 
1116+     let  psbt_input = psbt:: Input  { 
1117+         witness_utxo :  Some ( utxo. txout . clone ( ) ) , 
1118+         ..Default :: default ( ) 
1119+     } ; 
1120+ 
1121+     let  mut  builder = wallet1. build_tx ( ) ; 
1122+     builder
1123+         . add_recipient ( addr. script_pubkey ( ) ,  60_000 ) 
1124+         . only_witness_utxo ( ) 
1125+         . add_foreign_utxo ( utxo. outpoint ,  psbt_input,  foreign_utxo_satisfaction) 
1126+         . unwrap ( ) ; 
1127+     let  psbt = builder. finish ( ) . unwrap ( ) ; 
1128+     let  tx = psbt. extract_tx ( ) ; 
1129+     wallet1. calculate_fee ( & tx) . unwrap ( ) ; 
1130+ } 
1131+ 
1132+ #[ test]  
1133+ fn  test_calculate_fee_with_inserted_foreign_utxo ( )  { 
1134+     let  ( mut  wallet1,  _)  = get_funded_wallet ( get_test_wpkh ( ) ) ; 
1135+     let  ( wallet2,  _)  =
1136+         get_funded_wallet ( "wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)" ) ; 
1137+ 
1138+     let  addr = Address :: from_str ( "2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX" ) 
1139+         . unwrap ( ) 
1140+         . assume_checked ( ) ; 
1141+     let  utxo = wallet2. list_unspent ( ) . next ( ) . expect ( "must take!" ) ; 
1142+     #[ allow( deprecated) ]  
1143+     let  foreign_utxo_satisfaction = wallet2
1144+         . get_descriptor_for_keychain ( KeychainKind :: External ) 
1145+         . max_satisfaction_weight ( ) 
1146+         . unwrap ( ) ; 
1147+ 
1148+     let  psbt_input = psbt:: Input  { 
1149+         witness_utxo :  Some ( utxo. txout . clone ( ) ) , 
1150+         ..Default :: default ( ) 
1151+     } ; 
1152+ 
1153+     let  mut  builder = wallet1. build_tx ( ) ; 
1154+     builder
1155+         . add_recipient ( addr. script_pubkey ( ) ,  60_000 ) 
1156+         . only_witness_utxo ( ) 
1157+         . add_foreign_utxo ( utxo. outpoint ,  psbt_input,  foreign_utxo_satisfaction) 
1158+         . unwrap ( ) ; 
1159+     let  psbt = builder. finish ( ) . unwrap ( ) ; 
1160+     let  psbt_fee = psbt. fee_amount ( ) . expect ( "psbt fee" ) ; 
1161+     let  tx = psbt. extract_tx ( ) ; 
1162+ 
1163+     wallet1. insert_txout ( utxo. outpoint ,  utxo. txout ) ; 
1164+     let  wallet1_fee = wallet1. calculate_fee ( & tx) . expect ( "wallet fee" ) ; 
1165+     assert_eq ! ( psbt_fee,  wallet1_fee) ; 
1166+ } 
1167+ 
11011168#[ test]  
11021169#[ should_panic( expected = "Generic(\" Foreign utxo missing witness_utxo or non_witness_utxo\" )" ) ]  
11031170fn  test_add_foreign_utxo_invalid_psbt_input ( )  { 
@@ -1122,8 +1189,8 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
11221189        get_funded_wallet ( "wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)" ) ; 
11231190
11241191    let  utxo2 = wallet2. list_unspent ( ) . next ( ) . unwrap ( ) ; 
1125-     let  tx1 = wallet1. get_tx ( txid1) . unwrap ( ) . node . tx . clone ( ) ; 
1126-     let  tx2 = wallet2. get_tx ( txid2) . unwrap ( ) . node . tx . clone ( ) ; 
1192+     let  tx1 = wallet1. get_tx ( txid1) . unwrap ( ) . tx_node . tx . clone ( ) ; 
1193+     let  tx2 = wallet2. get_tx ( txid2) . unwrap ( ) . tx_node . tx . clone ( ) ; 
11271194
11281195    #[ allow( deprecated) ]  
11291196    let  satisfaction_weight = wallet2
@@ -1212,7 +1279,7 @@ fn test_add_foreign_utxo_only_witness_utxo() {
12121279
12131280    { 
12141281        let  mut  builder = builder. clone ( ) ; 
1215-         let  tx2 = wallet2. get_tx ( txid2) . unwrap ( ) . node . tx ; 
1282+         let  tx2 = wallet2. get_tx ( txid2) . unwrap ( ) . tx_node . tx ; 
12161283        let  psbt_input = psbt:: Input  { 
12171284            non_witness_utxo :  Some ( tx2. clone ( ) ) , 
12181285            ..Default :: default ( ) 
@@ -2842,7 +2909,7 @@ fn test_taproot_sign_using_non_witness_utxo() {
28422909    let  mut  psbt = builder. finish ( ) . unwrap ( ) ; 
28432910
28442911    psbt. inputs [ 0 ] . witness_utxo  = None ; 
2845-     psbt. inputs [ 0 ] . non_witness_utxo  = Some ( wallet. get_tx ( prev_txid) . unwrap ( ) . node . tx . clone ( ) ) ; 
2912+     psbt. inputs [ 0 ] . non_witness_utxo  = Some ( wallet. get_tx ( prev_txid) . unwrap ( ) . tx_node . tx . clone ( ) ) ; 
28462913    assert ! ( 
28472914        psbt. inputs[ 0 ] . non_witness_utxo. is_some( ) , 
28482915        "Previous tx should be present in the database" 
0 commit comments