Merge branch 'bcmr-fix' into 'master'

bugfix: BCMR authchain

See merge request riftenlabs/riftenlabs-indexer!7
This commit is contained in:
Dagur Valberg Johannsson 2024-05-28 10:27:18 +00:00
commit f398b77974

View file

@ -192,22 +192,25 @@ pub fn index_bcmr(
})
.collect();
let mut position_index: HashMap<OutPointHash, usize> = HashMap::default();
// Look for authchain updates. We collect all candidates first.
let mut candidates: HashMap<OutPointHash, Transaction> = sorted
.into_iter()
let mut candidates: HashMap<OutPointHash, (&Transaction, usize)> = sorted
.par_iter()
.enumerate()
.filter_map(|(pos, tx)| {
let prevout = tx.input.first().expect("tx with no inputs").previous_output;
if prevout.vout != 0 {
// authchain needs to spend first output of a previous tx
None
} else {
let utxohash = compute_outpoint_hash(&prevout.txid, prevout.vout);
position_index.insert(utxohash, pos);
Some((utxohash, tx))
}
.flat_map(|(tx_pos, tx)| {
let tx_candidates: Vec<(OutPointHash, (&Transaction, usize))> = tx
.input
.iter()
.filter_map(|i| {
let prevout = &i.previous_output;
if prevout.vout != 0 {
// authchain needs to spend first output of a previous tx
None
} else {
let utxohash = compute_outpoint_hash(&prevout.txid, prevout.vout);
Some((utxohash, (tx, tx_pos)))
}
})
.collect();
tx_candidates
})
.collect();
@ -247,11 +250,11 @@ pub fn index_bcmr(
let mut smallest_index = usize::MAX;
for prev_autheader in matches {
let tx = candidates
let (tx, tx_pos) = candidates
.remove(&prev_autheader.utxo)
.expect("match not in candidate list");
let bcmr = parse_bcmr(&tx);
let bcmr = parse_bcmr(tx);
let txid = tx.txid();
let utxohash = compute_outpoint_hash(&txid, 0);
@ -274,25 +277,15 @@ pub fn index_bcmr(
bcmr.map(|bcmr| bcmr.op_return),
)?;
smallest_index = cmp::min(
smallest_index,
*position_index
.get(&prev_autheader.utxo)
.expect("entry not in position index"),
);
smallest_index = cmp::min(smallest_index, tx_pos);
inserts += 1;
}
// since it's ttor sorted; there can be no chained updates above the first candidate;
// and we can remove all candidates above smallest_index
position_index.retain(|hash, pos| {
if pos > &mut smallest_index {
true
} else {
candidates.remove(hash);
false
}
});
// Because transactions are TTOR sorted; there will be no new candidates above the "smallest index" autheader.
candidates = candidates
.into_par_iter()
.filter(|(_, (_, tx_pos))| tx_pos > &smallest_index)
.collect();
}
Ok(inserts)