Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sequence number #2460

Merged
merged 11 commits into from Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
233 changes: 98 additions & 135 deletions src/index.rs

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions src/index/entry.rs
Expand Up @@ -26,22 +26,26 @@ impl Entry for BlockHash {
pub(crate) struct InscriptionEntry {
pub(crate) fee: u64,
pub(crate) height: u64,
pub(crate) number: i64,
pub(crate) inscription_number: i64,
pub(crate) sequence_number: u64,
pub(crate) parent: Option<InscriptionId>,
pub(crate) sat: Option<Sat>,
pub(crate) timestamp: u32,
}

pub(crate) type InscriptionEntryValue = (u64, u64, i64, ParentValue, u64, u32);
pub(crate) type InscriptionEntryValue = (u64, u64, i64, u64, ParentValue, u64, u32);

impl Entry for InscriptionEntry {
type Value = InscriptionEntryValue;

fn load((fee, height, number, parent, sat, timestamp): InscriptionEntryValue) -> Self {
fn load(
(fee, height, inscription_number, sequence_number, parent, sat, timestamp): InscriptionEntryValue,
) -> Self {
Self {
fee,
height,
number,
inscription_number,
sequence_number,
parent: ParentEntry::load(parent),
sat: if sat == u64::MAX {
None
Expand All @@ -56,7 +60,8 @@ impl Entry for InscriptionEntry {
(
self.fee,
self.height,
self.number,
self.inscription_number,
self.sequence_number,
self.parent.store(),
match self.sat {
Some(sat) => sat.n(),
Expand Down
45 changes: 29 additions & 16 deletions src/index/updater.rs
Expand Up @@ -378,24 +378,32 @@ impl<'index> Updater<'_> {
}

let mut height_to_block_hash = wtx.open_table(HEIGHT_TO_BLOCK_HASH)?;
let mut height_to_last_inscription_number =
wtx.open_table(HEIGHT_TO_LAST_INSCRIPTION_NUMBER)?;
let mut height_to_last_sequence_number = wtx.open_table(HEIGHT_TO_LAST_SEQUENCE_NUMBER)?;
let mut inscription_id_to_inscription_entry =
wtx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_ENTRY)?;
let mut inscription_id_to_satpoint = wtx.open_table(INSCRIPTION_ID_TO_SATPOINT)?;
let mut inscription_number_to_inscription_id =
wtx.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?;
let mut reinscription_id_to_seq_num = wtx.open_table(REINSCRIPTION_ID_TO_SEQUENCE_NUMBER)?;
let mut sat_to_inscription_id = wtx.open_multimap_table(SAT_TO_INSCRIPTION_ID)?;
let mut inscription_id_to_children = wtx.open_multimap_table(INSCRIPTION_ID_TO_CHILDREN)?;
let mut satpoint_to_inscription_id = wtx.open_multimap_table(SATPOINT_TO_INSCRIPTION_ID)?;
let mut sequence_number_to_inscription_id =
wtx.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ID)?;
let mut statistic_to_count = wtx.open_table(STATISTIC_TO_COUNT)?;

let mut lost_sats = statistic_to_count
.get(&Statistic::LostSats.key())?
.map(|lost_sats| lost_sats.value())
.unwrap_or(0);

let cursed_inscription_count = statistic_to_count
.get(&Statistic::CursedInscriptions.key())?
.map(|count| count.value())
.unwrap_or(0);

let blessed_inscription_count = statistic_to_count
.get(&Statistic::BlessedInscriptions.key())?
.map(|count| count.value())
.unwrap_or(0);

let unbound_inscriptions = statistic_to_count
.get(&Statistic::UnboundInscriptions.key())?
.map(|unbound_inscriptions| unbound_inscriptions.value())
Expand All @@ -408,9 +416,10 @@ impl<'index> Updater<'_> {
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 reinscription_id_to_seq_num,
&mut sat_to_inscription_id,
&mut satpoint_to_inscription_id,
block.header.time,
Expand Down Expand Up @@ -515,13 +524,23 @@ impl<'index> Updater<'_> {
}

self.index_block_inscription_numbers(
&mut height_to_last_inscription_number,
&mut height_to_last_sequence_number,
&inscription_updater,
index_inscriptions,
)?;

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::BlessedInscriptions.key(),
&inscription_updater.blessed_inscription_count,
)?;

statistic_to_count.insert(
&Statistic::UnboundInscriptions.key(),
&inscription_updater.unbound_inscriptions,
Expand Down Expand Up @@ -608,21 +627,15 @@ impl<'index> Updater<'_> {

fn index_block_inscription_numbers(
&mut self,
height_to_inscription_number: &mut Table<u64, (i64, i64)>,
height_to_sequence_number: &mut Table<u64, u64>,
inscription_updater: &InscriptionUpdater,
index_inscription: bool,
) -> Result {
if !index_inscription {
return Ok(());
}

height_to_inscription_number.insert(
&self.height,
(
inscription_updater.next_number,
inscription_updater.next_cursed_number,
),
)?;
height_to_sequence_number.insert(&self.height, inscription_updater.next_sequence_number)?;

Ok(())
}
Expand Down
67 changes: 32 additions & 35 deletions src/index/updater/inscription_updater.rs
Expand Up @@ -29,12 +29,12 @@ pub(super) struct InscriptionUpdater<'a, 'db, 'tx> {
value_receiver: &'a mut Receiver<u64>,
id_to_entry: &'a mut Table<'db, 'tx, &'static InscriptionIdValue, InscriptionEntryValue>,
pub(super) lost_sats: u64,
pub(super) next_cursed_number: i64,
pub(super) next_number: i64,
number_to_id: &'a mut Table<'db, 'tx, i64, &'static InscriptionIdValue>,
pub(super) cursed_inscription_count: u64,
pub(super) blessed_inscription_count: u64,
pub(super) next_sequence_number: u64,
sequence_number_to_id: &'a mut Table<'db, 'tx, u64, &'static InscriptionIdValue>,
outpoint_to_value: &'a mut Table<'db, 'tx, &'static OutPointValue, u64>,
reward: u64,
reinscription_id_to_seq_num: &'a mut Table<'db, 'tx, &'static InscriptionIdValue, u64>,
sat_to_inscription_id: &'a mut MultimapTable<'db, 'tx, u64, &'static InscriptionIdValue>,
satpoint_to_id:
&'a mut MultimapTable<'db, 'tx, &'static SatPointValue, &'static InscriptionIdValue>,
Expand All @@ -56,9 +56,10 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
value_receiver: &'a mut Receiver<u64>,
id_to_entry: &'a mut Table<'db, 'tx, &'static InscriptionIdValue, InscriptionEntryValue>,
lost_sats: u64,
number_to_id: &'a mut Table<'db, 'tx, i64, &'static InscriptionIdValue>,
cursed_inscription_count: u64,
blessed_inscription_count: u64,
sequence_number_to_id: &'a mut Table<'db, 'tx, u64, &'static InscriptionIdValue>,
outpoint_to_value: &'a mut Table<'db, 'tx, &'static OutPointValue, u64>,
reinscription_id_to_seq_num: &'a mut Table<'db, 'tx, &'static InscriptionIdValue, u64>,
sat_to_inscription_id: &'a mut MultimapTable<'db, 'tx, u64, &'static InscriptionIdValue>,
satpoint_to_id: &'a mut MultimapTable<
'db,
Expand All @@ -70,14 +71,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
unbound_inscriptions: u64,
value_cache: &'a mut HashMap<OutPoint, u64>,
) -> Result<Self> {
let next_cursed_number = number_to_id
.iter()?
.next()
.and_then(|result| result.ok())
.map(|(number, _id)| number.value() - 1)
.unwrap_or(-1);

let next_number = number_to_id
let next_sequence_number = sequence_number_to_id
.iter()?
.next_back()
.and_then(|result| result.ok())
Expand All @@ -92,12 +86,12 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
value_receiver,
id_to_entry,
lost_sats,
next_cursed_number,
next_number,
number_to_id,
cursed_inscription_count,
blessed_inscription_count,
next_sequence_number,
sequence_number_to_id,
outpoint_to_value,
reward: Height(height).subsidy(),
reinscription_id_to_seq_num,
sat_to_inscription_id,
satpoint_to_id,
timestamp,
Expand Down Expand Up @@ -127,7 +121,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {

// find existing inscriptions on input (transfers of inscriptions)
for (old_satpoint, inscription_id) in Index::inscriptions_on_output_ordered(
self.reinscription_id_to_seq_num,
self.id_to_entry,
self.satpoint_to_id,
tx_in.previous_output,
)? {
Expand Down Expand Up @@ -184,15 +178,11 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
} else if inscription.tx_in_offset != 0 {
Some(Curse::NotAtOffsetZero)
} else if inscribed_offsets.contains_key(&offset) {
let seq_num = self.reinscription_id_to_seq_num.len()?;
let seq_num = self.id_to_entry.len()?;

let sat = Self::calculate_sat(input_sat_ranges, offset);
log::info!("processing reinscription {inscription_id} on sat {:?}: sequence number {seq_num}, inscribed offsets {:?}", sat, inscribed_offsets);

// if reinscription track its ordering
self
.reinscription_id_to_seq_num
.insert(&inscription_id.store(), seq_num)?;
log::info!("processing reinscription {inscription_id} on sat {:?}: sequence number {seq_num}, inscribed offsets {:?}", sat, inscribed_offsets);

Some(Curse::Reinscription)
} else {
Expand All @@ -215,7 +205,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
match self.id_to_entry.get(&inscription_id.store()) {
Ok(option) => option.map(|entry| {
let loaded_entry = InscriptionEntry::load(entry.value());
loaded_entry.number < 0
loaded_entry.inscription_number < 0
}),
Err(_) => None,
}
Expand Down Expand Up @@ -417,19 +407,25 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
parent,
unbound,
} => {
let number = if cursed {
let next_cursed_number = self.next_cursed_number;
self.next_cursed_number -= 1;
let inscription_number = if cursed {
let number: i64 = self.cursed_inscription_count.try_into().unwrap();
self.cursed_inscription_count += 1;

next_cursed_number
// because cursed numbers start at -1
-(number + 1)
} else {
let next_number = self.next_number;
self.next_number += 1;
let number: i64 = self.blessed_inscription_count.try_into().unwrap();
self.blessed_inscription_count += 1;

next_number
number
};

self.number_to_id.insert(number, &inscription_id)?;
let sequence_number = self.next_sequence_number;
self.next_sequence_number += 1;

self
.sequence_number_to_id
.insert(sequence_number, &inscription_id)?;

let sat = if unbound {
None
Expand All @@ -446,7 +442,8 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
&InscriptionEntry {
fee,
height: self.height,
number,
inscription_number,
sequence_number,
parent,
sat,
timestamp: self.timestamp,
Expand Down
26 changes: 15 additions & 11 deletions src/subcommand/server.rs
Expand Up @@ -711,7 +711,7 @@ impl Server {

let chain = page_config.chain;
match chain {
Chain::Mainnet => builder.title("Inscriptions"),
Chain::Mainnet => builder.title("Inscriptions".to_string()),
_ => builder.title(format!("Inscriptions – {chain:?}")),
};

Expand All @@ -720,8 +720,8 @@ impl Server {
for (number, id) in index.get_feed_inscriptions(300)? {
builder.item(
rss::ItemBuilder::default()
.title(format!("Inscription {number}"))
.link(format!("/inscription/{id}"))
.title(Some(format!("Inscription {number}")))
.link(Some(format!("/inscription/{id}")))
.guid(Some(rss::Guid {
value: format!("/inscription/{id}"),
permalink: true,
Expand Down Expand Up @@ -994,9 +994,13 @@ impl Server {
)
};

let previous = index.get_inscription_id_by_inscription_number(entry.number - 1)?;
let previous = if let Some(n) = entry.sequence_number.checked_sub(1) {
index.get_inscription_id_by_sequence_number(n)?
} else {
None
};

let next = index.get_inscription_id_by_inscription_number(entry.number + 1)?;
let next = index.get_inscription_id_by_sequence_number(entry.sequence_number + 1)?;

let children = index.get_children_by_inscription_id(inscription_id)?;

Expand All @@ -1010,7 +1014,7 @@ impl Server {
inscription_id,
entry.parent,
next,
entry.number,
entry.inscription_number,
output,
previous,
entry.sat,
Expand All @@ -1027,7 +1031,7 @@ impl Server {
inscription,
inscription_id,
next,
number: entry.number,
inscription_number: entry.inscription_number,
output,
parent: entry.parent,
previous,
Expand Down Expand Up @@ -1088,7 +1092,7 @@ impl Server {
async fn inscriptions_from(
Extension(page_config): Extension<Arc<PageConfig>>,
Extension(index): Extension<Arc<Index>>,
Path(from): Path<i64>,
Path(from): Path<u64>,
accept_json: AcceptJson,
) -> ServerResult<Response> {
Self::inscriptions_inner(page_config, index, Some(from), 100, accept_json).await
Expand All @@ -1097,7 +1101,7 @@ impl Server {
async fn inscriptions_from_n(
Extension(page_config): Extension<Arc<PageConfig>>,
Extension(index): Extension<Arc<Index>>,
Path((from, n)): Path<(i64, usize)>,
Path((from, n)): Path<(u64, usize)>,
accept_json: AcceptJson,
) -> ServerResult<Response> {
Self::inscriptions_inner(page_config, index, Some(from), n, accept_json).await
Expand All @@ -1106,7 +1110,7 @@ impl Server {
async fn inscriptions_inner(
page_config: Arc<PageConfig>,
index: Arc<Index>,
from: Option<i64>,
from: Option<u64>,
n: usize,
accept_json: AcceptJson,
) -> ServerResult<Response> {
Expand Down Expand Up @@ -1917,7 +1921,7 @@ mod tests {
}

#[test]
fn unbound_output_recieves_unbound_inscriptions() {
fn unbound_output_receives_unbound_inscriptions() {
let server = TestServer::new_with_regtest();

server.mine_blocks(1);
Expand Down