From 805b949da1d5447e4b16fd25dc28d07a300fd4ac Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 24 Oct 2023 11:49:52 -0700 Subject: [PATCH] Display inscription on /rune (#2542) --- src/index.rs | 16 ++ src/index/updater.rs | 270 +++++++++++++++--------------- src/index/updater/rune_updater.rs | 24 +++ src/inscription_id.rs | 9 + src/sat_point.rs | 2 +- src/subcommand/server.rs | 34 ++-- src/templates/inscription.rs | 94 +++++------ src/templates/rune.rs | 7 +- templates/inscription.html | 4 + templates/rune.html | 9 +- tests/json_api.rs | 3 +- 11 files changed, 264 insertions(+), 208 deletions(-) diff --git a/src/index.rs b/src/index.rs index 9572560be1..249caa1b41 100644 --- a/src/index.rs +++ b/src/index.rs @@ -56,6 +56,7 @@ define_multimap_table! { SAT_TO_INSCRIPTION_ID, u64, &InscriptionIdValue } define_table! { HEIGHT_TO_BLOCK_HASH, u64, &BlockHashValue } define_table! { HEIGHT_TO_LAST_SEQUENCE_NUMBER, u64, u64 } define_table! { INSCRIPTION_ID_TO_INSCRIPTION_ENTRY, &InscriptionIdValue, InscriptionEntryValue } +define_table! { INSCRIPTION_ID_TO_RUNE, &InscriptionIdValue, u128 } define_table! { INSCRIPTION_ID_TO_SATPOINT, &InscriptionIdValue, &SatPointValue } define_table! { INSCRIPTION_NUMBER_TO_INSCRIPTION_ID, i64, &InscriptionIdValue } define_table! { OUTPOINT_TO_RUNE_BALANCES, &OutPointValue, &[u8] } @@ -273,6 +274,7 @@ impl Index { tx.open_table(HEIGHT_TO_BLOCK_HASH)?; tx.open_table(HEIGHT_TO_LAST_SEQUENCE_NUMBER)?; tx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_ENTRY)?; + tx.open_table(INSCRIPTION_ID_TO_RUNE)?; tx.open_table(INSCRIPTION_ID_TO_SATPOINT)?; tx.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?; tx.open_table(OUTPOINT_TO_RUNE_BALANCES)?; @@ -795,6 +797,20 @@ impl Index { .collect() } + pub(crate) fn get_rune_by_inscription_id( + &self, + inscription_id: InscriptionId, + ) -> Result> { + Ok( + self + .database + .begin_read()? + .open_table(INSCRIPTION_ID_TO_RUNE)? + .get(&inscription_id.store())? + .map(|entry| Rune(entry.value())), + ) + } + pub(crate) fn get_inscription_ids_by_sat(&self, sat: Sat) -> Result> { let rtx = &self.database.begin_read()?; diff --git a/src/index/updater.rs b/src/index/updater.rs index 8a3c3550f0..828ab88515 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -376,23 +376,6 @@ impl<'index> Updater<'_> { } } - if index.index_runes { - let mut outpoint_to_rune_balances = wtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?; - let mut rune_id_to_rune_entry = wtx.open_table(RUNE_ID_TO_RUNE_ENTRY)?; - let mut rune_to_rune_id = wtx.open_table(RUNE_TO_RUNE_ID)?; - let mut statistic_to_count = wtx.open_table(STATISTIC_TO_COUNT)?; - let mut rune_updater = RuneUpdater::new( - self.height, - &mut outpoint_to_rune_balances, - &mut rune_id_to_rune_entry, - &mut rune_to_rune_id, - &mut statistic_to_count, - )?; - for (i, (tx, txid)) in block.txdata.iter().enumerate() { - rune_updater.index_runes(i, tx, *txid)?; - } - } - let mut height_to_block_hash = wtx.open_table(HEIGHT_TO_BLOCK_HASH)?; let mut height_to_last_sequence_number = wtx.open_table(HEIGHT_TO_LAST_SEQUENCE_NUMBER)?; let mut inscription_id_to_inscription_entry = @@ -427,143 +410,166 @@ 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, + )?; + + statistic_to_count.insert(&Statistic::LostSats.key(), &inscription_updater.lost_sats)?; - 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)?; + let mut rune_id_to_rune_entry = wtx.open_table(RUNE_ID_TO_RUNE_ENTRY)?; + let mut rune_to_rune_id = wtx.open_table(RUNE_TO_RUNE_ID)?; + let mut inscription_id_to_rune = wtx.open_table(INSCRIPTION_ID_TO_RUNE)?; + let mut rune_updater = RuneUpdater::new( + self.height, + &mut outpoint_to_rune_balances, + &mut rune_id_to_rune_entry, + &inscription_id_to_inscription_entry, + &mut inscription_id_to_rune, + &mut rune_to_rune_id, + &mut statistic_to_count, + )?; + for (i, (tx, txid)) in block.txdata.iter().enumerate() { + rune_updater.index_runes(i, tx, *txid)?; + } + } height_to_block_hash.insert(&self.height, &block.header.block_hash().store())?; diff --git a/src/index/updater/rune_updater.rs b/src/index/updater/rune_updater.rs index 38d691c1e5..530de24097 100644 --- a/src/index/updater/rune_updater.rs +++ b/src/index/updater/rune_updater.rs @@ -14,6 +14,9 @@ struct Allocation { pub(super) struct RuneUpdater<'a, 'db, 'tx> { height: u64, id_to_entry: &'a mut Table<'db, 'tx, RuneIdValue, RuneEntryValue>, + inscription_id_to_inscription_entry: + &'a Table<'db, 'tx, &'static InscriptionIdValue, InscriptionEntryValue>, + inscription_id_to_rune: &'a mut Table<'db, 'tx, &'static InscriptionIdValue, u128>, minimum: Rune, outpoint_to_balances: &'a mut Table<'db, 'tx, &'static OutPointValue, &'static [u8]>, rune_to_id: &'a mut Table<'db, 'tx, u128, RuneIdValue>, @@ -26,6 +29,13 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> { height: u64, outpoint_to_balances: &'a mut Table<'db, 'tx, &'static OutPointValue, &'static [u8]>, id_to_entry: &'a mut Table<'db, 'tx, RuneIdValue, RuneEntryValue>, + inscription_id_to_inscription_entry: &'a Table< + 'db, + 'tx, + &'static InscriptionIdValue, + InscriptionEntryValue, + >, + inscription_id_to_rune: &'a mut Table<'db, 'tx, &'static InscriptionIdValue, u128>, rune_to_id: &'a mut Table<'db, 'tx, u128, RuneIdValue>, statistic_to_count: &'a mut Table<'db, 'tx, u64, u64>, ) -> Result { @@ -38,6 +48,8 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> { id_to_entry, minimum: Rune::minimum_at_height(Height(height)), outpoint_to_balances, + inscription_id_to_inscription_entry, + inscription_id_to_rune, rune_to_id, runes, statistic_to_count, @@ -204,6 +216,18 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> { } .store(), )?; + + let inscription_id = InscriptionId { txid, index: 0 }; + + if self + .inscription_id_to_inscription_entry + .get(&inscription_id.store())? + .is_some() + { + self + .inscription_id_to_rune + .insert(&inscription_id.store(), rune.0)?; + } } } diff --git a/src/inscription_id.rs b/src/inscription_id.rs index 7ea91939a8..36b05495a2 100644 --- a/src/inscription_id.rs +++ b/src/inscription_id.rs @@ -6,6 +6,15 @@ pub struct InscriptionId { pub index: u32, } +impl Default for InscriptionId { + fn default() -> Self { + Self { + txid: Txid::all_zeros(), + index: 0, + } + } +} + impl InscriptionId { pub(crate) fn parent_value(self) -> Vec { let index = self.index.to_le_bytes(); diff --git a/src/sat_point.rs b/src/sat_point.rs index 044cae49fd..75c034cf82 100644 --- a/src/sat_point.rs +++ b/src/sat_point.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Debug, PartialEq, Copy, Clone, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Copy, Clone, Eq, PartialOrd, Ord, Default)] pub struct SatPoint { pub outpoint: OutPoint, pub offset: u64, diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 9f69a6d9b8..5f79faac42 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -568,23 +568,14 @@ impl Server { ) })?; - let inscription = InscriptionId { + let parent = InscriptionId { txid: entry.etching, index: 0, }; - let inscription = index - .inscription_exists(inscription)? - .then_some(inscription); + let parent = index.inscription_exists(parent)?.then_some(parent); - Ok( - RuneHtml { - id, - entry, - inscription, - } - .page(page_config), - ) + Ok(RuneHtml { id, entry, parent }.page(page_config)) } async fn runes( @@ -1096,6 +1087,8 @@ impl Server { let children = index.get_children_by_inscription_id(inscription_id)?; + let rune = index.get_rune_by_inscription_id(inscription_id)?; + Ok(if accept_json.0 { Json(InscriptionJson::new( page_config.chain, @@ -1112,6 +1105,7 @@ impl Server { entry.sat, satpoint, timestamp(entry.timestamp), + rune, )) .into_response() } else { @@ -1130,6 +1124,7 @@ impl Server { sat: entry.sat, satpoint, timestamp: timestamp(entry.timestamp), + rune, } .page(page_config) .into_response() @@ -3316,6 +3311,7 @@ mod tests { format!( r".*Rune NVTDIJZYIPU.*

Rune NVTDIJZYIPU

+
id
2/1
@@ -3331,12 +3327,24 @@ mod tests {
\$
etching
{txid}
-
inscription
+
parent
{txid}i0
.*" ), ); + + server.assert_response_regex( + format!("/inscription/{txid}i0"), + StatusCode::OK, + ".* +
+ .* +
rune
+
NVTDIJZYIPU
+
+.*", + ); } #[test] diff --git a/src/templates/inscription.rs b/src/templates/inscription.rs index 48e5029fe4..5c16f4244a 100644 --- a/src/templates/inscription.rs +++ b/src/templates/inscription.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Boilerplate)] +#[derive(Boilerplate, Default)] pub(crate) struct InscriptionHtml { pub(crate) chain: Chain, pub(crate) children: Vec, @@ -8,11 +8,12 @@ pub(crate) struct InscriptionHtml { pub(crate) genesis_height: u64, pub(crate) inscription: Inscription, pub(crate) inscription_id: InscriptionId, - pub(crate) next: Option, pub(crate) inscription_number: i64, + pub(crate) next: Option, pub(crate) output: Option, pub(crate) parent: Option, pub(crate) previous: Option, + pub(crate) rune: Option, pub(crate) sat: Option, pub(crate) satpoint: SatPoint, pub(crate) timestamp: DateTime, @@ -27,11 +28,12 @@ pub struct InscriptionJson { pub genesis_fee: u64, pub genesis_height: u64, pub inscription_id: InscriptionId, - pub next: Option, pub inscription_number: i64, + pub next: Option, pub output_value: Option, pub parent: Option, pub previous: Option, + pub rune: Option, pub sat: Option, pub satpoint: SatPoint, pub timestamp: i64, @@ -53,6 +55,7 @@ impl InscriptionJson { sat: Option, satpoint: SatPoint, timestamp: DateTime, + rune: Option, ) -> Self { Self { inscription_id, @@ -73,6 +76,7 @@ impl InscriptionJson { timestamp: timestamp.timestamp(), previous, next, + rune, } } } @@ -95,20 +99,12 @@ mod tests { fn without_sat_nav_links_or_output() { assert_regex_match!( InscriptionHtml { - children: Vec::new(), - parent: None, - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(1), - next: None, inscription_number: 1, - output: None, - previous: None, - sat: None, satpoint: satpoint(1, 0), - timestamp: timestamp(0), + ..Default::default() }, "

Inscription 1

@@ -154,20 +150,13 @@ mod tests { fn with_output() { assert_regex_match!( InscriptionHtml { - children: Vec::new(), - parent: None, - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(1), - next: None, inscription_number: 1, output: Some(tx_out(1, address())), - previous: None, - sat: None, satpoint: satpoint(1, 0), - timestamp: timestamp(0), + ..Default::default() }, "

Inscription 1

@@ -193,20 +182,14 @@ mod tests { fn with_sat() { assert_regex_match!( InscriptionHtml { - children: Vec::new(), - parent: None, - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(1), - next: None, inscription_number: 1, output: Some(tx_out(1, address())), - previous: None, sat: Some(Sat(1)), satpoint: satpoint(1, 0), - timestamp: timestamp(0), + ..Default::default() }, "

Inscription 1

@@ -228,19 +211,15 @@ mod tests { assert_regex_match!( InscriptionHtml { children: Vec::new(), - parent: None, - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(2), next: Some(inscription_id(3)), inscription_number: 1, output: Some(tx_out(1, address())), previous: Some(inscription_id(1)), - sat: None, satpoint: satpoint(1, 0), - timestamp: timestamp(0), + ..Default::default() }, "

Inscription 1

@@ -259,23 +238,17 @@ mod tests { fn with_cursed_and_unbound() { assert_regex_match!( InscriptionHtml { - children: Vec::new(), - parent: None, - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(2), - next: None, inscription_number: -1, output: Some(tx_out(1, address())), - previous: None, - sat: None, satpoint: SatPoint { outpoint: unbound_outpoint(), offset: 0 }, timestamp: timestamp(0), + ..Default::default() }, "

Inscription -1

@@ -297,20 +270,13 @@ mod tests { fn with_parent() { assert_regex_match!( InscriptionHtml { - children: Vec::new(), parent: Some(inscription_id(2)), - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(1), - next: None, inscription_number: 1, - output: None, - previous: None, - sat: None, satpoint: satpoint(1, 0), - timestamp: timestamp(0), + ..Default::default() }, "

Inscription 1

@@ -359,19 +325,12 @@ mod tests { assert_regex_match!( InscriptionHtml { children: vec![inscription_id(2), inscription_id(3)], - parent: None, - chain: Chain::Mainnet, genesis_fee: 1, - genesis_height: 0, inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), inscription_id: inscription_id(1), - next: None, inscription_number: 1, - output: None, - previous: None, - sat: None, satpoint: satpoint(1, 0), - timestamp: timestamp(0), + ..Default::default() }, "

Inscription 1

@@ -419,4 +378,29 @@ mod tests { .unindent() ); } + + #[test] + fn with_rune() { + assert_regex_match!( + InscriptionHtml { + genesis_fee: 1, + inscription: inscription("text/plain;charset=utf-8", "HELLOWORLD"), + inscription_id: inscription_id(1), + inscription_number: 1, + satpoint: satpoint(1, 0), + rune: Some(Rune(0)), + ..Default::default() + }, + " +

Inscription 1

+ .* +
+ .* +
rune
+
A
+
+ " + .unindent() + ); + } } diff --git a/src/templates/rune.rs b/src/templates/rune.rs index 54760e9655..d24770ec9e 100644 --- a/src/templates/rune.rs +++ b/src/templates/rune.rs @@ -4,7 +4,7 @@ use super::*; pub(crate) struct RuneHtml { pub(crate) entry: RuneEntry, pub(crate) id: RuneId, - pub(crate) inscription: Option, + pub(crate) parent: Option, } impl PageContent for RuneHtml { @@ -34,12 +34,13 @@ mod tests { height: 10, index: 9, }, - inscription: Some(InscriptionId { + parent: Some(InscriptionId { txid: Txid::all_zeros(), index: 0, }), }, r"

Rune BCGDENLQRQWDSLRUGSNLBTMFIJAV

+
id
10/9
@@ -55,7 +56,7 @@ mod tests {
\$
etching
0{64}
-
inscription
+
parent
0{64}i0
" diff --git a/templates/inscription.html b/templates/inscription.html index 08d9c09256..cf1d23df5a 100644 --- a/templates/inscription.html +++ b/templates/inscription.html @@ -79,4 +79,8 @@

Inscription {{ self.inscription_number }}

%% } +%% if let Some(rune) = self.rune { +
rune
+
{{ rune }}
+%% } diff --git a/templates/rune.html b/templates/rune.html index ea330ffef3..24a1bc2674 100644 --- a/templates/rune.html +++ b/templates/rune.html @@ -1,4 +1,7 @@

Rune {{ self.entry.rune }}

+%% if let Some(parent) = self.parent { +{{Iframe::main(parent)}} +%% }
id
{{ self.id }}
@@ -16,8 +19,8 @@

Rune {{ self.entry.rune }}

%% }
etching
{{ self.entry.etching }}
-%% if let Some(inscription) = self.inscription { -
inscription
-
{{ inscription }}
+%% if let Some(parent) = self.parent { +
parent
+
{{ parent }}
%% }
diff --git a/tests/json_api.rs b/tests/json_api.rs index a89f31c4fd..296ac2286f 100644 --- a/tests/json_api.rs +++ b/tests/json_api.rs @@ -158,7 +158,8 @@ fn get_inscription() { content_length: Some(3), timestamp: 2, previous: None, - next: None + next: None, + rune: None, } ) }