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