Skip to content

Commit 84e721d

Browse files
committed
rust: populate script_pubkey and derivation_path
Using data from the db given the txid/vout
1 parent e58cc87 commit 84e721d

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

subprojects/gdk_rust/gdk_electrum/src/account.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,11 +906,39 @@ pub fn discover_account(
906906
Ok(false)
907907
}
908908

909+
/// Populate `derivation_path` and `scriptpubkey` in `UnspentOutput` by looking in our internal
910+
/// cache by provided `subaccount`, `txid` and `pt_idx` (vout) and return an error if not present.
911+
/// This allows to have this data if missing, but also avoid trusting the user input for this fields.
912+
pub fn populate_unspent_from_db(
913+
account: &Account,
914+
request: &mut CreateTransaction,
915+
) -> Result<(), Error> {
916+
let store = account.store.read()?;
917+
918+
for u in request.utxos.0.values_mut().flat_map(|e| e.iter_mut()) {
919+
let cache = store.account_cache(u.subaccount)?;
920+
let txid = BETxid::from_hex(&u.txhash, account.network.id())?;
921+
let tx_entry = cache.all_txs.get(&txid).ok_or_else(|| Error::TxNotFound(txid))?;
922+
let tx = &tx_entry.tx;
923+
let vout = u.pt_idx;
924+
if (vout as usize) >= tx.output_len() {
925+
return Err(Error::Generic("vout greater or equal number of outputs".into()));
926+
}
927+
let script_pubkey = tx.output_script(vout);
928+
let derivation_path =
929+
cache.paths.get(&script_pubkey).ok_or_else(|| Error::ScriptPubkeyNotFound)?;
930+
u.user_path = account.get_full_path(derivation_path).into();
931+
u.scriptpubkey = script_pubkey;
932+
}
933+
Ok(())
934+
}
935+
909936
#[allow(clippy::cognitive_complexity)]
910937
pub fn create_tx(
911938
account: &Account,
912939
request: &mut CreateTransaction,
913940
) -> Result<TransactionMeta, Error> {
941+
let _ = populate_unspent_from_db(account, request);
914942
info!("create_tx {:?}", request);
915943

916944
let network = &account.network;

0 commit comments

Comments
 (0)