essential_check/
predicate.rs1use crate::sign::secp256k1;
4#[cfg(feature = "tracing")]
5use essential_hash::content_addr;
6use essential_types::{contract, predicate::Predicate};
7use thiserror::Error;
8
9#[derive(Debug, Error)]
11pub enum InvalidSignedContract {
12 #[error("invalid signature: {0}")]
14 Signature(#[from] secp256k1::Error),
15 #[error("invalid contract: {0}")]
17 Set(#[from] InvalidContract),
18}
19
20#[derive(Debug, Error)]
22pub enum InvalidContract {
23 #[error("the number of predicates ({0}) exceeds the limit ({MAX_PREDICATES})")]
25 TooManyPredicates(usize),
26 #[error("predicate at index {0} is invalid: {1}")]
28 Predicate(usize, InvalidPredicate),
29}
30
31#[derive(Debug, Error)]
33pub enum InvalidPredicate {
34 #[error(
36 "the number of nodes ({0}) exceeds the limit ({})",
37 Predicate::MAX_NODES
38 )]
39 TooManyNodes(usize),
40 #[error(
42 "the number of edges ({0}) exceeds the limit ({})",
43 Predicate::MAX_EDGES
44 )]
45 TooManyEdges(usize),
46}
47
48pub const MAX_PREDICATES: usize = 100;
50
51#[cfg_attr(feature = "tracing", tracing::instrument(skip_all, fields(addr = %content_addr(&signed_contract.contract)), err))]
55pub fn check_signed_contract(
56 signed_contract: &contract::SignedContract,
57) -> Result<(), InvalidSignedContract> {
58 essential_sign::contract::verify(signed_contract)?;
59 check_contract(signed_contract.contract.as_ref())?;
60 Ok(())
61}
62
63pub fn check_contract(predicates: &[Predicate]) -> Result<(), InvalidContract> {
67 if predicates.len() > MAX_PREDICATES {
68 return Err(InvalidContract::TooManyPredicates(predicates.len()));
69 }
70 for (ix, predicate) in predicates.iter().enumerate() {
71 check(predicate).map_err(|e| InvalidContract::Predicate(ix, e))?;
72 }
73 Ok(())
74}
75
76pub fn check(predicate: &Predicate) -> Result<(), InvalidPredicate> {
80 if predicate.nodes.len() > Predicate::MAX_NODES.into() {
81 return Err(InvalidPredicate::TooManyNodes(predicate.nodes.len()));
82 }
83 if predicate.edges.len() > Predicate::MAX_EDGES.into() {
84 return Err(InvalidPredicate::TooManyEdges(predicate.edges.len()));
85 }
86 Ok(())
88}