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

Show inscriptions on /ordinal #645

Merged
merged 3 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use {
bitcoin::BlockHeader,
bitcoincore_rpc::{json::GetBlockHeaderResult, Auth, Client},
rayon::iter::{IntoParallelRefIterator, ParallelIterator},
redb::WriteStrategy,
redb::{MultimapTableDefinition, ReadableMultimapTable, WriteStrategy},
std::sync::atomic::{AtomicBool, Ordering},
};

Expand All @@ -14,6 +14,8 @@ const HASH_TO_RUNE: TableDefinition<[u8; 32], str> = TableDefinition::new("HASH_
const HEIGHT_TO_HASH: TableDefinition<u64, [u8; 32]> = TableDefinition::new("HEIGHT_TO_HASH");
const ORDINAL_TO_SATPOINT: TableDefinition<u64, [u8; 44]> =
TableDefinition::new("ORDINAL_TO_SATPOINT");
const ORDINAL_TO_RUNE_HASHES: MultimapTableDefinition<u64, [u8; 32]> =
MultimapTableDefinition::new("ORDINAL_TO_RUNE_HASHES");
const OUTPOINT_TO_ORDINAL_RANGES: TableDefinition<[u8; 36], [u8]> =
TableDefinition::new("OUTPOINT_TO_ORDINAL_RANGES");
const STATISTICS: TableDefinition<u64, u64> = TableDefinition::new("STATISTICS");
Expand Down Expand Up @@ -125,6 +127,7 @@ impl Index {
tx
};

tx.open_multimap_table(ORDINAL_TO_RUNE_HASHES)?;
tx.open_table(HASH_TO_RUNE)?;
tx.open_table(HEIGHT_TO_HASH)?;
tx.open_table(ORDINAL_TO_SATPOINT)?;
Expand Down Expand Up @@ -408,6 +411,21 @@ impl Index {
Ok(blocks)
}

pub(crate) fn inscriptions(&self, ordinal: Ordinal) -> Result<Vec<sha256::Hash>> {
let rtx = self.database.begin_read()?;

let table = rtx.open_multimap_table(ORDINAL_TO_RUNE_HASHES)?;

let mut values = table.get(&ordinal.0)?;

let mut inscriptions = Vec::new();
while let Some(value) = values.next() {
inscriptions.push(sha256::Hash::from_inner(*value));
}

Ok(inscriptions)
}

pub(crate) fn rare_ordinal_satpoints(&self) -> Result<Vec<(Ordinal, SatPoint)>> {
let mut result = Vec::new();

Expand Down Expand Up @@ -548,12 +566,20 @@ impl Index {
pub(crate) fn insert_rune(&self, rune: &Rune) -> Result<(bool, sha256::Hash)> {
let json = serde_json::to_string(rune)?;
let hash = sha256::Hash::hash(json.as_ref());

let wtx = self.database.begin_write()?;

let created = wtx
.open_table(HASH_TO_RUNE)?
.insert(hash.as_inner(), &json)?
.is_none();

wtx
.open_multimap_table(ORDINAL_TO_RUNE_HASHES)?
.insert(&rune.ordinal.n(), &hash.into_inner())?;

wtx.commit()?;

Ok((created, hash))
}

Expand Down
36 changes: 35 additions & 1 deletion src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@ impl Server {
blocktime: index.blocktime(ordinal.height()).map_err(|err| {
ServerError::Internal(anyhow!("Failed to retrieve blocktime from index: {err}"))
})?,
inscriptions: index.inscriptions(ordinal).map_err(|err| {
ServerError::Internal(anyhow!(
"Failed to retrieve runes for ordinal {ordinal}: {err}"
))
})?,
}
.page(),
)
Expand Down Expand Up @@ -679,7 +684,7 @@ mod tests {
fn assert_response(&self, path: &str, status: StatusCode, expected_response: &str) {
let response = self.get(path);
assert_eq!(response.status(), status, "{}", response.text().unwrap());
assert_eq!(response.text().unwrap(), expected_response);
pretty_assert_eq!(response.text().unwrap(), expected_response);
}

fn assert_response_regex(&self, path: &str, status: StatusCode, regex: &str) {
Expand Down Expand Up @@ -1354,4 +1359,33 @@ mod tests {
r#"This ord instance only accepts regtest runes for publication"#,
);
}

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

test_server.assert_put(
"/rune",
"application/json",
r#"{"name": "foo", "chain": "regtest", "ordinal": 0}"#,
StatusCode::CREATED,
"8ca6ee12cb891766de56e5698a73cd6546f27a88bd27c8b8d914bc4162f9e4b5",
);

test_server.assert_put(
"/rune",
"application/json",
r#"{"name": "bar", "chain": "regtest", "ordinal": 0}"#,
StatusCode::CREATED,
"72ed622edc0e3753891809c931075f0da2c39ba491d2d715140208f930411339",
);

test_server.assert_response_regex(
"/ordinal/0",
StatusCode::OK,
".*<dt>inscriptions</dt>
<dd><a href=/rune/72ed622edc0e3753891809c931075f0da2c39ba491d2d715140208f930411339 class=monospace>72ed622edc0e3753891809c931075f0da2c39ba491d2d715140208f930411339</a></dd>
<dd><a href=/rune/8ca6ee12cb891766de56e5698a73cd6546f27a88bd27c8b8d914bc4162f9e4b5 class=monospace>8ca6ee12cb891766de56e5698a73cd6546f27a88bd27c8b8d914bc4162f9e4b5</a></dd>.*",
);
}
}
5 changes: 5 additions & 0 deletions src/subcommand/server/templates/ordinal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::*;
pub(crate) struct OrdinalHtml {
pub(crate) ordinal: Ordinal,
pub(crate) blocktime: Blocktime,
pub(crate) inscriptions: Vec<sha256::Hash>,
}

impl Content for OrdinalHtml {
Expand All @@ -22,6 +23,7 @@ mod tests {
OrdinalHtml {
ordinal: Ordinal(0),
blocktime: Blocktime::Confirmed(0),
inscriptions: Vec::new(),
}
.to_string(),
"
Expand All @@ -38,6 +40,7 @@ mod tests {
<dt>offset</dt><dd>0</dd>
<dt>rarity</dt><dd><span class=mythic>mythic</span></dd>
<dt>time</dt><dd>1970-01-01 00:00:00</dd>
<dt>inscriptions</dt>
</dl>
<a>prev</a>
<a href=/ordinal/1>next</a>
Expand All @@ -52,6 +55,7 @@ mod tests {
OrdinalHtml {
ordinal: Ordinal(1),
blocktime: Blocktime::Confirmed(0),
inscriptions: Vec::new(),
}
.to_string(),
"
Expand All @@ -68,6 +72,7 @@ mod tests {
<dt>offset</dt><dd>1</dd>
<dt>rarity</dt><dd><span class=common>common</span></dd>
<dt>time</dt><dd>1970-01-01 00:00:00</dd>
<dt>inscriptions</dt>
</dl>
<a href=/ordinal/0>prev</a>
<a href=/ordinal/2>next</a>
Expand Down
4 changes: 4 additions & 0 deletions templates/ordinal.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ <h1>Ordinal {{ self.ordinal.n() }}</h1>
<dt>offset</dt><dd>{{ self.ordinal.third() }}</dd>
<dt>rarity</dt><dd><span class={{self.ordinal.rarity()}}>{{ self.ordinal.rarity() }}</span></dd>
<dt>time</dt><dd>{{ self.blocktime }}</dd>
<dt>inscriptions</dt>
%% for hash in &self.inscriptions {
<dd><a href=/rune/{{hash}} class=monospace>{{hash}}</a></dd>
%% }
</dl>
%% if self.ordinal.n() > 0 {
<a href=/ordinal/{{self.ordinal.n() - 1}}>prev</a>
Expand Down