Skip to content

Commit

Permalink
Display number of times a rune has been minted (ordinals#2901)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored and torkelrogstad committed Mar 11, 2024
1 parent ab057ec commit 4afa049
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 42 deletions.
60 changes: 53 additions & 7 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use {
},
super::*,
crate::{
subcommand::find::FindRangeOutput, subcommand::server::InscriptionQuery, templates::StatusHtml,
subcommand::{find::FindRangeOutput, server::InscriptionQuery},
templates::{RuneHtml, StatusHtml},
wallet::Wallet,
},
bitcoin::block::Header,
Expand Down Expand Up @@ -900,15 +901,60 @@ impl Index {
pub(crate) fn rune(&self, rune: Rune) -> Result<Option<(RuneId, RuneEntry)>> {
let rtx = self.database.begin_read()?;

let entry = match rtx.open_table(RUNE_TO_RUNE_ID)?.get(rune.0)? {
Some(id) => rtx
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.value())?
.map(|entry| (RuneId::load(id.value()), RuneEntry::load(entry.value()))),
None => None,
.get(id)?
.unwrap()
.value(),
);

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

pub(crate) fn rune_html(&self, rune: Rune) -> Result<Option<RuneHtml>> {
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);
};

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

let parent = InscriptionId {
txid: entry.etching,
index: 0,
};

let parent = rtx
.open_table(INSCRIPTION_ID_TO_SEQUENCE_NUMBER)?
.get(&parent.store())?
.is_some()
.then_some(parent);

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

pub(crate) fn runes(&self) -> Result<Vec<(RuneId, RuneEntry)>> {
Expand Down
15 changes: 11 additions & 4 deletions src/index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub(crate) struct RuneEntry {
pub(crate) end: Option<u32>,
pub(crate) etching: Txid,
pub(crate) limit: Option<u128>,
pub(crate) mints: u64,
pub(crate) number: u64,
pub(crate) rune: Rune,
pub(crate) spacers: u32,
Expand All @@ -51,7 +52,10 @@ pub(super) type RuneEntryValue = (
Option<u32>, // end
(u128, u128), // etching
Option<u128>, // limit
u64, // number
(
u64, // mints
u64, // number
),
u128, // rune
u32, // spacers
u128, // supply
Expand All @@ -77,6 +81,7 @@ impl Default for RuneEntry {
end: None,
etching: Txid::all_zeros(),
limit: None,
mints: 0,
number: 0,
rune: Rune(0),
spacers: 0,
Expand All @@ -98,7 +103,7 @@ impl Entry for RuneEntry {
end,
etching,
limit,
number,
(mints, number),
rune,
spacers,
supply,
Expand All @@ -122,6 +127,7 @@ impl Entry for RuneEntry {
])
},
limit,
mints,
number,
rune: Rune(rune),
spacers,
Expand Down Expand Up @@ -151,7 +157,7 @@ impl Entry for RuneEntry {
)
},
self.limit,
self.number,
(self.mints, self.number),
self.rune.0,
self.spacers,
self.supply,
Expand Down Expand Up @@ -437,6 +443,7 @@ mod tests {
0x1E, 0x1F,
]),
limit: Some(5),
mints: 11,
number: 6,
rune: Rune(7),
spacers: 8,
Expand All @@ -455,7 +462,7 @@ mod tests {
0x1F1E1D1C1B1A19181716151413121110,
),
Some(5),
6,
(11, 6),
7,
8,
9,
Expand Down
16 changes: 16 additions & 0 deletions src/index/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,11 +595,27 @@ impl<'index> Updater<'_> {
statistic_to_count: &mut statistic_to_count,
timestamp: block.header.time,
transaction_id_to_rune: &mut transaction_id_to_rune,
updates: HashMap::new(),
};

for (i, (tx, txid)) in block.txdata.iter().enumerate() {
rune_updater.index_runes(i, tx, *txid)?;
}

for (rune_id, update) in rune_updater.updates {
let mut entry = RuneEntry::load(
rune_id_to_rune_entry
.get(&rune_id.store())?
.unwrap()
.value(),
);

entry.burned += update.burned;
entry.mints += update.mints;
entry.supply += update.supply;

rune_id_to_rune_entry.insert(&rune_id.store(), entry.store())?;
}
}

if index.index_transactions {
Expand Down
28 changes: 20 additions & 8 deletions src/index/updater/rune_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ struct Allocation {
symbol: Option<char>,
}

#[derive(Default)]
pub(crate) struct RuneUpdate {
pub(crate) burned: u128,
pub(crate) mints: u64,
pub(crate) supply: u128,
}

pub(super) struct RuneUpdater<'a, 'db, 'tx> {
pub(super) height: u32,
pub(super) id_to_entry: &'a mut Table<'db, 'tx, RuneIdValue, RuneEntryValue>,
Expand All @@ -31,6 +38,7 @@ pub(super) struct RuneUpdater<'a, 'db, 'tx> {
pub(super) statistic_to_count: &'a mut Table<'db, 'tx, u64, u64>,
pub(super) timestamp: u32,
pub(super) transaction_id_to_rune: &'a mut Table<'db, 'tx, &'static TxidValue, u128>,
pub(super) updates: HashMap<RuneId, RuneUpdate>,
}

impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {
Expand Down Expand Up @@ -258,10 +266,12 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {
for (id, amount) in mintable {
let minted = limits[&id] - amount;
if minted > 0 {
let id = RuneId::try_from(id).unwrap().store();
let mut entry = RuneEntry::load(self.id_to_entry.get(id)?.unwrap().value());
entry.supply += minted;
self.id_to_entry.insert(id, entry.store())?;
let update = self
.updates
.entry(RuneId::try_from(id).unwrap())
.or_default();
update.mints += 1;
update.supply += minted;
}
}
}
Expand Down Expand Up @@ -293,6 +303,7 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {
deadline: deadline.and_then(|deadline| (!burn).then_some(deadline)),
divisibility,
etching: txid,
mints: 0,
number,
rune,
spacers,
Expand Down Expand Up @@ -399,10 +410,11 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {

// increment entries with burned runes
for (id, amount) in burned {
let id = RuneId::try_from(id).unwrap().store();
let mut entry = RuneEntry::load(self.id_to_entry.get(id)?.unwrap().value());
entry.burned += amount;
self.id_to_entry.insert(id, entry.store())?;
self
.updates
.entry(RuneId::try_from(id).unwrap())
.or_default()
.burned += amount;
}

Ok(())
Expand Down
27 changes: 19 additions & 8 deletions src/runes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -964,18 +964,19 @@ mod tests {
[(
id,
RuneEntry {
etching: txid0,
rune: Rune(RUNE),
timestamp: 2,
divisibility: 1,
limit: None,
symbol: Some('$'),
end: None,
spacers: 1,
burned: 0,
deadline: None,
divisibility: 1,
end: None,
etching: txid0,
limit: None,
mints: 0,
number: 0,
rune: Rune(RUNE),
spacers: 1,
supply: 0,
symbol: Some('$'),
timestamp: 2,
},
)],
[],
Expand Down Expand Up @@ -4277,6 +4278,7 @@ mod tests {
rune: Rune(RUNE),
limit: Some(1000),
timestamp: 2,
mints: 0,
..Default::default()
},
)],
Expand Down Expand Up @@ -4310,6 +4312,7 @@ mod tests {
limit: Some(1000),
supply: 1000,
timestamp: 2,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -4349,6 +4352,7 @@ mod tests {
limit: Some(1000),
supply: 2000,
timestamp: 2,
mints: 2,
..Default::default()
},
)],
Expand Down Expand Up @@ -4444,6 +4448,7 @@ mod tests {
supply: 1000,
end: Some(4),
timestamp: 2,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -4484,6 +4489,7 @@ mod tests {
supply: 1000,
end: Some(4),
timestamp: 2,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -4655,6 +4661,7 @@ mod tests {
rune: Rune(RUNE),
supply: 1000,
timestamp: 2,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -4695,6 +4702,7 @@ mod tests {
supply: 1000,
deadline: Some(4),
timestamp: 2,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -4779,6 +4787,7 @@ mod tests {
limit: Some(1000),
supply: 1000,
timestamp: 2,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -5057,6 +5066,7 @@ mod tests {
limit: Some(1000),
timestamp: 2,
supply: 2000,
mints: 1,
..Default::default()
},
)],
Expand Down Expand Up @@ -5166,6 +5176,7 @@ mod tests {
limit: Some(1000),
timestamp: 2,
supply: 1000,
mints: 1,
..Default::default()
},
)],
Expand Down
7 changes: 5 additions & 2 deletions src/subcommand/runes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct RuneInfo {
pub id: RuneId,
pub index: u16,
pub limit: Option<u128>,
pub mints: u64,
pub number: u64,
pub rune: Rune,
pub spacers: u32,
Expand Down Expand Up @@ -48,6 +49,7 @@ pub(crate) fn run(options: Options) -> SubcommandResult {
end,
etching,
limit,
mints,
number,
rune,
spacers,
Expand All @@ -62,18 +64,19 @@ pub(crate) fn run(options: Options) -> SubcommandResult {
burned,
deadline,
divisibility,
end,
etching,
height: id.height,
id,
index: id.index,
end,
limit,
mints,
number,
timestamp: crate::timestamp(timestamp),
rune,
spacers,
supply,
symbol,
timestamp: crate::timestamp(timestamp),
},
)
},
Expand Down
Loading

0 comments on commit 4afa049

Please sign in to comment.