use super::{Blockchain, Capability, ConfigurableBlockchain, Progress};
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
use crate::error::Error;
-use crate::types::{KeychainKind, TransactionDetails, UTXO};
+use crate::types::{KeychainKind, LocalUtxo, TransactionDetails};
use crate::FeeRate;
use peer::*;
database.get_path_from_script_pubkey(&output.script_pubkey)?
{
debug!("{} output #{} is mine, adding utxo", tx.txid(), i);
- updates.set_utxo(&UTXO {
+ updates.set_utxo(&LocalUtxo {
outpoint: OutPoint::new(tx.txid(), i as u32),
txout: output.clone(),
keychain,
use super::*;
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
use crate::error::Error;
-use crate::types::{KeychainKind, TransactionDetails, UTXO};
+use crate::types::{KeychainKind, LocalUtxo, TransactionDetails};
use crate::wallet::time::Instant;
use crate::wallet::utils::ChunksIterator;
// this output is ours, we have a path to derive it
if let Some((keychain, _child)) = db.get_path_from_script_pubkey(&output.script_pubkey)? {
debug!("{} output #{} is mine, adding utxo", txid, i);
- updates.set_utxo(&UTXO {
+ updates.set_utxo(&LocalUtxo {
outpoint: OutPoint::new(tx.txid(), i as u32),
txout: output.clone(),
keychain,
child
)
}
- fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> {
+ fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
impl_inner_method!(AnyDatabase, self, set_utxo, utxo)
}
fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
) -> Result<Option<(KeychainKind, u32)>, Error> {
impl_inner_method!(AnyDatabase, self, del_path_from_script_pubkey, script)
}
- fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
impl_inner_method!(AnyDatabase, self, del_utxo, outpoint)
}
fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
impl_inner_method!(AnyDatabase, self, iter_script_pubkeys, keychain)
}
- fn iter_utxos(&self) -> Result<Vec<UTXO>, Error> {
+ fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
impl_inner_method!(AnyDatabase, self, iter_utxos)
}
fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
) -> Result<Option<(KeychainKind, u32)>, Error> {
impl_inner_method!(AnyDatabase, self, get_path_from_script_pubkey, script)
}
- fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
impl_inner_method!(AnyDatabase, self, get_utxo, outpoint)
}
fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
) -> Result<(), Error> {
impl_inner_method!(AnyBatch, self, set_script_pubkey, script, keychain, child)
}
- fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> {
+ fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
impl_inner_method!(AnyBatch, self, set_utxo, utxo)
}
fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
) -> Result<Option<(KeychainKind, u32)>, Error> {
impl_inner_method!(AnyBatch, self, del_path_from_script_pubkey, script)
}
- fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
impl_inner_method!(AnyBatch, self, del_utxo, outpoint)
}
fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
Ok(())
}
- fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> {
+ fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key();
let value = json!({
"t": utxo.txout,
}
}
- fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
let key = MapKey::UTXO(Some(outpoint)).as_map_key();
let res = self.remove(key);
let res = $process_delete!(res);
let txout = serde_json::from_value(val["t"].take())?;
let keychain = serde_json::from_value(val["i"].take())?;
- Ok(Some(UTXO { outpoint: outpoint.clone(), txout, keychain }))
+ Ok(Some(LocalUtxo { outpoint: outpoint.clone(), txout, keychain }))
}
}
}
.collect()
}
- fn iter_utxos(&self) -> Result<Vec<UTXO>, Error> {
+ fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
let key = MapKey::UTXO(None).as_map_key();
self.scan_prefix(key)
.map(|x| -> Result<_, Error> {
let txout = serde_json::from_value(val["t"].take())?;
let keychain = serde_json::from_value(val["i"].take())?;
- Ok(UTXO {
+ Ok(LocalUtxo {
outpoint,
txout,
keychain,
.transpose()
}
- fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
let key = MapKey::UTXO(Some(outpoint)).as_map_key();
self.get(key)?
.map(|b| -> Result<_, Error> {
let txout = serde_json::from_value(val["t"].take())?;
let keychain = serde_json::from_value(val["i"].take())?;
- Ok(UTXO {
+ Ok(LocalUtxo {
outpoint: *outpoint,
txout,
keychain,
Ok(())
}
- fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> {
+ fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key();
self.map
.insert(key, Box::new((utxo.txout.clone(), utxo.keychain)));
}
}
}
- fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
let key = MapKey::UTXO(Some(outpoint)).as_map_key();
let res = self.map.remove(&key);
self.deleted_keys.push(key);
None => Ok(None),
Some(b) => {
let (txout, keychain) = b.downcast_ref().cloned().unwrap();
- Ok(Some(UTXO {
+ Ok(Some(LocalUtxo {
outpoint: *outpoint,
txout,
keychain,
.collect()
}
- fn iter_utxos(&self) -> Result<Vec<UTXO>, Error> {
+ fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
let key = MapKey::UTXO(None).as_map_key();
self.map
.range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
.map(|(k, v)| {
let outpoint = deserialize(&k[1..]).unwrap();
let (txout, keychain) = v.downcast_ref().cloned().unwrap();
- Ok(UTXO {
+ Ok(LocalUtxo {
outpoint,
txout,
keychain,
}))
}
- fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
+ fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
let key = MapKey::UTXO(Some(outpoint)).as_map_key();
Ok(self.map.get(&key).map(|b| {
let (txout, keychain) = b.downcast_ref().cloned().unwrap();
- UTXO {
+ LocalUtxo {
outpoint: *outpoint,
txout,
keychain,
db.set_tx(&tx_details).unwrap();
for (vout, out) in tx.output.iter().enumerate() {
- db.set_utxo(&UTXO {
+ db.set_utxo(&LocalUtxo {
txout: out.clone(),
outpoint: OutPoint {
txid,
keychain: KeychainKind,
child: u32,
) -> Result<(), Error>;
- /// Store a [`UTXO`]
- fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error>;
+ /// Store a [`LocalUtxo`]
+ fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error>;
/// Store a raw transaction
fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error>;
/// Store the metadata of a transaction
&mut self,
script: &Script,
) -> Result<Option<(KeychainKind, u32)>, Error>;
- /// Delete a [`UTXO`] given its [`OutPoint`]
- fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error>;
+ /// Delete a [`LocalUtxo`] given its [`OutPoint`]
+ fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>;
/// Delete a raw transaction given its [`Txid`]
fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error>;
/// Delete the metadata of a transaction and optionally the raw transaction itself
/// Return the list of script_pubkeys
fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error>;
- /// Return the list of [`UTXO`]s
- fn iter_utxos(&self) -> Result<Vec<UTXO>, Error>;
+ /// Return the list of [`LocalUtxo`]s
+ fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error>;
/// Return the list of raw transactions
fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error>;
/// Return the list of transactions metadata
&self,
script: &Script,
) -> Result<Option<(KeychainKind, u32)>, Error>;
- /// Fetch a [`UTXO`] given its [`OutPoint`]
- fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error>;
+ /// Fetch a [`LocalUtxo`] given its [`OutPoint`]
+ fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>;
/// Fetch a raw transaction given its [`Txid`]
fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
/// Fetch the transaction metadata and optionally also the raw transaction
value: 133742,
script_pubkey: script,
};
- let utxo = UTXO {
+ let utxo = LocalUtxo {
txout,
outpoint,
keychain: KeychainKind::External,
/// A wallet unspent output
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
-pub struct UTXO {
+pub struct LocalUtxo {
/// Reference to a transaction output
pub outpoint: OutPoint,
/// Transaction output
//! fn coin_select(
//! &self,
//! database: &D,
-//! required_utxos: Vec<(UTXO, usize)>,
-//! optional_utxos: Vec<(UTXO, usize)>,
+//! required_utxos: Vec<(LocalUtxo, usize)>,
+//! optional_utxos: Vec<(LocalUtxo, usize)>,
//! fee_rate: FeeRate,
//! amount_needed: u64,
//! fee_amount: f32,
use crate::database::Database;
use crate::error::Error;
-use crate::types::{FeeRate, UTXO};
+use crate::types::{FeeRate, LocalUtxo};
use rand::seq::SliceRandom;
#[cfg(not(test))]
#[derive(Debug)]
pub struct CoinSelectionResult {
/// List of outputs selected for use as inputs
- pub selected: Vec<UTXO>,
+ pub selected: Vec<LocalUtxo>,
/// Sum of the selected inputs' value
pub selected_amount: u64,
/// Total fee amount in satoshi
fn coin_select(
&self,
database: &D,
- required_utxos: Vec<(UTXO, usize)>,
- optional_utxos: Vec<(UTXO, usize)>,
+ required_utxos: Vec<(LocalUtxo, usize)>,
+ optional_utxos: Vec<(LocalUtxo, usize)>,
fee_rate: FeeRate,
amount_needed: u64,
fee_amount: f32,
fn coin_select(
&self,
_database: &D,
- required_utxos: Vec<(UTXO, usize)>,
- mut optional_utxos: Vec<(UTXO, usize)>,
+ required_utxos: Vec<(LocalUtxo, usize)>,
+ mut optional_utxos: Vec<(LocalUtxo, usize)>,
fee_rate: FeeRate,
amount_needed: u64,
mut fee_amount: f32,
#[derive(Debug, Clone)]
// Adds fee information to an UTXO.
struct OutputGroup {
- utxo: UTXO,
+ utxo: LocalUtxo,
// weight needed to satisfy the UTXO, as described in `Descriptor::max_satisfaction_weight`
satisfaction_weight: usize,
// Amount of fees for spending a certain utxo, calculated using a certain FeeRate
}
impl OutputGroup {
- fn new(utxo: UTXO, satisfaction_weight: usize, fee_rate: FeeRate) -> Self {
+ fn new(utxo: LocalUtxo, satisfaction_weight: usize, fee_rate: FeeRate) -> Self {
let fee = (TXIN_BASE_WEIGHT + satisfaction_weight) as f32 / 4.0 * fee_rate.as_sat_vb();
let effective_value = utxo.txout.value as i64 - fee.ceil() as i64;
OutputGroup {
fn coin_select(
&self,
_database: &D,
- required_utxos: Vec<(UTXO, usize)>,
- optional_utxos: Vec<(UTXO, usize)>,
+ required_utxos: Vec<(LocalUtxo, usize)>,
+ optional_utxos: Vec<(LocalUtxo, usize)>,
fee_rate: FeeRate,
amount_needed: u64,
fee_amount: f32,
const P2WPKH_WITNESS_SIZE: usize = 73 + 33 + 2;
- fn get_test_utxos() -> Vec<(UTXO, usize)> {
+ fn get_test_utxos() -> Vec<(LocalUtxo, usize)> {
vec![
(
- UTXO {
+ LocalUtxo {
outpoint: OutPoint::from_str(
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
)
P2WPKH_WITNESS_SIZE,
),
(
- UTXO {
+ LocalUtxo {
outpoint: OutPoint::from_str(
"65d92ddff6b6dc72c89624a6491997714b90f6004f928d875bc0fd53f264fa85:0",
)
]
}
- fn generate_random_utxos(rng: &mut StdRng, utxos_number: usize) -> Vec<(UTXO, usize)> {
+ fn generate_random_utxos(rng: &mut StdRng, utxos_number: usize) -> Vec<(LocalUtxo, usize)> {
let mut res = Vec::new();
for _ in 0..utxos_number {
res.push((
- UTXO {
+ LocalUtxo {
outpoint: OutPoint::from_str(
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
)
res
}
- fn generate_same_value_utxos(utxos_value: u64, utxos_number: usize) -> Vec<(UTXO, usize)> {
+ fn generate_same_value_utxos(utxos_value: u64, utxos_number: usize) -> Vec<(LocalUtxo, usize)> {
let utxo = (
- UTXO {
+ LocalUtxo {
outpoint: OutPoint::from_str(
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
)
vec![utxo; utxos_number]
}
- fn sum_random_utxos(mut rng: &mut StdRng, utxos: &mut Vec<(UTXO, usize)>) -> u64 {
+ fn sum_random_utxos(mut rng: &mut StdRng, utxos: &mut Vec<(LocalUtxo, usize)>) -> u64 {
let utxos_picked_len = rng.gen_range(2, utxos.len() / 2);
utxos.shuffle(&mut rng);
utxos[..utxos_picked_len]
///
/// Note that this methods only operate on the internal database, which first needs to be
/// [`Wallet::sync`] manually.
- pub fn list_unspent(&self) -> Result<Vec<UTXO>, Error> {
+ pub fn list_unspent(&self) -> Result<Vec<LocalUtxo>, Error> {
self.database.borrow().iter_utxos()
}
/// Returns the `UTXO` owned by this wallet corresponding to `outpoint` if it exists in the
/// wallet's database.
- pub fn get_utxo(&self, outpoint: OutPoint) -> Result<Option<UTXO>, Error> {
+ pub fn get_utxo(&self, outpoint: OutPoint) -> Result<Option<LocalUtxo>, Error> {
self.database.borrow().get_utxo(&outpoint)
}
}
};
- let utxo = UTXO {
+ let utxo = LocalUtxo {
outpoint: txin.previous_output,
txout,
keychain,
Ok(())
}
- fn get_available_utxos(&self) -> Result<Vec<(UTXO, usize)>, Error> {
+ fn get_available_utxos(&self) -> Result<Vec<(LocalUtxo, usize)>, Error> {
Ok(self
.list_unspent()?
.into_iter()
&self,
change_policy: tx_builder::ChangeSpendPolicy,
unspendable: &HashSet<OutPoint>,
- manually_selected: Vec<(UTXO, usize)>,
+ manually_selected: Vec<(LocalUtxo, usize)>,
must_use_all_available: bool,
manual_only: bool,
must_only_use_confirmed_tx: bool,
- ) -> Result<(Vec<(UTXO, usize)>, Vec<(UTXO, usize)>), Error> {
+ ) -> Result<(Vec<(LocalUtxo, usize)>, Vec<(LocalUtxo, usize)>), Error> {
// must_spend <- manually selected utxos
// may_spend <- all other available utxos
let mut may_spend = self.get_available_utxos()?;
fn complete_transaction(
&self,
tx: Transaction,
- selected: Vec<UTXO>,
+ selected: Vec<LocalUtxo>,
params: TxParams,
) -> Result<PSBT, Error> {
use bitcoin::util::psbt::serialize::Serialize;
use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
use crate::{database::BatchDatabase, Error, Wallet};
use crate::{
- types::{FeeRate, KeychainKind, UTXO},
+ types::{FeeRate, KeychainKind, LocalUtxo},
TransactionDetails,
};
/// Context in which the [`TxBuilder`] is valid
pub(crate) fee_policy: Option<FeePolicy>,
pub(crate) internal_policy_path: Option<BTreeMap<String, Vec<usize>>>,
pub(crate) external_policy_path: Option<BTreeMap<String, Vec<usize>>>,
- pub(crate) utxos: Vec<(UTXO, usize)>,
+ pub(crate) utxos: Vec<(LocalUtxo, usize)>,
pub(crate) unspendable: HashSet<OutPoint>,
pub(crate) manually_selected_only: bool,
pub(crate) sighash: Option<SigHashType>,
}
impl ChangeSpendPolicy {
- pub(crate) fn is_satisfied_by(&self, utxo: &UTXO) -> bool {
+ pub(crate) fn is_satisfied_by(&self, utxo: &LocalUtxo) -> bool {
match self {
ChangeSpendPolicy::ChangeAllowed => true,
ChangeSpendPolicy::OnlyChange => utxo.keychain == KeychainKind::Internal,
assert_eq!(tx.output[2].script_pubkey, From::from(vec![0xAA, 0xEE]));
}
- fn get_test_utxos() -> Vec<UTXO> {
+ fn get_test_utxos() -> Vec<LocalUtxo> {
vec![
- UTXO {
+ LocalUtxo {
outpoint: OutPoint {
txid: Default::default(),
vout: 0,
txout: Default::default(),
keychain: KeychainKind::External,
},
- UTXO {
+ LocalUtxo {
outpoint: OutPoint {
txid: Default::default(),
vout: 1,