Skip to content

Commit

Permalink
Merge branch 'master' into shorten_recursion_examples
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptoni9n authored Feb 17, 2025
2 parents 09b205f + 176e3fe commit 0d2fd6d
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 36 deletions.
4 changes: 1 addition & 3 deletions docs/src/guides/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5127,6 +5127,4 @@ curl -s -H "Accept: application/json" \

## Recursive Endpoints

See [Recursion](../inscriptions/recursion.md) for an explanation of these.

{{#include ../inscriptions/recursion.md:35:3483}}
See [Recursion](../inscriptions/recursion.md).
122 changes: 122 additions & 0 deletions docs/src/inscriptions/recursion.md
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,128 @@ curl -s \
```
</details>

<details>
<summary>
<code>GET</code>
<code><b>/r/parents/&lt;INSCRIPTION_ID&gt;/inscriptions</b></code>
</summary>

### Description

Details of the first 100 parent inscriptions.

### Example

```bash
curl -s -H "Accept: application/json" \
http://0.0.0.0:80/r/parents/4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019i0/inscriptions
```

```json
{
"parents": [
{
"charms": [],
"fee": 21730,
"height": 775167,
"id": "92c409fb749b1005fe9a1482d3a74a8e73936a72644f4979df8184aba473841di0",
"number": 4573,
"output": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:13",
"sat": null,
"satpoint": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:13:0",
"timestamp": 1675607405
},
{
"charms": [],
"fee": 14977,
"height": 775167,
"id": "c689cbcb8e31858c5e1476d04af4e7e7cedd1fb4fb9cae5bb62036936a08282di0",
"number": 4576,
"output": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:14",
"sat": null,
"satpoint": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:14:0",
"timestamp": 1675607405
},
{
"charms": [],
"fee": 12533,
"height": 775167,
"id": "982d15f6b3510307ef845f1cb3352b27e2b048616b7c0642367ebc05bbd36d3ai0",
"number": 4578,
"output": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:12",
"sat": null,
"satpoint": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:12:0",
"timestamp": 1675607405
}
...
],
"more": true,
"page": 0
}
```
</details>

<details>
<summary>
<code>GET</code>
<code><b>/r/parents/&lt;INSCRIPTION_ID&gt;/inscriptions/&lt;PAGE&gt;</b></code>
</summary>

### Description

Details of the set of 100 parent inscriptions on &lt;PAGE&gt;.

### Example

```bash
curl -s -H "Accept: application/json" \
http://0.0.0.0:80/r/parents/4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019i0/inscriptions/1
```

```json
{
"parents": [
{
"charms": [],
"fee": 65049,
"height": 775443,
"id": "972994a55c338e8458bfd156642f4aa56bdab54c68658d6b64d932fedef3c81fi0",
"number": 10804,
"output": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:102",
"sat": null,
"satpoint": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:102:0",
"timestamp": 1675780989
},
{
"charms": [],
"fee": 60111,
"height": 775443,
"id": "dbc21f2d3323df24a378fef3bdbe4e79c4947ce7da54968affcdefa7eda80d21i0",
"number": 10805,
"output": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:110",
"sat": null,
"satpoint": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:110:0",
"timestamp": 1675780989
},
{
"charms": [],
"fee": 49881,
"height": 775443,
"id": "97870f7cf65992a66d0413a7e6773190e686f185500f78c30f989f2d1f1ba922i0",
"number": 10806,
"output": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:101",
"sat": null,
"satpoint": "4a86d375a70a4ecc7ffcd910e05f5e0771ae6a50133543f1bf6b5651adbf0019:101:0",
"timestamp": 1675780989
}
...
],
"more": false,
"page": 1
}
```
</details>

<details>
<summary>
<code>GET</code>
Expand Down
11 changes: 9 additions & 2 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,14 @@ pub struct Children {

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ChildInscriptions {
pub children: Vec<ChildInscriptionRecursive>,
pub children: Vec<RelativeInscriptionRecursive>,
pub more: bool,
pub page: usize,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ParentInscriptions {
pub parents: Vec<RelativeInscriptionRecursive>,
pub more: bool,
pub page: usize,
}
Expand Down Expand Up @@ -132,7 +139,7 @@ pub struct InscriptionRecursive {
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ChildInscriptionRecursive {
pub struct RelativeInscriptionRecursive {
pub charms: Vec<Charm>,
pub fee: u64,
pub height: u32,
Expand Down
8 changes: 4 additions & 4 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1308,17 +1308,17 @@ impl Index {
pub fn get_parents_by_sequence_number_paginated(
&self,
parent_sequence_numbers: Vec<u32>,
page_size: usize,
page_index: usize,
) -> Result<(Vec<InscriptionId>, bool)> {
const PAGE_SIZE: usize = 100;
let rtx = self.database.begin_read()?;

let sequence_number_to_entry = rtx.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)?;

let mut parents = parent_sequence_numbers
.iter()
.skip(page_index * PAGE_SIZE)
.take(PAGE_SIZE.saturating_add(1))
.skip(page_index * page_size)
.take(page_size.saturating_add(1))
.map(|sequence_number| {
sequence_number_to_entry
.get(sequence_number)
Expand All @@ -1327,7 +1327,7 @@ impl Index {
})
.collect::<Result<Vec<InscriptionId>>>()?;

let more_parents = parents.len() > PAGE_SIZE;
let more_parents = parents.len() > page_size;

if more_parents {
parents.pop();
Expand Down
134 changes: 133 additions & 1 deletion src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,14 @@ impl Server {
"/r/parents/{inscription_id}/{page}",
get(r::parents_paginated),
)
.route(
"/r/parents/{inscription_id}/inscriptions",
get(r::parent_inscriptions),
)
.route(
"/r/parents/{inscription_id}/inscriptions/{page}",
get(r::parent_inscriptions_paginated),
)
.route("/r/sat/{sat_number}", get(r::sat))
.route("/r/sat/{sat_number}/at/{index}", get(r::sat_at_index))
.route("/r/sat/{sat_number}/{page}", get(r::sat_paginated))
Expand Down Expand Up @@ -1825,7 +1833,8 @@ impl Server {
.get_inscription_entry(id)?
.ok_or_not_found(|| format!("inscription {id}"))?;

let (parents, more) = index.get_parents_by_sequence_number_paginated(child.parents, page)?;
let (parents, more) =
index.get_parents_by_sequence_number_paginated(child.parents, 100, page)?;

let prev_page = page.checked_sub(1);

Expand Down Expand Up @@ -6445,6 +6454,129 @@ next
assert_eq!(child_inscriptions_json.page, 1);
}

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

let mut builder = script::Builder::new();
for _ in 0..111 {
builder = Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
unrecognized_even_field: false,
..default()
}
.append_reveal_script_to_builder(builder);
}

let witness = Witness::from_slice(&[builder.into_bytes(), Vec::new()]);

let parents_txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, witness)],
..default()
});

server.mine_blocks(1);

let mut builder = script::Builder::new();
builder = Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parents: (0..111)
.map(|i| {
InscriptionId {
txid: parents_txid,
index: i,
}
.value()
})
.collect(),
unrecognized_even_field: false,
..default()
}
.append_reveal_script_to_builder(builder);

let witness = Witness::from_slice(&[builder.into_bytes(), Vec::new()]);

let child_txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &[(2, 0, 0, witness), (2, 1, 0, Default::default())],
..default()
});

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

server.assert_response(
format!("/r/parents/{child_inscription_id}/inscriptions"),
StatusCode::NOT_FOUND,
&format!("inscription {child_inscription_id} not found"),
);

server.mine_blocks(1);

let first_parent_inscription_id = InscriptionId {
txid: parents_txid,
index: 0,
};
let hundredth_parent_inscription_id = InscriptionId {
txid: parents_txid,
index: 99,
};
let hundred_first_parent_inscription_id = InscriptionId {
txid: parents_txid,
index: 100,
};
let hundred_eleventh_parent_inscription_id = InscriptionId {
txid: parents_txid,
index: 110,
};

let parent_inscriptions_json = server.get_json::<api::ParentInscriptions>(format!(
"/r/parents/{child_inscription_id}/inscriptions"
));

assert_eq!(parent_inscriptions_json.parents.len(), 100);

assert_eq!(
parent_inscriptions_json.parents[0].id,
first_parent_inscription_id
);
assert_eq!(parent_inscriptions_json.parents[0].number, 0); // parents are #0 and -1 to -110, child is #1

assert_eq!(
parent_inscriptions_json.parents[99].id,
hundredth_parent_inscription_id
);
assert_eq!(parent_inscriptions_json.parents[99].number, -99); // all but 1st parent are cursed

assert!(parent_inscriptions_json.more);
assert_eq!(parent_inscriptions_json.page, 0);

let parent_inscriptions_json = server.get_json::<api::ParentInscriptions>(format!(
"/r/parents/{child_inscription_id}/inscriptions/1"
));

assert_eq!(parent_inscriptions_json.parents.len(), 11);

assert_eq!(
parent_inscriptions_json.parents[0].id,
hundred_first_parent_inscription_id
);
assert_eq!(parent_inscriptions_json.parents[0].number, -100);

assert_eq!(
parent_inscriptions_json.parents[10].id,
hundred_eleventh_parent_inscription_id
);
assert_eq!(parent_inscriptions_json.parents[10].number, -110);

assert!(!parent_inscriptions_json.more);
assert_eq!(parent_inscriptions_json.page, 1);
}

#[test]
fn inscriptions_in_block_page() {
let server = TestServer::builder()
Expand Down
Loading

0 comments on commit 0d2fd6d

Please sign in to comment.