Skip to content

Commit

Permalink
Add prev and next links to /inscription (ordinals#1193)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Jan 11, 2023
1 parent d3df998 commit f5203a6
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 202 deletions.
30 changes: 30 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ macro_rules! define_table {

define_table! { HEIGHT_TO_BLOCK_HASH, u64, &BlockHashArray }
define_table! { INSCRIPTION_ID_TO_HEIGHT, &InscriptionIdArray, u64 }
define_table! { INSCRIPTION_ID_TO_INSCRIPTION_NUMBER, &InscriptionIdArray, u64}
define_table! { INSCRIPTION_ID_TO_SAT, &InscriptionIdArray, u64 }
define_table! { INSCRIPTION_ID_TO_SATPOINT, &InscriptionIdArray, &SatPointArray }
define_table! { INSCRIPTION_NUMBER_TO_INSCRIPTION_ID, u64, &InscriptionIdArray }
Expand Down Expand Up @@ -235,6 +236,7 @@ impl Index {

tx.open_table(HEIGHT_TO_BLOCK_HASH)?;
tx.open_table(INSCRIPTION_ID_TO_HEIGHT)?;
tx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_NUMBER)?;
tx.open_table(INSCRIPTION_ID_TO_SAT)?;
tx.open_table(INSCRIPTION_ID_TO_SATPOINT)?;
tx.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?;
Expand Down Expand Up @@ -496,6 +498,34 @@ impl Index {
)
}

pub(crate) fn get_inscription_number_by_inscription_id(
&self,
id: InscriptionId,
) -> Result<Option<u64>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_INSCRIPTION_NUMBER)?
.get(&id.as_inner())?
.map(|n| n.value()),
)
}

pub(crate) fn get_inscription_id_by_inscription_number(
&self,
n: u64,
) -> Result<Option<InscriptionId>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?
.get(&n)?
.map(|id| decode_inscription_id(*id.value())),
)
}

pub(crate) fn get_sat_by_inscription_id(
&self,
inscription_id: InscriptionId,
Expand Down
3 changes: 3 additions & 0 deletions src/index/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ impl Updater {
}

let mut inscription_id_to_height = wtx.open_table(INSCRIPTION_ID_TO_HEIGHT)?;
let mut inscription_id_to_inscription_number =
wtx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_NUMBER)?;
let mut inscription_id_to_sat = wtx.open_table(INSCRIPTION_ID_TO_SAT)?;
let mut inscription_id_to_satpoint = wtx.open_table(INSCRIPTION_ID_TO_SATPOINT)?;
let mut inscription_number_to_inscription_id =
Expand All @@ -291,6 +293,7 @@ impl Updater {
let mut inscription_updater = InscriptionUpdater::new(
self.height,
&mut inscription_id_to_height,
&mut inscription_id_to_inscription_number,
&mut inscription_id_to_satpoint,
index,
&mut inscription_id_to_sat,
Expand Down
6 changes: 6 additions & 0 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub(super) struct InscriptionUpdater<'a, 'db, 'tx> {
flotsam: Vec<Flotsam>,
height: u64,
id_to_height: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_number: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_satpoint: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, &'tx SatPointArray>,
index: &'a Index,
inscription_id_to_sat: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
Expand All @@ -32,6 +33,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
pub(super) fn new(
height: u64,
id_to_height: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_number: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_satpoint: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, &'tx SatPointArray>,
index: &'a Index,
inscription_id_to_sat: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
Expand All @@ -53,6 +55,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
flotsam: Vec::new(),
height,
id_to_height,
id_to_number,
id_to_satpoint,
index,
inscription_id_to_sat,
Expand Down Expand Up @@ -203,6 +206,9 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
}
Origin::New => {
self.id_to_height.insert(&inscription_id, &self.height)?;
self
.id_to_number
.insert(&inscription_id, &self.next_number)?;
self
.number_to_id
.insert(&self.next_number, &inscription_id)?;
Expand Down
51 changes: 21 additions & 30 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,13 +635,32 @@ impl Server {
.nth(satpoint.outpoint.vout.try_into().unwrap())
.ok_or_not_found(|| format!("inscription {inscription_id} current transaction output"))?;

let number = index
.get_inscription_number_by_inscription_id(inscription_id)?
.ok_or_not_found(|| format!("inscription {inscription_id} number"))?;

let previous = if let Some(previous) = number.checked_sub(1) {
Some(
index
.get_inscription_id_by_inscription_number(previous)?
.ok_or_not_found(|| format!("inscription {previous}"))?,
)
} else {
None
};

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

Ok(
InscriptionHtml {
chain,
genesis_height,
inscription,
inscription_id,
number,
next,
output,
previous,
sat,
satpoint,
}
Expand Down Expand Up @@ -1327,43 +1346,15 @@ mod tests {
test_server.assert_response_regex(
format!("/block/{block_hash}"),
StatusCode::OK,
".*<h1>Block 2</h1>
<dl>
<dt>hash</dt><dd class=monospace>[[:xdigit:]]{64}</dd>
<dt>target</dt><dd class=monospace>[[:xdigit:]]{64}</dd>
<dt>timestamp</dt><dd>0</dd>
<dt>size</dt><dd>202</dd>
<dt>weight</dt><dd>808</dd>
<dt>previous blockhash</dt><dd><a href=/block/659f9b67fbc0b5cba0ef6ebc0aea322e1c246e29e43210bd581f5f3bd36d17bf class=monospace>659f9b67fbc0b5cba0ef6ebc0aea322e1c246e29e43210bd581f5f3bd36d17bf</a></dd>
</dl>
<a href=/block/1>prev</a>
next
<h2>2 Transactions</h2>
<ul class=monospace>
<li><a href=/tx/[[:xdigit:]]{64}>[[:xdigit:]]{64}</a></li>
<li><a href=/tx/[[:xdigit:]]{64}>[[:xdigit:]]{64}</a></li>
</ul>.*",
".*<h1>Block 2</h1>.*",
);
}

#[test]
fn block_by_height() {
let test_server = TestServer::new();

test_server.assert_response_regex(
"/block/0",
StatusCode::OK,
".*<h1>Block 0</h1>
<dl>
<dt>hash</dt><dd class=monospace>[[:xdigit:]]{64}</dd>
<dt>target</dt><dd class=monospace>[[:xdigit:]]{64}</dd>
<dt>timestamp</dt><dd>1231006505</dd>
<dt>size</dt><dd>285</dd>
<dt>weight</dt><dd>1140</dd>
</dl>
prev
next.*",
);
test_server.assert_response_regex("/block/0", StatusCode::OK, ".*<h1>Block 0</h1>.*");
}

#[test]
Expand Down
122 changes: 24 additions & 98 deletions src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,22 @@ pub(crate) trait PageContent: Display + 'static {
mod tests {
use super::*;

#[test]
fn page_mainnet() {
struct Foo;
struct Foo;

impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "<h1>Foo</h1>")
}
impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "<h1>Foo</h1>")
}
}

impl PageContent for Foo {
fn title(&self) -> String {
"Foo".to_string()
}
impl PageContent for Foo {
fn title(&self) -> String {
"Foo".to_string()
}
}

#[test]
fn page() {
assert_regex_match!(
Foo.page(Chain::Mainnet, true),
"<!doctype html>
Expand All @@ -90,6 +90,7 @@ mod tests {
<title>Foo</title>
<link href=/static/index.css rel=stylesheet>
<link href=/static/modern-normalize.css rel=stylesheet>
<script src=/static/index.js defer></script>
</head>
<body>
<header>
Expand All @@ -114,101 +115,26 @@ mod tests {
}

#[test]
fn page_no_sat_index() {
struct Foo;

impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "<h1>Foo</h1>")
}
}

impl PageContent for Foo {
fn title(&self) -> String {
"Foo".to_string()
}
}
fn page_mainnet() {
assert_regex_match!(
Foo.page(Chain::Mainnet, true),
r".*<nav>\s*<a href=/>Ordinals<sup>alpha</sup></a>.*"
);
}

#[test]
fn page_no_sat_index() {
assert_regex_match!(
Foo.page(Chain::Mainnet, false).to_string(),
"<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta name=format-detection content='telephone=no'>
<meta name=viewport content='width=device-width,initial-scale=1.0'>
<title>Foo</title>
<link href=/static/index.css rel=stylesheet>
<link href=/static/modern-normalize.css rel=stylesheet>
</head>
<body>
<header>
<nav>
<a href=/>Ordinals<sup>alpha</sup></a>
.*
<a href=/clock>Clock</a>
<form action=/search method=get>
<input type=text .*>
<input type=submit value=Search>
</form>
</nav>
</header>
<main>
<h1>Foo</h1>
</main>
</body>
</html>
"
Foo.page(Chain::Mainnet, false),
r".*<nav>\s*<a href=/>Ordinals<sup>alpha</sup></a>.*<a href=/clock>Clock</a>\s*<form action=/search.*",
);
}

#[test]
fn page_signet() {
struct Foo;

impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "<h1>Foo</h1>")
}
}

impl PageContent for Foo {
fn title(&self) -> String {
"Foo".to_string()
}
}

assert_regex_match!(
Foo.page(Chain::Signet, true).to_string(),
"<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta name=format-detection content='telephone=no'>
<meta name=viewport content='width=device-width,initial-scale=1.0'>
<title>Foo</title>
<link href=/static/index.css rel=stylesheet>
<link href=/static/modern-normalize.css rel=stylesheet>
</head>
<body>
<header>
<nav>
<a href=/>Ordinals<sup>signet</sup></a>
.*
<a href=/clock>Clock</a>
<a href=/rare.txt>rare.txt</a>
<form action=/search method=get>
<input type=text .*>
<input type=submit value=Search>
</form>
</nav>
</header>
<main>
<h1>Foo</h1>
</main>
</body>
</html>
"
Foo.page(Chain::Signet, true),
r".*<nav>\s*<a href=/>Ordinals<sup>signet</sup></a>.*"
);
}
}
Loading

0 comments on commit f5203a6

Please sign in to comment.