Bläddra i källkod

drk: Add stub for block subscription.

parazyd 3 år sedan
förälder
incheckning
bdf67b41d1
4 ändrade filer med 95 tillägg och 4 borttagningar
  1. 23 0
      bin/drk/src/main.rs
  2. 63 0
      bin/drk/src/rpc_blockchain.rs
  3. 6 4
      src/consensus/state.rs
  4. 3 0
      src/error.rs

+ 23 - 0
bin/drk/src/main.rs

@@ -34,6 +34,9 @@ use darkfi::{
 /// Airdrop methods
 mod rpc_airdrop;
 
+/// Blockchain methods
+mod rpc_blockchain;
+
 /// Wallet operation methods for darkfid's JSON-RPC
 mod rpc_wallet;
 
@@ -91,6 +94,14 @@ enum Subcmd {
         /// Optional address to send tokens to (defaults to main address in wallet)
         address: Option<String>,
     },
+
+    /// Subscribe to incoming blocks from darkfid
+    ///
+    /// This subscription will listen for incoming blocks from darkfid and look
+    /// through their transactions to see if there's any that interest us.
+    /// With `drk` we look at transactions calling the money contract so we can
+    /// find coins sent to us and fill our wallet with the necessary metadata.
+    Subscribe,
 }
 
 pub struct Drk {
@@ -197,5 +208,17 @@ async fn main() -> Result<()> {
             println!("Transaction ID: {}", txid);
             Ok(())
         }
+
+        Subcmd::Subscribe => {
+            let rpc_client = RpcClient::new(args.endpoint)
+                .await
+                .with_context(|| "Could not connect to darkfid RPC endpoint")?;
+
+            let drk = Drk { rpc_client };
+
+            drk.subscribe_blocks().await.with_context(|| "Block subscription failed")?;
+
+            Ok(())
+        }
     }
 }

+ 63 - 0
bin/drk/src/rpc_blockchain.rs

@@ -0,0 +1,63 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2022 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use anyhow::{anyhow, Result};
+use darkfi::{
+    rpc::jsonrpc::{JsonRequest, JsonResult},
+    system::Subscriber,
+};
+use serde_json::json;
+
+use super::Drk;
+
+impl Drk {
+    /// Subscribes to darkfid's JSON-RPC notification endpoint that serves
+    /// new finalized blocks. Upon receiving them, all the transactions are
+    /// scanned and we check if any of them call the money contract, and if
+    /// the payments are intended for us. If so, we decrypt them and append
+    /// the metadata to our wallet.
+    pub async fn subscribe_blocks(&self) -> Result<()> {
+        eprintln!("Subscribing to receive notifications of incoming blocks");
+        let subscriber = Subscriber::new();
+
+        let req = JsonRequest::new("blockchain.subscribe_blocks", json!([]));
+        self.rpc_client.subscribe(req, subscriber.clone()).await?;
+
+        let subscription = subscriber.subscribe().await;
+
+        let e = loop {
+            match subscription.receive().await {
+                JsonResult::Notification(n) => {
+                    println!("Got Block notification: {:?}", n);
+                }
+
+                JsonResult::Error(e) => {
+                    // Some error happened in the transmission
+                    break anyhow!("Got error from JSON-RPC: {:?}", e)
+                }
+
+                x => {
+                    // And this is weird
+                    break anyhow!("Got unexpected data from JSON-RPC: {:?}", x)
+                }
+            }
+        };
+
+        Err(e)
+    }
+}

+ 6 - 4
src/consensus/state.rs

@@ -1143,7 +1143,7 @@ impl ValidatorState {
 
         // TODO: Don't hardcode this:
         let blocks_subscriber = self.subscribers.get("blocks").unwrap();
-        let params = json!([bs58::encode(&serialize(proposal)).into_string()]);
+        let params = json!([bs58::encode(&serialize(&block)).into_string()]);
         let notif = JsonNotification::new("blockchain.subscribe_blocks", params);
         blocks_subscriber.notify(notif).await;
 
@@ -1183,9 +1183,11 @@ impl ValidatorState {
 
         // TODO: Don't hardcode this:
         let blocks_subscriber = self.subscribers.get("blocks").unwrap();
-        let params = json!([bs58::encode(&serialize(proposal)).into_string()]);
-        let notif = JsonNotification::new("blockchain.subscribe_blocks", params);
-        blocks_subscriber.notify(notif).await;
+        for block in new_blocks {
+            let params = json!([bs58::encode(&serialize(&block)).into_string()]);
+            let notif = JsonNotification::new("blockchain.subscribe_blocks", params);
+            blocks_subscriber.notify(notif).await;
+        }
 
         Ok(())
     }

+ 3 - 0
src/error.rs

@@ -217,6 +217,9 @@ pub enum Error {
     #[error("JSON-RPC error: {0}")]
     JsonRpcError(String),
 
+    #[error("Unexpected JSON-RPC data received: {0}")]
+    UnexpectedJsonRpc(String),
+
     #[error("Received proposal from unknown node")]
     UnknownNodeError,