mirror of
https://github.com/Qortal/piratewallet-light-cli.git
synced 2025-07-29 19:31:25 +00:00
Mark confirmed spent notes properly
This commit is contained in:
@@ -148,7 +148,8 @@ impl LightClient {
|
||||
"value" => nd.note.value,
|
||||
"is_change" => nd.is_change,
|
||||
"address" => LightWallet::address_from_extfvk(&nd.extfvk, nd.diversifier),
|
||||
"spent" => nd.spent.map(|spent_txid| format!("{}", spent_txid))
|
||||
"spent" => nd.spent.map(|spent_txid| format!("{}", spent_txid)),
|
||||
"unconfirmed_spent" => nd.unconfirmed_spent.map(|spent_txid| format!("{}", spent_txid)),
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@@ -99,9 +99,11 @@ pub struct SaplingNoteData {
|
||||
pub note: Note<Bls12>,
|
||||
witnesses: Vec<IncrementalWitness<Node>>,
|
||||
nullifier: [u8; 32],
|
||||
pub spent: Option<TxId>,
|
||||
pub spent: Option<TxId>, // If this note was confirmed spent
|
||||
pub unconfirmed_spent: Option<TxId>, // If this note was spent in a send, but has not yet been confirmed.
|
||||
pub memo: Option<Memo>,
|
||||
pub is_change: bool,
|
||||
// TODO: We need to remove the unconfirmed_spent (i.e., set it to None) if the Tx has expired
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +164,7 @@ impl SaplingNoteData {
|
||||
witnesses: vec![witness],
|
||||
nullifier: nf,
|
||||
spent: None,
|
||||
unconfirmed_spent: None,
|
||||
memo: None,
|
||||
is_change: output.is_change,
|
||||
}
|
||||
@@ -196,6 +199,9 @@ impl SaplingNoteData {
|
||||
let mut nullifier = [0u8; 32];
|
||||
reader.read_exact(&mut nullifier)?;
|
||||
|
||||
// Note that this is only the spent field, we ignore the unconfirmed_spent field.
|
||||
// The reason is that unconfirmed spents are only in memory, and we need to get the actual value of spent
|
||||
// from the blockchain anyway.
|
||||
let spent = Optional::read(&mut reader, |r| {
|
||||
let mut txid_bytes = [0u8; 32];
|
||||
r.read_exact(&mut txid_bytes)?;
|
||||
@@ -221,6 +227,7 @@ impl SaplingNoteData {
|
||||
witnesses,
|
||||
nullifier,
|
||||
spent,
|
||||
unconfirmed_spent: None,
|
||||
memo,
|
||||
is_change,
|
||||
})
|
||||
@@ -334,7 +341,8 @@ struct SpendableNote {
|
||||
|
||||
impl SpendableNote {
|
||||
fn from(txid: TxId, nd: &SaplingNoteData, anchor_offset: usize) -> Option<Self> {
|
||||
if nd.spent.is_none() {
|
||||
// Include only notes that haven't been spent, or haven't been included in an unconfirmed spend yet.
|
||||
if nd.spent.is_none() && nd.unconfirmed_spent.is_none() {
|
||||
let witness = nd.witnesses.get(nd.witnesses.len() - anchor_offset - 1);
|
||||
|
||||
witness.map(|w| SpendableNote {
|
||||
@@ -602,7 +610,7 @@ impl LightWallet {
|
||||
None => true
|
||||
}
|
||||
})
|
||||
.map(|nd| if nd.spent.is_none() { nd.note.value } else { 0 })
|
||||
.map(|nd| if nd.spent.is_none() && nd.unconfirmed_spent.is_none() { nd.note.value } else { 0 })
|
||||
.sum::<u64>()
|
||||
} else {
|
||||
0
|
||||
@@ -684,6 +692,8 @@ impl LightWallet {
|
||||
let mut txs = self.txs.write().unwrap();
|
||||
|
||||
// Create a Vec containing all unspent nullifiers.
|
||||
// Include only the confirmed spent nullifiers, since unconfirmed ones still need to be included
|
||||
// during scan_block below.
|
||||
let nfs: Vec<_> = txs
|
||||
.iter()
|
||||
.map(|(txid, tx)| {
|
||||
@@ -751,7 +761,11 @@ impl LightWallet {
|
||||
.iter_mut()
|
||||
.find(|nd| &nd.nullifier[..] == &spend.nf[..])
|
||||
.unwrap();
|
||||
|
||||
// Mark the note as spent, and remove the unconfirmed part of it
|
||||
spent_note.spent = Some(tx.txid);
|
||||
spent_note.unconfirmed_spent = None::<TxId>;
|
||||
|
||||
total_shielded_value_spent += spent_note.note.value;
|
||||
}
|
||||
|
||||
@@ -904,6 +918,7 @@ impl LightWallet {
|
||||
println!("Transaction ID: {}", tx.txid());
|
||||
|
||||
// Mark notes as spent.
|
||||
// TODO: This is only a non-confirmed spend, and the note should be marked as such.
|
||||
let mut txs = self.txs.write().unwrap();
|
||||
for selected in notes {
|
||||
let mut spent_note = txs
|
||||
@@ -913,7 +928,7 @@ impl LightWallet {
|
||||
.iter_mut()
|
||||
.find(|nd| &nd.nullifier[..] == &selected.nullifier[..])
|
||||
.unwrap();
|
||||
spent_note.spent = Some(tx.txid());
|
||||
spent_note.unconfirmed_spent = Some(tx.txid());
|
||||
}
|
||||
|
||||
// Return the encoded transaction, so the caller can send it.
|
||||
|
Reference in New Issue
Block a user