Skip to content

Commit

Permalink
add some etching and minting tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brady.ouren committed Jul 15, 2024
1 parent 7c63291 commit 0096cdf
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 16 deletions.
118 changes: 103 additions & 15 deletions src/db/cache/transaction_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{

use bitcoin::ScriptBuf;
use chainhook_sdk::utils::Context;
use maplit::hashmap;
use ordinals::{Cenotaph, Edict, Etching, Rune, RuneId};

use crate::{
Expand Down Expand Up @@ -61,6 +62,18 @@ impl TransactionCache {
}
}

pub fn empty(location: TransactionLocation) -> Self {
TransactionCache {
location,
next_event_index: 0,
etching: None,
output_pointer: None,
input_runes: hashmap! {},
eligible_outputs: hashmap! {},
total_outputs: 0,
}
}

/// Burns the rune balances input to this transaction.
pub fn apply_cenotaph_input_burn(&mut self, _cenotaph: &Cenotaph) -> Vec<DbLedgerEntry> {
let mut results = vec![];
Expand Down Expand Up @@ -393,22 +406,19 @@ impl TransactionCache {
mod test {
use chainhook_sdk::utils::Context;
use maplit::hashmap;
use ordinals::{Etching, Rune, RuneId, Terms};
use ordinals::{Edict, Etching, Rune, Terms};

use crate::db::{
cache::transaction_location::TransactionLocation,
models::{
db_ledger_operation::DbLedgerOperation,
db_rune::{self, DbRune},
},
cache::{transaction_location::TransactionLocation, utils::is_rune_mintable},
models::{db_ledger_operation::DbLedgerOperation, db_rune::DbRune},
};

use super::TransactionCache;

#[test]
fn etches_rune() {
let location = TransactionLocation::dummy();
let mut cache = TransactionCache::new(location.clone(), hashmap! {}, hashmap! {}, None, 0);
let mut cache = TransactionCache::empty(location.clone());
let etching = Etching {
divisibility: Some(2),
premine: Some(1000),
Expand All @@ -434,36 +444,114 @@ mod test {
assert_eq!(db_ledger_entry.rune_id, "840000:0");
}

#[test]
fn etches_cenotaph_rune() {
//
let location = TransactionLocation::dummy();
let mut cache = TransactionCache::empty(location.clone());

// Create a cenotaph rune
let rune = Rune::reserved(location.block_height, location.tx_index);
let number = 2;

let (_rune_id, db_rune, db_ledger_entry) = cache.apply_cenotaph_etching(&rune, number);

// the etched rune has supply zero and is unmintable.
assert_eq!(is_rune_mintable(&db_rune, 0, &location), false);
assert_eq!(db_rune.id, "840000:0");
assert_eq!(db_ledger_entry.operation, DbLedgerOperation::Etching);
assert_eq!(db_ledger_entry.rune_id, "840000:0");
assert_eq!(db_ledger_entry.amount, None);
}

#[test]
fn mints_rune() {
let location = TransactionLocation::dummy();
let mut cache = TransactionCache::new(location.clone(), hashmap! {}, hashmap! {}, None, 0);
let mut cache = TransactionCache::empty(location.clone());
let db_rune = &DbRune::factory();
let rune_id = &db_rune.rune_id();

let ledger_entry = cache.apply_mint(rune_id, 0, db_rune, &Context::empty());
let ledger_entry = cache.apply_mint(&rune_id, 0, &db_rune, &Context::empty());

assert!(ledger_entry.is_some());
let ledger_entry = ledger_entry.unwrap();
assert_eq!(ledger_entry.operation, DbLedgerOperation::Mint);
assert_eq!(ledger_entry.rune_id, rune_id.to_string());
// ledger entry is minted with the correct amount
assert_eq!(ledger_entry.amount, Some(db_rune.terms_amount.unwrap()));

// test: ledger entry is produced (Mint) with the correct minted amount
// test: minted amount is added to the input runes (`cache.input_runes`)
assert!(cache.input_runes.contains_key(&rune_id));
}

#[test]
fn does_not_mint_fully_minted_rune() {
// test: ledger entry is None
let location = TransactionLocation::dummy();
let mut cache = TransactionCache::empty(location.clone());
let etching = Etching {
divisibility: Some(2),
premine: Some(1000),
rune: Some(Rune::reserved(location.block_height, location.tx_index)),
spacers: None,
symbol: Some('x'),
terms: Some(Terms {
amount: Some(1000),
cap: Some(1000),
height: (None, None),
offset: (None, None),
}),
turbo: true,
};
let (rune_id, db_rune, _db_ledger_entry) = cache.apply_etching(&etching, 1);
let _ = cache.apply_mint(&rune_id, 0, &db_rune, &Context::empty());
// Note: it seems like premine is ignored? Would assume the above mint wouldn't be needed
let ledger_entry = cache.apply_mint(&rune_id, 1000, &db_rune, &Context::empty());
assert!(ledger_entry.is_none());
}

// ******************* unfinished below ****************
#[test]
fn burns_cenotaph_mint() {
//
let location = TransactionLocation::dummy();
let mut cache = TransactionCache::empty(location.clone());

// Create a cenotaph rune
let rune = Rune::reserved(location.block_height, location.tx_index);
let number = 2;

let (rune_id, db_rune, _db_ledger_entry) = cache.apply_cenotaph_etching(&rune, number);
let ledger_entry = cache.apply_cenotaph_mint(&rune_id, 0, &db_rune, &Context::empty());
assert!(ledger_entry.is_some());
assert_eq!(ledger_entry.unwrap().operation, DbLedgerOperation::Burn);
}

#[test]
fn moves_runes_with_edict() {
//
}
let location = TransactionLocation::dummy();
let location2 = TransactionLocation::dummy();
let mut cache = TransactionCache::empty(location.clone());
let db_rune = &DbRune::factory();
let rune_id = &db_rune.rune_id();

let ledger_entry = cache.apply_mint(&rune_id, 0, &db_rune, &Context::empty());

assert!(ledger_entry.is_some());
let edict = Edict {
id: rune_id.clone(),
amount: 1000,
output: location2.tx_index,
};

let ledger_entry = cache.apply_edict(&edict, &Context::empty());
assert_eq!(
ledger_entry.first().unwrap().operation,
DbLedgerOperation::Send
);
assert_eq!(
ledger_entry.last().unwrap().operation,
DbLedgerOperation::Receive
);
}
#[test]
fn allocates_remaining_runes() {
//
}
Expand Down
8 changes: 8 additions & 0 deletions src/db/models/db_ledger_entry.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt;

use ordinals::RuneId;
use tokio_postgres::Row;

Expand All @@ -24,6 +26,12 @@ pub struct DbLedgerEntry {
pub timestamp: PgBigIntU32,
}

impl fmt::Display for DbLedgerEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.rune_id)
}
}

impl DbLedgerEntry {
pub fn from_values(
amount: Option<u128>,
Expand Down
2 changes: 1 addition & 1 deletion src/db/types/pg_numeric_u128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub fn pg_numeric_bytes_to_u128(raw: &[u8]) -> u128 {
result
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PgNumericU128(pub u128);

impl ToSql for PgNumericU128 {
Expand Down

0 comments on commit 0096cdf

Please sign in to comment.