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

Added parents recursive endpoint #3749

Merged
merged 4 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions docs/src/inscriptions/recursion.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ The recursive endpoints are:
- `/r/children/<INSCRIPTION_ID>/<PAGE>`: the set of 100 child inscription ids on `<PAGE>`.
- `/r/inscription/<INSCRIPTION_ID>`: information about an inscription
- `/r/metadata/<INSCRIPTION_ID>`: JSON string containing the hex-encoded CBOR metadata.
- `/r/parents/<INSCRIPTION_ID>`: the first 100 parent inscription ids.
- `/r/parents/<INSCRIPTION_ID>/<PAGE>`: the set of 100 parent inscription ids on `<PAGE>`.
- `/r/sat/<SAT_NUMBER>`: the first 100 inscription ids on a sat.
- `/r/sat/<SAT_NUMBER>/<PAGE>`: the set of 100 inscription ids on `<PAGE>`.
- `/r/sat/<SAT_NUMBER>/at/<INDEX>`: the inscription id at `<INDEX>` of all inscriptions on a sat. `<INDEX>` may be a negative number to index from the back. `0` being the first and `-1` being the most recent for example.
Expand Down
106 changes: 106 additions & 0 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ impl Server {
get(Self::children_recursive_paginated),
)
.route("/r/metadata/:inscription_id", get(Self::metadata))
.route("/r/parents/:inscription_id", get(Self::parents_recursive))
.route(
"/r/parents/:inscription_id/:page",
get(Self::parents_recursive_paginated),
)
.route("/r/sat/:sat_number", get(Self::sat_inscriptions))
.route(
"/r/sat/:sat_number/:page",
Expand Down Expand Up @@ -1902,6 +1907,38 @@ impl Server {
})
}

async fn parents_recursive(
Extension(index): Extension<Arc<Index>>,
Path(inscription_id): Path<InscriptionId>,
) -> ServerResult {
Self::parents_recursive_paginated(Extension(index), Path((inscription_id, 0))).await
}

async fn parents_recursive_paginated(
Extension(index): Extension<Arc<Index>>,
Path((inscription_id, page)): Path<(InscriptionId, usize)>,
) -> ServerResult {
task::block_in_place(|| {
let child = index
.get_inscription_entry(inscription_id)?
.ok_or_not_found(|| format!("inscription {inscription_id}"))?;

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

let page_index =
u32::try_from(page).map_err(|_| anyhow!("page index {} out of range", page))?;

Ok(
Json(api::Inscriptions {
ids,
more,
page_index,
})
.into_response(),
)
})
}

async fn sat_inscriptions(
Extension(index): Extension<Arc<Index>>,
Path(sat): Path<u64>,
Expand Down Expand Up @@ -6031,6 +6068,75 @@ next
assert_eq!(children_json.page, 1);
}

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

let mut parent_ids = Vec::new();
let mut inputs = Vec::new();
for i in 0..111 {
parent_ids.push(InscriptionId {
txid: server.core.broadcast_tx(TransactionTemplate {
inputs: &[(i + 1, 0, 0, inscription("text/plain", "hello").to_witness())],
..default()
}),
index: 0,
});

inputs.push((i + 2, 1, 0, Witness::default()));

server.mine_blocks(1);
}

inputs.insert(
0,
(
112,
0,
0,
Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parents: parent_ids.iter().map(|id| id.value()).collect(),
..default()
}
.to_witness(),
),
);

let txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &inputs,
..default()
});

server.mine_blocks(1);

let inscription_id = InscriptionId { txid, index: 0 };

let first_parent_inscription_id = parent_ids[0];
let hundredth_parent_inscription_id = parent_ids[99];
let hundred_first_parent_inscription_id = parent_ids[100];
let hundred_eleventh_parent_inscription_id = parent_ids[110];

let parents_json = server.get_json::<api::Inscriptions>(format!("/r/parents/{inscription_id}"));

assert_eq!(parents_json.ids.len(), 100);
assert_eq!(parents_json.ids[0], first_parent_inscription_id);
assert_eq!(parents_json.ids[99], hundredth_parent_inscription_id);
assert!(parents_json.more);
assert_eq!(parents_json.page_index, 0);

let parents_json =
server.get_json::<api::Inscriptions>(format!("/r/parents/{inscription_id}/1"));

assert_eq!(parents_json.ids.len(), 11);
assert_eq!(parents_json.ids[0], hundred_first_parent_inscription_id);
assert_eq!(parents_json.ids[10], hundred_eleventh_parent_inscription_id);
assert!(!parents_json.more);
assert_eq!(parents_json.page_index, 1);
}

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