Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions dash/src/test_utils/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ use std::ops::Range;
use crate::{Address, OutPoint, ScriptBuf, Transaction, TxIn, TxOut, Txid, Witness};

impl Transaction {
/// Creates a transaction with no inputs or outputs.
pub fn empty() -> Transaction {
Transaction {
version: 1,
lock_time: 0,
input: Vec::new(),
output: Vec::new(),
special_transaction_payload: None,
}
}

pub fn dummy(
address: &Address,
inputs_ids_range: Range<u8>,
Expand Down
23 changes: 6 additions & 17 deletions key-wallet/src/managed_account/transaction_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,9 @@ mod tests {
use super::*;
use dashcore::hashes::Hash;

fn create_test_transaction() -> Transaction {
// Create a minimal test transaction
Transaction {
version: 1,
lock_time: 0,
input: Vec::new(),
output: Vec::new(),
special_transaction_payload: None,
}
}

#[test]
fn test_transaction_record_creation() {
let tx = create_test_transaction();
let tx = Transaction::empty();
let record = TransactionRecord::new(tx.clone(), 1234567890, 50000, true);

assert_eq!(record.txid, tx.txid());
Expand All @@ -162,7 +151,7 @@ mod tests {

#[test]
fn test_confirmations_calculation() {
let tx = create_test_transaction();
let tx = Transaction::empty();
let mut record = TransactionRecord::new(tx, 1234567890, 50000, true);

// Unconfirmed transaction
Expand All @@ -187,7 +176,7 @@ mod tests {

#[test]
fn test_incoming_outgoing() {
let tx = create_test_transaction();
let tx = Transaction::empty();

let incoming = TransactionRecord::new(tx.clone(), 1234567890, 50000, false);
assert!(incoming.is_incoming());
Expand All @@ -202,7 +191,7 @@ mod tests {

#[test]
fn test_confirmed_transaction_creation() {
let tx = create_test_transaction();
let tx = Transaction::empty();
let block_hash = BlockHash::all_zeros();
let record =
TransactionRecord::new_confirmed(tx.clone(), 100, block_hash, 1234567890, 50000, true);
Expand All @@ -214,7 +203,7 @@ mod tests {

#[test]
fn test_mark_unconfirmed() {
let tx = create_test_transaction();
let tx = Transaction::empty();
let block_hash = BlockHash::all_zeros();
let mut record =
TransactionRecord::new_confirmed(tx, 100, block_hash, 1234567890, 50000, true);
Expand All @@ -230,7 +219,7 @@ mod tests {

#[test]
fn test_labels_and_fees() {
let tx = create_test_transaction();
let tx = Transaction::empty();
let mut record = TransactionRecord::new(tx, 1234567890, -50000, true);

assert_eq!(record.fee, None);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Tests for asset unlock transaction handling

use super::helpers::create_test_transaction;
use super::helpers::test_addr;
use crate::transaction_checking::transaction_router::{
AccountTypeToCheck, TransactionRouter, TransactionType,
};
Expand All @@ -12,9 +12,10 @@ use dashcore::blockdata::transaction::special_transaction::asset_unlock::qualifi
use dashcore::blockdata::transaction::special_transaction::asset_unlock::request_info::AssetUnlockRequestInfo;
use dashcore::blockdata::transaction::special_transaction::asset_unlock::unqualified_asset_unlock::AssetUnlockBasePayload;
use dashcore::blockdata::transaction::special_transaction::TransactionPayload;
use dashcore::blockdata::transaction::Transaction;
use dashcore::bls_sig_utils::BLSSignature;
use dashcore::hashes::Hash;
use dashcore::{BlockHash, OutPoint, ScriptBuf, Transaction, TxIn, TxOut, Txid};
use dashcore::{BlockHash, OutPoint, ScriptBuf, TxIn, TxOut, Txid};

#[test]
fn test_asset_unlock_routing() {
Expand All @@ -37,7 +38,8 @@ fn test_asset_unlock_routing() {
#[test]
fn test_asset_unlock_classification() {
// Test that AssetUnlock transactions are properly classified
let mut tx = create_test_transaction(1, vec![100_000_000]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000_000]);

// Create an asset unlock payload
let base = AssetUnlockBasePayload {
Expand Down Expand Up @@ -93,7 +95,7 @@ async fn test_asset_unlock_transaction_routing() {
.expect("Failed to generate receive address");

// Create an asset unlock transaction
let tx = Transaction {
let tx = dashcore::Transaction {
version: 3, // Version 3 for special transactions
lock_time: 0,
input: vec![TxIn {
Expand Down Expand Up @@ -180,7 +182,8 @@ async fn test_asset_unlock_routing_to_bip32_account() {
.expect("Failed to generate receive address");

// Create an asset unlock transaction to our address
let mut tx = create_test_transaction(0, vec![]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..0, &[]);
tx.output.push(TxOut {
value: 200_000_000, // 2 DASH unlocked
script_pubkey: address.script_pubkey(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use dashcore::blockdata::transaction::special_transaction::provider_update_regis
use dashcore::blockdata::transaction::special_transaction::provider_update_revocation::ProviderUpdateRevocationPayload;
use dashcore::blockdata::transaction::special_transaction::provider_update_service::ProviderUpdateServicePayload;
use dashcore::blockdata::transaction::special_transaction::TransactionPayload;
use dashcore::blockdata::transaction::Transaction;
use dashcore::bls_sig_utils::{BLSPublicKey, BLSSignature};
use dashcore::hash_types::{MerkleRootMasternodeList, MerkleRootQuorums};
use dashcore::hashes::Hash;
Expand All @@ -19,16 +20,19 @@ use dashcore::Txid;
#[test]
fn test_classify_standard_transaction() {
// Standard payment with 1 input, 2 outputs
let tx = create_test_transaction(1, vec![50_000_000, 49_000_000]);
let addr = test_addr();
let tx = Transaction::dummy(&addr, 0..1, &[50_000_000, 49_000_000]);
assert_eq!(TransactionRouter::classify_transaction(&tx), TransactionType::Standard);
}

#[test]
fn test_classify_coinjoin_transaction() {
// CoinJoin with multiple inputs and denomination outputs
let tx = create_test_transaction(
5,
vec![
let addr = test_addr();
let tx = Transaction::dummy(
&addr,
0..5,
&[
100_000_000, // 1 DASH denomination
100_000_000, // 1 DASH denomination
10_000_000, // 0.1 DASH denomination
Expand All @@ -48,16 +52,19 @@ fn test_classify_asset_lock_transaction() {
#[test]
fn test_not_coinjoin_few_inputs() {
// Not enough inputs to be CoinJoin
let tx = create_test_transaction(2, vec![100_000_000, 100_000_000]);
let addr = test_addr();
let tx = Transaction::dummy(&addr, 0..2, &[100_000_000, 100_000_000]);
assert_eq!(TransactionRouter::classify_transaction(&tx), TransactionType::Standard);
}

#[test]
fn test_not_coinjoin_no_denominations() {
// Many inputs/outputs but no standard denominations
let tx = create_test_transaction(
4,
vec![
let addr = test_addr();
let tx = Transaction::dummy(
&addr,
0..4,
&[
123_456_789, // Non-standard amount
987_654_321, // Non-standard amount
555_555_555, // Non-standard amount
Expand All @@ -69,7 +76,8 @@ fn test_not_coinjoin_no_denominations() {

#[test]
fn test_classify_provider_update_registrar_transaction() {
let mut tx = create_test_transaction(1, vec![100_000_000]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000_000]);
// Create a provider update registrar payload
let payload = ProviderUpdateRegistrarPayload {
version: 1,
Expand All @@ -92,7 +100,8 @@ fn test_classify_provider_update_registrar_transaction() {

#[test]
fn test_classify_provider_update_service_transaction() {
let mut tx = create_test_transaction(1, vec![100_000_000]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000_000]);
// Create a provider update service payload
let payload = ProviderUpdateServicePayload {
version: 1,
Expand All @@ -118,7 +127,8 @@ fn test_classify_provider_update_service_transaction() {

#[test]
fn test_classify_provider_update_revocation_transaction() {
let mut tx = create_test_transaction(1, vec![100_000_000]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000_000]);
// Create a provider update revocation payload
let payload = ProviderUpdateRevocationPayload {
version: 1,
Expand All @@ -138,7 +148,8 @@ fn test_classify_provider_update_revocation_transaction() {

#[test]
fn test_classify_asset_unlock_transaction() {
let mut tx = create_test_transaction(1, vec![100_000_000]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000_000]);
// Create an asset unlock payload
let base = AssetUnlockBasePayload {
version: 1,
Expand All @@ -161,7 +172,8 @@ fn test_classify_asset_unlock_transaction() {

#[test]
fn test_classify_coinbase_transaction() {
let mut tx = create_test_transaction(1, vec![100_000_000]);
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000_000]);
// Create a coinbase payload
let payload = CoinbasePayload {
version: 3,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Tests for coinbase transaction handling

use super::helpers::test_addr;
use crate::transaction_checking::transaction_router::{
AccountTypeToCheck, TransactionRouter, TransactionType,
};
Expand All @@ -12,7 +13,7 @@ use dashcore::blockdata::transaction::special_transaction::TransactionPayload;
use dashcore::bls_sig_utils::BLSSignature;
use dashcore::hash_types::{MerkleRootMasternodeList, MerkleRootQuorums};
use dashcore::hashes::Hash;
use dashcore::{BlockHash, OutPoint, ScriptBuf, Transaction, TxIn, TxOut, Txid};
use dashcore::{BlockHash, OutPoint, ScriptBuf, Transaction, TxIn, TxOut};

/// Helper to create a coinbase transaction
fn create_coinbase_transaction() -> Transaction {
Expand All @@ -38,28 +39,6 @@ fn create_coinbase_transaction() -> Transaction {
}
}

/// Helper to create a basic transaction
fn create_basic_transaction() -> Transaction {
Transaction {
version: 2,
lock_time: 0,
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_byte_array([1u8; 32]),
vout: 0,
},
script_sig: ScriptBuf::new(),
sequence: 0xffffffff,
witness: dashcore::Witness::default(),
}],
output: vec![TxOut {
value: 100000,
script_pubkey: ScriptBuf::new(),
}],
special_transaction_payload: None,
}
}

#[tokio::test]
async fn test_coinbase_transaction_routing_to_bip44_receive_address() {
// Create a wallet with a BIP44 account
Expand Down Expand Up @@ -236,7 +215,8 @@ async fn test_update_state_flag_behavior() {
};

// Create a test transaction
let mut tx = create_basic_transaction();
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000]);
tx.output.push(TxOut {
value: 75000,
script_pubkey: address.script_pubkey(),
Expand Down Expand Up @@ -307,7 +287,8 @@ async fn test_update_state_flag_behavior() {
#[test]
fn test_coinbase_classification() {
// Test that coinbase transactions are properly classified
let mut tx = create_basic_transaction();
let addr = test_addr();
let mut tx = Transaction::dummy(&addr, 0..1, &[100_000]);

// Create a coinbase payload
let payload = CoinbasePayload {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ use super::helpers::*;
use crate::transaction_checking::transaction_router::{
AccountTypeToCheck, TransactionRouter, TransactionType,
};
use dashcore::blockdata::transaction::Transaction;

#[test]
fn test_coinjoin_mixing_round() {
// Standard CoinJoin mixing round
let tx = create_test_transaction(
6, // Multiple participants
vec![
let addr = test_addr();
let tx = Transaction::dummy(
&addr,
0..6, // Multiple participants
&[
10_000_000, // 0.1 DASH denomination
10_000_000, // 0.1 DASH denomination
10_000_000, // 0.1 DASH denomination
Expand All @@ -31,9 +34,11 @@ fn test_coinjoin_mixing_round() {
#[test]
fn test_coinjoin_with_multiple_denominations() {
// CoinJoin with mixed denominations
let tx = create_test_transaction(
8,
vec![
let addr = test_addr();
let tx = Transaction::dummy(
&addr,
0..8,
&[
100_000_000, // 1 DASH
100_000_000, // 1 DASH
10_000_000, // 0.1 DASH
Expand All @@ -55,9 +60,11 @@ fn test_coinjoin_with_multiple_denominations() {
#[test]
fn test_coinjoin_threshold_exactly_half_denominations() {
// Edge case: exactly half outputs are denominations
let tx = create_test_transaction(
4,
vec![
let addr = test_addr();
let tx = Transaction::dummy(
&addr,
0..4,
&[
100_000_000, // Denomination
100_000_000, // Denomination
50_000_000, // Non-denomination
Expand All @@ -73,9 +80,11 @@ fn test_coinjoin_threshold_exactly_half_denominations() {
#[test]
fn test_not_coinjoin_just_under_threshold() {
// Just under 50% denominations
let tx = create_test_transaction(
3,
vec![
let addr = test_addr();
let tx = Transaction::dummy(
&addr,
0..3,
&[
100_000_000, // Denomination
50_000_000, // Non-denomination
75_000_000, // Non-denomination
Expand Down
Loading
Loading