use blvm_sdk::governance::psbt::{
Bip32Derivation, PartialSignature, PartiallySignedTransaction, PsbtGlobalKey, PsbtInputKey,
PsbtOutputKey, SighashType, PSBT_MAGIC, PSBT_SEPARATOR,
};
fn create_mock_unsigned_tx() -> Vec<u8> {
vec![
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]
}
#[test]
fn test_psbt_creation() {
let unsigned_tx = create_mock_unsigned_tx();
let psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
assert_eq!(psbt.version, 0);
assert!(psbt
.global
.contains_key(&vec![PsbtGlobalKey::UnsignedTx as u8]));
}
#[test]
fn test_psbt_version() {
let unsigned_tx = create_mock_unsigned_tx();
let psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
assert_eq!(psbt.version, 0);
assert!(psbt
.global
.contains_key(&vec![PsbtGlobalKey::Version as u8]));
}
#[test]
fn test_psbt_magic_bytes() {
assert_eq!(PSBT_MAGIC, [0x70, 0x73, 0x62, 0x74]); }
#[test]
fn test_psbt_separator() {
assert_eq!(PSBT_SEPARATOR, 0xff);
}
#[test]
fn test_psbt_add_input() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
psbt.inputs.push(std::collections::HashMap::new());
assert_eq!(psbt.inputs.len(), 1);
}
#[test]
fn test_psbt_add_output() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
psbt.outputs.push(std::collections::HashMap::new());
assert_eq!(psbt.outputs.len(), 1);
}
#[test]
fn test_psbt_multiple_inputs_outputs() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
psbt.inputs.push(std::collections::HashMap::new());
psbt.inputs.push(std::collections::HashMap::new());
psbt.outputs.push(std::collections::HashMap::new());
psbt.outputs.push(std::collections::HashMap::new());
assert_eq!(psbt.inputs.len(), 2);
assert_eq!(psbt.outputs.len(), 2);
}
#[test]
fn test_psbt_global_key_types() {
assert_eq!(PsbtGlobalKey::UnsignedTx as u8, 0x00);
assert_eq!(PsbtGlobalKey::Xpub as u8, 0x01);
assert_eq!(PsbtGlobalKey::Version as u8, 0xfb);
assert_eq!(PsbtGlobalKey::Proprietary as u8, 0xfc);
}
#[test]
fn test_psbt_input_key_types() {
assert_eq!(PsbtInputKey::NonWitnessUtxo as u8, 0x00);
assert_eq!(PsbtInputKey::WitnessUtxo as u8, 0x01);
assert_eq!(PsbtInputKey::PartialSig as u8, 0x02);
assert_eq!(PsbtInputKey::SighashType as u8, 0x03);
assert_eq!(PsbtInputKey::RedeemScript as u8, 0x04);
assert_eq!(PsbtInputKey::WitnessScript as u8, 0x05);
assert_eq!(PsbtInputKey::Bip32Derivation as u8, 0x06);
assert_eq!(PsbtInputKey::FinalScriptSig as u8, 0x07);
assert_eq!(PsbtInputKey::FinalScriptWitness as u8, 0x08);
}
#[test]
fn test_psbt_output_key_types() {
assert_eq!(PsbtOutputKey::RedeemScript as u8, 0x00);
assert_eq!(PsbtOutputKey::WitnessScript as u8, 0x01);
assert_eq!(PsbtOutputKey::Bip32Derivation as u8, 0x02);
}
#[test]
fn test_sighash_type_all() {
let sighash = SighashType::All;
assert_eq!(sighash.to_byte(), 0x01);
let parsed = SighashType::from_byte(0x01);
assert_eq!(parsed, Some(SighashType::All));
}
#[test]
fn test_sighash_type_none() {
let sighash = SighashType::None;
assert_eq!(sighash.to_byte(), 0x02);
let parsed = SighashType::from_byte(0x02);
assert_eq!(parsed, Some(SighashType::None));
}
#[test]
fn test_sighash_type_single() {
let sighash = SighashType::Single;
assert_eq!(sighash.to_byte(), 0x03);
let parsed = SighashType::from_byte(0x03);
assert_eq!(parsed, Some(SighashType::Single));
}
#[test]
fn test_sighash_type_anyonecanpay() {
assert_eq!(SighashType::AllAnyoneCanPay.to_byte(), 0x81);
assert_eq!(SighashType::NoneAnyoneCanPay.to_byte(), 0x82);
assert_eq!(SighashType::SingleAnyoneCanPay.to_byte(), 0x83);
assert_eq!(
SighashType::from_byte(0x81),
Some(SighashType::AllAnyoneCanPay)
);
assert_eq!(
SighashType::from_byte(0x82),
Some(SighashType::NoneAnyoneCanPay)
);
assert_eq!(
SighashType::from_byte(0x83),
Some(SighashType::SingleAnyoneCanPay)
);
}
#[test]
fn test_sighash_type_invalid() {
let parsed = SighashType::from_byte(0xff);
assert_eq!(parsed, None);
}
#[test]
fn test_bip32_derivation_creation() {
let derivation = Bip32Derivation {
pubkey: vec![0x02; 33], path: vec![0x80000000, 0x80000001, 0x80000002], master_fingerprint: [0x12, 0x34, 0x56, 0x78],
};
assert_eq!(derivation.pubkey.len(), 33);
assert_eq!(derivation.path.len(), 3);
assert_eq!(derivation.master_fingerprint, [0x12, 0x34, 0x56, 0x78]);
}
#[test]
fn test_bip32_derivation_path() {
let derivation = Bip32Derivation {
pubkey: vec![0x02; 33],
path: vec![
0x8000002c, 0x80000000, 0x80000000, 0x00000000, 0x00000000, ],
master_fingerprint: [0x12, 0x34, 0x56, 0x78],
};
assert_eq!(derivation.path[0], 0x8000002c); assert_eq!(derivation.path[1], 0x80000000); }
#[test]
fn test_partial_signature_creation() {
let partial_sig = PartialSignature {
pubkey: vec![0x02; 33], signature: vec![0x30, 0x45, 0x02, 0x21], };
assert_eq!(partial_sig.pubkey.len(), 33);
assert!(!partial_sig.signature.is_empty());
}
#[test]
fn test_partial_signature_structure() {
let pubkey = vec![0x03; 33];
let signature = vec![0x30, 0x44, 0x02, 0x20, 0x01, 0x02, 0x03];
let partial_sig = PartialSignature {
pubkey: pubkey.clone(),
signature: signature.clone(),
};
assert_eq!(partial_sig.pubkey, pubkey);
assert_eq!(partial_sig.signature, signature);
}
#[test]
fn test_psbt_global_map_unsigned_tx() {
let unsigned_tx = create_mock_unsigned_tx();
let psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let key = vec![PsbtGlobalKey::UnsignedTx as u8];
assert!(psbt.global.contains_key(&key));
let tx_data = psbt.global.get(&key).unwrap();
assert_eq!(tx_data, &unsigned_tx);
}
#[test]
fn test_psbt_global_map_version() {
let unsigned_tx = create_mock_unsigned_tx();
let psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let key = vec![PsbtGlobalKey::Version as u8];
assert!(psbt.global.contains_key(&key));
let version_data = psbt.global.get(&key).unwrap();
assert_eq!(version_data, &vec![0x00]); }
#[test]
fn test_psbt_input_map_witness_utxo() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut input_map = std::collections::HashMap::new();
let witness_utxo = vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; input_map.insert(vec![PsbtInputKey::WitnessUtxo as u8], witness_utxo.clone());
psbt.inputs.push(input_map);
assert!(psbt.inputs[0].contains_key(&vec![PsbtInputKey::WitnessUtxo as u8]));
}
#[test]
fn test_psbt_input_map_partial_sig() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut input_map = std::collections::HashMap::new();
let partial_sig_data = vec![0x30, 0x45, 0x02, 0x21]; input_map.insert(
vec![PsbtInputKey::PartialSig as u8],
partial_sig_data.clone(),
);
psbt.inputs.push(input_map);
assert!(psbt.inputs[0].contains_key(&vec![PsbtInputKey::PartialSig as u8]));
}
#[test]
fn test_psbt_input_map_sighash_type() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut input_map = std::collections::HashMap::new();
let sighash_byte = vec![SighashType::All.to_byte()];
input_map.insert(vec![PsbtInputKey::SighashType as u8], sighash_byte.clone());
psbt.inputs.push(input_map);
assert!(psbt.inputs[0].contains_key(&vec![PsbtInputKey::SighashType as u8]));
}
#[test]
fn test_psbt_input_map_bip32_derivation() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut input_map = std::collections::HashMap::new();
let derivation_data = vec![0x02; 33]; input_map.insert(
vec![PsbtInputKey::Bip32Derivation as u8],
derivation_data.clone(),
);
psbt.inputs.push(input_map);
assert!(psbt.inputs[0].contains_key(&vec![PsbtInputKey::Bip32Derivation as u8]));
}
#[test]
fn test_psbt_output_map_redeem_script() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut output_map = std::collections::HashMap::new();
let redeem_script = vec![0x76, 0xa9, 0x14]; output_map.insert(
vec![PsbtOutputKey::RedeemScript as u8],
redeem_script.clone(),
);
psbt.outputs.push(output_map);
assert!(psbt.outputs[0].contains_key(&vec![PsbtOutputKey::RedeemScript as u8]));
}
#[test]
fn test_psbt_output_map_witness_script() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut output_map = std::collections::HashMap::new();
let witness_script = vec![0x00, 0x14]; output_map.insert(
vec![PsbtOutputKey::WitnessScript as u8],
witness_script.clone(),
);
psbt.outputs.push(output_map);
assert!(psbt.outputs[0].contains_key(&vec![PsbtOutputKey::WitnessScript as u8]));
}
#[test]
fn test_psbt_output_map_bip32_derivation() {
let unsigned_tx = create_mock_unsigned_tx();
let mut psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let mut output_map = std::collections::HashMap::new();
let derivation_data = vec![0x02; 33]; output_map.insert(
vec![PsbtOutputKey::Bip32Derivation as u8],
derivation_data.clone(),
);
psbt.outputs.push(output_map);
assert!(psbt.outputs[0].contains_key(&vec![PsbtOutputKey::Bip32Derivation as u8]));
}
#[test]
fn test_psbt_has_unsigned_tx() {
let unsigned_tx = create_mock_unsigned_tx();
let psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
let key = vec![PsbtGlobalKey::UnsignedTx as u8];
assert!(psbt.global.contains_key(&key));
}
#[test]
fn test_psbt_empty_inputs_outputs() {
let unsigned_tx = create_mock_unsigned_tx();
let psbt = PartiallySignedTransaction::new(&unsigned_tx).unwrap();
assert_eq!(psbt.inputs.len(), 0);
assert_eq!(psbt.outputs.len(), 0);
}