Skip to content

Commit

Permalink
Add inscription charms
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed Nov 16, 2023
1 parent b0c8cdf commit 5d6adc6
Show file tree
Hide file tree
Showing 9 changed files with 449 additions and 110 deletions.
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 => "🌅",
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
106 changes: 68 additions & 38 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 @@ -242,6 +237,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
hidden,
parent,
pointer,
reinscription,
unbound,
},
} = flotsam
Expand All @@ -255,6 +251,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
hidden,
parent,
pointer,
reinscription,
unbound,
},
}
Expand Down Expand Up @@ -361,20 +358,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 +389,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 +425,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
20 changes: 20 additions & 0 deletions src/sat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ impl Sat {
self.epoch().starting_height() + self.epoch_position() / self.epoch().subsidy()
}

pub(crate) fn nineball(self) -> bool {
self.n() >= 50 * COIN_VALUE * 9 && self.n() < 50 * COIN_VALUE * 10
}

pub(crate) fn cycle(self) -> u64 {
Epoch::from(self).0 / CYCLE_EPOCHS
}
Expand Down Expand Up @@ -591,6 +595,7 @@ mod tests {

#[test]
fn percentile_round_trip() {
#[track_caller]
fn case(n: u64) {
let expected = Sat(n);
let actual = expected.percentile().parse::<Sat>().unwrap();
Expand All @@ -607,6 +612,7 @@ mod tests {

#[test]
fn is_common() {
#[track_caller]
fn case(n: u64) {
assert_eq!(Sat(n).is_common(), Sat(n).rarity() == Rarity::Common);
}
Expand All @@ -620,4 +626,18 @@ mod tests {
case(2067187500000000);
case(2067187500000000 + 1);
}

#[test]
fn nineball() {
for height in 0..10 {
let sat = Sat(height * 50 * COIN_VALUE);
assert_eq!(
sat.nineball(),
sat.height() == 9,
"nineball: {} height: {}",
sat.nineball(),
sat.height()
);
}
}
}
Loading

0 comments on commit 5d6adc6

Please sign in to comment.