diff --git a/src/blockchain/compact_filters/mod.rs b/src/blockchain/compact_filters/mod.rs index 233ea89a..a0d45f02 100644 --- a/src/blockchain/compact_filters/mod.rs +++ b/src/blockchain/compact_filters/mod.rs @@ -193,7 +193,7 @@ impl CompactFiltersBlockchain { updates.set_utxo(&UTXO { outpoint: OutPoint::new(tx.txid(), i as u32), txout: output.clone(), - is_internal: script_type.is_internal(), + script_type, })?; incoming += output.value; diff --git a/src/blockchain/utils.rs b/src/blockchain/utils.rs index 3d7a3d98..06c39b01 100644 --- a/src/blockchain/utils.rs +++ b/src/blockchain/utils.rs @@ -358,7 +358,7 @@ fn save_transaction_details_and_utxos( updates.set_utxo(&UTXO { outpoint: OutPoint::new(tx.txid(), i as u32), txout: output.clone(), - is_internal: script_type.is_internal(), + script_type, })?; incoming += output.value; diff --git a/src/database/keyvalue.rs b/src/database/keyvalue.rs index e61ff06e..1b860a70 100644 --- a/src/database/keyvalue.rs +++ b/src/database/keyvalue.rs @@ -55,7 +55,7 @@ macro_rules! impl_batch_operations { let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key(); let value = json!({ "t": utxo.txout, - "i": utxo.is_internal, + "i": utxo.script_type, }); self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*; @@ -130,9 +130,9 @@ macro_rules! impl_batch_operations { Some(b) => { let mut val: serde_json::Value = serde_json::from_slice(&b)?; let txout = serde_json::from_value(val["t"].take())?; - let is_internal = serde_json::from_value(val["i"].take())?; + let script_type = serde_json::from_value(val["i"].take())?; - Ok(Some(UTXO { outpoint: outpoint.clone(), txout, is_internal })) + Ok(Some(UTXO { outpoint: outpoint.clone(), txout, script_type })) } } } @@ -243,12 +243,12 @@ impl Database for Tree { let mut val: serde_json::Value = serde_json::from_slice(&v)?; let txout = serde_json::from_value(val["t"].take())?; - let is_internal = serde_json::from_value(val["i"].take())?; + let script_type = serde_json::from_value(val["i"].take())?; Ok(UTXO { outpoint, txout, - is_internal, + script_type, }) }) .collect() @@ -311,12 +311,12 @@ impl Database for Tree { .map(|b| -> Result<_, Error> { let mut val: serde_json::Value = serde_json::from_slice(&b)?; let txout = serde_json::from_value(val["t"].take())?; - let is_internal = serde_json::from_value(val["i"].take())?; + let script_type = serde_json::from_value(val["i"].take())?; Ok(UTXO { outpoint: *outpoint, txout, - is_internal, + script_type, }) }) .transpose() diff --git a/src/database/memory.rs b/src/database/memory.rs index 707cd951..52bef1c2 100644 --- a/src/database/memory.rs +++ b/src/database/memory.rs @@ -160,7 +160,7 @@ impl BatchOperations for MemoryDatabase { fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> { let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key(); self.map - .insert(key, Box::new((utxo.txout.clone(), utxo.is_internal))); + .insert(key, Box::new((utxo.txout.clone(), utxo.script_type))); Ok(()) } @@ -231,11 +231,11 @@ impl BatchOperations for MemoryDatabase { match res { None => Ok(None), Some(b) => { - let (txout, is_internal) = b.downcast_ref().cloned().unwrap(); + let (txout, script_type) = b.downcast_ref().cloned().unwrap(); Ok(Some(UTXO { outpoint: *outpoint, txout, - is_internal, + script_type, })) } } @@ -322,11 +322,11 @@ impl Database for MemoryDatabase { .range::, _>((Included(&key), Excluded(&after(&key)))) .map(|(k, v)| { let outpoint = deserialize(&k[1..]).unwrap(); - let (txout, is_internal) = v.downcast_ref().cloned().unwrap(); + let (txout, script_type) = v.downcast_ref().cloned().unwrap(); Ok(UTXO { outpoint, txout, - is_internal, + script_type, }) }) .collect() @@ -385,11 +385,11 @@ impl Database for MemoryDatabase { fn get_utxo(&self, outpoint: &OutPoint) -> Result, Error> { let key = MapKey::UTXO(Some(outpoint)).as_map_key(); Ok(self.map.get(&key).map(|b| { - let (txout, is_internal) = b.downcast_ref().cloned().unwrap(); + let (txout, script_type) = b.downcast_ref().cloned().unwrap(); UTXO { outpoint: *outpoint, txout, - is_internal, + script_type, } })) } @@ -507,7 +507,7 @@ impl MemoryDatabase { txid, vout: vout as u32, }, - is_internal: false, + script_type: ScriptType::External, }) .unwrap(); } diff --git a/src/database/mod.rs b/src/database/mod.rs index 3e77a07f..3cd8d9a7 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -301,7 +301,7 @@ pub mod test { let utxo = UTXO { txout, outpoint, - is_internal: false, + script_type: ScriptType::External, }; tree.set_utxo(&utxo).unwrap(); diff --git a/src/types.rs b/src/types.rs index e4e33d10..6c7090cd 100644 --- a/src/types.rs +++ b/src/types.rs @@ -43,10 +43,6 @@ impl ScriptType { ScriptType::Internal => b'i', } } - - pub fn is_internal(&self) -> bool { - self == &ScriptType::Internal - } } impl AsRef<[u8]> for ScriptType { @@ -96,7 +92,7 @@ impl std::default::Default for FeeRate { pub struct UTXO { pub outpoint: OutPoint, pub txout: TxOut, - pub is_internal: bool, + pub script_type: ScriptType, } /// A wallet transaction diff --git a/src/wallet/coin_selection.rs b/src/wallet/coin_selection.rs index 19e252db..5063f745 100644 --- a/src/wallet/coin_selection.rs +++ b/src/wallet/coin_selection.rs @@ -538,7 +538,7 @@ mod test { value: 100_000, script_pubkey: Script::new(), }, - is_internal: false, + script_type: ScriptType::External, }, P2WPKH_WITNESS_SIZE, ), @@ -552,7 +552,7 @@ mod test { value: 200_000, script_pubkey: Script::new(), }, - is_internal: true, + script_type: ScriptType::Internal, }, P2WPKH_WITNESS_SIZE, ), @@ -572,7 +572,7 @@ mod test { value: rng.gen_range(0, 200000000), script_pubkey: Script::new(), }, - is_internal: false, + script_type: ScriptType::External, }, P2WPKH_WITNESS_SIZE, )); @@ -591,7 +591,7 @@ mod test { value: utxos_value, script_pubkey: Script::new(), }, - is_internal: false, + script_type: ScriptType::External, }, P2WPKH_WITNESS_SIZE, ); diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 1c3f5198..a6c64a6c 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -611,18 +611,6 @@ where } let deriv_ctx = descriptor_to_pk_ctx(&self.secp); - - let external_weight = self - .get_descriptor_for_script_type(ScriptType::External) - .0 - .max_satisfaction_weight(deriv_ctx) - .unwrap(); - let internal_weight = self - .get_descriptor_for_script_type(ScriptType::Internal) - .0 - .max_satisfaction_weight(deriv_ctx) - .unwrap(); - let original_sequence = tx.input[0].sequence; // remove the inputs from the tx and process them @@ -636,26 +624,31 @@ where .get_previous_output(&txin.previous_output)? .ok_or(Error::UnknownUTXO)?; - let (weight, is_internal) = match self + let (weight, script_type) = match self .database .borrow() .get_path_from_script_pubkey(&txout.script_pubkey)? { - Some((ScriptType::Internal, _)) => (internal_weight, true), - Some((ScriptType::External, _)) => (external_weight, false), + Some((script_type, _)) => ( + self.get_descriptor_for_script_type(script_type) + .0 + .max_satisfaction_weight(deriv_ctx) + .unwrap(), + script_type, + ), None => { // estimate the weight based on the scriptsig/witness size present in the // original transaction let weight = serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len(); - (weight, false) + (weight, ScriptType::External) } }; let utxo = UTXO { outpoint: txin.previous_output, txout, - is_internal, + script_type, }; Ok((utxo, weight)) @@ -1052,30 +1045,20 @@ where fn get_available_utxos(&self) -> Result, Error> { let deriv_ctx = descriptor_to_pk_ctx(&self.secp); - - let external_weight = self - .get_descriptor_for_script_type(ScriptType::External) - .0 - .max_satisfaction_weight(deriv_ctx) - .unwrap(); - let internal_weight = self - .get_descriptor_for_script_type(ScriptType::Internal) - .0 - .max_satisfaction_weight(deriv_ctx) - .unwrap(); - - let add_weight = |utxo: UTXO| { - let weight = match utxo.is_internal { - true => internal_weight, - false => external_weight, - }; - - (utxo, weight) - }; - - let utxos = self.list_unspent()?.into_iter().map(add_weight).collect(); - - Ok(utxos) + Ok(self + .list_unspent()? + .into_iter() + .map(|utxo| { + let script_type = utxo.script_type; + ( + utxo, + self.get_descriptor_for_script_type(script_type) + .0 + .max_satisfaction_weight(deriv_ctx) + .unwrap(), + ) + }) + .collect()) } /// Given the options returns the list of utxos that must be used to form the diff --git a/src/wallet/tx_builder.rs b/src/wallet/tx_builder.rs index 2b0c8e5b..aad24899 100644 --- a/src/wallet/tx_builder.rs +++ b/src/wallet/tx_builder.rs @@ -566,8 +566,8 @@ impl ChangeSpendPolicy { pub(crate) fn is_satisfied_by(&self, utxo: &UTXO) -> bool { match self { ChangeSpendPolicy::ChangeAllowed => true, - ChangeSpendPolicy::OnlyChange => utxo.is_internal, - ChangeSpendPolicy::ChangeForbidden => !utxo.is_internal, + ChangeSpendPolicy::OnlyChange => utxo.script_type == ScriptType::Internal, + ChangeSpendPolicy::ChangeForbidden => utxo.script_type == ScriptType::External, } } } @@ -662,7 +662,7 @@ mod test { vout: 0, }, txout: Default::default(), - is_internal: false, + script_type: ScriptType::External, }, UTXO { outpoint: OutPoint { @@ -670,7 +670,7 @@ mod test { vout: 1, }, txout: Default::default(), - is_internal: true, + script_type: ScriptType::Internal, }, ] } @@ -695,7 +695,7 @@ mod test { .collect::>(); assert_eq!(filtered.len(), 1); - assert_eq!(filtered[0].is_internal, false); + assert_eq!(filtered[0].script_type, ScriptType::External); } #[test] @@ -707,7 +707,7 @@ mod test { .collect::>(); assert_eq!(filtered.len(), 1); - assert_eq!(filtered[0].is_internal, true); + assert_eq!(filtered[0].script_type, ScriptType::Internal); } #[test] diff --git a/testutils-macros/src/lib.rs b/testutils-macros/src/lib.rs index baabefac..87b586cc 100644 --- a/testutils-macros/src/lib.rs +++ b/testutils-macros/src/lib.rs @@ -120,7 +120,7 @@ pub fn bdk_blockchain_tests(attr: TokenStream, item: TokenStream) -> TokenStream wallet.sync(noop_progress(), None).unwrap(); assert_eq!(wallet.get_balance().unwrap(), 50_000); - assert_eq!(wallet.list_unspent().unwrap()[0].is_internal, false); + assert_eq!(wallet.list_unspent().unwrap()[0].script_type, ScriptType::External); let list_tx_item = &wallet.list_transactions(false).unwrap()[0]; assert_eq!(list_tx_item.txid, txid);