Merge commit 'refs/pull/210/head' of github.com:bitcoindevkit/bdk

This commit is contained in:
Alekos Filini 2020-12-07 11:21:21 +01:00
commit eef59e463d
No known key found for this signature in database
GPG Key ID: 5E8AFC3034FDFA4F
10 changed files with 54 additions and 75 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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()

View File

@ -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();
} }

View File

@ -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();

View File

@ -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

View File

@ -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,
); );

View File

@ -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

View File

@ -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]

View File

@ -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);