validate.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. use pasta_curves::pallas;
  2. use darkfi::{
  3. crypto::types::DrkCircuitField,
  4. util::serial::{SerialDecodable, SerialEncodable},
  5. Error as DarkFiError,
  6. };
  7. use std::any::{Any, TypeId};
  8. use crate::{
  9. demo::{CallDataBase, StateRegistry, Transaction},
  10. example_contract::state::State,
  11. };
  12. type Result<T> = std::result::Result<T, Error>;
  13. #[derive(Debug, Clone, thiserror::Error)]
  14. pub enum Error {
  15. #[error("ValueExists")]
  16. ValueExists,
  17. #[error("DarkFi error: {0}")]
  18. DarkFiError(String),
  19. }
  20. impl From<DarkFiError> for Error {
  21. fn from(err: DarkFiError) -> Self {
  22. Self::DarkFiError(err.to_string())
  23. }
  24. }
  25. pub struct CallData {
  26. pub header: Header,
  27. }
  28. impl CallDataBase for CallData {
  29. fn zk_public_values(&self) -> Vec<Vec<DrkCircuitField>> {
  30. vec![vec![self.header.public_c]]
  31. }
  32. fn zk_proof_addrs(&self) -> Vec<String> {
  33. vec!["example-foo".to_string()]
  34. }
  35. fn as_any(&self) -> &dyn Any {
  36. self
  37. }
  38. }
  39. #[derive(Clone, SerialEncodable, SerialDecodable)]
  40. pub struct Header {
  41. pub public_c: pallas::Base,
  42. }
  43. pub fn state_transition(
  44. states: &StateRegistry,
  45. func_call_index: usize,
  46. parent_tx: &Transaction,
  47. ) -> Result<Update> {
  48. let func_call = &parent_tx.func_calls[func_call_index];
  49. let call_data = func_call.call_data.as_any();
  50. assert_eq!((&*call_data).type_id(), TypeId::of::<CallData>());
  51. let call_data = call_data.downcast_ref::<CallData>();
  52. // This will be inside wasm so unwrap is fine.
  53. let call_data = call_data.unwrap();
  54. let example_state = states.lookup::<State>(&"EXAMPLE".to_string()).unwrap();
  55. if example_state.public_exists(&call_data.header.public_c) {
  56. return Err(Error::ValueExists)
  57. }
  58. Ok(Update { public_value: call_data.header.public_c })
  59. }
  60. #[derive(Clone)]
  61. pub struct Update {
  62. public_value: pallas::Base,
  63. }
  64. pub fn apply(states: &mut StateRegistry, update: Update) {
  65. let example_state = states.lookup_mut::<State>(&"EXAMPLE".to_string()).unwrap();
  66. example_state.add_public_value(update.public_value);
  67. }