Explorar o código

client: check from the tx if it's valid before send it to gateway

ghassmo %!s(int64=4) %!d(string=hai) anos
pai
achega
5189cb0670
Modificáronse 3 ficheiros con 52 adicións e 17 borrados
  1. 2 1
      src/bin/cashierd.rs
  2. 19 9
      src/bin/darkfid.rs
  3. 31 7
      src/client.rs

+ 2 - 1
src/bin/cashierd.rs

@@ -576,7 +576,7 @@ impl Cashierd {
 
         client
             .connect_to_subscriber_from_cashier(
-                state,
+                state.clone(),
                 self.cashier_wallet.clone(),
                 notify.clone(),
                 executor.clone(),
@@ -619,6 +619,7 @@ impl Cashierd {
                             received_balance,
                             token_notification.token_id,
                             true,
+                            state.clone(),
                         )
                         .await?;
                 }

+ 19 - 9
src/bin/darkfid.rs

@@ -67,30 +67,36 @@ impl RequestHandler for Darkfid {
 
 struct Darkfid {
     client: Arc<Mutex<Client>>,
+    state: Arc<Mutex<State>>,
     sol_tokenlist: SolTokenList,
     drk_tokenlist: DrkTokenList,
     cashiers: Vec<Cashier>,
 }
 
 impl Darkfid {
-    async fn new(client: Arc<Mutex<Client>>, cashiers: Vec<Cashier>) -> Result<Self> {
+    async fn new(
+        client: Arc<Mutex<Client>>,
+        state: Arc<Mutex<State>>,
+        cashiers: Vec<Cashier>,
+    ) -> Result<Self> {
         let sol_tokenlist = SolTokenList::new()?;
         let drk_tokenlist = DrkTokenList::new(sol_tokenlist.clone())?;
 
         Ok(Self {
             client,
+            state,
             sol_tokenlist,
             drk_tokenlist,
             cashiers,
         })
     }
 
-    async fn start(&mut self, state: Arc<Mutex<State>>, executor: Arc<Executor<'_>>) -> Result<()> {
+    async fn start(&mut self, executor: Arc<Executor<'_>>) -> Result<()> {
         self.client.lock().await.start().await?;
         self.client
             .lock()
             .await
-            .connect_to_subscriber(state, executor)
+            .connect_to_subscriber(self.state.clone(), executor)
             .await?;
 
         Ok(())
@@ -402,7 +408,12 @@ impl Darkfid {
                 self.client
                     .lock()
                     .await
-                    .transfer(token_id.clone(), cashier_public, amount_in_apo)
+                    .transfer(
+                        token_id.clone(),
+                        cashier_public,
+                        amount_in_apo,
+                        self.state.clone(),
+                    )
                     .await?;
 
                 Ok(())
@@ -484,7 +495,7 @@ impl Darkfid {
             self.client
                 .lock()
                 .await
-                .transfer(token_id.clone(), drk_address, amount)
+                .transfer(token_id.clone(), drk_address, amount, self.state.clone())
                 .await?;
 
             Ok(())
@@ -559,8 +570,6 @@ async fn start(executor: Arc<Executor<'_>>, config: &DarkfidConfig) -> Result<()
 
     let client = Arc::new(Mutex::new(client));
 
-    let mut darkfid = Darkfid::new(client, cashiers).await?;
-
     let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
     let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
 
@@ -573,6 +582,8 @@ async fn start(executor: Arc<Executor<'_>>, config: &DarkfidConfig) -> Result<()
         public_keys: cashier_keys,
     }));
 
+    let mut darkfid = Darkfid::new(client, state, cashiers).await?;
+
     let server_config = RpcServerConfig {
         socket_addr: config.rpc_listen_address.clone(),
         use_tls: config.serve_tls,
@@ -580,7 +591,7 @@ async fn start(executor: Arc<Executor<'_>>, config: &DarkfidConfig) -> Result<()
         identity_pass: config.tls_identity_password.clone(),
     };
 
-    darkfid.start(state, executor.clone()).await?;
+    darkfid.start(executor.clone()).await?;
     listen_and_serve(server_config, Arc::new(darkfid), executor).await
 }
 
@@ -610,7 +621,6 @@ async fn main() -> Result<()> {
     let config: DarkfidConfig = Config::<DarkfidConfig>::load(config_path)?;
 
     if args.is_present("refresh") {
-
         debug!(target: "DARKFI DAEMON", "Refresh the wallet and the database");
 
         let wallet = WalletDb::new(

+ 31 - 7
src/client.rs

@@ -91,13 +91,15 @@ impl Client {
         token_id: jubjub::Fr,
         pub_key: jubjub::SubgroupPoint,
         amount: u64,
+        state: Arc<Mutex<State>>,
     ) -> ClientResult<()> {
+
         debug!(target: "CLIENT", "Start transfer {}", amount);
 
         let token_id_exists = self.wallet.token_id_exists(&token_id)?;
 
         if token_id_exists {
-            self.send(pub_key, amount, token_id, false).await?;
+            self.send(pub_key, amount, token_id, false, state).await?;
         } else {
             return Err(ClientFailed::NotEnoughValue(amount));
         }
@@ -113,6 +115,7 @@ impl Client {
         amount: u64,
         token_id: jubjub::Fr,
         clear_input: bool,
+        state: Arc<Mutex<State>>,
     ) -> ClientResult<()> {
         debug!(target: "CLIENT", "Start send {}", amount);
 
@@ -120,11 +123,16 @@ impl Client {
             return Err(ClientFailed::InvalidAmount(amount as u64));
         }
 
-        let slab = self
+        let (slab, tx) = self
             .build_slab_from_tx(pub_key, amount, token_id, clear_input)
             .await?;
 
-        self.gateway.put_slab(slab).await?;
+        // check if it's valid before send it to gateway
+        if let Err(err) = self.update_state(tx, state).await {
+            return Err(ClientFailed::from(err));
+        } else {
+            self.gateway.put_slab(slab).await?;
+        }
 
         debug!(target: "CLIENT", "End send {}", amount);
 
@@ -137,7 +145,7 @@ impl Client {
         value: u64,
         token_id: jubjub::Fr,
         clear_input: bool,
-    ) -> Result<Slab> {
+    ) -> Result<(Slab, tx::Transaction)> {
         debug!(target: "CLIENT", "Start build slab from tx");
 
         let mut clear_inputs: Vec<tx::TransactionBuilderClearInputInfo> = vec![];
@@ -168,9 +176,11 @@ impl Client {
             outputs,
         };
 
+        let tx: tx::Transaction;
+
         let mut tx_data = vec![];
         {
-            let tx = builder.build(&self.mint_params, &self.spend_params);
+            tx = builder.build(&self.mint_params, &self.spend_params);
             tx.encode(&mut tx_data).expect("encode tx");
         }
 
@@ -178,7 +188,7 @@ impl Client {
 
         debug!(target: "CLIENT", "End build slab from tx");
 
-        Ok(slab)
+        Ok((slab, tx))
     }
 
     async fn build_inputs(
@@ -317,7 +327,7 @@ impl Client {
                 let tx = tx::Transaction::decode(&slab.get_payload()[..]);
 
                 if let Err(e) = tx {
-                    warn!("TX: {}", e.to_string());
+                    warn!("TX Decode: {}", e.to_string());
                     continue;
                 }
 
@@ -348,6 +358,20 @@ impl Client {
         Ok(())
     }
 
+    async fn update_state(&self, tx: tx::Transaction, state: Arc<Mutex<State>>) -> Result<()> {
+        let mut state = state.lock().await;
+
+        let update = state_transition(&state, tx)?;
+
+        let secret_keys: Vec<jubjub::Fr> = vec![self.main_keypair.private];
+
+        state
+            .apply(update, secret_keys.clone(), None, self.wallet.clone())
+            .await?;
+
+        Ok(())
+    }
+
     pub async fn init_db(&self) -> Result<()> {
         self.wallet.init_db().await
     }