Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add inscription charms #2681

Merged
merged 4 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/charm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#[derive(Copy, Clone)]
pub(crate) enum Charm {
Cursed,
Epic,
Legendary,
Lost,
Nineball,
Rare,
Reinscription,
Unbound,
Uncommon,
}

impl Charm {
pub(crate) const ALL: [Charm; 9] = [
Charm::Uncommon,
Charm::Rare,
Charm::Epic,
Charm::Legendary,
Charm::Nineball,
Charm::Reinscription,
Charm::Cursed,
Charm::Unbound,
Charm::Lost,
];

fn flag(self) -> u16 {
1 << self as u16
}

pub(crate) fn set(self, charms: &mut u16) {
*charms |= self.flag();
}

pub(crate) fn is_set(self, charms: u16) -> bool {
charms & self.flag() != 0
}

pub(crate) fn icon(self) -> &'static str {
match self {
Charm::Cursed => "👹",
Charm::Epic => "🪻",
Charm::Legendary => "🌝",
Charm::Lost => "🤔",
Charm::Nineball => "9️⃣",
Charm::Rare => "🧿",
Charm::Reinscription => "♻️",
Charm::Unbound => "🔓",
Charm::Uncommon => "🌱",
}
}

pub(crate) fn title(self) -> &'static str {
match self {
Charm::Cursed => "cursed",
Charm::Epic => "epic",
Charm::Legendary => "legendary",
Charm::Lost => "lost",
Charm::Nineball => "nineball",
Charm::Rare => "rare",
Charm::Reinscription => "reinscription",
Charm::Unbound => "unbound",
Charm::Uncommon => "uncommon",
}
}
}
6 changes: 5 additions & 1 deletion src/index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ impl Entry for RuneId {

#[derive(Debug)]
pub(crate) struct InscriptionEntry {
pub(crate) charms: u16,
pub(crate) fee: u64,
pub(crate) height: u64,
pub(crate) inscription_number: i64,
Expand All @@ -149,6 +150,7 @@ pub(crate) struct InscriptionEntry {
}

pub(crate) type InscriptionEntryValue = (
u16, // charms
u64, // fee
u64, // height
i64, // inscription number
Expand All @@ -162,9 +164,10 @@ impl Entry for InscriptionEntry {
type Value = InscriptionEntryValue;

fn load(
(fee, height, inscription_number, parent, sat, sequence_number, timestamp): InscriptionEntryValue,
(charms, fee, height, inscription_number, parent, sat, sequence_number, timestamp): InscriptionEntryValue,
) -> Self {
Self {
charms,
fee,
height,
inscription_number,
Expand All @@ -181,6 +184,7 @@ impl Entry for InscriptionEntry {

fn store(self) -> Self::Value {
(
self.charms,
self.fee,
self.height,
self.inscription_number,
Expand Down
148 changes: 76 additions & 72 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
use {super::*, inscription::Curse};
use super::*;

#[derive(Debug, PartialEq, Copy, Clone)]
enum Curse {
DuplicateField,
IncompleteField,
NotAtOffsetZero,
NotInFirstInput,
Pointer,
Pushnum,
Reinscription,
UnrecognizedEvenField,
}

#[derive(Debug, Clone)]
pub(super) struct Flotsam {
Expand All @@ -15,6 +27,7 @@ enum Origin {
hidden: bool,
parent: Option<InscriptionId>,
pointer: Option<u64>,
reinscription: bool,
unbound: bool,
},
Old {
Expand Down Expand Up @@ -123,6 +136,8 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
index: id_counter,
};

let reinscription = inscribed_offsets.contains_key(&offset);

let curse = if inscription.payload.unrecognized_even_field {
Some(Curse::UnrecognizedEvenField)
} else if inscription.payload.duplicate_field {
Expand All @@ -137,22 +152,12 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
Some(Curse::Pointer)
} else if inscription.pushnum {
Some(Curse::Pushnum)
} else if inscribed_offsets.contains_key(&offset) {
let seq_num = self.next_sequence_number;

let sat = Self::calculate_sat(input_sat_ranges, offset);

log::info!("processing reinscription {inscription_id} on sat {:?}: sequence number {seq_num}, inscribed offsets {:?}", sat, inscribed_offsets);

} else if reinscription {
Some(Curse::Reinscription)
} else {
None
};

if curse.is_some() {
log::info!("found cursed inscription {inscription_id}: {:?}", curse);
}

let cursed = if let Some(Curse::Reinscription) = curse {
let first_reinscription = inscribed_offsets
.get(&offset)
Expand All @@ -172,28 +177,18 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
})
.unwrap_or(false);

log::info!("{inscription_id}: is first reinscription: {first_reinscription}, initial inscription is cursed: {initial_inscription_is_cursed}");

!(initial_inscription_is_cursed && first_reinscription)
} else {
curse.is_some()
};

let unbound = current_input_value == 0 || curse == Some(Curse::UnrecognizedEvenField);

if curse.is_some() || unbound {
log::info!(
"indexing inscription {inscription_id} with curse {:?} as cursed {} and unbound {}",
curse,
cursed,
unbound
);
}

floating_inscriptions.push(Flotsam {
inscription_id,
offset,
origin: Origin::New {
reinscription,
cursed,
fee: 0,
hidden: inscription.payload.hidden(),
Expand Down Expand Up @@ -229,40 +224,16 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {

// still have to normalize over inscription size
let total_output_value = tx.output.iter().map(|txout| txout.value).sum::<u64>();
let mut floating_inscriptions = floating_inscriptions
.into_iter()
.map(|flotsam| {
if let Flotsam {
inscription_id,
offset,
origin:
Origin::New {
cursed,
fee: _,
hidden,
parent,
pointer,
unbound,
},
} = flotsam
{
Flotsam {
inscription_id,
offset,
origin: Origin::New {
cursed,
fee: (total_input_value - total_output_value) / u64::from(id_counter),
hidden,
parent,
pointer,
unbound,
},
}
} else {
flotsam
}
})
.collect::<Vec<Flotsam>>();

for flotsam in &mut floating_inscriptions {
if let Flotsam {
origin: Origin::New { ref mut fee, .. },
..
} = flotsam
{
*fee = (total_input_value - total_output_value) / u64::from(id_counter);
}
}

let is_coinbase = tx
.input
Expand Down Expand Up @@ -361,20 +332,19 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
input_sat_ranges: Option<&VecDeque<(u64, u64)>>,
input_offset: u64,
) -> Option<Sat> {
let mut sat = None;
if let Some(input_sat_ranges) = input_sat_ranges {
let mut offset = 0;
for (start, end) in input_sat_ranges {
let size = end - start;
if offset + size > input_offset {
let n = start + input_offset - offset;
sat = Some(Sat(n));
break;
}
offset += size;
let input_sat_ranges = input_sat_ranges?;

let mut offset = 0;
for (start, end) in input_sat_ranges {
let size = end - start;
if offset + size > input_offset {
let n = start + input_offset - offset;
return Some(Sat(n));
}
offset += size;
}
sat

unreachable!()
}

fn update_inscription_location(
Expand All @@ -393,10 +363,11 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
Origin::New {
cursed,
fee,
hidden,
parent,
pointer: _,
reinscription,
unbound,
hidden,
..
} => {
let inscription_number = if cursed {
let number: i64 = self.cursed_inscription_count.try_into().unwrap();
Expand Down Expand Up @@ -428,19 +399,52 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
Self::calculate_sat(input_sat_ranges, flotsam.offset)
};

let mut charms = 0;

if cursed {
Charm::Cursed.set(&mut charms);
}

if reinscription {
Charm::Reinscription.set(&mut charms);
}

if let Some(sat) = sat {
if sat.nineball() {
Charm::Nineball.set(&mut charms);
}

match sat.rarity() {
Rarity::Common | Rarity::Mythic => {}
Rarity::Uncommon => Charm::Uncommon.set(&mut charms),
Rarity::Rare => Charm::Rare.set(&mut charms),
Rarity::Epic => Charm::Epic.set(&mut charms),
Rarity::Legendary => Charm::Legendary.set(&mut charms),
}
}

if new_satpoint.outpoint == OutPoint::null() {
Charm::Lost.set(&mut charms);
}

if unbound {
Charm::Unbound.set(&mut charms);
}

if let Some(Sat(n)) = sat {
self.sat_to_inscription_id.insert(&n, &inscription_id)?;
}

self.id_to_entry.insert(
&inscription_id,
&InscriptionEntry {
charms,
fee,
height: self.height,
inscription_number,
sequence_number,
parent,
sat,
sequence_number,
timestamp: self.timestamp,
}
.store(),
Expand Down
12 changes: 0 additions & 12 deletions src/inscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,6 @@ use {
std::str,
};

#[derive(Debug, PartialEq, Clone)]
pub(crate) enum Curse {
DuplicateField,
IncompleteField,
NotAtOffsetZero,
NotInFirstInput,
Pointer,
Pushnum,
Reinscription,
UnrecognizedEvenField,
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Eq, Default)]
pub struct Inscription {
pub body: Option<Vec<u8>>,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use {
self::{
arguments::Arguments,
blocktime::Blocktime,
charm::Charm,
config::Config,
decimal::Decimal,
degree::Degree,
Expand Down Expand Up @@ -108,6 +109,7 @@ macro_rules! tprintln {
mod arguments;
mod blocktime;
mod chain;
mod charm;
mod config;
mod decimal;
mod degree;
Expand Down
Loading