Skip to content

Commit

Permalink
WIP: JUST ONE MORE TEST TO FIX!
Browse files Browse the repository at this point in the history
  • Loading branch information
evanlinjin committed Oct 4, 2022
1 parent f8d9c97 commit eff7a50
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 32 deletions.
1 change: 1 addition & 0 deletions src/bdk_core/coin_select/coin_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ impl WeightedValue {
/// `satisfaction_weight` is the weight of `scriptSigLen + scriptSig + scriptWitnessLen +
/// scriptWitness`.
pub fn new(value: u64, satisfaction_weight: u32, is_segwit: bool) -> WeightedValue {
println!("- wv satisfaction weight: {}", satisfaction_weight);
let weight = TXIN_BASE_WEIGHT + satisfaction_weight;
WeightedValue {
value,
Expand Down
18 changes: 17 additions & 1 deletion src/psbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ mod test {
let fee_amount = psbt.fee_amount();
assert!(fee_amount.is_some());

let weight = psbt.clone().extract_tx().weight();
println!("psbt weight: {}", weight);
println!("inputs: {}", psbt.clone().extract_tx().input.len());

let unfinalized_fee_rate = psbt.fee_rate().unwrap();

let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
Expand All @@ -188,15 +192,27 @@ mod test {
let mut builder = wallet.build_tx();
builder.drain_to(addr.script_pubkey()).drain_wallet();
builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
let (mut psbt, _) = builder.finish().unwrap();
let (mut psbt, details) = builder.finish().unwrap();
let fee_amount = psbt.fee_amount();
assert!(fee_amount.is_some());
let unfinalized_fee_rate = psbt.fee_rate().unwrap();
println!("unfinalized fee rate: {:?}", unfinalized_fee_rate);

let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
assert!(finalized);

let tx = psbt.clone().extract_tx();
// println!("tx: {:#?}", tx);
println!("scriptSig weight: {}", tx.input[0].script_sig.len() * 4);
println!("weight: {}", tx.weight());
let vb = tx.weight() as f32 / 4.0;
println!("vbytes: {}", vb);
let fee = details.fee.unwrap_or(0);
println!("fee: {}", details.fee.unwrap_or(0));
println!("feerate: {} sats/vb", fee as f32 / vb);

let finalized_fee_rate = psbt.fee_rate().unwrap();
println!("finalized fee rate: {:?}", finalized_fee_rate);
assert!(finalized_fee_rate.as_sat_per_vb() >= expected_fee_rate);
assert!(finalized_fee_rate.as_sat_per_vb() < unfinalized_fee_rate.as_sat_per_vb());
}
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/coin_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl CoinSelectionAlgorithm for LargestFirstCoinSelection {
let pool = {
let mut pool = selector.unselected().collect::<Vec<_>>();
pool.sort_unstable_by_key(|(_, candidate)| candidate.value);
pool.reverse();
pool
};

Expand All @@ -226,6 +227,7 @@ impl CoinSelectionAlgorithm for LargestFirstCoinSelection {
}

selector.select(index);
println!("selected: index={}, value={}", index, _candidate.value);
selection = selector.finish();
}

Expand Down
99 changes: 68 additions & 31 deletions src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,17 @@ where
};

let selection = coin_selection.coin_select(&raw_candidates, selector)?;
let (_, excess_strategy) = selection.best_strategy();
println!(
"create_tx: weight={}, fee={}, feerate={}sats/wu",
excess_strategy.weight,
excess_strategy.fee,
excess_strategy.feerate()
);
println!(
"create_tx: feerate={}sats/vb",
excess_strategy.feerate() * 4.0
);

// fee_amount += coin_selection.fee_amount;
// let excess = &coin_selection.excess;
Expand All @@ -938,8 +949,6 @@ where
})
.collect();

let (_, excess_strategy) = selection.best_strategy();

if let Some(drain_value) = excess_strategy.drain_value {
tx.output.push(TxOut {
value: drain_value,
Expand Down Expand Up @@ -1016,23 +1025,27 @@ where
.map(|utxo| utxo.utxo.clone())
.collect::<Vec<_>>();

let sent = selected.iter().map(|utxo| utxo.txout().value).sum::<u64>();
let sent = selected
.iter()
.filter(|utxo| {
self.database
.borrow()
.is_mine(&utxo.txout().script_pubkey)
.unwrap_or(false)
})
.map(|utxo| utxo.txout().value)
.sum::<u64>();

let received = tx
.output
.iter()
.map(|txo| {
if self
.database
.filter(|txo| {
self.database
.borrow()
.is_mine(&txo.script_pubkey)
.unwrap_or(false)
{
txo.value
} else {
0
}
})
.map(|txo| txo.value)
.sum::<u64>();

let psbt = self.complete_transaction(tx, selected, params)?;
Expand Down Expand Up @@ -2740,7 +2753,7 @@ pub(crate) mod test {
}

#[test]
#[should_panic(expected = "InsufficientFunds")]
// #[should_panic(expected = "InsufficientFunds")]
fn test_create_tx_absolute_high_fee() {
let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
let addr = wallet.get_address(New).unwrap();
Expand All @@ -2749,7 +2762,10 @@ pub(crate) mod test {
.drain_to(addr.script_pubkey())
.drain_wallet()
.fee_absolute(60_000);
let (_psbt, _details) = builder.finish().unwrap();
// let (_psbt, _details) = builder.finish().unwrap();
assert!(
matches!(builder.finish(), Err(Error::Generic(s)) if s.contains("insufficient coins"))
);
}

#[test]
Expand Down Expand Up @@ -2786,7 +2802,7 @@ pub(crate) mod test {
}

#[test]
#[should_panic(expected = "InsufficientFunds")]
// #[should_panic(expected = "InsufficientFunds")]
fn test_create_tx_drain_to_dust_amount() {
let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
let addr = wallet.get_address(New).unwrap();
Expand All @@ -2796,7 +2812,10 @@ pub(crate) mod test {
.drain_to(addr.script_pubkey())
.drain_wallet()
.fee_rate(FeeRate::from_sat_per_vb(455.0));
builder.finish().unwrap();
// builder.finish().unwrap();
assert!(
matches!(builder.finish(), Err(Error::Generic(s)) if s.contains("insufficient coins"))
);
}

#[test]
Expand Down Expand Up @@ -3042,7 +3061,7 @@ pub(crate) mod test {
}

#[test]
#[should_panic(expected = "InsufficientFunds")]
// #[should_panic(expected = "InsufficientFunds")]
fn test_create_tx_manually_selected_insufficient() {
let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
let small_output_txid = crate::populate_test_db!(
Expand All @@ -3061,7 +3080,10 @@ pub(crate) mod test {
})
.unwrap()
.manually_selected_only();
builder.finish().unwrap();
// builder.finish().unwrap();
assert!(
matches!(builder.finish(), Err(Error::Generic(s)) if s.contains("insufficient coins"))
);
}

#[test]
Expand Down Expand Up @@ -3780,7 +3802,7 @@ pub(crate) mod test {
}

#[test]
#[should_panic(expected = "InsufficientFunds")]
// #[should_panic(expected = "InsufficientFunds")]
fn test_bump_fee_remove_output_manually_selected_only() {
let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
// receive an extra tx so that our wallet has two utxos. then we manually pick only one of
Expand Down Expand Up @@ -3828,11 +3850,15 @@ pub(crate) mod test {
builder
.manually_selected_only()
.fee_rate(FeeRate::from_sat_per_vb(255.0));
builder.finish().unwrap();
// builder.finish().unwrap();
assert!(
matches!(builder.finish(), Err(Error::Generic(s)) if s.contains("insufficient coins"))
);
}

#[test]
fn test_bump_fee_add_input() {
// funded wallet already has 50_000 utxo
let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
crate::populate_test_db!(
wallet.database.borrow_mut(),
Expand Down Expand Up @@ -4254,7 +4280,7 @@ pub(crate) mod test {
}

#[test]
#[should_panic(expected = "InsufficientFunds")]
// #[should_panic(expected = "InsufficientFunds")]
fn test_bump_fee_unconfirmed_inputs_only() {
// We try to bump the fee, but:
// - We can't reduce the change, as we have no change
Expand Down Expand Up @@ -4296,7 +4322,10 @@ pub(crate) mod test {

let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_rate(FeeRate::from_sat_per_vb(25.0));
builder.finish().unwrap();
assert!(
matches!(builder.finish(), Err(Error::Generic(s)) if s.contains("insufficient coins"))
);
// builder.finish().unwrap();
}

#[test]
Expand Down Expand Up @@ -5556,25 +5585,33 @@ pub(crate) mod test {
.add_recipient(addr.script_pubkey(), balance.immature / 2)
.current_height(confirmation_time);
assert!(matches!(
builder.finish().unwrap_err(),
Error::InsufficientFunds {
needed: _,
available: 0
}
builder.finish(),
Err(Error::Generic(s)) if s.contains("insufficient coins")
));
// assert!(matches!(
// builder.finish().unwrap_err(),
// Error::InsufficientFunds {
// needed: _,
// available: 0
// }
// ));

// Still unspendable...
let mut builder = wallet.build_tx();
builder
.add_recipient(addr.script_pubkey(), balance.immature / 2)
.current_height(not_yet_mature_time);
assert!(matches!(
builder.finish().unwrap_err(),
Error::InsufficientFunds {
needed: _,
available: 0
}
builder.finish(),
Err(Error::Generic(s)) if s.contains("insufficient coins")
));
// assert!(matches!(
// builder.finish().unwrap_err(),
// Error::InsufficientFunds {
// needed: _,
// available: 0
// }
// ));

// ...Now the coinbase is mature :)
let sync_time = SyncTime {
Expand Down

0 comments on commit eff7a50

Please sign in to comment.