Skip to content

Commit

Permalink
ci: fix codecov (#26)
Browse files Browse the repository at this point in the history
* test: new structure

* fix: codecov rust
  • Loading branch information
rafaelcr authored Jul 9, 2024
1 parent 68784da commit 62af797
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 169 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,15 @@ jobs:
docker-compose -f docker/docker-compose.dev.postgres.yml up -d
docker-compose -f docker/docker-compose.dev.postgres.yml logs -t -f --no-color &> docker-compose-logs.txt &
- name: Cargo test
- name: Update Rust
run: |
rustup update
RUST_BACKTRACE=1 cargo test --all -- --test-threads=1
- name: Install and run cargo-tarpaulin
run: |
cargo install cargo-tarpaulin
cargo --version
cargo tarpaulin --out lcov -- --test-threads=1
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
Expand Down
16 changes: 10 additions & 6 deletions src/db/cache/index_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ use crate::{
};

use super::{
db_cache::DbCache,
transaction_cache::{InputRuneBalance, TransactionCache},
transaction_location::TransactionLocation,
utils::move_block_output_cache_to_output_cache,
db_cache::DbCache, input_rune_balance::InputRuneBalance, transaction_cache::TransactionCache,
transaction_location::TransactionLocation, utils::move_block_output_cache_to_output_cache,
};

/// Holds rune data across multiple blocks for faster computations. Processes rune events as they happen during transactions and
Expand Down Expand Up @@ -106,7 +104,10 @@ impl IndexCache {
try_debug!(ctx, "INPUT {rune_id} {balances:?} {location}");
}
if input_runes.len() > 0 {
try_debug!(ctx, "First output: {first_eligible_output:?}, total_outputs: {total_outputs}");
try_debug!(
ctx,
"First output: {first_eligible_output:?}, total_outputs: {total_outputs}"
);
}
}
self.tx_cache = TransactionCache::new(
Expand All @@ -125,7 +126,10 @@ impl IndexCache {
}

pub fn end_block(&mut self) {
move_block_output_cache_to_output_cache(&mut self.block_output_cache, &mut self.output_cache);
move_block_output_cache_to_output_cache(
&mut self.block_output_cache,
&mut self.output_cache,
);
}

pub async fn apply_runestone(
Expand Down
29 changes: 29 additions & 0 deletions src/db/cache/input_rune_balance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#[derive(Debug, Clone)]
pub struct InputRuneBalance {
/// Previous owner of this balance. If this is `None`, it means the balance was just minted or premined.
pub address: Option<String>,
/// How much balance was input to this transaction.
pub amount: u128,
}

#[cfg(test)]
impl InputRuneBalance {
pub fn dummy() -> Self {
InputRuneBalance {
address: Some(
"bc1p8zxlhgdsq6dmkzk4ammzcx55c3hfrg69ftx0gzlnfwq0wh38prds0nzqwf".to_string(),
),
amount: 1000,
}
}

pub fn amount(&mut self, amount: u128) -> &mut Self {
self.amount = amount;
return self;
}

pub fn address(&mut self, address: Option<String>) -> &mut Self {
self.address = address;
return self;
}
}
1 change: 1 addition & 0 deletions src/db/cache/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod db_cache;
pub mod index_cache;
pub mod input_rune_balance;
pub mod transaction_cache;
pub mod transaction_location;
pub mod utils;
13 changes: 4 additions & 9 deletions src/db/cache/transaction_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@ use crate::{
try_debug, try_info, try_warn,
};

use super::{transaction_location::TransactionLocation, utils::move_rune_balance_to_output};

#[derive(Debug, Clone)]
pub struct InputRuneBalance {
/// Previous owner of this balance. If this is `None`, it means the balance was just minted or premined.
pub address: Option<String>,
/// How much balance was input to this transaction.
pub amount: u128,
}
use super::{
input_rune_balance::InputRuneBalance, transaction_location::TransactionLocation,
utils::move_rune_balance_to_output,
};

/// Holds cached data relevant to a single transaction during indexing.
pub struct TransactionCache {
Expand Down
2 changes: 1 addition & 1 deletion src/db/cache/transaction_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl fmt::Display for TransactionLocation {

#[cfg(test)]
impl TransactionLocation {
pub fn factory() -> Self {
pub fn dummy() -> Self {
TransactionLocation {
network: Network::Bitcoin,
block_hash: "0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5"
Expand Down
245 changes: 95 additions & 150 deletions src/db/cache/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
try_info, try_warn,
};

use super::{transaction_cache::InputRuneBalance, transaction_location::TransactionLocation};
use super::{input_rune_balance::InputRuneBalance, transaction_location::TransactionLocation};

/// Takes all transaction inputs and transforms them into rune balances to be allocated for operations. Looks inside an output LRU
/// cache and the DB when there are cache misses.
Expand Down Expand Up @@ -88,7 +88,7 @@ pub fn move_block_output_cache_to_output_cache(
block_output_cache.clear();
}

/// Creates a new ledger entry.
/// Creates a new ledger entry while incrementing the `next_event_index`.
pub fn new_ledger_entry(
location: &TransactionLocation,
amount: Option<u128>,
Expand Down Expand Up @@ -286,166 +286,111 @@ pub fn is_rune_mintable(

#[cfg(test)]
mod test {
use std::collections::{HashMap, VecDeque};
use test_case::test_case;
mod move_balance {
use std::collections::{HashMap, VecDeque};

use bitcoin::ScriptBuf;
use chainhook_sdk::utils::Context;
use ordinals::RuneId;
use bitcoin::ScriptBuf;
use chainhook_sdk::utils::Context;
use ordinals::RuneId;

use crate::db::{
cache::{
transaction_cache::InputRuneBalance, transaction_location::TransactionLocation,
utils::move_rune_balance_to_output,
},
models::{db_ledger_operation::DbLedgerOperation, db_rune::DbRune},
types::{pg_numeric_u128::PgNumericU128, pg_numeric_u64::PgNumericU64},
};

use super::is_rune_mintable;

#[test]
fn receives_are_registered_first() {
let ctx = Context::empty();
let location = TransactionLocation {
network: bitcoin::Network::Bitcoin,
block_hash: "00000000000000000002c0cc73626b56fb3ee1ce605b0ce125cc4fb58775a0a9"
.to_string(),
block_height: 840002,
timestamp: 0,
tx_id: "37cd29676d626492cd9f20c60bc4f20347af9c0d91b5689ed75c05bb3e2f73ef".to_string(),
tx_index: 2936,
use crate::db::{
cache::{
input_rune_balance::InputRuneBalance, transaction_location::TransactionLocation,
utils::move_rune_balance_to_output,
},
models::db_ledger_operation::DbLedgerOperation,
};
let mut available_inputs = VecDeque::new();
// An input from a previous tx
available_inputs.push_back(InputRuneBalance {
address: Some(
"bc1p8zxlhgdsq6dmkzk4ammzcx55c3hfrg69ftx0gzlnfwq0wh38prds0nzqwf".to_string(),
),
amount: 1000,
});
// A mint
available_inputs.push_back(InputRuneBalance {
address: None,
amount: 1000,
});
let mut eligible_outputs = HashMap::new();
eligible_outputs.insert(
0u32,
ScriptBuf::from_hex(
"5120388dfba1b0069bbb0ad5eef62c1a94c46e91a3454accf40bf34b80f75e2708db",
)
.unwrap(),
);
let mut next_event_index = 0;
let results = move_rune_balance_to_output(
&location,
Some(0),
&RuneId::new(840000, 25).unwrap(),
&mut available_inputs,
&eligible_outputs,
0,
&mut next_event_index,
&ctx,
);

let receive = results.get(0).unwrap();
assert_eq!(receive.event_index.0, 0u32);
assert_eq!(receive.operation, DbLedgerOperation::Receive);
assert_eq!(receive.amount.unwrap().0, 2000u128);
#[test]
fn ledger_writes_receive_before_send() {
let address =
Some("bc1p8zxlhgdsq6dmkzk4ammzcx55c3hfrg69ftx0gzlnfwq0wh38prds0nzqwf".to_string());
let mut available_inputs = VecDeque::new();
let mut input1 = InputRuneBalance::dummy();
input1.address(address.clone()).amount(1000);
available_inputs.push_back(input1);
let mut input2 = InputRuneBalance::dummy();
input2.address(None).amount(1000);
available_inputs.push_back(input2);
let mut eligible_outputs = HashMap::new();
eligible_outputs.insert(
0u32,
ScriptBuf::from_hex(
"5120388dfba1b0069bbb0ad5eef62c1a94c46e91a3454accf40bf34b80f75e2708db",
)
.unwrap(),
);
let mut next_event_index = 0;

let send = results.get(1).unwrap();
assert_eq!(send.event_index.0, 1u32);
assert_eq!(send.operation, DbLedgerOperation::Send);
assert_eq!(send.amount.unwrap().0, 1000u128);
let results = move_rune_balance_to_output(
&TransactionLocation::dummy(),
Some(0),
&RuneId::new(840000, 25).unwrap(),
&mut available_inputs,
&eligible_outputs,
0,
&mut next_event_index,
&Context::empty(),
);

assert_eq!(results.len(), 2);
}
let receive = results.get(0).unwrap();
assert_eq!(receive.event_index.0, 0u32);
assert_eq!(receive.operation, DbLedgerOperation::Receive);
assert_eq!(receive.amount.unwrap().0, 2000u128);

#[test_case(840000 => false; "early block")]
#[test_case(840500 => false; "late block")]
#[test_case(840150 => true; "block in window")]
#[test_case(840100 => true; "first block")]
#[test_case(840200 => true; "last block")]
fn mint_block_height_terms_are_validated(block_height: u64) -> bool {
let mut rune = DbRune::factory();
rune.terms_height_start(Some(PgNumericU64(840100)));
rune.terms_height_end(Some(PgNumericU64(840200)));
let mut location = TransactionLocation::factory();
location.block_height(block_height);
is_rune_mintable(&rune, 0, &location)
}
let send = results.get(1).unwrap();
assert_eq!(send.event_index.0, 1u32);
assert_eq!(send.operation, DbLedgerOperation::Send);
assert_eq!(send.amount.unwrap().0, 1000u128);

#[test_case(840000 => false; "early block")]
#[test_case(840500 => false; "late block")]
#[test_case(840150 => true; "block in window")]
#[test_case(840100 => true; "first block")]
#[test_case(840200 => true; "last block")]
fn mint_block_offset_terms_are_validated(block_height: u64) -> bool {
let mut rune = DbRune::factory();
rune.terms_offset_start(Some(PgNumericU64(100)));
rune.terms_offset_end(Some(PgNumericU64(200)));
let mut location = TransactionLocation::factory();
location.block_height(block_height);
is_rune_mintable(&rune, 0, &location)
assert_eq!(results.len(), 2);
}
}

#[test_case(0 => true; "first mint")]
#[test_case(49 => true; "last mint")]
#[test_case(50 => false; "out of range")]
fn mint_cap_is_validated(cap: u128) -> bool {
let mut rune = DbRune::factory();
rune.terms_cap(Some(PgNumericU128(50)));
is_rune_mintable(&rune, cap, &TransactionLocation::factory())
}
mod mint_validation {
use test_case::test_case;

// use std::{collections::HashMap, num::NonZeroUsize, str::FromStr};
use crate::db::{
cache::{transaction_location::TransactionLocation, utils::is_rune_mintable},
models::db_rune::DbRune,
types::{pg_numeric_u128::PgNumericU128, pg_numeric_u64::PgNumericU64},
};

// use chainhook_sdk::{
// types::{
// bitcoin::{OutPoint, TxIn},
// TransactionIdentifier,
// },
// utils::Context,
// };
// use lru::LruCache;
// use ordinals::RuneId;
#[test_case(840000 => false; "early block")]
#[test_case(840500 => false; "late block")]
#[test_case(840150 => true; "block in window")]
#[test_case(840100 => true; "first block")]
#[test_case(840200 => true; "last block")]
fn mint_block_height_terms_are_validated(block_height: u64) -> bool {
let mut rune = DbRune::factory();
rune.terms_height_start(Some(PgNumericU64(840100)));
rune.terms_height_end(Some(PgNumericU64(840200)));
let mut location = TransactionLocation::dummy();
location.block_height(block_height);
is_rune_mintable(&rune, 0, &location)
}

// use crate::db::cache::transaction_cache::InputRuneBalance;
#[test_case(840000 => false; "early block")]
#[test_case(840500 => false; "late block")]
#[test_case(840150 => true; "block in window")]
#[test_case(840100 => true; "first block")]
#[test_case(840200 => true; "last block")]
fn mint_block_offset_terms_are_validated(block_height: u64) -> bool {
let mut rune = DbRune::factory();
rune.terms_offset_start(Some(PgNumericU64(100)));
rune.terms_offset_end(Some(PgNumericU64(200)));
let mut location = TransactionLocation::dummy();
location.block_height(block_height);
is_rune_mintable(&rune, 0, &location)
}

// #[test]
// fn from_output_cache() {
// let tx_inputs = vec![TxIn {
// previous_output: OutPoint {
// txid: TransactionIdentifier {
// hash: "aea76e5ef8135851d0387074cf7672013779e4506e56122e0e698e12ede62681"
// .to_string(),
// },
// vout: 2,
// value: 100,
// block_height: 848300,
// },
// script_sig: "".to_string(),
// sequence: 1,
// witness: vec![],
// }];
// let mut value = HashMap::new();
// value.insert(
// RuneId::from_str("840000:1").unwrap(),
// vec![InputRuneBalance {
// address: Some("1EDYZPvGqKzZYp6DoTtcgXwvSAkA9d9UKU".to_string()),
// amount: 10000,
// }],
// );
// let mut output_cache: LruCache<(String, u32), HashMap<RuneId, Vec<InputRuneBalance>>> =
// LruCache::new(NonZeroUsize::new(2).unwrap());
// output_cache.put(
// (
// "aea76e5ef8135851d0387074cf7672013779e4506e56122e0e698e12ede62681".to_string(),
// 2,
// ),
// value,
// );
// let ctx = Context::empty();
// }
#[test_case(0 => true; "first mint")]
#[test_case(49 => true; "last mint")]
#[test_case(50 => false; "out of range")]
fn mint_cap_is_validated(cap: u128) -> bool {
let mut rune = DbRune::factory();
rune.terms_cap(Some(PgNumericU128(50)));
is_rune_mintable(&rune, cap, &TransactionLocation::dummy())
}
}
}
Loading

0 comments on commit 62af797

Please sign in to comment.