From 62af797af7a0461440ca810f527581d6fcfaaede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 8 Jul 2024 21:36:25 -0600 Subject: [PATCH] ci: fix codecov (#26) * test: new structure * fix: codecov rust --- .github/workflows/ci.yml | 9 +- src/db/cache/index_cache.rs | 16 +- src/db/cache/input_rune_balance.rs | 29 ++++ src/db/cache/mod.rs | 1 + src/db/cache/transaction_cache.rs | 13 +- src/db/cache/transaction_location.rs | 2 +- src/db/cache/utils.rs | 245 +++++++++++---------------- src/db/mod.rs | 2 +- 8 files changed, 148 insertions(+), 169 deletions(-) create mode 100644 src/db/cache/input_rune_balance.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 428bcda..615a00d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/src/db/cache/index_cache.rs b/src/db/cache/index_cache.rs index f81456d..a0d727b 100644 --- a/src/db/cache/index_cache.rs +++ b/src/db/cache/index_cache.rs @@ -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 @@ -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( @@ -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( diff --git a/src/db/cache/input_rune_balance.rs b/src/db/cache/input_rune_balance.rs new file mode 100644 index 0000000..be65068 --- /dev/null +++ b/src/db/cache/input_rune_balance.rs @@ -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, + /// 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) -> &mut Self { + self.address = address; + return self; + } +} diff --git a/src/db/cache/mod.rs b/src/db/cache/mod.rs index d09a35a..c558589 100644 --- a/src/db/cache/mod.rs +++ b/src/db/cache/mod.rs @@ -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; diff --git a/src/db/cache/transaction_cache.rs b/src/db/cache/transaction_cache.rs index c8d3d76..3e4770c 100644 --- a/src/db/cache/transaction_cache.rs +++ b/src/db/cache/transaction_cache.rs @@ -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, - /// 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 { diff --git a/src/db/cache/transaction_location.rs b/src/db/cache/transaction_location.rs index 4eaf127..71dad84 100644 --- a/src/db/cache/transaction_location.rs +++ b/src/db/cache/transaction_location.rs @@ -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" diff --git a/src/db/cache/utils.rs b/src/db/cache/utils.rs index 009ebed..fc13ed3 100644 --- a/src/db/cache/utils.rs +++ b/src/db/cache/utils.rs @@ -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. @@ -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, @@ -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>> = - // 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()) + } + } } diff --git a/src/db/mod.rs b/src/db/mod.rs index fbca077..3e68746 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, process, str::FromStr}; -use cache::transaction_cache::InputRuneBalance; +use cache::input_rune_balance::InputRuneBalance; use chainhook_sdk::utils::Context; use models::{ db_balance_change::DbBalanceChange, db_ledger_entry::DbLedgerEntry, db_rune::DbRune,