Skip to content

Commit

Permalink
Encode runestones with tags (#2547)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Oct 17, 2023
1 parent 659ce6c commit 4219f35
Show file tree
Hide file tree
Showing 6 changed files with 760 additions and 434 deletions.
13 changes: 13 additions & 0 deletions src/index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ pub(crate) struct RuneEntry {
pub(crate) symbol: Option<char>,
}

impl Default for RuneEntry {
fn default() -> Self {
Self {
burned: 0,
divisibility: 0,
etching: Txid::all_zeros(),
rune: Rune(0),
supply: 0,
symbol: None,
}
}
}

pub(super) type RuneEntryValue = (u128, u8, (u128, u128), u128, u128, u32);

impl Entry for RuneEntry {
Expand Down
103 changes: 58 additions & 45 deletions src/index/updater/rune_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {
}
}

let burn = runestone
.as_ref()
.map(|runestone| runestone.burn)
.unwrap_or_default();

// A vector of allocated transaction output rune balances
let mut allocated: Vec<HashMap<u128, u128>> = vec![HashMap::new(); tx.output.len()];

Expand Down Expand Up @@ -90,42 +95,44 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {
None => None,
};

for Edict { id, amount, output } in runestone.edicts {
// Skip edicts not referring to valid outputs
if output >= tx.output.len() as u128 {
continue;
}

let (balance, id) = if id == 0 {
// If this edict allocates new issuance runes, skip it
// if no issuance was present, or if the issuance was invalid.
// Additionally, replace ID 0 with the newly assigned ID, and
// get the unallocated balance of the issuance.
match allocation.as_mut() {
Some(Allocation { balance, id, .. }) => (balance, *id),
None => continue,
if !burn {
for Edict { id, amount, output } in runestone.edicts {
// Skip edicts not referring to valid outputs
if output >= tx.output.len() as u128 {
continue;
}
} else {
// Get the unallocated balance of the given ID
match unallocated.get_mut(&id) {
Some(balance) => (balance, id),
None => continue,

let (balance, id) = if id == 0 {
// If this edict allocates new issuance runes, skip it
// if no issuance was present, or if the issuance was invalid.
// Additionally, replace ID 0 with the newly assigned ID, and
// get the unallocated balance of the issuance.
match allocation.as_mut() {
Some(Allocation { balance, id, .. }) => (balance, *id),
None => continue,
}
} else {
// Get the unallocated balance of the given ID
match unallocated.get_mut(&id) {
Some(balance) => (balance, id),
None => continue,
}
};

// Get the allocatable amount
let amount = if amount == 0 {
*balance
} else {
amount.min(*balance)
};

// If the amount to be allocated is greater than zero,
// deduct it from the remaining balance, and increment
// the allocated entry.
if amount > 0 {
*balance -= amount;
*allocated[output as usize].entry(id).or_default() += amount;
}
};

// Get the allocatable amount
let amount = if amount == 0 {
*balance
} else {
amount.min(*balance)
};

// If the amount to be allocated is greater than zero,
// deduct it from the remaining balance, and increment
// the allocated entry.
if amount > 0 {
*balance -= amount;
*allocated[output as usize].entry(id).or_default() += amount;
}
}

Expand Down Expand Up @@ -154,22 +161,28 @@ impl<'a, 'db, 'tx> RuneUpdater<'a, 'db, 'tx> {
}
}

// Assign all un-allocated runes to the first non OP_RETURN output
if let Some((vout, _)) = tx
.output
.iter()
.enumerate()
.find(|(_, tx_out)| !tx_out.script_pubkey.is_op_return())
{
let mut burned: HashMap<u128, u128> = HashMap::new();

if burn {
for (id, balance) in unallocated {
if balance > 0 {
*allocated[vout].entry(id).or_default() += balance;
*burned.entry(id).or_default() += balance;
}
} else {
// Assign all un-allocated runes to the first non OP_RETURN output
if let Some((vout, _)) = tx
.output
.iter()
.enumerate()
.find(|(_, tx_out)| !tx_out.script_pubkey.is_op_return())
{
for (id, balance) in unallocated {
if balance > 0 {
*allocated[vout].entry(id).or_default() += balance;
}
}
}
}

let mut burned: HashMap<u128, u128> = HashMap::new();

// update outpoint balances
let mut buffer: Vec<u8> = Vec::new();
for (vout, balances) in allocated.into_iter().enumerate() {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use {
serde::{Deserialize, Deserializer, Serialize, Serializer},
std::{
cmp,
collections::{BTreeMap, HashSet, VecDeque},
collections::{BTreeMap, HashMap, HashSet, VecDeque},
env,
ffi::OsString,
fmt::{self, Display, Formatter},
Expand Down
Loading

0 comments on commit 4219f35

Please sign in to comment.