1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
#[cfg(not(feature = "std"))] use alloc::vec::Vec; #[cfg(not(feature = "std"))] use core::result::Result; #[cfg(not(feature = "std"))] use core::convert::AsRef; use bitvec::prelude::BitVec; use crate::merkle::get_root; /// Different types of comparisions of Plasma Transactions. /// /// Plasma Transactions form a DAG where only one pathway back to the origin is /// considered valid. However, there may be multiple pathways, so it is important /// to allow this behavior to be compared in order to understand which transaction /// is legitimate. /// /// # Note /// This comparision is used in the history verification logic, as well as withdrawal /// challenge detection logic. Different clients may have a privledged view of this /// ordering, since transactions may be encrypted in some context and unencrypted in /// others, which means relationships may differ depending on information privledge /// of the client. #[derive(Debug, PartialEq)] pub enum TxnCmp { /// LHS & RHS are the same exact transaction Same, /// LHS is the parent of RHS Parent, /// RHS is the parent of LHS Child, /// LHS & RHS have same parent, but LHS is earlier EarlierSibling, /// LHS & RHS have same parent, but RHS is earlier LaterSibling, /// LHS & RHS are the same txn to two different receivers DoubleSpend, /// LHS & RHS have no relationship to each other Unrelated, } /// Plasma Cash Transaction trait for a given Token. /// /// All the methods a Plasma Cash Transaction must implement to allow /// transaction and history verification logic to work. This allows /// custom transactions to be defined that allow significant customization /// of the semantics of transactions while conforming to the Plasma Cash /// specification, which creates safety in the Layer 1 ⇋ Layer 2 bridge. /// /// # Note /// The design of this trait was such that it could be flexible enough to /// support both transparent and encrypted transactions. When used with /// encrypted transactions, there may be a logical difference in handling /// transactions verification between publicly accessible information and /// privledged parties to the transaction, so that should be taken into /// account when using this API. /// /// # Example /// Users of this API should should define this e.g. /// ```ignore /// struct Transaction { ... } /// /// impl PlasmaCashTxn for Transaction { ... } /// ``` pub trait PlasmaCashTxn { type HashType: AsRef<[u8]>; /// Needed to obtain the key for a Merkle Proof. fn token_id(&self) -> BitVec; /// Transaction is well-formed (implementation-specific). /// /// # Note /// This might be used for certain use-cases to verify zk proofs, /// whereas other use cases might have only signature validation. fn valid(&self) -> bool; /// Return "Leaf Hash" of this transaction. /// /// # Note /// The "Leaf Hash" may be the encoded transaction structure directly, /// or it may be a publicly accessible committment, as required for certain /// applications such as Zero Knowledge Proofs. /// /// Implementation is left up to the end user, but this must return a consistent /// hash for use in the Sparse Merkle Tree data structure that Plasma Cash /// is standardized around for it's key: value txn datastore. /// /// It does *not* have to match the hash function used for SMT proofs, but it must /// be consistent and of the same size as the hashes returned by `hash_fn()` for /// the smt proof validation to work. // TODO Validate security proof fn leaf_hash(&self) -> Self::HashType; /// Returns an empty leaf hash. /// /// Used for proofs of exclusion in txn trie. fn empty_leaf_hash() -> Self::HashType; /// Function used to verify proofs. fn hash_fn() -> (fn(&[u8]) -> Self::HashType); /// Returns the relationship of another transaction (other) to this /// one (self). /// /// See [TxnCmp](enum.TxnCmp.html) enum definition for more information. fn compare(&self, other: &Self) -> TxnCmp; /// Obtain the root hash following the SMT algorithm. /// /// # Note /// Proof must be in un-compressed form (`proof.len() == smt.depth()`) fn get_root(&self, proof: Vec<Self::HashType>) -> Result<Self::HashType, &'static str> { get_root(&self.token_id(), self.leaf_hash(), proof, Self::hash_fn()) } }