perf(lite-backend): trim per-note witness history in place
The block scan replaced each note's witness list with the result of split_off(), which allocates a new buffer on every call: every block, each note with history paid an allocation and, once its list was full, a copy of all 100 entries. The duplicate of the newest witness is now pushed and, when the list exceeds 100 entries, the oldest is drained in place; notes with no history are skipped. The list keeps the same entries in the same order, so nothing in the output changes. The witness tests and the oracle pass, and a differential run against the unmodified backend is byte-identical (every witness entry and the whole saved file after every operation) apart from the lists the previous commit clears. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2237,15 +2237,16 @@ pub fn scan_full_mempool_tx(&self, tx: &Transaction, height: i32, _datetime: u64
|
||||
// Prepare the note witnesses for updating
|
||||
for tx in txs.values_mut() {
|
||||
for nd in tx.notes.iter_mut() {
|
||||
// Duplicate the most recent witness
|
||||
// Duplicate the most recent witness (nothing to do for notes with no history)
|
||||
if let Some(witness) = nd.witnesses.last() {
|
||||
let clone = witness.clone();
|
||||
nd.witnesses.push(clone);
|
||||
// Trim the oldest witnesses in place (no fresh Vec per note per block)
|
||||
let len = nd.witnesses.len();
|
||||
if len > MAX_REORG {
|
||||
nd.witnesses.drain(..len - MAX_REORG);
|
||||
}
|
||||
}
|
||||
// Trim the oldest witnesses
|
||||
nd.witnesses = nd
|
||||
.witnesses
|
||||
.split_off(nd.witnesses.len().saturating_sub(100));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user