Skip to content

Commit

Permalink
Refactor inscription parsing (#2461)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed Sep 25, 2023
1 parent 528ecab commit 35ccc84
Show file tree
Hide file tree
Showing 8 changed files with 797 additions and 636 deletions.
692 changes: 692 additions & 0 deletions src/envelope.rs

Large diffs are not rendered by default.

69 changes: 66 additions & 3 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,9 +731,10 @@ impl Index {
}

Ok(self.get_transaction(inscription_id.txid)?.and_then(|tx| {
Inscription::from_transaction(&tx)
.get(inscription_id.index as usize)
.map(|transaction_inscription| transaction_inscription.inscription.clone())
ParsedEnvelope::from_transaction(&tx)
.into_iter()
.nth(inscription_id.index as usize)
.map(|envelope| envelope.payload)
}))
}

Expand Down Expand Up @@ -2722,6 +2723,68 @@ mod tests {
}
}

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

let witness = envelope(&[
b"ord",
&[1],
b"text/plain;charset=utf-8",
&[1],
b"text/plain;charset=utf-8",
]);

let txid = context.rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, witness)],
..Default::default()
});

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

context.mine_blocks(1);

assert_eq!(
context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap()
.inscription_number,
-1
);
}
}

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

let witness = envelope(&[b"ord", &[1]]);

let txid = context.rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, witness)],
..Default::default()
});

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

context.mine_blocks(1);

assert_eq!(
context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap()
.inscription_number,
-1
);
}
}

#[test]
// https://github.com/ordinals/ord/issues/2062
fn zero_value_transaction_inscription_not_cursed_but_unbound() {
Expand Down
4 changes: 2 additions & 2 deletions src/index/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ impl<'index> Updater<'_> {
}
} else {
for (tx, txid) in block.txdata.iter().skip(1).chain(block.txdata.first()) {
inscription_updater.index_transaction_inscriptions(tx, *txid, None)?;
inscription_updater.index_envelopes(tx, *txid, None)?;
}
}

Expand Down Expand Up @@ -571,7 +571,7 @@ impl<'index> Updater<'_> {
index_inscriptions: bool,
) -> Result {
if index_inscriptions {
inscription_updater.index_transaction_inscriptions(tx, txid, Some(input_sat_ranges))?;
inscription_updater.index_envelopes(tx, txid, Some(input_sat_ranges))?;
}

for (vout, output) in tx.output.iter().enumerate() {
Expand Down
24 changes: 14 additions & 10 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
})
}

pub(super) fn index_transaction_inscriptions(
pub(super) fn index_envelopes(
&mut self,
tx: &Transaction,
txid: Txid,
input_sat_ranges: Option<&VecDeque<(u64, u64)>>,
) -> Result {
let mut new_inscriptions = Inscription::from_transaction(tx).into_iter().peekable();
let mut envelopes = ParsedEnvelope::from_transaction(tx).into_iter().peekable();
let mut floating_inscriptions = Vec::new();
let mut inscribed_offsets = BTreeMap::new();
let mut total_input_value = 0;
Expand Down Expand Up @@ -161,8 +161,8 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
total_input_value += current_input_value;

// go through all inscriptions in this input
while let Some(inscription) = new_inscriptions.peek() {
if inscription.tx_in_index != u32::try_from(input_index).unwrap() {
while let Some(inscription) = envelopes.peek() {
if inscription.input != u32::try_from(input_index).unwrap() {
break;
}

Expand All @@ -171,11 +171,15 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
index: id_counter,
};

let curse = if inscription.inscription.unrecognized_even_field {
let curse = if inscription.payload.unrecognized_even_field {
Some(Curse::UnrecognizedEvenField)
} else if inscription.tx_in_index != 0 {
} else if inscription.payload.duplicate_field {
Some(Curse::DuplicateField)
} else if inscription.payload.incomplete_field {
Some(Curse::IncompleteField)
} else if inscription.input != 0 {
Some(Curse::NotInFirstInput)
} else if inscription.tx_in_offset != 0 {
} else if inscription.offset != 0 {
Some(Curse::NotAtOffsetZero)
} else if inscribed_offsets.contains_key(&offset) {
let seq_num = self.id_to_entry.len()?;
Expand Down Expand Up @@ -220,7 +224,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
};

let unbound = current_input_value == 0
|| inscription.tx_in_offset != 0
|| inscription.offset != 0
|| curse == Some(Curse::UnrecognizedEvenField);

if curse.is_some() || unbound {
Expand All @@ -238,12 +242,12 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
origin: Origin::New {
cursed,
fee: 0,
parent: inscription.inscription.parent(),
parent: inscription.payload.parent(),
unbound,
},
});

new_inscriptions.next();
envelopes.next();
id_counter += 1;
}
}
Expand Down

0 comments on commit 35ccc84

Please sign in to comment.