drive/verify/
grovedb_proof_envelope.rs1use crate::error::proof::ProofError;
2use crate::error::Error;
3
4pub const MINIMUM_GROVEDB_PROOF_ENVELOPE_VERSION: u32 = 1;
15
16pub fn require_supported_grovedb_proof_envelope(
25 proof: &[u8],
26 label: &'static str,
27) -> Result<(), Error> {
28 let config = bincode::config::standard()
29 .with_big_endian()
30 .with_limit::<16>();
31 let (version, _): (u32, usize) =
32 bincode::decode_from_slice(proof, config).map_err(|error| {
33 Error::Proof(ProofError::InvalidGroveDBProofEnvelope {
34 proof: label,
35 reason: error.to_string(),
36 })
37 })?;
38
39 if version < MINIMUM_GROVEDB_PROOF_ENVELOPE_VERSION {
40 return Err(Error::Proof(
41 ProofError::UnsupportedGroveDBProofEnvelopeVersion {
42 proof: label,
43 version,
44 minimum: MINIMUM_GROVEDB_PROOF_ENVELOPE_VERSION,
45 },
46 ));
47 }
48
49 Ok(())
50}
51
52#[cfg(test)]
53mod tests {
54 use super::{require_supported_grovedb_proof_envelope, MINIMUM_GROVEDB_PROOF_ENVELOPE_VERSION};
55 use crate::error::proof::ProofError;
56 use crate::error::Error;
57
58 fn envelope(version: u32) -> Vec<u8> {
59 bincode::encode_to_vec(version, bincode::config::standard().with_big_endian())
60 .expect("encode envelope version")
61 }
62
63 #[test]
64 fn should_reject_a_v0_envelope() {
65 let error = require_supported_grovedb_proof_envelope(&envelope(0), "forward proof")
66 .expect_err("V0 must be rejected");
67
68 assert!(
69 matches!(
70 error,
71 Error::Proof(ProofError::UnsupportedGroveDBProofEnvelopeVersion {
72 proof: "forward proof",
73 version: 0,
74 minimum: MINIMUM_GROVEDB_PROOF_ENVELOPE_VERSION,
75 })
76 ),
77 "unexpected error: {error}"
78 );
79 assert_eq!(
80 error.to_string(),
81 "proof: unsupported GroveDB proof envelope version 0 in the forward proof: at least version 1 is required"
82 );
83 }
84
85 #[test]
86 fn should_reject_bytes_without_an_envelope_discriminant() {
87 let error = require_supported_grovedb_proof_envelope(&[], "proof")
88 .expect_err("empty bytes carry no envelope");
89
90 assert!(
91 matches!(
92 error,
93 Error::Proof(ProofError::InvalidGroveDBProofEnvelope { proof: "proof", .. })
94 ),
95 "unexpected error: {error}"
96 );
97 }
98
99 #[test]
100 fn should_pass_envelopes_at_or_above_the_minimum() {
101 for version in [1u32, 2u32] {
102 require_supported_grovedb_proof_envelope(&envelope(version), "proof")
103 .unwrap_or_else(|error| panic!("envelope {version} must pass: {error}"));
104 }
105 }
106}