diff --git a/src/chain.rs b/src/chain.rs index 89c8123bfd..f8ef180cdc 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -47,6 +47,15 @@ impl Chain { } } + pub(crate) fn jubilee_height(self) -> u32 { + match self { + Self::Mainnet => 824544, + Self::Regtest => 110, + Self::Signet => 175392, + Self::Testnet => 2544192, + } + } + pub(crate) fn genesis_block(self) -> Block { bitcoin::blockdata::constants::genesis_block(self.network()) } diff --git a/src/index.rs b/src/index.rs index 9f4ebb39b6..7b2ffe1396 100644 --- a/src/index.rs +++ b/src/index.rs @@ -3043,6 +3043,63 @@ mod tests { } } + #[test] + fn inscriptions_are_uncursed_after_jubilee() { + for context in Context::configurations() { + context.mine_blocks(108); + + 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.clone())], + ..Default::default() + }); + + let inscription_id = InscriptionId { txid, index: 0 }; + + context.mine_blocks(1); + + assert_eq!(context.rpc_server.height(), 109); + + assert_eq!( + context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap() + .inscription_number, + -1 + ); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(2, 0, 0, witness)], + ..Default::default() + }); + + let inscription_id = InscriptionId { txid, index: 0 }; + + context.mine_blocks(1); + + assert_eq!(context.rpc_server.height(), 110); + + assert_eq!( + context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap() + .inscription_number, + 0 + ); + } + } + #[test] fn duplicate_field_inscriptions_are_cursed() { for context in Context::configurations() { diff --git a/src/index/updater.rs b/src/index/updater.rs index 515869255a..077628c9a5 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -422,6 +422,7 @@ impl<'index> Updater<'_> { let mut inscription_updater = InscriptionUpdater { blessed_inscription_count, + chain: self.index.options.chain(), cursed_inscription_count, flotsam: Vec::new(), height: self.height, diff --git a/src/index/updater/inscription_updater.rs b/src/index/updater/inscription_updater.rs index 83b3a7d370..5d4cb3a1c5 100644 --- a/src/index/updater/inscription_updater.rs +++ b/src/index/updater/inscription_updater.rs @@ -38,6 +38,7 @@ enum Origin { pub(super) struct InscriptionUpdater<'a, 'db, 'tx> { pub(super) blessed_inscription_count: u64, + pub(super) chain: Chain, pub(super) cursed_inscription_count: u64, pub(super) flotsam: Vec, pub(super) height: u32, @@ -135,7 +136,9 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { let inscribed_offset = inscribed_offsets.get(&offset); - let curse = if inscription.payload.unrecognized_even_field { + let curse = if self.height >= self.chain.jubilee_height() { + None + } else if inscription.payload.unrecognized_even_field { Some(Curse::UnrecognizedEvenField) } else if inscription.payload.duplicate_field { Some(Curse::DuplicateField) diff --git a/test-bitcoincore-rpc/src/lib.rs b/test-bitcoincore-rpc/src/lib.rs index 3993db2e55..3d11b8f132 100644 --- a/test-bitcoincore-rpc/src/lib.rs +++ b/test-bitcoincore-rpc/src/lib.rs @@ -223,6 +223,10 @@ impl Handle { self.state().broadcast_tx(template) } + pub fn height(&self) -> u64 { + u64::try_from(self.state().blocks.len()).unwrap() - 1 + } + pub fn invalidate_tip(&self) -> BlockHash { self.state().pop_block() }