Просмотр исходного кода

daod: rework to follow arch outline in the docs

narodnik 4 лет назад
Родитель
Сommit
811f586446
3 измененных файлов с 54 добавлено и 23 удалено
  1. 1 0
      Cargo.lock
  2. 1 0
      bin/daod/Cargo.toml
  3. 52 23
      bin/daod/src/demo.rs

+ 1 - 0
Cargo.lock

@@ -1177,6 +1177,7 @@ dependencies = [
  "serde_json",
  "simplelog",
  "smol",
+ "thiserror",
  "url",
 ]
 

+ 1 - 0
bin/daod/Cargo.toml

@@ -22,6 +22,7 @@ log = "0.4.17"
 num_cpus = "1.13.1"
 simplelog = "0.12.0"
 url = "2.2.2"
+thiserror = "1.0.32"
 
 # Crypto
 incrementalmerkletree = "0.3.0"

+ 52 - 23
bin/daod/src/demo.rs

@@ -190,7 +190,7 @@ mod dao_contract {
             time::Instant,
         };
 
-        use super::super::Transaction;
+        use super::super::{StateRegistry, Transaction};
 
         pub struct Builder {
             dao_proposer_limit: u64,
@@ -222,32 +222,52 @@ mod dao_contract {
 
             /// Consumes self, and produces the actual Tx
             pub fn build(self) -> Box<dyn Any> {
-                Box::new(FuncCall {})
+                Box::new(CallData {})
             }
         }
 
-        pub struct FuncCall {}
+        pub struct CallData {}
 
-        impl FuncCall {}
-
-        pub fn state_transition(tx: Transaction, func_call_index: usize) {
-            let func_call = &tx.func_calls[func_call_index].1;
-            assert_eq!((&*func_call).type_id(), TypeId::of::<FuncCall>());
+        #[derive(Debug, Clone, thiserror::Error)]
+        pub enum Error {
+            #[error("Malformed packet")]
+            MalformedPacket,
+        }
+        type Result<T> = std::result::Result<T, Error>;
+
+        pub fn state_transition(
+            states: &StateRegistry,
+            func_call_index: usize,
+            parent_tx: &Transaction,
+        ) -> Result<Update> {
+            let func_call = &parent_tx.func_calls[func_call_index];
+            let call_data = &func_call.call_data;
+
+            assert_eq!((&*call_data).type_id(), TypeId::of::<CallData>());
+            let func_call = func_call.call_data.downcast_ref::<CallData>();
+            Ok(Update {})
         }
+
+        pub struct Update {}
+
+        pub fn apply(states: &mut StateRegistry, update: Update) {}
     }
 }
 
-// This will be a hash. Just use a string for the demo.
-type FuncId = String;
-// Use an Any type so plugins can inject their code.
-// An alternative is using a trait with downcast (see MessageSubsystem in net/)
-type GenericFuncCall = Box<dyn Any>;
-
 pub struct Transaction {
-    func_calls: Vec<(FuncId, GenericFuncCall)>,
+    func_calls: Vec<FuncCall>,
 }
 
+// These would normally be a hash or sth
 type ContractId = String;
+type FuncId = String;
+
+struct FuncCall {
+    contract_id: ContractId,
+    func_id: FuncId,
+    call_data: Box<dyn Any>,
+}
+
 type GenericContractState = Box<dyn Any>;
 
 pub struct StateRegistry {
@@ -279,7 +299,7 @@ pub async fn demo() -> Result<()> {
     let dao_approval_ratio = 2;
 
     // Lookup table for smart contract states
-    let mut state_registry = StateRegistry::new();
+    let mut states = StateRegistry::new();
 
     /////////////////////////////////////////////////
 
@@ -311,12 +331,12 @@ pub async fn demo() -> Result<()> {
         faucet_signature_public,
         secrets: vec![keypair.secret],
     });
-    state_registry.register("MoneyContract".to_string(), money_state);
+    states.register("MoneyContract".to_string(), money_state);
 
     /////////////////////////////////////////////////
 
     let dao_state = dao_contract::State::new();
-    state_registry.register("dao_contract".to_string(), dao_state);
+    states.register("dao_contract".to_string(), dao_state);
 
     // For this demo lets create 10 random preexisting DAO bullas
     for _ in 0..10 {
@@ -362,14 +382,23 @@ pub async fn demo() -> Result<()> {
         dao_keypair.public,
         dao_bulla_blind,
     );
-    let func_call = builder.build();
-
-    let tx = Transaction { func_calls: vec![("dao_contract::mint".to_string(), func_call)] };
-    for (func_id, func_call) in &tx.func_calls {
+    let call_data = builder.build();
+
+    let tx = Transaction {
+        func_calls: vec![FuncCall {
+            contract_id: "DAO".to_string(),
+            func_id: "DAO::mint()".to_string(),
+            call_data,
+        }],
+    };
+    for (idx, func_call) in tx.func_calls.iter().enumerate() {
         // So then the verifier will lookup the corresponding state_transition and apply
         // functions based off the func_id
-        if func_id == "dao_contract::mint" {
+        if func_call.func_id == "DAO::mint()" {
             debug!("dao_contract::mint::state_transition()");
+
+            let update = dao_contract::mint::state_transition(&states, idx, &tx).unwrap();
+            dao_contract::mint::apply(&mut states, update);
         }
     }