Skip to content

Commit

Permalink
Enforce deduplication for non-deterministic parent encoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
arik-so committed Mar 8, 2024
1 parent 8b09432 commit e335afd
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
58 changes: 58 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4630,6 +4630,64 @@ mod tests {
}
}

#[test]
fn inscription_with_distinct_parent_tag_encodings_for_same_parent_has_singular_parent_entry() {
for context in Context::configurations() {
context.mine_blocks(1);

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

context.mine_blocks(1);

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

let trailing_zero_inscription_id: Vec<u8> = parent_inscription_id
.value()
.into_iter()
.chain(vec![0, 0, 0, 0])
.collect();

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

context.mine_blocks(1);

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

assert_eq!(
context.index.get_parents_by_inscription_id(inscription_id),
vec![parent_inscription_id]
);

assert_eq!(
context
.index
.get_children_by_inscription_id(parent_inscription_id)
.unwrap(),
vec![inscription_id]
);
}
}

#[test]
fn inscription_with_three_parent_tags_and_two_parents_has_two_parent_entries() {
for context in Context::configurations() {
Expand Down
10 changes: 6 additions & 4 deletions src/inscriptions/inscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,18 @@ impl Inscription {

/// Returns a deduplicated list of parent inscription IDs the inscription claims to have.
pub(crate) fn parents(&self) -> Vec<InscriptionId> {
let mut unique_parents: HashSet<Vec<u8>> = HashSet::with_capacity(self.parents.len());
let mut unique_parents: HashSet<InscriptionId> = HashSet::with_capacity(self.parents.len());
self
.parents
.iter()
.map(|p| {
if !unique_parents.insert(p.clone()) {
let Some(parent_id) = Self::inscription_id_field(&Some(p.clone())) else {
return None;
};
if !unique_parents.insert(parent_id) {
return None;
}
// the option detour is a bit awkward
Self::inscription_id_field(&Some(p.clone()))
Some(parent_id)
})
.flatten()
.collect()
Expand Down

0 comments on commit e335afd

Please sign in to comment.