Skip to content

Commit

Permalink
fix bug of vindicated tag
Browse files Browse the repository at this point in the history
  • Loading branch information
yann-sjtu committed Jan 5, 2024
2 parents 5253168 + b9b1ddd commit 40d14f8
Show file tree
Hide file tree
Showing 23 changed files with 665 additions and 152 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Changelog
=========

[0.14.1](https://github.com/ordinals/ord/releases/tag/0.14.1) - 2023-01-03
--------------------------------------------------------------------------

### Fixed
- Fix wallet create (#2943)

## Misc
- Clean up justfile (#2939)

[0.14.0](https://github.com/ordinals/ord/releases/tag/0.14.0) - 2023-01-02
--------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ord"
description = "◉ Ordinal wallet and block explorer"
version = "0.14.0"
version = "0.14.1"
license = "CC0-1.0"
edition = "2021"
autotests = false
Expand Down
6 changes: 4 additions & 2 deletions deploy/setup
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ esac

touch ~/.hushlogin

sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

mkdir -p \
/etc/systemd/system/bitcoind.service.d \
/etc/systemd/system/ord.service.d
Expand Down Expand Up @@ -62,6 +60,10 @@ ufw allow http
ufw allow https
ufw allow ssh

sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sshd -t
systemctl restart sshd

case $CHAIN in
main)
ufw allow 8333
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ install-personal-key key='~/.ssh/id_ed25519.pub':
#!/usr/bin/env bash
set -euxo pipefail
for server in alpha balance regtest signet stability testnet; do
ssh-copy-id -i '{{ key }}' root@$server.ordinals.net
ssh-copy-id -i {{ key }} root@$server.ordinals.net
done
log unit='ord' domain='alpha.ordinals.net':
Expand Down
285 changes: 243 additions & 42 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use {
super::*,
crate::{
subcommand::{find::FindRangeOutput, server::InscriptionQuery},
templates::{RuneHtml, StatusHtml},
templates::StatusHtml,
},
bitcoin::block::Header,
bitcoincore_rpc::{json::GetBlockHeaderResult, Client},
Expand All @@ -38,7 +38,7 @@ use {
},
};

pub(crate) use self::entry::RuneEntry;
pub use self::entry::RuneEntry;
pub(super) use self::entry::{
InscriptionEntry, InscriptionEntryValue, InscriptionIdValue, OutPointValue, TxidValue,
};
Expand Down Expand Up @@ -110,18 +110,18 @@ pub enum List {
#[derive(Copy, Clone)]
pub(crate) enum Statistic {
Schema = 0,
BlessedInscriptions,
Commits,
CursedInscriptions,
IndexRunes,
IndexSats,
LostSats,
OutputsTraversed,
ReservedRunes,
Runes,
SatRanges,
UnboundInscriptions,
IndexTransactions,
BlessedInscriptions = 1,
Commits = 2,
CursedInscriptions = 3,
IndexRunes = 4,
IndexSats = 5,
LostSats = 6,
OutputsTraversed = 7,
ReservedRunes = 8,
Runes = 9,
SatRanges = 10,
UnboundInscriptions = 11,
IndexTransactions = 12,
}

impl Statistic {
Expand Down Expand Up @@ -472,6 +472,7 @@ impl Index {

Ok(StatusHtml {
blessed_inscriptions,
chain: self.options.chain(),
cursed_inscriptions,
height,
inscriptions: blessed_inscriptions + cursed_inscriptions,
Expand Down Expand Up @@ -920,29 +921,10 @@ impl Index {
)
}

pub(crate) fn rune(&self, rune: Rune) -> Result<Option<(RuneId, RuneEntry)>> {
let rtx = self.database.begin_read()?;

let Some(id) = rtx
.open_table(RUNE_TO_RUNE_ID)?
.get(rune.0)?
.map(|guard| guard.value())
else {
return Ok(None);
};

let entry = RuneEntry::load(
rtx
.open_table(RUNE_ID_TO_RUNE_ENTRY)?
.get(id)?
.unwrap()
.value(),
);

Ok(Some((RuneId::load(id), entry)))
}

pub(crate) fn rune_html(&self, rune: Rune) -> Result<Option<RuneHtml>> {
pub(crate) fn rune(
&self,
rune: Rune,
) -> Result<Option<(RuneId, RuneEntry, Option<InscriptionId>)>> {
let rtx = self.database.begin_read()?;

let Some(id) = rtx
Expand Down Expand Up @@ -972,11 +954,7 @@ impl Index {
.is_some()
.then_some(parent);

Ok(Some(RuneHtml {
entry,
id: RuneId::load(id),
parent,
}))
Ok(Some((RuneId::load(id), entry, parent)))
}

pub(crate) fn runes(&self) -> Result<Vec<(RuneId, RuneEntry)>> {
Expand Down Expand Up @@ -5872,4 +5850,227 @@ mod tests {
);
}
}

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

// Before the jubilee, an inscription on a sat using a pushnum opcode is
// cursed and not vindicated.

let script = script::Builder::new()
.push_opcode(opcodes::OP_FALSE)
.push_opcode(opcodes::all::OP_IF)
.push_slice(b"ord")
.push_slice([])
.push_opcode(opcodes::all::OP_PUSHNUM_1)
.push_opcode(opcodes::all::OP_ENDIF)
.into_script();

let witness = Witness::from_slice(&[script.into_bytes(), Vec::new()]);

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);

let entry = context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap();

assert!(Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Cursed));

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Vindicated));

let sat = entry.sat;

assert_eq!(entry.inscription_number, -1);

// Before the jubilee, reinscription on the same sat is not cursed and
// not vindicated.

let inscription = Inscription::default();

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

context.mine_blocks(1);

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

let entry = context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap();

assert_eq!(entry.inscription_number, 0);

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Cursed));

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Vindicated));

assert_eq!(sat, entry.sat);

// Before the jubilee, a third reinscription on the same sat is cursed
// and not vindicated.

let inscription = Inscription::default();

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

context.mine_blocks(1);

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

let entry = context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap();

assert!(Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Cursed));

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Vindicated));

assert_eq!(entry.inscription_number, -2);

assert_eq!(sat, entry.sat);
}
}

#[test]
fn post_jubilee_first_reinscription_after_vindicated_inscription_not_vindicated() {
for context in Context::configurations() {
context.mine_blocks(110);
// After the jubilee, an inscription on a sat using a pushnum opcode is
// vindicated and not cursed.

let script = script::Builder::new()
.push_opcode(opcodes::OP_FALSE)
.push_opcode(opcodes::all::OP_IF)
.push_slice(b"ord")
.push_slice([])
.push_opcode(opcodes::all::OP_PUSHNUM_1)
.push_opcode(opcodes::all::OP_ENDIF)
.into_script();

let witness = Witness::from_slice(&[script.into_bytes(), Vec::new()]);

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);

let entry = context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap();

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Cursed));

assert!(Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Vindicated));

let sat = entry.sat;

assert_eq!(entry.inscription_number, 0);

// After the jubilee, a reinscription on the same is not cursed and not
// vindicated.

let inscription = Inscription::default();

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

context.mine_blocks(1);

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

let entry = context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap();

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Cursed));

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Vindicated));

assert_eq!(entry.inscription_number, 1);

assert_eq!(sat, entry.sat);

// After the jubilee, a third reinscription on the same is vindicated and
// not cursed.

let inscription = Inscription::default();

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

context.mine_blocks(1);

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

let entry = context
.index
.get_inscription_entry(inscription_id)
.unwrap()
.unwrap();

assert!(!Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Cursed));

assert!(Charm::charms(entry.charms)
.iter()
.any(|charm| *charm == Charm::Vindicated));

assert_eq!(entry.inscription_number, 2);

assert_eq!(sat, entry.sat);
}
}
}
Loading

0 comments on commit 40d14f8

Please sign in to comment.