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