drive/verify/contract/
mod.rs1use crate::error::Error;
2
3mod verify_contract;
4mod verify_contract_history;
5mod verify_contract_return_serialization;
6mod verify_contracts_by_range;
7mod verify_contracts_versions;
8
9fn retry_contract_verification_with_history<R, RetryFn, HasPresentContractFn>(
10 result: Result<R, Error>,
11 contract_known_keeps_history: Option<bool>,
12 contract_id: [u8; 32],
13 in_multiple_contract_proof_form: bool,
14 retry: RetryFn,
15 has_present_contract: HasPresentContractFn,
16) -> Result<R, Error>
17where
18 RetryFn: FnOnce() -> Result<R, Error>,
19 HasPresentContractFn: Fn(&R) -> bool,
20{
21 if contract_known_keeps_history.is_some() {
22 return result;
23 }
24
25 match &result {
26 Ok(value) if has_present_contract(value) => result,
27 Ok(_) => {
28 tracing::debug!(
29 ?contract_id,
30 keeps_history = false,
31 retry_keeps_history = true,
32 in_multiple_contract_proof_form,
33 "retrying contract verification with history enabled after absence"
34 );
35
36 let retry_result = retry();
37 if matches!(retry_result.as_ref(), Ok(value) if has_present_contract(value)) {
38 retry_result
39 } else {
40 result
41 }
42 }
43 Err(error) => {
44 tracing::debug!(
45 ?contract_id,
46 keeps_history = false,
47 retry_keeps_history = true,
48 in_multiple_contract_proof_form,
49 error = ?error,
50 "retrying contract verification with history enabled after error"
51 );
52
53 let retry_result = retry();
54 if matches!(retry_result.as_ref(), Ok(value) if has_present_contract(value)) {
55 retry_result
56 } else {
57 result
58 }
59 }
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::retry_contract_verification_with_history;
66 use crate::error::proof::ProofError;
67 use crate::error::Error;
68
69 #[test]
70 fn should_preserve_original_error_when_retry_returns_absence() {
71 let result = retry_contract_verification_with_history(
72 Err(Error::Proof(ProofError::IncompleteProof("first error"))),
73 None,
74 [1; 32],
75 false,
76 || Ok(None::<u8>),
77 Option::is_some,
78 );
79
80 assert!(matches!(
81 result,
82 Err(Error::Proof(ProofError::IncompleteProof("first error")))
83 ));
84 }
85
86 #[test]
87 fn should_return_retry_result_when_retry_finds_contract_after_error() {
88 let result = retry_contract_verification_with_history(
89 Err(Error::Proof(ProofError::IncompleteProof("first error"))),
90 None,
91 [1; 32],
92 false,
93 || Ok(Some(7u8)),
94 Option::is_some,
95 );
96
97 assert!(matches!(result, Ok(Some(7))));
98 }
99}