validate.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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, UpdateBase},
  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 public_value: pallas::Base,
  27. }
  28. impl CallDataBase for CallData {
  29. fn zk_public_values(&self) -> Vec<(String, Vec<DrkCircuitField>)> {
  30. vec![("example-foo".to_string(), vec![self.header.public_c])]
  31. }
  32. fn as_any(&self) -> &dyn Any {
  33. self
  34. }
  35. }
  36. pub fn state_transition(
  37. states: &StateRegistry,
  38. func_call_index: usize,
  39. parent_tx: &Transaction,
  40. ) -> Result<Box<dyn UpdateBase>> {
  41. let func_call = &parent_tx.func_calls[func_call_index];
  42. let call_data = func_call.call_data.as_any();
  43. assert_eq!((&*call_data).type_id(), TypeId::of::<CallData>());
  44. let call_data = call_data.downcast_ref::<CallData>();
  45. // This will be inside wasm so unwrap is fine.
  46. let call_data = call_data.unwrap();
  47. let example_state = states.lookup::<State>(&"Example".to_string()).unwrap();
  48. if example_state.public_exists(&call_data.header.public_c) {
  49. return Err(Error::ValueExists)
  50. }
  51. Ok(Box::new(Update { public_value: call_data.header.public_c }))
  52. }
  53. #[derive(Clone)]
  54. pub struct Update {
  55. public_value: pallas::Base,
  56. }
  57. impl UpdateBase for Update {
  58. fn apply(self: Box<Self>, states: &mut StateRegistry) {
  59. let example_state = states.lookup_mut::<State>(&"Example".to_string()).unwrap();
  60. example_state.add_public_value(self.public_value);
  61. }
  62. //fn as_any(&self) -> &dyn Any {
  63. // self
  64. //}
  65. }