Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored May 24, 2024
2 parents 8d37dba + aba1d7a commit 2c4203f
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 21 deletions.
16 changes: 0 additions & 16 deletions docs/src/inscriptions/recursion.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,3 @@ percentile in sats/vB.
"id":"17541f6adf6eb160d52bc6eb0a3546c7c1d2adfe607b1a3cddc72cc0619526adi0"
}
```

- `/r/children/60bcf821240064a9c55225c4f01711b0ebbcab39aa3fafeefe4299ab158536fai0/49`:

```json
{
"ids":[
"7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4900",
"7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4901",
...
"7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4935",
"7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4936"
],
"more":false,
"page":49
}
```
17 changes: 17 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,7 @@ impl Index {
pub(crate) fn inscription_info(
&self,
query: query::Inscription,
child: Option<usize>,
) -> Result<Option<(api::Inscription, Option<TxOut>, Inscription)>> {
let rtx = self.database.begin_read()?;

Expand All @@ -1908,6 +1909,22 @@ impl Index {
return Ok(None);
};

let sequence_number = if let Some(child) = child {
let Some(child) = rtx
.open_multimap_table(SEQUENCE_NUMBER_TO_CHILDREN)?
.get(sequence_number)?
.nth(child)
.transpose()?
.map(|child| child.value())
else {
return Ok(None);
};

child
} else {
sequence_number
};

let sequence_number_to_inscription_entry =
rtx.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)?;

Expand Down
9 changes: 9 additions & 0 deletions src/index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ impl RuneEntry {
.unwrap_or_default()
}

pub fn max_supply(&self) -> u128 {
self.premine
+ self.terms.and_then(|terms| terms.cap).unwrap_or_default()
* self
.terms
.and_then(|terms| terms.amount)
.unwrap_or_default()
}

pub fn pile(&self, amount: u128) -> Pile {
Pile {
amount,
Expand Down
117 changes: 114 additions & 3 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ impl Server {
.route("/feed.xml", get(Self::feed))
.route("/input/:block/:transaction/:input", get(Self::input))
.route("/inscription/:inscription_query", get(Self::inscription))
.route(
"/inscription/:inscription_query/:child",
get(Self::inscription_child),
)
.route("/inscriptions", get(Self::inscriptions))
.route("/inscriptions", post(Self::inscriptions_json))
.route("/inscriptions/:page", get(Self::inscriptions_paginated))
Expand Down Expand Up @@ -1595,8 +1599,27 @@ impl Server {
async fn inscription(
Extension(server_config): Extension<Arc<ServerConfig>>,
Extension(index): Extension<Arc<Index>>,
AcceptJson(accept_json): AcceptJson,
Path(DeserializeFromStr(query)): Path<DeserializeFromStr<query::Inscription>>,
) -> ServerResult {
Self::inscription_inner(server_config, &index, accept_json, query, None).await
}

async fn inscription_child(
Extension(server_config): Extension<Arc<ServerConfig>>,
Extension(index): Extension<Arc<Index>>,
AcceptJson(accept_json): AcceptJson,
Path((DeserializeFromStr(query), child)): Path<(DeserializeFromStr<query::Inscription>, usize)>,
) -> ServerResult {
Self::inscription_inner(server_config, &index, accept_json, query, Some(child)).await
}

async fn inscription_inner(
server_config: Arc<ServerConfig>,
index: &Index,
accept_json: bool,
query: query::Inscription,
child: Option<usize>,
) -> ServerResult {
task::block_in_place(|| {
if let query::Inscription::Sat(_) = query {
Expand All @@ -1606,7 +1629,7 @@ impl Server {
}

let (info, txout, inscription) = index
.inscription_info(query)?
.inscription_info(query, child)?
.ok_or_not_found(|| format!("inscription {query}"))?;

Ok(if accept_json {
Expand Down Expand Up @@ -1650,7 +1673,7 @@ impl Server {
for inscription in inscriptions {
let query = query::Inscription::Id(inscription);
let (info, _, _) = index
.inscription_info(query)?
.inscription_info(query, None)?
.ok_or_not_found(|| format!("inscription {query}"))?;

response.push(info);
Expand Down Expand Up @@ -2312,7 +2335,12 @@ mod tests {
regex: impl AsRef<str>,
) {
let response = self.get(path);
assert_eq!(response.status(), status);
assert_eq!(
response.status(),
status,
"response: {}",
response.text().unwrap()
);
assert_regex_match!(response.text().unwrap(), regex.as_ref());
}

Expand Down Expand Up @@ -2986,6 +3014,8 @@ mod tests {
<dd>no</dd>
<dt>supply</dt>
<dd>340282366920938463463374607431768211455\u{A0}%</dd>
<dt>mint progress</dt>
<dd>100%</dd>
<dt>premine</dt>
<dd>340282366920938463463374607431768211455\u{A0}%</dd>
<dt>premine percentage</dt>
Expand Down Expand Up @@ -5258,6 +5288,87 @@ next
);
}

#[test]
fn inscription_child() {
let server = TestServer::builder().chain(Chain::Regtest).build();
server.mine_blocks(1);

let parent_txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, inscription("text/plain", "hello").to_witness())],
..default()
});

server.mine_blocks(2);

let parent_inscription_id = InscriptionId {
txid: parent_txid,
index: 0,
};

let child_txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &[
(
2,
0,
0,
Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parents: vec![parent_inscription_id.value()],
..default()
}
.to_witness(),
),
(
3,
0,
0,
Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parents: vec![parent_inscription_id.value()],
..default()
}
.to_witness(),
),
(2, 1, 0, Default::default()),
],
..default()
});

server.mine_blocks(1);

let child0 = InscriptionId {
txid: child_txid,
index: 0,
};

server.assert_response_regex(
format!("/inscription/{parent_inscription_id}/0"),
StatusCode::OK,
format!(
".*<title>Inscription 1</title>.*
.*<dt>id</dt>
.*<dd class=monospace>{child0}</dd>.*"
),
);

let child1 = InscriptionId {
txid: child_txid,
index: 1,
};

server.assert_response_regex(
format!("/inscription/{parent_inscription_id}/1"),
StatusCode::OK,
format!(
".*<title>Inscription -1</title>.*
.*<dt>id</dt>
.*<dd class=monospace>{child1}</dd>.*"
),
);
}

#[test]
fn inscription_with_parent_page() {
let server = TestServer::builder().chain(Chain::Regtest).build();
Expand Down
2 changes: 2 additions & 0 deletions src/templates/rune.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ mod tests {
</dd>
<dt>supply</dt>
<dd>100.123456889\u{A0}%</dd>
<dt>mint progress</dt>
<dd>99.01%</dd>
<dt>premine</dt>
<dd>0.123456789\u{A0}%</dd>
<dt>premine percentage</dt>
Expand Down
2 changes: 2 additions & 0 deletions templates/rune.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ <h1>{{ self.entry.spaced_rune }}</h1>
%% }
<dt>supply</dt>
<dd>{{ self.entry.pile(self.entry.supply()) }}</dd>
<dt>mint progress</dt>
<dd>{{ Decimal { value: ((self.entry.supply() as f64 / self.entry.max_supply() as f64) * 10000.0) as u128, scale: 2 } }}%</dd>
<dt>premine</dt>
<dd>{{ self.entry.pile(self.entry.premine) }}</dd>
<dt>premine percentage</dt>
Expand Down
14 changes: 12 additions & 2 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use {
executable_path::executable_path,
mockcore::TransactionTemplate,
ord::{
api, chain::Chain, outgoing::Outgoing, subcommand::runes::RuneInfo, wallet::batch,
InscriptionId, RuneEntry,
api, chain::Chain, decimal::Decimal, outgoing::Outgoing, subcommand::runes::RuneInfo,
wallet::batch, InscriptionId, RuneEntry,
},
ordinals::{
Artifact, Charm, Edict, Pile, Rarity, Rune, RuneId, Runestone, Sat, SatPoint, SpacedRune,
Expand Down Expand Up @@ -321,6 +321,14 @@ fn batch(core: &mockcore::Handle, ord: &TestServer, batchfile: batch::File) -> E

let RuneId { block, tx } = id;

let supply_int = supply.to_integer(divisibility).unwrap();
let premine_int = premine.to_integer(divisibility).unwrap();

let mint_progress = Decimal {
value: ((premine_int as f64 / supply_int as f64) * 10000.0) as u128,
scale: 2,
};

ord.assert_response_regex(
format!("/rune/{rune}"),
format!(
Expand All @@ -334,6 +342,8 @@ fn batch(core: &mockcore::Handle, ord: &TestServer, batchfile: batch::File) -> E
{}
<dt>supply</dt>
<dd>{premine} {symbol}</dd>
<dt>mint progress</dt>
<dd>{mint_progress}%</dd>
<dt>premine</dt>
<dd>{premine} {symbol}</dd>
<dt>premine percentage</dt>
Expand Down

0 comments on commit 2c4203f

Please sign in to comment.