Merge commit 'refs/pull/210/head' of github.com:bitcoindevkit/bdk
This commit is contained in:
commit
eef59e463d
@ -193,7 +193,7 @@ impl CompactFiltersBlockchain {
|
|||||||
updates.set_utxo(&UTXO {
|
updates.set_utxo(&UTXO {
|
||||||
outpoint: OutPoint::new(tx.txid(), i as u32),
|
outpoint: OutPoint::new(tx.txid(), i as u32),
|
||||||
txout: output.clone(),
|
txout: output.clone(),
|
||||||
is_internal: script_type.is_internal(),
|
script_type,
|
||||||
})?;
|
})?;
|
||||||
incoming += output.value;
|
incoming += output.value;
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ fn save_transaction_details_and_utxos<D: BatchDatabase>(
|
|||||||
updates.set_utxo(&UTXO {
|
updates.set_utxo(&UTXO {
|
||||||
outpoint: OutPoint::new(tx.txid(), i as u32),
|
outpoint: OutPoint::new(tx.txid(), i as u32),
|
||||||
txout: output.clone(),
|
txout: output.clone(),
|
||||||
is_internal: script_type.is_internal(),
|
script_type,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
incoming += output.value;
|
incoming += output.value;
|
||||||
|
@ -55,7 +55,7 @@ macro_rules! impl_batch_operations {
|
|||||||
let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key();
|
let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key();
|
||||||
let value = json!({
|
let value = json!({
|
||||||
"t": utxo.txout,
|
"t": utxo.txout,
|
||||||
"i": utxo.is_internal,
|
"i": utxo.script_type,
|
||||||
});
|
});
|
||||||
self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*;
|
self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*;
|
||||||
|
|
||||||
@ -130,9 +130,9 @@ macro_rules! impl_batch_operations {
|
|||||||
Some(b) => {
|
Some(b) => {
|
||||||
let mut val: serde_json::Value = serde_json::from_slice(&b)?;
|
let mut val: serde_json::Value = serde_json::from_slice(&b)?;
|
||||||
let txout = serde_json::from_value(val["t"].take())?;
|
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 mut val: serde_json::Value = serde_json::from_slice(&v)?;
|
||||||
let txout = serde_json::from_value(val["t"].take())?;
|
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 {
|
Ok(UTXO {
|
||||||
outpoint,
|
outpoint,
|
||||||
txout,
|
txout,
|
||||||
is_internal,
|
script_type,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
@ -311,12 +311,12 @@ impl Database for Tree {
|
|||||||
.map(|b| -> Result<_, Error> {
|
.map(|b| -> Result<_, Error> {
|
||||||
let mut val: serde_json::Value = serde_json::from_slice(&b)?;
|
let mut val: serde_json::Value = serde_json::from_slice(&b)?;
|
||||||
let txout = serde_json::from_value(val["t"].take())?;
|
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 {
|
Ok(UTXO {
|
||||||
outpoint: *outpoint,
|
outpoint: *outpoint,
|
||||||
txout,
|
txout,
|
||||||
is_internal,
|
script_type,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.transpose()
|
.transpose()
|
||||||
|
@ -160,7 +160,7 @@ impl BatchOperations for MemoryDatabase {
|
|||||||
fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> {
|
fn set_utxo(&mut self, utxo: &UTXO) -> Result<(), Error> {
|
||||||
let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key();
|
let key = MapKey::UTXO(Some(&utxo.outpoint)).as_map_key();
|
||||||
self.map
|
self.map
|
||||||
.insert(key, Box::new((utxo.txout.clone(), utxo.is_internal)));
|
.insert(key, Box::new((utxo.txout.clone(), utxo.script_type)));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -231,11 +231,11 @@ impl BatchOperations for MemoryDatabase {
|
|||||||
match res {
|
match res {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(b) => {
|
Some(b) => {
|
||||||
let (txout, is_internal) = b.downcast_ref().cloned().unwrap();
|
let (txout, script_type) = b.downcast_ref().cloned().unwrap();
|
||||||
Ok(Some(UTXO {
|
Ok(Some(UTXO {
|
||||||
outpoint: *outpoint,
|
outpoint: *outpoint,
|
||||||
txout,
|
txout,
|
||||||
is_internal,
|
script_type,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,11 +322,11 @@ impl Database for MemoryDatabase {
|
|||||||
.range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
|
.range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
let outpoint = deserialize(&k[1..]).unwrap();
|
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 {
|
Ok(UTXO {
|
||||||
outpoint,
|
outpoint,
|
||||||
txout,
|
txout,
|
||||||
is_internal,
|
script_type,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
@ -385,11 +385,11 @@ impl Database for MemoryDatabase {
|
|||||||
fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
|
fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<UTXO>, Error> {
|
||||||
let key = MapKey::UTXO(Some(outpoint)).as_map_key();
|
let key = MapKey::UTXO(Some(outpoint)).as_map_key();
|
||||||
Ok(self.map.get(&key).map(|b| {
|
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 {
|
UTXO {
|
||||||
outpoint: *outpoint,
|
outpoint: *outpoint,
|
||||||
txout,
|
txout,
|
||||||
is_internal,
|
script_type,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -507,7 +507,7 @@ impl MemoryDatabase {
|
|||||||
txid,
|
txid,
|
||||||
vout: vout as u32,
|
vout: vout as u32,
|
||||||
},
|
},
|
||||||
is_internal: false,
|
script_type: ScriptType::External,
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ pub mod test {
|
|||||||
let utxo = UTXO {
|
let utxo = UTXO {
|
||||||
txout,
|
txout,
|
||||||
outpoint,
|
outpoint,
|
||||||
is_internal: false,
|
script_type: ScriptType::External,
|
||||||
};
|
};
|
||||||
|
|
||||||
tree.set_utxo(&utxo).unwrap();
|
tree.set_utxo(&utxo).unwrap();
|
||||||
|
@ -43,10 +43,6 @@ impl ScriptType {
|
|||||||
ScriptType::Internal => b'i',
|
ScriptType::Internal => b'i',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_internal(&self) -> bool {
|
|
||||||
self == &ScriptType::Internal
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<[u8]> for ScriptType {
|
impl AsRef<[u8]> for ScriptType {
|
||||||
@ -96,7 +92,7 @@ impl std::default::Default for FeeRate {
|
|||||||
pub struct UTXO {
|
pub struct UTXO {
|
||||||
pub outpoint: OutPoint,
|
pub outpoint: OutPoint,
|
||||||
pub txout: TxOut,
|
pub txout: TxOut,
|
||||||
pub is_internal: bool,
|
pub script_type: ScriptType,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wallet transaction
|
/// A wallet transaction
|
||||||
|
@ -538,7 +538,7 @@ mod test {
|
|||||||
value: 100_000,
|
value: 100_000,
|
||||||
script_pubkey: Script::new(),
|
script_pubkey: Script::new(),
|
||||||
},
|
},
|
||||||
is_internal: false,
|
script_type: ScriptType::External,
|
||||||
},
|
},
|
||||||
P2WPKH_WITNESS_SIZE,
|
P2WPKH_WITNESS_SIZE,
|
||||||
),
|
),
|
||||||
@ -552,7 +552,7 @@ mod test {
|
|||||||
value: 200_000,
|
value: 200_000,
|
||||||
script_pubkey: Script::new(),
|
script_pubkey: Script::new(),
|
||||||
},
|
},
|
||||||
is_internal: true,
|
script_type: ScriptType::Internal,
|
||||||
},
|
},
|
||||||
P2WPKH_WITNESS_SIZE,
|
P2WPKH_WITNESS_SIZE,
|
||||||
),
|
),
|
||||||
@ -572,7 +572,7 @@ mod test {
|
|||||||
value: rng.gen_range(0, 200000000),
|
value: rng.gen_range(0, 200000000),
|
||||||
script_pubkey: Script::new(),
|
script_pubkey: Script::new(),
|
||||||
},
|
},
|
||||||
is_internal: false,
|
script_type: ScriptType::External,
|
||||||
},
|
},
|
||||||
P2WPKH_WITNESS_SIZE,
|
P2WPKH_WITNESS_SIZE,
|
||||||
));
|
));
|
||||||
@ -591,7 +591,7 @@ mod test {
|
|||||||
value: utxos_value,
|
value: utxos_value,
|
||||||
script_pubkey: Script::new(),
|
script_pubkey: Script::new(),
|
||||||
},
|
},
|
||||||
is_internal: false,
|
script_type: ScriptType::External,
|
||||||
},
|
},
|
||||||
P2WPKH_WITNESS_SIZE,
|
P2WPKH_WITNESS_SIZE,
|
||||||
);
|
);
|
||||||
|
@ -611,18 +611,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let deriv_ctx = descriptor_to_pk_ctx(&self.secp);
|
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;
|
let original_sequence = tx.input[0].sequence;
|
||||||
|
|
||||||
// remove the inputs from the tx and process them
|
// remove the inputs from the tx and process them
|
||||||
@ -636,26 +624,31 @@ where
|
|||||||
.get_previous_output(&txin.previous_output)?
|
.get_previous_output(&txin.previous_output)?
|
||||||
.ok_or(Error::UnknownUTXO)?;
|
.ok_or(Error::UnknownUTXO)?;
|
||||||
|
|
||||||
let (weight, is_internal) = match self
|
let (weight, script_type) = match self
|
||||||
.database
|
.database
|
||||||
.borrow()
|
.borrow()
|
||||||
.get_path_from_script_pubkey(&txout.script_pubkey)?
|
.get_path_from_script_pubkey(&txout.script_pubkey)?
|
||||||
{
|
{
|
||||||
Some((ScriptType::Internal, _)) => (internal_weight, true),
|
Some((script_type, _)) => (
|
||||||
Some((ScriptType::External, _)) => (external_weight, false),
|
self.get_descriptor_for_script_type(script_type)
|
||||||
|
.0
|
||||||
|
.max_satisfaction_weight(deriv_ctx)
|
||||||
|
.unwrap(),
|
||||||
|
script_type,
|
||||||
|
),
|
||||||
None => {
|
None => {
|
||||||
// estimate the weight based on the scriptsig/witness size present in the
|
// estimate the weight based on the scriptsig/witness size present in the
|
||||||
// original transaction
|
// original transaction
|
||||||
let weight =
|
let weight =
|
||||||
serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len();
|
serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len();
|
||||||
(weight, false)
|
(weight, ScriptType::External)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let utxo = UTXO {
|
let utxo = UTXO {
|
||||||
outpoint: txin.previous_output,
|
outpoint: txin.previous_output,
|
||||||
txout,
|
txout,
|
||||||
is_internal,
|
script_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((utxo, weight))
|
Ok((utxo, weight))
|
||||||
@ -1052,30 +1045,20 @@ where
|
|||||||
|
|
||||||
fn get_available_utxos(&self) -> Result<Vec<(UTXO, usize)>, Error> {
|
fn get_available_utxos(&self) -> Result<Vec<(UTXO, usize)>, Error> {
|
||||||
let deriv_ctx = descriptor_to_pk_ctx(&self.secp);
|
let deriv_ctx = descriptor_to_pk_ctx(&self.secp);
|
||||||
|
Ok(self
|
||||||
let external_weight = self
|
.list_unspent()?
|
||||||
.get_descriptor_for_script_type(ScriptType::External)
|
.into_iter()
|
||||||
.0
|
.map(|utxo| {
|
||||||
.max_satisfaction_weight(deriv_ctx)
|
let script_type = utxo.script_type;
|
||||||
.unwrap();
|
(
|
||||||
let internal_weight = self
|
utxo,
|
||||||
.get_descriptor_for_script_type(ScriptType::Internal)
|
self.get_descriptor_for_script_type(script_type)
|
||||||
.0
|
.0
|
||||||
.max_satisfaction_weight(deriv_ctx)
|
.max_satisfaction_weight(deriv_ctx)
|
||||||
.unwrap();
|
.unwrap(),
|
||||||
|
)
|
||||||
let add_weight = |utxo: UTXO| {
|
})
|
||||||
let weight = match utxo.is_internal {
|
.collect())
|
||||||
true => internal_weight,
|
|
||||||
false => external_weight,
|
|
||||||
};
|
|
||||||
|
|
||||||
(utxo, weight)
|
|
||||||
};
|
|
||||||
|
|
||||||
let utxos = self.list_unspent()?.into_iter().map(add_weight).collect();
|
|
||||||
|
|
||||||
Ok(utxos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the options returns the list of utxos that must be used to form the
|
/// Given the options returns the list of utxos that must be used to form the
|
||||||
|
@ -566,8 +566,8 @@ impl ChangeSpendPolicy {
|
|||||||
pub(crate) fn is_satisfied_by(&self, utxo: &UTXO) -> bool {
|
pub(crate) fn is_satisfied_by(&self, utxo: &UTXO) -> bool {
|
||||||
match self {
|
match self {
|
||||||
ChangeSpendPolicy::ChangeAllowed => true,
|
ChangeSpendPolicy::ChangeAllowed => true,
|
||||||
ChangeSpendPolicy::OnlyChange => utxo.is_internal,
|
ChangeSpendPolicy::OnlyChange => utxo.script_type == ScriptType::Internal,
|
||||||
ChangeSpendPolicy::ChangeForbidden => !utxo.is_internal,
|
ChangeSpendPolicy::ChangeForbidden => utxo.script_type == ScriptType::External,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -662,7 +662,7 @@ mod test {
|
|||||||
vout: 0,
|
vout: 0,
|
||||||
},
|
},
|
||||||
txout: Default::default(),
|
txout: Default::default(),
|
||||||
is_internal: false,
|
script_type: ScriptType::External,
|
||||||
},
|
},
|
||||||
UTXO {
|
UTXO {
|
||||||
outpoint: OutPoint {
|
outpoint: OutPoint {
|
||||||
@ -670,7 +670,7 @@ mod test {
|
|||||||
vout: 1,
|
vout: 1,
|
||||||
},
|
},
|
||||||
txout: Default::default(),
|
txout: Default::default(),
|
||||||
is_internal: true,
|
script_type: ScriptType::Internal,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -695,7 +695,7 @@ mod test {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(filtered.len(), 1);
|
assert_eq!(filtered.len(), 1);
|
||||||
assert_eq!(filtered[0].is_internal, false);
|
assert_eq!(filtered[0].script_type, ScriptType::External);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -707,7 +707,7 @@ mod test {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(filtered.len(), 1);
|
assert_eq!(filtered.len(), 1);
|
||||||
assert_eq!(filtered[0].is_internal, true);
|
assert_eq!(filtered[0].script_type, ScriptType::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -120,7 +120,7 @@ pub fn bdk_blockchain_tests(attr: TokenStream, item: TokenStream) -> TokenStream
|
|||||||
wallet.sync(noop_progress(), None).unwrap();
|
wallet.sync(noop_progress(), None).unwrap();
|
||||||
|
|
||||||
assert_eq!(wallet.get_balance().unwrap(), 50_000);
|
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];
|
let list_tx_item = &wallet.list_transactions(false).unwrap()[0];
|
||||||
assert_eq!(list_tx_item.txid, txid);
|
assert_eq!(list_tx_item.txid, txid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user