From 0000831b188c619fecce46e31fb71c322e4c127e Mon Sep 17 00:00:00 2001 From: raphjaph Date: Mon, 13 Nov 2023 17:23:12 -0300 Subject: [PATCH 1/4] Fix lost sats bug --- src/index.rs | 8 +- src/index/updater.rs | 236 +++++++++++++++++++++---------------------- 2 files changed, 124 insertions(+), 120 deletions(-) diff --git a/src/index.rs b/src/index.rs index 9ce53cfaca..9f56aea601 100644 --- a/src/index.rs +++ b/src/index.rs @@ -2348,7 +2348,9 @@ mod tests { #[test] fn lost_sats_are_tracked_correctly() { - let context = Context::builder().arg("--index-sats").build(); + let context = Context::builder() + .args(["--index-sats", "--first-inscription-height", "10"]) + .build(); assert_eq!(context.index.statistic(Statistic::LostSats), 0); context.mine_blocks(1); @@ -2375,7 +2377,9 @@ mod tests { #[test] fn lost_sat_ranges_are_tracked_correctly() { - let context = Context::builder().arg("--index-sats").build(); + let context = Context::builder() + .args(["--index-sats", "--first-inscription-height", "10"]) + .build(); let null_ranges = || match context.index.list(OutPoint::null()).unwrap().unwrap() { List::Unspent(ranges) => ranges, diff --git a/src/index/updater.rs b/src/index/updater.rs index 4affe64fdf..de6ba1f56f 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -410,147 +410,147 @@ impl<'index> Updater<'_> { .map(|unbound_inscriptions| unbound_inscriptions.value()) .unwrap_or(0); - { - let mut inscription_updater = InscriptionUpdater::new( - self.height, - &mut inscription_id_to_children, - &mut inscription_id_to_satpoint, - value_receiver, - &mut inscription_id_to_inscription_entry, - lost_sats, - &mut inscription_number_to_inscription_id, - cursed_inscription_count, - blessed_inscription_count, - &mut sequence_number_to_inscription_id, - &mut outpoint_to_value, - &mut sat_to_inscription_id, - &mut satpoint_to_inscription_id, - block.header.time, - unbound_inscriptions, - value_cache, - )?; - - if self.index.index_sats { - let mut sat_to_satpoint = wtx.open_table(SAT_TO_SATPOINT)?; - let mut outpoint_to_sat_ranges = wtx.open_table(OUTPOINT_TO_SAT_RANGES)?; + let mut inscription_updater = InscriptionUpdater::new( + self.height, + &mut inscription_id_to_children, + &mut inscription_id_to_satpoint, + value_receiver, + &mut inscription_id_to_inscription_entry, + lost_sats, + &mut inscription_number_to_inscription_id, + cursed_inscription_count, + blessed_inscription_count, + &mut sequence_number_to_inscription_id, + &mut outpoint_to_value, + &mut sat_to_inscription_id, + &mut satpoint_to_inscription_id, + block.header.time, + unbound_inscriptions, + value_cache, + )?; - let mut coinbase_inputs = VecDeque::new(); + if self.index.index_sats { + let mut sat_to_satpoint = wtx.open_table(SAT_TO_SATPOINT)?; + let mut outpoint_to_sat_ranges = wtx.open_table(OUTPOINT_TO_SAT_RANGES)?; - let h = Height(self.height); - if h.subsidy() > 0 { - let start = h.starting_sat(); - coinbase_inputs.push_front((start.n(), (start + h.subsidy()).n())); - self.sat_ranges_since_flush += 1; - } + let mut coinbase_inputs = VecDeque::new(); - for (tx_offset, (tx, txid)) in block.txdata.iter().enumerate().skip(1) { - log::trace!("Indexing transaction {tx_offset}…"); + let h = Height(self.height); + if h.subsidy() > 0 { + let start = h.starting_sat(); + coinbase_inputs.push_front((start.n(), (start + h.subsidy()).n())); + self.sat_ranges_since_flush += 1; + } - let mut input_sat_ranges = VecDeque::new(); + for (tx_offset, (tx, txid)) in block.txdata.iter().enumerate().skip(1) { + log::trace!("Indexing transaction {tx_offset}…"); - for input in &tx.input { - let key = input.previous_output.store(); + let mut input_sat_ranges = VecDeque::new(); - let sat_ranges = match self.range_cache.remove(&key) { - Some(sat_ranges) => { - self.outputs_cached += 1; - sat_ranges - } - None => outpoint_to_sat_ranges - .remove(&key)? - .ok_or_else(|| { - anyhow!("Could not find outpoint {} in index", input.previous_output) - })? - .value() - .to_vec(), - }; + for input in &tx.input { + let key = input.previous_output.store(); - for chunk in sat_ranges.chunks_exact(11) { - input_sat_ranges.push_back(SatRange::load(chunk.try_into().unwrap())); + let sat_ranges = match self.range_cache.remove(&key) { + Some(sat_ranges) => { + self.outputs_cached += 1; + sat_ranges } - } - - self.index_transaction_sats( - tx, - *txid, - &mut sat_to_satpoint, - &mut input_sat_ranges, - &mut sat_ranges_written, - &mut outputs_in_block, - &mut inscription_updater, - index_inscriptions, - )?; - - coinbase_inputs.extend(input_sat_ranges); - } + None => outpoint_to_sat_ranges + .remove(&key)? + .ok_or_else(|| anyhow!("Could not find outpoint {} in index", input.previous_output))? + .value() + .to_vec(), + }; - if let Some((tx, txid)) = block.txdata.get(0) { - self.index_transaction_sats( - tx, - *txid, - &mut sat_to_satpoint, - &mut coinbase_inputs, - &mut sat_ranges_written, - &mut outputs_in_block, - &mut inscription_updater, - index_inscriptions, - )?; + for chunk in sat_ranges.chunks_exact(11) { + input_sat_ranges.push_back(SatRange::load(chunk.try_into().unwrap())); + } } - if !coinbase_inputs.is_empty() { - let mut lost_sat_ranges = outpoint_to_sat_ranges - .remove(&OutPoint::null().store())? - .map(|ranges| ranges.value().to_vec()) - .unwrap_or_default(); - - for (start, end) in coinbase_inputs { - if !Sat(start).is_common() { - sat_to_satpoint.insert( - &start, - &SatPoint { - outpoint: OutPoint::null(), - offset: lost_sats, - } - .store(), - )?; - } + self.index_transaction_sats( + tx, + *txid, + &mut sat_to_satpoint, + &mut input_sat_ranges, + &mut sat_ranges_written, + &mut outputs_in_block, + &mut inscription_updater, + index_inscriptions, + )?; + + coinbase_inputs.extend(input_sat_ranges); + } - lost_sat_ranges.extend_from_slice(&(start, end).store()); + if let Some((tx, txid)) = block.txdata.get(0) { + self.index_transaction_sats( + tx, + *txid, + &mut sat_to_satpoint, + &mut coinbase_inputs, + &mut sat_ranges_written, + &mut outputs_in_block, + &mut inscription_updater, + index_inscriptions, + )?; + } - lost_sats += end - start; + if !coinbase_inputs.is_empty() { + let mut lost_sat_ranges = outpoint_to_sat_ranges + .remove(&OutPoint::null().store())? + .map(|ranges| ranges.value().to_vec()) + .unwrap_or_default(); + + for (start, end) in coinbase_inputs { + if !Sat(start).is_common() { + sat_to_satpoint.insert( + &start, + &SatPoint { + outpoint: OutPoint::null(), + offset: lost_sats, + } + .store(), + )?; } - outpoint_to_sat_ranges.insert(&OutPoint::null().store(), lost_sat_ranges.as_slice())?; - } - } else { - for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) { - inscription_updater.index_envelopes(tx, *txid, None)?; + lost_sat_ranges.extend_from_slice(&(start, end).store()); + + lost_sats += end - start; } + + outpoint_to_sat_ranges.insert(&OutPoint::null().store(), lost_sat_ranges.as_slice())?; } + } else { + for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) { + inscription_updater.index_envelopes(tx, *txid, None)?; + } + } - self.index_block_inscription_numbers( - &mut height_to_last_sequence_number, - &inscription_updater, - index_inscriptions, - )?; + self.index_block_inscription_numbers( + &mut height_to_last_sequence_number, + &inscription_updater, + index_inscriptions, + )?; + if !index_inscriptions && self.index.index_sats { + statistic_to_count.insert(&Statistic::LostSats.key(), &lost_sats)?; + } else { statistic_to_count.insert(&Statistic::LostSats.key(), &inscription_updater.lost_sats)?; + } - statistic_to_count.insert( - &Statistic::CursedInscriptions.key(), - &inscription_updater.cursed_inscription_count, - )?; + statistic_to_count.insert( + &Statistic::CursedInscriptions.key(), + &inscription_updater.cursed_inscription_count, + )?; - statistic_to_count.insert( - &Statistic::BlessedInscriptions.key(), - &inscription_updater.blessed_inscription_count, - )?; + statistic_to_count.insert( + &Statistic::BlessedInscriptions.key(), + &inscription_updater.blessed_inscription_count, + )?; - statistic_to_count.insert( - &Statistic::UnboundInscriptions.key(), - &inscription_updater.unbound_inscriptions, - )?; - } + statistic_to_count.insert( + &Statistic::UnboundInscriptions.key(), + &inscription_updater.unbound_inscriptions, + )?; if index.index_runes { let mut outpoint_to_rune_balances = wtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?; From 9de5b4dea1b18409f405e3d56fab834b155ac153 Mon Sep 17 00:00:00 2001 From: raphjaph Date: Mon, 13 Nov 2023 17:26:24 -0300 Subject: [PATCH 2/4] quick fix --- src/index/updater.rs | 242 ++++++++++++++++++++++--------------------- 1 file changed, 123 insertions(+), 119 deletions(-) diff --git a/src/index/updater.rs b/src/index/updater.rs index de6ba1f56f..0f5463d537 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -410,147 +410,151 @@ impl<'index> Updater<'_> { .map(|unbound_inscriptions| unbound_inscriptions.value()) .unwrap_or(0); - let mut inscription_updater = InscriptionUpdater::new( - self.height, - &mut inscription_id_to_children, - &mut inscription_id_to_satpoint, - value_receiver, - &mut inscription_id_to_inscription_entry, - lost_sats, - &mut inscription_number_to_inscription_id, - cursed_inscription_count, - blessed_inscription_count, - &mut sequence_number_to_inscription_id, - &mut outpoint_to_value, - &mut sat_to_inscription_id, - &mut satpoint_to_inscription_id, - block.header.time, - unbound_inscriptions, - value_cache, - )?; + { + let mut inscription_updater = InscriptionUpdater::new( + self.height, + &mut inscription_id_to_children, + &mut inscription_id_to_satpoint, + value_receiver, + &mut inscription_id_to_inscription_entry, + lost_sats, + &mut inscription_number_to_inscription_id, + cursed_inscription_count, + blessed_inscription_count, + &mut sequence_number_to_inscription_id, + &mut outpoint_to_value, + &mut sat_to_inscription_id, + &mut satpoint_to_inscription_id, + block.header.time, + unbound_inscriptions, + value_cache, + )?; - if self.index.index_sats { - let mut sat_to_satpoint = wtx.open_table(SAT_TO_SATPOINT)?; - let mut outpoint_to_sat_ranges = wtx.open_table(OUTPOINT_TO_SAT_RANGES)?; + if self.index.index_sats { + let mut sat_to_satpoint = wtx.open_table(SAT_TO_SATPOINT)?; + let mut outpoint_to_sat_ranges = wtx.open_table(OUTPOINT_TO_SAT_RANGES)?; - let mut coinbase_inputs = VecDeque::new(); + let mut coinbase_inputs = VecDeque::new(); - let h = Height(self.height); - if h.subsidy() > 0 { - let start = h.starting_sat(); - coinbase_inputs.push_front((start.n(), (start + h.subsidy()).n())); - self.sat_ranges_since_flush += 1; - } + let h = Height(self.height); + if h.subsidy() > 0 { + let start = h.starting_sat(); + coinbase_inputs.push_front((start.n(), (start + h.subsidy()).n())); + self.sat_ranges_since_flush += 1; + } - for (tx_offset, (tx, txid)) in block.txdata.iter().enumerate().skip(1) { - log::trace!("Indexing transaction {tx_offset}…"); + for (tx_offset, (tx, txid)) in block.txdata.iter().enumerate().skip(1) { + log::trace!("Indexing transaction {tx_offset}…"); - let mut input_sat_ranges = VecDeque::new(); + let mut input_sat_ranges = VecDeque::new(); - for input in &tx.input { - let key = input.previous_output.store(); + for input in &tx.input { + let key = input.previous_output.store(); - let sat_ranges = match self.range_cache.remove(&key) { - Some(sat_ranges) => { - self.outputs_cached += 1; - sat_ranges - } - None => outpoint_to_sat_ranges - .remove(&key)? - .ok_or_else(|| anyhow!("Could not find outpoint {} in index", input.previous_output))? - .value() - .to_vec(), - }; + let sat_ranges = match self.range_cache.remove(&key) { + Some(sat_ranges) => { + self.outputs_cached += 1; + sat_ranges + } + None => outpoint_to_sat_ranges + .remove(&key)? + .ok_or_else(|| { + anyhow!("Could not find outpoint {} in index", input.previous_output) + })? + .value() + .to_vec(), + }; - for chunk in sat_ranges.chunks_exact(11) { - input_sat_ranges.push_back(SatRange::load(chunk.try_into().unwrap())); + for chunk in sat_ranges.chunks_exact(11) { + input_sat_ranges.push_back(SatRange::load(chunk.try_into().unwrap())); + } } + + self.index_transaction_sats( + tx, + *txid, + &mut sat_to_satpoint, + &mut input_sat_ranges, + &mut sat_ranges_written, + &mut outputs_in_block, + &mut inscription_updater, + index_inscriptions, + )?; + + coinbase_inputs.extend(input_sat_ranges); } - self.index_transaction_sats( - tx, - *txid, - &mut sat_to_satpoint, - &mut input_sat_ranges, - &mut sat_ranges_written, - &mut outputs_in_block, - &mut inscription_updater, - index_inscriptions, - )?; - - coinbase_inputs.extend(input_sat_ranges); - } + if let Some((tx, txid)) = block.txdata.get(0) { + self.index_transaction_sats( + tx, + *txid, + &mut sat_to_satpoint, + &mut coinbase_inputs, + &mut sat_ranges_written, + &mut outputs_in_block, + &mut inscription_updater, + index_inscriptions, + )?; + } - if let Some((tx, txid)) = block.txdata.get(0) { - self.index_transaction_sats( - tx, - *txid, - &mut sat_to_satpoint, - &mut coinbase_inputs, - &mut sat_ranges_written, - &mut outputs_in_block, - &mut inscription_updater, - index_inscriptions, - )?; - } + if !coinbase_inputs.is_empty() { + let mut lost_sat_ranges = outpoint_to_sat_ranges + .remove(&OutPoint::null().store())? + .map(|ranges| ranges.value().to_vec()) + .unwrap_or_default(); + + for (start, end) in coinbase_inputs { + if !Sat(start).is_common() { + sat_to_satpoint.insert( + &start, + &SatPoint { + outpoint: OutPoint::null(), + offset: lost_sats, + } + .store(), + )?; + } - if !coinbase_inputs.is_empty() { - let mut lost_sat_ranges = outpoint_to_sat_ranges - .remove(&OutPoint::null().store())? - .map(|ranges| ranges.value().to_vec()) - .unwrap_or_default(); - - for (start, end) in coinbase_inputs { - if !Sat(start).is_common() { - sat_to_satpoint.insert( - &start, - &SatPoint { - outpoint: OutPoint::null(), - offset: lost_sats, - } - .store(), - )?; - } + lost_sat_ranges.extend_from_slice(&(start, end).store()); - lost_sat_ranges.extend_from_slice(&(start, end).store()); + lost_sats += end - start; + } - lost_sats += end - start; + outpoint_to_sat_ranges.insert(&OutPoint::null().store(), lost_sat_ranges.as_slice())?; + } + } else { + for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) { + inscription_updater.index_envelopes(tx, *txid, None)?; } - - outpoint_to_sat_ranges.insert(&OutPoint::null().store(), lost_sat_ranges.as_slice())?; - } - } else { - for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) { - inscription_updater.index_envelopes(tx, *txid, None)?; } - } - self.index_block_inscription_numbers( - &mut height_to_last_sequence_number, - &inscription_updater, - index_inscriptions, - )?; + self.index_block_inscription_numbers( + &mut height_to_last_sequence_number, + &inscription_updater, + index_inscriptions, + )?; - if !index_inscriptions && self.index.index_sats { - statistic_to_count.insert(&Statistic::LostSats.key(), &lost_sats)?; - } else { - statistic_to_count.insert(&Statistic::LostSats.key(), &inscription_updater.lost_sats)?; - } + if !index_inscriptions && self.index.index_sats { + statistic_to_count.insert(&Statistic::LostSats.key(), &lost_sats)?; + } else { + statistic_to_count.insert(&Statistic::LostSats.key(), &inscription_updater.lost_sats)?; + } - statistic_to_count.insert( - &Statistic::CursedInscriptions.key(), - &inscription_updater.cursed_inscription_count, - )?; + statistic_to_count.insert( + &Statistic::CursedInscriptions.key(), + &inscription_updater.cursed_inscription_count, + )?; - statistic_to_count.insert( - &Statistic::BlessedInscriptions.key(), - &inscription_updater.blessed_inscription_count, - )?; + statistic_to_count.insert( + &Statistic::BlessedInscriptions.key(), + &inscription_updater.blessed_inscription_count, + )?; - statistic_to_count.insert( - &Statistic::UnboundInscriptions.key(), - &inscription_updater.unbound_inscriptions, - )?; + statistic_to_count.insert( + &Statistic::UnboundInscriptions.key(), + &inscription_updater.unbound_inscriptions, + )?; + } if index.index_runes { let mut outpoint_to_rune_balances = wtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?; From 01111577fc1843b89fa2ba99805d7bb57160f0a6 Mon Sep 17 00:00:00 2001 From: raphjaph Date: Mon, 13 Nov 2023 17:35:58 -0300 Subject: [PATCH 3/4] quick fix --- src/index/updater.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/index/updater.rs b/src/index/updater.rs index 0f5463d537..4b478baeaf 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -534,11 +534,14 @@ impl<'index> Updater<'_> { index_inscriptions, )?; - if !index_inscriptions && self.index.index_sats { - statistic_to_count.insert(&Statistic::LostSats.key(), &lost_sats)?; - } else { - statistic_to_count.insert(&Statistic::LostSats.key(), &inscription_updater.lost_sats)?; - } + statistic_to_count.insert( + &Statistic::LostSats.key(), + &if self.index.index_sats { + lost_sats + } else { + inscription_updater.lost_sats + }, + )?; statistic_to_count.insert( &Statistic::CursedInscriptions.key(), From 54f5094b92ea58342a95644b64af3b1f4379746d Mon Sep 17 00:00:00 2001 From: raphjaph Date: Mon, 13 Nov 2023 17:36:55 -0300 Subject: [PATCH 4/4] remove unnecessary braces --- src/index/updater.rs | 254 +++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 129 deletions(-) diff --git a/src/index/updater.rs b/src/index/updater.rs index 4b478baeaf..71521efc63 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -410,154 +410,150 @@ impl<'index> Updater<'_> { .map(|unbound_inscriptions| unbound_inscriptions.value()) .unwrap_or(0); - { - let mut inscription_updater = InscriptionUpdater::new( - self.height, - &mut inscription_id_to_children, - &mut inscription_id_to_satpoint, - value_receiver, - &mut inscription_id_to_inscription_entry, - lost_sats, - &mut inscription_number_to_inscription_id, - cursed_inscription_count, - blessed_inscription_count, - &mut sequence_number_to_inscription_id, - &mut outpoint_to_value, - &mut sat_to_inscription_id, - &mut satpoint_to_inscription_id, - block.header.time, - unbound_inscriptions, - value_cache, - )?; - - if self.index.index_sats { - let mut sat_to_satpoint = wtx.open_table(SAT_TO_SATPOINT)?; - let mut outpoint_to_sat_ranges = wtx.open_table(OUTPOINT_TO_SAT_RANGES)?; + let mut inscription_updater = InscriptionUpdater::new( + self.height, + &mut inscription_id_to_children, + &mut inscription_id_to_satpoint, + value_receiver, + &mut inscription_id_to_inscription_entry, + lost_sats, + &mut inscription_number_to_inscription_id, + cursed_inscription_count, + blessed_inscription_count, + &mut sequence_number_to_inscription_id, + &mut outpoint_to_value, + &mut sat_to_inscription_id, + &mut satpoint_to_inscription_id, + block.header.time, + unbound_inscriptions, + value_cache, + )?; - let mut coinbase_inputs = VecDeque::new(); + if self.index.index_sats { + let mut sat_to_satpoint = wtx.open_table(SAT_TO_SATPOINT)?; + let mut outpoint_to_sat_ranges = wtx.open_table(OUTPOINT_TO_SAT_RANGES)?; - let h = Height(self.height); - if h.subsidy() > 0 { - let start = h.starting_sat(); - coinbase_inputs.push_front((start.n(), (start + h.subsidy()).n())); - self.sat_ranges_since_flush += 1; - } + let mut coinbase_inputs = VecDeque::new(); - for (tx_offset, (tx, txid)) in block.txdata.iter().enumerate().skip(1) { - log::trace!("Indexing transaction {tx_offset}…"); + let h = Height(self.height); + if h.subsidy() > 0 { + let start = h.starting_sat(); + coinbase_inputs.push_front((start.n(), (start + h.subsidy()).n())); + self.sat_ranges_since_flush += 1; + } - let mut input_sat_ranges = VecDeque::new(); + for (tx_offset, (tx, txid)) in block.txdata.iter().enumerate().skip(1) { + log::trace!("Indexing transaction {tx_offset}…"); - for input in &tx.input { - let key = input.previous_output.store(); + let mut input_sat_ranges = VecDeque::new(); - let sat_ranges = match self.range_cache.remove(&key) { - Some(sat_ranges) => { - self.outputs_cached += 1; - sat_ranges - } - None => outpoint_to_sat_ranges - .remove(&key)? - .ok_or_else(|| { - anyhow!("Could not find outpoint {} in index", input.previous_output) - })? - .value() - .to_vec(), - }; + for input in &tx.input { + let key = input.previous_output.store(); - for chunk in sat_ranges.chunks_exact(11) { - input_sat_ranges.push_back(SatRange::load(chunk.try_into().unwrap())); + let sat_ranges = match self.range_cache.remove(&key) { + Some(sat_ranges) => { + self.outputs_cached += 1; + sat_ranges } - } - - self.index_transaction_sats( - tx, - *txid, - &mut sat_to_satpoint, - &mut input_sat_ranges, - &mut sat_ranges_written, - &mut outputs_in_block, - &mut inscription_updater, - index_inscriptions, - )?; - - coinbase_inputs.extend(input_sat_ranges); - } + None => outpoint_to_sat_ranges + .remove(&key)? + .ok_or_else(|| anyhow!("Could not find outpoint {} in index", input.previous_output))? + .value() + .to_vec(), + }; - if let Some((tx, txid)) = block.txdata.get(0) { - self.index_transaction_sats( - tx, - *txid, - &mut sat_to_satpoint, - &mut coinbase_inputs, - &mut sat_ranges_written, - &mut outputs_in_block, - &mut inscription_updater, - index_inscriptions, - )?; + for chunk in sat_ranges.chunks_exact(11) { + input_sat_ranges.push_back(SatRange::load(chunk.try_into().unwrap())); + } } - if !coinbase_inputs.is_empty() { - let mut lost_sat_ranges = outpoint_to_sat_ranges - .remove(&OutPoint::null().store())? - .map(|ranges| ranges.value().to_vec()) - .unwrap_or_default(); - - for (start, end) in coinbase_inputs { - if !Sat(start).is_common() { - sat_to_satpoint.insert( - &start, - &SatPoint { - outpoint: OutPoint::null(), - offset: lost_sats, - } - .store(), - )?; - } + self.index_transaction_sats( + tx, + *txid, + &mut sat_to_satpoint, + &mut input_sat_ranges, + &mut sat_ranges_written, + &mut outputs_in_block, + &mut inscription_updater, + index_inscriptions, + )?; + + coinbase_inputs.extend(input_sat_ranges); + } - lost_sat_ranges.extend_from_slice(&(start, end).store()); + if let Some((tx, txid)) = block.txdata.get(0) { + self.index_transaction_sats( + tx, + *txid, + &mut sat_to_satpoint, + &mut coinbase_inputs, + &mut sat_ranges_written, + &mut outputs_in_block, + &mut inscription_updater, + index_inscriptions, + )?; + } - lost_sats += end - start; + if !coinbase_inputs.is_empty() { + let mut lost_sat_ranges = outpoint_to_sat_ranges + .remove(&OutPoint::null().store())? + .map(|ranges| ranges.value().to_vec()) + .unwrap_or_default(); + + for (start, end) in coinbase_inputs { + if !Sat(start).is_common() { + sat_to_satpoint.insert( + &start, + &SatPoint { + outpoint: OutPoint::null(), + offset: lost_sats, + } + .store(), + )?; } - outpoint_to_sat_ranges.insert(&OutPoint::null().store(), lost_sat_ranges.as_slice())?; - } - } else { - for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) { - inscription_updater.index_envelopes(tx, *txid, None)?; - } - } + lost_sat_ranges.extend_from_slice(&(start, end).store()); - self.index_block_inscription_numbers( - &mut height_to_last_sequence_number, - &inscription_updater, - index_inscriptions, - )?; - - statistic_to_count.insert( - &Statistic::LostSats.key(), - &if self.index.index_sats { - lost_sats - } else { - inscription_updater.lost_sats - }, - )?; + lost_sats += end - start; + } - statistic_to_count.insert( - &Statistic::CursedInscriptions.key(), - &inscription_updater.cursed_inscription_count, - )?; + outpoint_to_sat_ranges.insert(&OutPoint::null().store(), lost_sat_ranges.as_slice())?; + } + } else { + for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) { + inscription_updater.index_envelopes(tx, *txid, None)?; + } + } - statistic_to_count.insert( - &Statistic::BlessedInscriptions.key(), - &inscription_updater.blessed_inscription_count, - )?; + self.index_block_inscription_numbers( + &mut height_to_last_sequence_number, + &inscription_updater, + index_inscriptions, + )?; - statistic_to_count.insert( - &Statistic::UnboundInscriptions.key(), - &inscription_updater.unbound_inscriptions, - )?; - } + statistic_to_count.insert( + &Statistic::LostSats.key(), + &if self.index.index_sats { + lost_sats + } else { + inscription_updater.lost_sats + }, + )?; + + statistic_to_count.insert( + &Statistic::CursedInscriptions.key(), + &inscription_updater.cursed_inscription_count, + )?; + + statistic_to_count.insert( + &Statistic::BlessedInscriptions.key(), + &inscription_updater.blessed_inscription_count, + )?; + + statistic_to_count.insert( + &Statistic::UnboundInscriptions.key(), + &inscription_updater.unbound_inscriptions, + )?; if index.index_runes { let mut outpoint_to_rune_balances = wtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?;