Skip to content

Commit dcb8054

Browse files
author
Ludo Galabru
committed
feat: improving curse approach
1 parent 4fe71f2 commit dcb8054

File tree

3 files changed

+57
-25
lines changed

3 files changed

+57
-25
lines changed

components/chainhook-event-observer/src/hord/inscription.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::BTreeMap;
22
use std::str::FromStr;
33

44
use bitcoincore_rpc::bitcoin::Transaction;
5+
use chainhook_types::OrdinalInscriptionCurseType;
56
use {
67
bitcoincore_rpc::bitcoin::{
78
blockdata::{
@@ -21,8 +22,9 @@ const CONTENT_TYPE_TAG: &[u8] = &[1];
2122

2223
#[derive(Debug, PartialEq, Clone)]
2324
pub struct Inscription {
24-
body: Option<Vec<u8>>,
25-
content_type: Option<Vec<u8>>,
25+
pub body: Option<Vec<u8>>,
26+
pub content_type: Option<Vec<u8>>,
27+
pub curse: Option<OrdinalInscriptionCurseType>,
2628
}
2729

2830
impl Inscription {
@@ -143,12 +145,20 @@ impl<'a> InscriptionParser<'a> {
143145
for tag in fields.keys() {
144146
if let Some(lsb) = tag.first() {
145147
if lsb % 2 == 0 {
146-
return Err(InscriptionError::UnrecognizedEvenField);
148+
return Ok(Some(Inscription {
149+
body,
150+
content_type,
151+
curse: Some(OrdinalInscriptionCurseType::Tag(*lsb)),
152+
}));
147153
}
148154
}
149155
}
150156

151-
return Ok(Some(Inscription { body, content_type }));
157+
return Ok(Some(Inscription {
158+
body,
159+
content_type,
160+
curse: None,
161+
}));
152162
}
153163

154164
Ok(None)

components/chainhook-event-observer/src/hord/mod.rs

+35-21
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use bitcoincore_rpc::bitcoin::hashes::hex::FromHex;
66
use bitcoincore_rpc::bitcoin::{Address, Network, Script};
77
use bitcoincore_rpc_json::bitcoin::Witness;
88
use chainhook_types::{
9-
BitcoinBlockData, OrdinalInscriptionRevealData, OrdinalInscriptionTransferData,
10-
OrdinalOperation, TransactionIdentifier,
9+
BitcoinBlockData, OrdinalInscriptionCurseType, OrdinalInscriptionRevealData,
10+
OrdinalInscriptionTransferData, OrdinalOperation, TransactionIdentifier,
1111
};
1212
use dashmap::DashMap;
1313
use fxhash::{FxBuildHasher, FxHasher};
@@ -56,18 +56,28 @@ pub fn parse_ordinal_operations(
5656
for (input_index, input) in tx.vin.iter().enumerate() {
5757
if let Some(ref witness_data) = input.txinwitness {
5858
let witness = Witness::from_vec(witness_data.clone());
59-
let inscription = match InscriptionParser::parse(&witness) {
59+
let mut inscription = match InscriptionParser::parse(&witness) {
6060
Ok(inscription) => inscription,
61-
Err(e) => {
62-
ctx.try_log(|logger| {
63-
slog::warn!(
64-
logger,
65-
"Inscription parsing error at block {}: #{:?}",
66-
block_height,
67-
e
68-
)
69-
});
70-
continue;
61+
Err(_e) => {
62+
let mut cursed_inscription = None;
63+
for bytes in witness_data.iter() {
64+
let script = Script::from(bytes.to_vec());
65+
let parser = InscriptionParser {
66+
instructions: script.instructions().peekable(),
67+
};
68+
69+
let mut inscription = match parser.parse_script() {
70+
Ok(inscription) => inscription,
71+
Err(_) => continue,
72+
};
73+
inscription.curse = Some(OrdinalInscriptionCurseType::P2wsh);
74+
cursed_inscription = Some(inscription);
75+
break;
76+
}
77+
match cursed_inscription {
78+
Some(inscription) => inscription,
79+
None => continue,
80+
}
7181
}
7282
};
7383

@@ -82,9 +92,6 @@ pub fn parse_ordinal_operations(
8292
.and_then(|o| Some(o.value.to_sat()))
8393
.unwrap_or(0);
8494

85-
let no_content_bytes = vec![];
86-
let inscription_content_bytes = inscription.body().unwrap_or(&no_content_bytes);
87-
8895
let inscriber_address = if let Ok(authors) = Address::from_script(
8996
&tx.vout[0].script_pub_key.script().unwrap(),
9097
bitcoincore_rpc::bitcoin::Network::Bitcoin,
@@ -94,6 +101,13 @@ pub fn parse_ordinal_operations(
94101
None
95102
};
96103

104+
if input_index > 0 {
105+
inscription.curse = Some(OrdinalInscriptionCurseType::Batch);
106+
}
107+
108+
let no_content_bytes = vec![];
109+
let inscription_content_bytes = inscription.body().take().unwrap_or(&no_content_bytes);
110+
97111
let payload = OrdinalInscriptionRevealData {
98112
content_type: inscription.content_type().unwrap_or("unknown").to_string(),
99113
content_bytes: format!("0x{}", hex::encode(&inscription_content_bytes)),
@@ -109,13 +123,13 @@ pub fn parse_ordinal_operations(
109123
ordinal_offset: 0,
110124
transfers_pre_inscription: 0,
111125
satpoint_post_inscription: format!("{}:0:0", tx.txid.clone()),
126+
curse_type: inscription.curse.take(),
112127
};
113128

114-
if input_index == 0 {
115-
operations.push(OrdinalOperation::InscriptionRevealed(payload));
116-
} else {
117-
operations.push(OrdinalOperation::CursedInscriptionRevealed(payload));
118-
}
129+
operations.push(match &payload.curse_type {
130+
Some(_) => OrdinalOperation::CursedInscriptionRevealed(payload),
131+
None => OrdinalOperation::InscriptionRevealed(payload),
132+
});
119133
}
120134
}
121135
operations

components/chainhook-types-rs/src/rosetta.rs

+8
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,13 @@ pub struct OrdinalInscriptionTransferData {
318318
pub post_transfer_output_value: Option<u64>,
319319
}
320320

321+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
322+
pub enum OrdinalInscriptionCurseType {
323+
Tag(u8),
324+
Batch,
325+
P2wsh,
326+
}
327+
321328
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
322329
pub struct OrdinalInscriptionRevealData {
323330
pub content_bytes: String,
@@ -334,6 +341,7 @@ pub struct OrdinalInscriptionRevealData {
334341
pub ordinal_offset: u64,
335342
pub transfers_pre_inscription: u32,
336343
pub satpoint_post_inscription: String,
344+
pub curse_type: Option<OrdinalInscriptionCurseType>,
337345
}
338346

339347
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]

0 commit comments

Comments
 (0)