fix: burned output check
Description
fixes the burned output check.
Adds in a unit test to ensure its correct
How Has This Been Tested?
Unit and integration
@@ -280,7 +280,7 @@ pub fn check_total_burned(body: &AggregateBody) -> Result<(), ValidationError> {
}
}
for kernel in body.kernels() {
- if kernel.is_burned() && burned_outputs.remove(kernel.get_burn_commitment()?) {
+ if kernel.is_burned() && !burned_outputs.remove(kernel.get_burn_commitment()?) {
return Err(ValidationError::InvalidBurnError(
"Burned kernel does not match burned output".to_string(),
));
@@ -1039,4 +1039,58 @@ mod test {
unpack_enum!(TransactionError::InvalidCoinbase = err);
}
}
+
+ use crate::{covenants::Covenant, transactions::transaction_components::KernelFeatures};
+
+ #[test]
+ fn check_burned_succeeds_for_valid_outputs() {
+ let mut kernel1 = test_helpers::create_test_kernel(0.into(), 0);
+ let mut kernel2 = test_helpers::create_test_kernel(0.into(), 0);
+
+ let (output1, _, _) = test_helpers::create_utxo(
+ 100.into(),
+ &CryptoFactories::default(),
+ &OutputFeatures::create_burn_output(),
+ &TariScript::default(),
+ &Covenant::default(),
+ 0.into(),
+ );
+ let (output2, _, _) = test_helpers::create_utxo(
+ 101.into(),
+ &CryptoFactories::default(),
+ &OutputFeatures::create_burn_output(),
+ &TariScript::default(),
+ &Covenant::default(),
+ 0.into(),
+ );
+ let (output3, _, _) = test_helpers::create_utxo(
+ 102.into(),
+ &CryptoFactories::default(),
+ &OutputFeatures::create_burn_output(),
+ &TariScript::default(),
+ &Covenant::default(),
+ 0.into(),
+ );
+
+ kernel1.features = KernelFeatures::create_burn();
+ kernel1.burn_commitment = Some(output1.commitment.clone());
+ kernel2.features = KernelFeatures::create_burn();
+ kernel2.burn_commitment = Some(output2.commitment.clone());
+ let kernel3 = kernel1.clone();
+
+ let mut body = AggregateBody::new(Vec::new(), vec![output1.clone(), output2.clone()], vec![
+ kernel1.clone(),
+ kernel2.clone(),
+ ]);
+ assert!(check_total_burned(&body).is_ok());
+ // lets add an extra kernel
+ body.add_kernels(&mut vec![kernel3]);
+ assert!(check_total_burned(&body).is_err());
+ // lets add a kernel commitment mismatch
+ body.add_outputs(&mut vec![output3.clone()]);
+ assert!(check_total_burned(&body).is_err());
+ // Lets try one with a commitment with no kernel
+ let body2 = AggregateBody::new(Vec::new(), vec![output1, output2, output3], vec![kernel1, kernel2]);
+ assert!(check_total_burned(&body2).is_err());
+ }
}
