Skip to content

Commit

Permalink
Merge pull request zingolabs#1230 from fluidvanadium/missing_index_bug
Browse files Browse the repository at this point in the history
Missing index bug
  • Loading branch information
zancas authored Jun 19, 2024
2 parents c0e4e68 + b77ceb4 commit 361854c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
16 changes: 12 additions & 4 deletions zingolib/src/wallet/transaction_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,9 @@ impl TransactionRecord {
&self,
sources: &[zcash_client_backend::ShieldedProtocol],
exclude: &[NoteId],
) -> Vec<(NoteId, u64)> {
) -> Result<Vec<(NoteId, u64)>, ()> {
let mut all = vec![];
let mut missing_output_index = false;
if sources.contains(&Sapling) {
self.sapling_notes.iter().for_each(|zingo_sapling_note| {
if zingo_sapling_note.is_unspent() {
Expand All @@ -380,6 +381,7 @@ impl TransactionRecord {
}
} else {
println!("note has no index");
missing_output_index = true;
}
}
});
Expand All @@ -394,11 +396,16 @@ impl TransactionRecord {
}
} else {
println!("note has no index");
missing_output_index = true;
}
}
});
}
all
if missing_output_index {
Err(())
} else {
Ok(all)
}
}
}
// read/write
Expand Down Expand Up @@ -979,8 +986,9 @@ mod tests {
fn select_spendable_note_ids_and_values() {
let transaction_record = nine_note_transaction_record_default();

let unspent_ids_and_values =
transaction_record.get_spendable_note_ids_and_values(&[Sapling, Orchard], &[]);
let unspent_ids_and_values = transaction_record
.get_spendable_note_ids_and_values(&[Sapling, Orchard], &[])
.unwrap();

assert_eq!(
unspent_ids_and_values,
Expand Down
22 changes: 18 additions & 4 deletions zingolib/src/wallet/transaction_records_by_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,19 +668,33 @@ impl TransactionRecordsById {
sources: &[zcash_client_backend::ShieldedProtocol],
anchor_height: zcash_primitives::consensus::BlockHeight,
exclude: &[NoteId],
) -> Vec<(NoteId, u64)> {
self.values()
) -> Result<Vec<(NoteId, u64)>, Vec<TxId>> {
let mut missing_output_index = vec![];
let ok = self
.values()
.flat_map(|transaction_record| {
if transaction_record
.status
.is_confirmed_before_or_at(&anchor_height)
{
transaction_record.get_spendable_note_ids_and_values(sources, exclude)
if let Ok(notes_from_tx) =
transaction_record.get_spendable_note_ids_and_values(sources, exclude)
{
notes_from_tx
} else {
missing_output_index.push(transaction_record.txid);
vec![]
}
} else {
vec![]
}
})
.collect()
.collect();
if missing_output_index.is_empty() {
Ok(ok)
} else {
Err(missing_output_index)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use zcash_primitives::{
transaction::{
components::{amount::NonNegativeAmount, TxOut},
fees::zip317::MARGINAL_FEE,
TxId,
},
};

Expand All @@ -36,6 +37,9 @@ pub enum InputSourceError {
/// Value outside the valid range of zatoshis
#[error("Value outside valid range of zatoshis. {0:?}")]
InvalidValue(BalanceError),
/// Wallet data is out of date
#[error("Output index data is missing! Wallet data is out of date, please rescan.")]
MissingOutputIndexes(Vec<TxId>),
}

// Calculate remaining difference between target and selected.
Expand Down Expand Up @@ -191,6 +195,7 @@ impl InputSource for TransactionRecordsById {
) -> Result<SpendableNotes<Self::NoteRef>, Self::Error> {
let mut unselected = self
.get_spendable_note_ids_and_values(sources, anchor_height, exclude)
.map_err(InputSourceError::MissingOutputIndexes)?
.into_iter()
.map(|(id, value)| NonNegativeAmount::from_u64(value).map(|value| (id, value)))
.collect::<Result<Vec<_>, _>>()
Expand Down

0 comments on commit 361854c

Please sign in to comment.