dpp/state_transition/traits/
state_transition_witness_validation.rs1use crate::address_funds::AddressWitnessVerificationOperations;
2use crate::consensus::signature::InvalidStateTransitionSignatureError;
3use crate::serialization::Signable;
4use crate::state_transition::StateTransitionWitnessSigned;
5use crate::validation::SimpleConsensusValidationResult;
6
7pub struct WitnessValidationResult {
9 pub validation_result: SimpleConsensusValidationResult,
11 pub operations: AddressWitnessVerificationOperations,
13}
14
15impl WitnessValidationResult {
16 pub fn new(
18 validation_result: SimpleConsensusValidationResult,
19 operations: AddressWitnessVerificationOperations,
20 ) -> Self {
21 Self {
22 validation_result,
23 operations,
24 }
25 }
26
27 pub fn new_with_error(error: crate::consensus::ConsensusError) -> Self {
29 Self {
30 validation_result: SimpleConsensusValidationResult::new_with_error(error),
31 operations: AddressWitnessVerificationOperations::new(),
32 }
33 }
34}
35
36pub trait StateTransitionWitnessValidation: StateTransitionWitnessSigned + Signable {
41 fn validate_witnesses(&self, signable_bytes: &[u8]) -> WitnessValidationResult {
53 let inputs = self.inputs();
54 let witnesses = self.witnesses();
55
56 if inputs.len() != witnesses.len() {
58 return WitnessValidationResult::new_with_error(
59 InvalidStateTransitionSignatureError::new(format!(
60 "Number of witnesses ({}) does not match number of inputs ({})",
61 witnesses.len(),
62 inputs.len()
63 ))
64 .into(),
65 );
66 }
67
68 let mut total_operations = AddressWitnessVerificationOperations::new();
69
70 for (i, (address, witness)) in inputs.keys().zip(witnesses.iter()).enumerate() {
72 match address.verify_bytes_against_witness(witness, signable_bytes) {
73 Ok(operations) => {
74 total_operations.combine(&operations);
75 }
76 Err(e) => {
77 return WitnessValidationResult::new_with_error(
78 InvalidStateTransitionSignatureError::new(format!(
79 "Witness {} verification failed: {}",
80 i, e
81 ))
82 .into(),
83 );
84 }
85 }
86 }
87
88 WitnessValidationResult::new(SimpleConsensusValidationResult::new(), total_operations)
89 }
90}