Skip to content

Commit

Permalink
Preview all inscriptions inside iframes (ordinals#1132)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed Jan 4, 2023
1 parent 75c6e42 commit 1ad94af
Show file tree
Hide file tree
Showing 32 changed files with 626 additions and 640 deletions.
2 changes: 1 addition & 1 deletion src/content.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[derive(Debug, PartialEq)]
pub(crate) enum Content<'a> {
IFrame,
Iframe,
Image,
Text(&'a str),
}
149 changes: 84 additions & 65 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,23 @@ type SatRangeArray = [u8; 11];

const SCHEMA_VERSION: u64 = 1;

const HEIGHT_TO_BLOCK_HASH: TableDefinition<u64, &BlockHashArray> =
TableDefinition::new("HEIGHT_TO_BLOCK_HASH");
const INSCRIPTION_ID_TO_HEIGHT: TableDefinition<&InscriptionIdArray, u64> =
TableDefinition::new("INSCRIPTION_ID_TO_HEIGHT");
const INSCRIPTION_ID_TO_SATPOINT: TableDefinition<&InscriptionIdArray, &SatPointArray> =
TableDefinition::new("INSCRIPTION_ID_TO_SATPOINT");
const INSCRIPTION_NUMBER_TO_INSCRIPTION_ID: TableDefinition<u64, &InscriptionIdArray> =
TableDefinition::new("INSCRIPTION_NUMBER_TO_INSCRIPTION_ID");
const OUTPOINT_TO_SAT_RANGES: TableDefinition<&OutPointArray, &[u8]> =
TableDefinition::new("OUTPOINT_TO_SAT_RANGES");
const OUTPOINT_TO_VALUE: TableDefinition<&OutPointArray, u64> =
TableDefinition::new("OUTPOINT_TO_VALUE");
const SATPOINT_TO_INSCRIPTION_ID: TableDefinition<&SatPointArray, &InscriptionIdArray> =
TableDefinition::new("SATPOINT_TO_INSCRIPTION_ID");
const SAT_TO_INSCRIPTION_ID: TableDefinition<u64, &InscriptionIdArray> =
TableDefinition::new("SAT_TO_INSCRIPTION_ID");
const SAT_TO_SATPOINT: TableDefinition<u64, &SatPointArray> =
TableDefinition::new("SAT_TO_SATPOINT");
const STATISTIC_TO_COUNT: TableDefinition<u64, u64> = TableDefinition::new("STATISTIC_TO_COUNT");
const WRITE_TRANSACTION_STARTING_BLOCK_COUNT_TO_TIMESTAMP: TableDefinition<u64, u128> =
TableDefinition::new("WRITE_TRANSACTION_START_BLOCK_COUNT_TO_TIMESTAMP");
macro_rules! define_table {
($name:ident, $key:ty, $value:ty) => {
const $name: TableDefinition<$key, $value> = TableDefinition::new(stringify!($name));
};
}

define_table! { HEIGHT_TO_BLOCK_HASH, u64, &BlockHashArray }
define_table! { INSCRIPTION_ID_TO_HEIGHT, &InscriptionIdArray, u64 }
define_table! { INSCRIPTION_ID_TO_SATPOINT, &InscriptionIdArray, &SatPointArray }
define_table! { INSCRIPTION_NUMBER_TO_INSCRIPTION_ID, u64, &InscriptionIdArray }
define_table! { OUTPOINT_TO_SAT_RANGES, &OutPointArray, &[u8] }
define_table! { OUTPOINT_TO_VALUE, &OutPointArray, u64}
define_table! { SATPOINT_TO_INSCRIPTION_ID, &SatPointArray, &InscriptionIdArray }
define_table! { SAT_TO_INSCRIPTION_ID, u64, &InscriptionIdArray }
define_table! { SAT_TO_SATPOINT, u64, &SatPointArray }
define_table! { STATISTIC_TO_COUNT, u64, u64 }
define_table! { WRITE_TRANSACTION_STARTING_BLOCK_COUNT_TO_TIMESTAMP, u64, u128 }

fn encode_outpoint(outpoint: OutPoint) -> OutPointArray {
let mut array = [0; 36];
Expand Down Expand Up @@ -487,39 +483,32 @@ impl Index {
self.client.get_block(&hash).into_option()
}

pub(crate) fn get_inscription_by_sat(
&self,
sat: Sat,
) -> Result<Option<(InscriptionId, Inscription)>> {
let db = self.database.begin_read()?;
let table = db.open_table(SAT_TO_INSCRIPTION_ID)?;

let Some(txid) = table.get(&sat.n())? else {
return Ok(None);
};

pub(crate) fn get_inscription_id_by_sat(&self, sat: Sat) -> Result<Option<InscriptionId>> {
Ok(
self
.get_inscription_by_inscription_id(Txid::from_inner(*txid.value()))?
.map(|(inscription, _)| (InscriptionId::from_inner(*txid.value()), inscription)),
.database
.begin_read()?
.open_table(SAT_TO_INSCRIPTION_ID)?
.get(&sat.n())?
.map(|inscription_id| decode_inscription_id(*inscription_id.value())),
)
}

pub(crate) fn get_inscription_by_inscription_id(
pub(crate) fn get_inscription_by_id(
&self,
txid: Txid,
inscription_id: InscriptionId,
) -> Result<Option<(Inscription, SatPoint)>> {
let Some(satpoint) = self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_SATPOINT)?
.get(txid.as_inner())?
.get(inscription_id.as_inner())?
.map(|satpoint| decode_satpoint(*satpoint.value()))
else {
return Ok(None);
};

let Some(inscription) = self.get_transaction(txid)?.and_then(|tx| Inscription::from_transaction(&tx)) else {
let Some(inscription) = self.get_transaction(inscription_id)?.and_then(|tx| Inscription::from_transaction(&tx)) else {
return Ok(None);
};

Expand Down Expand Up @@ -662,33 +651,18 @@ impl Index {
)
}

pub(crate) fn get_latest_inscriptions(
&self,
n: usize,
) -> Result<Vec<(Inscription, InscriptionId)>> {
let mut inscriptions = Vec::new();

for (_n, id) in self
.database
.begin_read()?
.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?
.iter()?
.rev()
{
let id = decode_inscription_id(*id.value());

let Some((inscription, _satpoint)) = self.get_inscription_by_inscription_id(id)? else {
continue;
};

inscriptions.push((inscription, id));

if inscriptions.len() == n {
break;
}
}

Ok(inscriptions)
pub(crate) fn get_latest_inscriptions(&self, n: usize) -> Result<Vec<InscriptionId>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?
.iter()?
.rev()
.take(n)
.map(|(_number, id)| decode_inscription_id(*id.value()))
.collect(),
)
}

pub(crate) fn get_genesis_height(&self, inscription_id: InscriptionId) -> Result<u64> {
Expand Down Expand Up @@ -889,6 +863,51 @@ mod tests {
}
}

#[test]
fn inscriptions_below_first_inscription_height_are_skipped() {
let inscription = inscription("text/plain", "hello");
let template = TransactionTemplate {
inputs: &[(1, 0, 0)],
witness: inscription.to_witness(),
..Default::default()
};

{
let context = Context::builder().build();
context.mine_blocks(1);
let inscription_id = context.rpc_server.broadcast_tx(template.clone());
context.mine_blocks(1);

assert_eq!(
context.index.get_inscription_by_id(inscription_id).unwrap(),
Some((
inscription,
SatPoint {
outpoint: OutPoint {
txid: inscription_id,
vout: 0,
},
offset: 0,
}
))
);
}

{
let context = Context::builder()
.arg("--first-inscription-height=3")
.build();
context.mine_blocks(1);
let inscription_id = context.rpc_server.broadcast_tx(template);
context.mine_blocks(1);

assert_eq!(
context.index.get_inscription_by_id(inscription_id).unwrap(),
None,
);
}
}

#[test]
fn list_first_coinbase_transaction() {
let context = Context::builder().arg("--index-sats").build();
Expand Down
29 changes: 18 additions & 11 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ use super::*;
pub(super) struct Flotsam {
inscription_id: InscriptionId,
offset: u64,
old_satpoint: Option<SatPoint>,
origin: Origin,
}

enum Origin {
New,
Old(SatPoint),
}

pub(super) struct InscriptionUpdater<'a, 'db, 'tx> {
Expand Down Expand Up @@ -68,7 +73,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
inscriptions.push(Flotsam {
inscription_id: txid,
offset: 0,
old_satpoint: None,
origin: Origin::New,
});
};

Expand Down Expand Up @@ -97,7 +102,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
inscriptions.push(Flotsam {
offset: input_value + old_satpoint.offset,
inscription_id: InscriptionId::from_inner(inscription_id),
old_satpoint: Some(old_satpoint),
origin: Origin::Old(old_satpoint),
});
}
self
Expand Down Expand Up @@ -155,9 +160,11 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
offset: flotsam.offset - output_value,
};

self.update_inscription_location(input_sat_ranges, flotsam, new_satpoint)?;

inscriptions.next();
self.update_inscription_location(
input_sat_ranges,
inscriptions.next().unwrap(),
new_satpoint,
)?;
}

output_value = end;
Expand All @@ -179,7 +186,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
outpoint: OutPoint::null(),
offset: self.lost_sats + flotsam.offset - output_value,
};
self.update_inscription_location(input_sat_ranges, &flotsam, new_satpoint)?;
self.update_inscription_location(input_sat_ranges, flotsam, new_satpoint)?;
}

Ok(self.reward - output_value)
Expand All @@ -196,16 +203,16 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
fn update_inscription_location(
&mut self,
input_sat_ranges: Option<&VecDeque<(u64, u64)>>,
flotsam: &Flotsam,
flotsam: Flotsam,
new_satpoint: SatPoint,
) -> Result {
let inscription_id = flotsam.inscription_id.into_inner();

match flotsam.old_satpoint {
Some(old_satpoint) => {
match flotsam.origin {
Origin::Old(old_satpoint) => {
self.satpoint_to_id.remove(&encode_satpoint(old_satpoint))?;
}
None => {
Origin::New => {
self.id_to_height.insert(&inscription_id, &self.height)?;
self
.number_to_id
Expand Down
9 changes: 3 additions & 6 deletions src/inscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Inscription {
let content = self.content.as_ref()?;

match self.content_type()? {
content_type::HTML | content_type::SVG => Some(Content::IFrame),
content_type::HTML | content_type::SVG => Some(Content::Iframe),
content_type::TEXT => Some(Content::Text(str::from_utf8(content).ok()?)),
content_type if content_type::is_image(content_type) => Some(Content::Image),
_ => None,
Expand All @@ -100,11 +100,8 @@ impl Inscription {
Some(self.content.as_ref()?)
}

pub(crate) fn content_html(&self, inscription_id: InscriptionId) -> Trusted<ContentHtml> {
Trusted(ContentHtml {
content: self.content(),
inscription_id,
})
pub(crate) fn into_content(self) -> Option<Vec<u8>> {
self.content
}

pub(crate) fn content_size(&self) -> Option<usize> {
Expand Down
1 change: 0 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use {
sat_point::SatPoint,
subcommand::Subcommand,
tally::Tally,
templates::ContentHtml,
},
anyhow::{anyhow, bail, Context, Error},
bitcoin::{
Expand Down
Loading

0 comments on commit 1ad94af

Please sign in to comment.