Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: unit tests for wallet/swapcoin.rs #96

Merged
merged 12 commits into from
Feb 29, 2024
392 changes: 392 additions & 0 deletions src/wallet/swapcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,3 +637,395 @@
)?)
}
}

#[cfg(test)]
mod tests {
use std::str::FromStr;

use super::*;
use bitcoin::PrivateKey;

#[test]
fn test_apply_privkey_watchonly_swapcoin() {
let secp = Secp256k1::new();

let privkey_sender = bitcoin::PrivateKey {
compressed: true,
network: bitcoin::Network::Testnet,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000001",
)
.unwrap(),
};

let privkey_receiver = bitcoin::PrivateKey {
compressed: true,
network: bitcoin::Network::Testnet,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000002",
)
.unwrap(),
};

let mut swapcoin = WatchOnlySwapCoin {
sender_pubkey: PublicKey::from_private_key(&secp, &privkey_sender),
receiver_pubkey: PublicKey::from_private_key(&secp, &privkey_receiver),
funding_amount: 100,
contract_tx: Transaction {
input: vec![],
output: vec![],
lock_time: LockTime::ZERO,
version: 2,
},

Check warning on line 679 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L679

Added line #L679 was not covered by tests
contract_redeemscript: ScriptBuf::default(),
};

Check warning on line 681 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L681

Added line #L681 was not covered by tests

let secret_key_1 =
SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000002")
.unwrap();
let secret_key_2 =
SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000069")
.unwrap();
// Test for applying the correct privkey
assert!(swapcoin.apply_privkey(secret_key_1).is_ok());
// Test for applying the incorrect privkey
assert!(swapcoin.apply_privkey(secret_key_2).is_err());
}

#[test]
fn test_apply_privkey_incoming_swapcoin() {
let secp = Secp256k1::new();
let other_privkey = bitcoin::PrivateKey {
compressed: true,
network: bitcoin::Network::Testnet,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000002",
)
.unwrap(),
};

let mut incoming_swapcoin = IncomingSwapCoin {
my_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000003",
)
.unwrap(),
other_privkey: Some(
secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000005",
)
.unwrap(),
),
other_pubkey: PublicKey::from_private_key(&secp, &other_privkey),
contract_tx: Transaction {
input: vec![],
output: vec![],
lock_time: LockTime::ZERO,
version: 2,
},

Check warning on line 724 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L724

Added line #L724 was not covered by tests
contract_redeemscript: ScriptBuf::default(),
hashlock_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000004",
)
.unwrap(),
funding_amount: 0,
others_contract_sig: None,
hash_preimage: None,
};

Check warning on line 733 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L733

Added line #L733 was not covered by tests

let secret_key_1 =
SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000002")
.unwrap();
let secret_key_2 =
SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000069")
.unwrap();
// Test for applying the correct privkey
assert!(incoming_swapcoin.apply_privkey(secret_key_1).is_ok());
// Test for applying the incorrect privkey
assert!(incoming_swapcoin.apply_privkey(secret_key_2).is_err());
// Test get_other_pubkey
let other_pubkey_from_method = incoming_swapcoin.get_other_pubkey();
assert_eq!(other_pubkey_from_method, &incoming_swapcoin.other_pubkey);
// Test is_hash_preimage_known for empty hash_preimage
assert!(!incoming_swapcoin.is_hash_preimage_known());
}

#[test]

fn test_apply_privkey_outgoing_swapcoin() {
let secp = Secp256k1::new();
let other_privkey = bitcoin::PrivateKey {
compressed: true,
network: bitcoin::Network::Testnet,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000001",
)
.unwrap(),
};
let mut outgoing_swapcoin = OutgoingSwapCoin {
my_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000002",
)
.unwrap(),
other_pubkey: PublicKey::from_private_key(&secp, &other_privkey),
contract_tx: Transaction {
input: vec![],
output: vec![],
lock_time: LockTime::ZERO,
version: 2,
},

Check warning on line 775 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L775

Added line #L775 was not covered by tests
contract_redeemscript: ScriptBuf::default(),
timelock_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000003",
)
.unwrap(),
funding_amount: 0,
others_contract_sig: None,
hash_preimage: None,
};

Check warning on line 784 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L784

Added line #L784 was not covered by tests
let secret_key_1 =
SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000001")
.unwrap();
let secret_key_2 =
SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000069")
.unwrap();

// Test for applying the correct privkey
assert!(outgoing_swapcoin.apply_privkey(secret_key_1).is_ok());
// Test for applying the incorrect privkey
assert!(outgoing_swapcoin.apply_privkey(secret_key_2).is_err());
// Test get_other_pubkey
assert_eq!(
outgoing_swapcoin.get_other_pubkey(),
&outgoing_swapcoin.other_pubkey
);
// Test is_hash_preimage_known
assert!(!outgoing_swapcoin.is_hash_preimage_known());
}

#[test]
fn test_sign_transaction_input_fail() {
let secp = Secp256k1::new();
let other_privkey = bitcoin::PrivateKey {
compressed: true,
network: bitcoin::Network::Testnet,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000002",
)
.unwrap(),
};
let index: usize = 10;
let mut input = TxIn::default();
let tx = Transaction {
input: vec![input.clone()],
output: vec![],
lock_time: LockTime::ZERO,
version: 2,
};

Check warning on line 823 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L823

Added line #L823 was not covered by tests

let contract_redeemscript = ScriptBuf::default(); // Example redeem script

let incoming_swapcoin = IncomingSwapCoin {
my_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000003",
)
.unwrap(),
other_privkey: Some(
secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000005",
)
.unwrap(),
),
other_pubkey: PublicKey::from_private_key(&secp, &other_privkey),
contract_tx: Transaction {
input: vec![],
output: vec![],
lock_time: LockTime::ZERO,
version: 2,
},

Check warning on line 844 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L844

Added line #L844 was not covered by tests
contract_redeemscript: ScriptBuf::default(),
hashlock_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000004",
)
.unwrap(),
funding_amount: 100_000,
others_contract_sig: None,
hash_preimage: None,
};

Check warning on line 853 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L853

Added line #L853 was not covered by tests
// Intentionally failing to sign with incomplete swapcoin
assert!(incoming_swapcoin
.sign_transaction_input(index, &tx, &mut input, &contract_redeemscript,)
.is_err());
let sign = bitcoin::ecdsa::Signature {
sig: secp256k1::ecdsa::Signature::from_compact(&[0; 64]).unwrap(),
hash_ty: bitcoin::sighash::EcdsaSighashType::All,
};
// Intentionally failing to verify with incomplete swapcoin
assert!(incoming_swapcoin
.verify_contract_tx_sender_sig(&sign)
.is_err());
}

#[test]

fn test_create_hashlock_spend_without_preimage() {
let secp = Secp256k1::new();
let other_privkey = PrivateKey {
compressed: true,
network: bitcoin::Network::Bitcoin,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000001",
)
.unwrap(),
};
let input = TxIn::default();
let output = TxOut::default();
let incoming_swapcoin = IncomingSwapCoin {
my_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000003",
)
.unwrap(),
other_privkey: Some(
secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000005",
)
.unwrap(),
),
other_pubkey: PublicKey::from_private_key(&secp, &other_privkey),
contract_tx: Transaction {
input: vec![input.clone()],
output: vec![output.clone()],
lock_time: LockTime::ZERO,
version: 2,
},

Check warning on line 899 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L899

Added line #L899 was not covered by tests
contract_redeemscript: ScriptBuf::default(),
hashlock_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000004",
)
.unwrap(),
funding_amount: 100_000,
others_contract_sig: None,
hash_preimage: Some(Preimage::from([0; 32])),
};

Check warning on line 908 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L908

Added line #L908 was not covered by tests
let destination_address: Address = Address::from_str("32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf")
.unwrap()
.require_network(bitcoin::Network::Bitcoin)
.unwrap();

let miner_fee = 136 * 10; //126 vbytes x 10 sat/vb, size calculated using testmempoolaccept
let mut tx = Transaction {
input: vec![TxIn {
previous_output: OutPoint {
txid: incoming_swapcoin.contract_tx.txid(),
vout: 0, //contract_tx is one-input-one-output
},
sequence: Sequence(1), //hashlock spends must have 1 because of the `OP_CSV 1`
witness: Witness::new(),
script_sig: ScriptBuf::new(),
}],

Check warning on line 924 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L924

Added line #L924 was not covered by tests
output: vec![TxOut {
script_pubkey: destination_address.script_pubkey(),
value: incoming_swapcoin.contract_tx.output[0].value - miner_fee,
}],

Check warning on line 928 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L928

Added line #L928 was not covered by tests
lock_time: LockTime::ZERO,
version: 2,
};

Check warning on line 931 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L931

Added line #L931 was not covered by tests
let index = 0;
let preimage = Vec::new();
incoming_swapcoin
.sign_hashlocked_transaction_input_given_preimage(
index,
&tx.clone(),
&mut tx.input[0],
incoming_swapcoin.contract_tx.output[0].value,
&preimage,
)
.unwrap();
// If the tx is succesful, check some field like:
assert!(tx.input[0].witness.len() == 3);
}

#[test]
fn test_sign_hashlocked_transaction_input() {
let secp = Secp256k1::new();
let other_privkey = PrivateKey {
compressed: true,
network: bitcoin::Network::Bitcoin,
inner: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000001",
)
.unwrap(),
};
let mut input = TxIn::default();
let output = TxOut::default();
let incoming_swapcoin = IncomingSwapCoin {
my_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000003",
)
.unwrap(),
other_privkey: Some(
secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000005",
)
.unwrap(),
),
other_pubkey: PublicKey::from_private_key(&secp, &other_privkey),
contract_tx: Transaction {
input: vec![input.clone()],
output: vec![output.clone()],
lock_time: LockTime::ZERO,
version: 2,
},

Check warning on line 977 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L977

Added line #L977 was not covered by tests
contract_redeemscript: ScriptBuf::default(),
hashlock_privkey: secp256k1::SecretKey::from_str(
"0000000000000000000000000000000000000000000000000000000000000004",
)
.unwrap(),
funding_amount: 100_000,
others_contract_sig: None,
hash_preimage: Some(Preimage::from([0; 32])),
};

Check warning on line 986 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L986

Added line #L986 was not covered by tests
let destination_address: Address = Address::from_str("32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf")
.unwrap()
.require_network(bitcoin::Network::Bitcoin)
.unwrap();

let miner_fee = 136 * 10;
let mut tx = Transaction {
input: vec![TxIn {
previous_output: OutPoint {
txid: incoming_swapcoin.contract_tx.txid(),
vout: 0, //contract_tx is one-input-one-output
},
sequence: Sequence(1), //hashlock spends must have 1 because of the `OP_CSV 1`
witness: Witness::new(),
script_sig: ScriptBuf::new(),
}],

Check warning on line 1002 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L1002

Added line #L1002 was not covered by tests
output: vec![TxOut {
script_pubkey: destination_address.script_pubkey(),
value: incoming_swapcoin.contract_tx.output[0].value - miner_fee,
}],

Check warning on line 1006 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L1006

Added line #L1006 was not covered by tests
lock_time: LockTime::ZERO,
version: 2,
};

Check warning on line 1009 in src/wallet/swapcoin.rs

View check run for this annotation

Codecov / codecov/patch

src/wallet/swapcoin.rs#L1009

Added line #L1009 was not covered by tests
let index = 0;
let input_value = 100;
let preimage = Vec::new();
incoming_swapcoin
.sign_hashlocked_transaction_input_given_preimage(
index,
&tx.clone(),
&mut tx.input[0],
incoming_swapcoin.contract_tx.output[0].value,
&preimage,
)
.unwrap();
// Check if the hashlocked transaction input is successful
let final_return = incoming_swapcoin.sign_hashlocked_transaction_input(
index,
&tx,
&mut input,
input_value,
);
assert!(final_return.is_ok());
}
}
Loading