Преглед на файлове

book/dchat: use anchors where possible, copy paste code where not.

also run cargo fmt.
lunar-mining преди 3 години
родител
ревизия
22151f6b7a
променени са 34 файла, в които са добавени 291 реда и са изтрити 272 реда
  1. 1 1
      doc/src/SUMMARY.md
  2. 1 1
      doc/src/learn/dchat/creating-dchat/message.md
  3. 16 11
      doc/src/learn/dchat/creating-dchat/protocol-dchat.md
  4. 31 14
      doc/src/learn/dchat/creating-dchat/register-protocol.md
  5. 2 2
      doc/src/learn/dchat/creating-dchat/sending-messages.md
  6. 12 5
      doc/src/learn/dchat/creating-dchat/ui.md
  7. 19 7
      doc/src/learn/dchat/deployment/error-handling.md
  8. 2 2
      doc/src/learn/dchat/deployment/getting-started.md
  9. 0 3
      doc/src/learn/dchat/deployment/sessions.md
  10. 11 5
      doc/src/learn/dchat/deployment/settings.md
  11. 12 8
      doc/src/learn/dchat/deployment/start-run-stop.md
  12. 19 6
      doc/src/learn/dchat/deployment/writing-a-daemon.md
  13. 19 15
      doc/src/learn/dchat/network-tools/accept-addr.md
  14. 0 112
      doc/src/learn/dchat/network-tools/darkfi-rpc.md
  15. 4 6
      doc/src/learn/dchat/network-tools/get-info.md
  16. 5 6
      doc/src/learn/dchat/network-tools/pong.md
  17. 17 7
      doc/src/learn/dchat/network-tools/rpc.md
  18. 2 7
      doc/src/learn/dchat/network-tools/server.md
  19. 4 0
      example/dchat/Cargo.toml
  20. 2 0
      example/dchat/src/dchat_error.rs
  21. 2 0
      example/dchat/src/dchatmsg.rs
  22. 28 4
      example/dchat/src/main.rs
  23. 8 0
      example/dchat/src/protocol_dchat.rs
  24. 8 0
      example/dchat/src/rpc.rs
  25. 1 1
      src/consensus/ouroboros/consts.rs
  26. 26 20
      src/consensus/ouroboros/epoch.rs
  27. 1 1
      src/consensus/ouroboros/mod.rs
  28. 14 15
      src/consensus/ouroboros/stakeholder.rs
  29. 4 8
      src/consensus/ouroboros/utils.rs
  30. 0 1
      src/crypto/leadcoin.rs
  31. 2 0
      src/net/channel.rs
  32. 10 0
      src/net/p2p.rs
  33. 4 0
      src/rpc/jsonrpc.rs
  34. 4 4
      src/zk/circuit/lead_contract.rs

+ 1 - 1
doc/src/SUMMARY.md

@@ -58,7 +58,7 @@
       - [Slap on a UI](learn/dchat/creating-dchat/ui.md)
       - [Slap on a UI](learn/dchat/creating-dchat/ui.md)
       - [Using dchat](learn/dchat/creating-dchat/using-dchat.md)
       - [Using dchat](learn/dchat/creating-dchat/using-dchat.md)
     - [Net tools](learn/dchat/network-tools/part-3.md)
     - [Net tools](learn/dchat/network-tools/part-3.md)
-      - [RPC interface](learn/dchat/network-tools/jsonrpcinterface.md)
+      - [RPC interface](learn/dchat/network-tools/rpc.md)
       - [Accept addr](learn/dchat/network-tools/accept-addr.md)
       - [Accept addr](learn/dchat/network-tools/accept-addr.md)
       - [Adding methods](learn/dchat/network-tools/pong.md)
       - [Adding methods](learn/dchat/network-tools/pong.md)
       - [RPC server](learn/dchat/network-tools/server.md)
       - [RPC server](learn/dchat/network-tools/server.md)

+ 1 - 1
doc/src/learn/dchat/creating-dchat/message.md

@@ -20,5 +20,5 @@ this in a `Mutex` to ensure thread safety and an `Arc` pointer so we can
 pass it around.
 pass it around.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/dchatmsg.rs::19}}
+{{#include ../../../../../example/dchat/src/dchatmsg.rs:msg}}
 ```
 ```

+ 16 - 11
doc/src/learn/dchat/creating-dchat/protocol-dchat.md

@@ -6,7 +6,7 @@ pointer to the `ProtocolJobsManager`. We'll also include the `DchatMsgsBuffer`
 in the struct as it will come in handy later on.
 in the struct as it will come in handy later on.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:1:13}}
+{{#include ../../../../../example/dchat/src/protocol_dchat.rs:protocol_dchat}}
 ```
 ```
 
 
 Next we'll implement the trait `ProtocolBase`. `ProtocolBase` requires
 Next we'll implement the trait `ProtocolBase`. `ProtocolBase` requires
@@ -14,8 +14,17 @@ two functions, `start()` and `name()`. In `start()` we will start up the
 `ProtocolJobsManager`. `name()` will return a `str` of the protocol name.
 `ProtocolJobsManager`. `name()` will return a `str` of the protocol name.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:42:46}}
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:48::}}
+#[async_trait]
+impl net::ProtocolBase for ProtocolDchat {
+    async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
+        self.jobsman.clone().start(executor.clone());
+        Ok(())
+    }
+
+    fn name(&self) -> &'static str {
+        "ProtocolDchat"
+    }
+}
 ```
 ```
 
 
 Once that's done, we'll need to create a `ProtocolDchat` constructor
 Once that's done, we'll need to create a `ProtocolDchat` constructor
@@ -28,8 +37,8 @@ We'll also initialize the `ProtocolJobsManager` and finally return a
 pointer to the protocol.
 pointer to the protocol.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:15:29}}
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:40}}
+{{#include ../../../../../example/dchat/src/protocol_dchat.rs:constructor}}
+}
 ```
 ```
 
 
 We're nearly there. But right now the protocol doesn't actually do
 We're nearly there. But right now the protocol doesn't actually do
@@ -39,16 +48,12 @@ a message on our `MessageSubscription` and adds it to `DchatMsgsBuffer`.
 Put this inside the `ProtocolDchat` implementation:
 Put this inside the `ProtocolDchat` implementation:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:31:39}}
+{{#include ../../../../../example/dchat/src/protocol_dchat.rs:receive}}
 ```
 ```
 
 
 As a final step, let's add that task to the `ProtocolJobManager` that is invoked
 As a final step, let's add that task to the `ProtocolJobManager` that is invoked
 in `start()`:
 in `start()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:44}}
-        //...
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:47}}
-        //...
-{{#include ../../../../../example/dchat/src/protocol_dchat.rs:50}}
+{{#include ../../../../../example/dchat/src/protocol_dchat.rs:start}}
 ```
 ```

+ 31 - 14
doc/src/learn/dchat/creating-dchat/register-protocol.md

@@ -9,7 +9,7 @@ handle to the p2p network contained in the `Dchat` struct. It will then
 call `register()` on the registry and pass the `ProtocolDchat` constructor.
 call `register()` on the registry and pass the `ProtocolDchat` constructor.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:86:97}}
+{{#include ../../../../../example/dchat/src/main.rs:register_protocol}}
 ```
 ```
 
 
 There's a lot going on here. `register()` takes a closure with two
 There's a lot going on here. `register()` takes a closure with two
@@ -40,33 +40,50 @@ in `main()` and pass it to `Dchat::new()`. Let's add `DchatMsgsBuffer` to the
 `Dchat` struct definition first.
 `Dchat` struct definition first.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:13:16}}
-{{#include ../../../../../example/dchat/src/main.rs:18}}
-
-{{#include ../../../../../example/dchat/src/main.rs:28:36}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:121}}
+{{#include ../../../../../example/dchat/src/main.rs:dchat}}
 ```
 ```
 
 
 And initialize it:
 And initialize it:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:183:184}}
+#[async_std::main]
+async fn main() -> Result<()> {
     //...
     //...
-{{#include ../../../../../example/dchat/src/main.rs:205}}
 
 
-    let mut dchat = Dchat::new(p2p, msgs);
+    let msgs: DchatMsgsBuffer = Arc::new(Mutex::new(vec![DchatMsg { msg: String::new() }]));
+
+    let mut dchat = Dchat::new(p2p.clone(), msgs);
+
     //...
     //...
-{{#include ../../../../../example/dchat/src/main.rs:224}}
+    let (_, result) = Parallel::new()
+        .each(0..nthreads, |_| smol::future::block_on(ex2.run(shutdown.recv())))
+        .finish(|| {
+            smol::future::block_on(async move {
+                dchat.start(ex3).await?;
+                drop(signal);
+                Ok(())
+            })
+        });
+
+    result
+}
 ```
 ```
 
 
 Finally, call `register_protocol()` in `dchat::start()`:
 Finally, call `register_protocol()` in `dchat::start()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:99:105}}
-        self.p2p.clone().run(ex.clone()).await?;
+    async fn start(&mut self, ex: Arc<Executor<'_>>) -> Result<()> {
+        let ex2 = ex.clone();
+
+        self.register_protocol(self.recv_msgs.clone()).await?;
+        self.p2p.clone().start(ex.clone()).await?;
+        ex2.spawn(self.p2p.clone().run(ex.clone())).detach();
+
+        self.p2p.stop().await;
+
+        Ok(())
+    }
 
 
-{{#include ../../../../../example/dchat/src/main.rs:110:114}}
 ```
 ```
 Now try running Alice and Bob and seeing what debug output you get. Keep
 Now try running Alice and Bob and seeing what debug output you get. Keep
 an eye out for the following:
 an eye out for the following:

+ 2 - 2
doc/src/learn/dchat/creating-dchat/sending-messages.md

@@ -8,7 +8,7 @@ introduce us to a new p2p method that is essential to our chat app:
 `p2p.broadcast()`.
 `p2p.broadcast()`.
 
 
 ```
 ```
-{{#include ../../../../../example/dchat/src/main.rs:116:120}}
+{{#include ../../../../../example/dchat/src/main.rs:send}}
 ```
 ```
 
 
 We pass a `String` called msg that will be taken from user input. We use
 We pass a `String` called msg that will be taken from user input. We use
@@ -18,7 +18,7 @@ can now support. Finally, we pass the message into `p2p.broadcast()`.
 Here's what happens under the hood:
 Here's what happens under the hood:
 
 
 ```rust
 ```rust
-{{#include ../../../../../src/net/p2p.rs:191:196}}
+{{#include ../../../../../src/net/p2p.rs:broadcast}}
 ```
 ```
 
 
 This is pretty straightforward: `broadcast()` takes a generic `Message` type
 This is pretty straightforward: `broadcast()` takes a generic `Message` type

+ 12 - 5
doc/src/learn/dchat/creating-dchat/ui.md

@@ -9,17 +9,24 @@ simply displays the messages that `ProtocolDchat` has saved in the
 Here's what it should look like:
 Here's what it should look like:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:38:84}}
+{{#include ../../../../../example/dchat/src/main.rs:menu}}
 ```
 ```
 
 
 We'll call `menu()` inside of `dchat::start()` along with our other methods, like so:
 We'll call `menu()` inside of `dchat::start()` along with our other methods, like so:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:99:100}}
+    async fn start(&mut self, ex: Arc<Executor<'_>>) -> Result<()> {
+        let ex2 = ex.clone();
 
 
-{{#include ../../../../../example/dchat/src/main.rs:104:105}}
+        self.register_protocol(self.recv_msgs.clone()).await?;
+        self.p2p.clone().start(ex.clone()).await?;
         self.p2p.clone().run(ex.clone()).await?;
         self.p2p.clone().run(ex.clone()).await?;
-{{#include ../../../../../example/dchat/src/main.rs:107:114}}
+
+        self.menu().await?;
+
+        self.p2p.stop().await;
+        Ok(())
+    }
 ```
 ```
 
 
 But wait- if you try running this code, you'll notice that the menu never
 But wait- if you try running this code, you'll notice that the menu never
@@ -31,5 +38,5 @@ to detach it in the background.
 The complete implementaion looks like this:
 The complete implementaion looks like this:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:99:114}}
+{{#include ../../../../../example/dchat/src/main.rs:start}}
 ```
 ```

+ 19 - 7
doc/src/learn/dchat/deployment/error-handling.md

@@ -4,17 +4,29 @@ Before we continue, we need to quickly add some error handling to handle
 the case where a user forgets to add the command-line flag.
 the case where a user forgets to add the command-line flag.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/dchat_error.rs:1:12}}
+{{#include ../../../../../example/dchat/src/dchat_error.rs:error}}
 ```
 ```
 
 
-Finally we can read the flag from the command-line by adding the following lines to `main()`:
+We can then read the flag from the command-line by adding the following
+lines to `main()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:13:14}}
-{{#include ../../../../../example/dchat/src/main.rs:18}}
+use crate::dchat_error::ErrorMissingSpecifier;
+use darkfi::net::Settings;
 
 
-{{#include ../../../../../example/dchat/src/main.rs:182:191}}
-//...
-{{#include ../../../../../example/dchat/src/main.rs:224}}
+{{#include ../../../../../example/dchat/src/main.rs:error}}
+
+async fn main() -> Result<()> {
+    // ...
+    let settings: Result<Settings> = match std::env::args().nth(1) {
+        Some(id) => match id.as_str() {
+            "a" => alice(),
+            "b" => bob(),
+            _ => Err(ErrorMissingSpecifier.into()),
+        },
+        None => Err(ErrorMissingSpecifier.into()),
+    };
+    // ...
+}
 ```
 ```
 
 

+ 2 - 2
doc/src/learn/dchat/deployment/getting-started.md

@@ -4,7 +4,7 @@ We'll create a new cargo directory and add DarkFi to our `Cargo.toml`,
 like so:
 like so:
 
 
 ```
 ```
-{{#include ../../../../../example/dchat/Cargo.toml::8}}
+{{#include ../../../../../example/dchat/Cargo.toml:darkfi}}
 ```
 ```
 
 
 Be sure to replace the path to DarkFi with the correct path for your
 Be sure to replace the path to DarkFi with the correct path for your
@@ -15,7 +15,7 @@ dchat. We'll need a few more external libraries too, so add these
 dependencies:
 dependencies:
 
 
 ```
 ```
-{{#include ../../../../../example/dchat/Cargo.toml:10:27}}
+{{#include ../../../../../example/dchat/Cargo.toml:dependencies}}
 ```
 ```
 
 
 
 

+ 0 - 3
doc/src/learn/dchat/deployment/sessions.md

@@ -26,6 +26,3 @@ a specified address.
 Loops through all the configured seeds and tries to connect to them
 Loops through all the configured seeds and tries to connect to them
 using a `Connector`. Either connects successfully, fails with an error or
 using a `Connector`. Either connects successfully, fails with an error or
 times out.
 times out.
-
-To create an inbound and outbound node, we will need to configure them
-using a type called `net::Settings`.

+ 11 - 5
doc/src/learn/dchat/deployment/settings.md

@@ -1,10 +1,16 @@
 # Settings
 # Settings
 
 
-On production-ready software, you would usually configure your node
-using a config file or command line inputs. On dchat we are keeping
-things ultra simple. We pass a command line flag that is either `a` or
-`b`. If we pass `a` we will initialize an inbound node. If we pass `b`
-we will initialize an outbound node.
+To create an inbound and outbound node, we
+will need to configure them using `net` type called
+[Settings](https://github.com/darkrenaissance/darkfi/blob/master/src/net/settings.rs).
+This type consists of several settings that allow you to configure nodes
+in different ways.
+
+You would usually configure `Settings` using a config file or command
+line inputs. On dchat we are keeping things ultra simple. We pass a
+command line flag that is either `a` or `b`. If we pass `a` we will
+initialize the `Settings` for an inbound node. If we pass `b` we will
+initialize an outbound node.
 
 
 Here's how that works. We define two methods called `alice()` and
 Here's how that works. We define two methods called `alice()` and
 `bob()`. `alice()` returns the `Settings` that will create an inbound
 `bob()`. `alice()` returns the `Settings` that will create an inbound

+ 12 - 8
doc/src/learn/dchat/deployment/start-run-stop.md

@@ -6,7 +6,7 @@ instance of the p2p network.
 Add the following to `main()`:
 Add the following to `main()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:196}}
+    let p2p = net::P2p::new(settings?).await;
 ```
 ```
 
 
 We will next create a `Dchat` struct that will store all the data required
 We will next create a `Dchat` struct that will store all the data required
@@ -29,13 +29,17 @@ takes an executor and runs three p2p methods, `p2p::start()`, `p2p::run()`,
 and `p2p::stop()`.
 and `p2p::stop()`.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:99:100}}
+    async fn start(&mut self, ex: Arc<Executor<'_>>) -> Result<()> {
+        let ex2 = ex.clone();
 
 
-{{#include ../../../../../example/dchat/src/main.rs:105}}
+        self.p2p.clone().start(ex.clone()).await?;
+        ex2.spawn(self.p2p.clone().run(ex.clone())).detach();
 
 
-        self.p2p.clone().run(ex.clone()).await?;
+        self.p2p.stop().await;
+
+        Ok(())
+    }
 
 
-{{#include ../../../../../example/dchat/src/main.rs:110:114}}
 ```
 ```
 Let's take a quick look at the underlying p2p methods we're using here.
 Let's take a quick look at the underlying p2p methods we're using here.
 
 
@@ -44,7 +48,7 @@ Let's take a quick look at the underlying p2p methods we're using here.
 This is [start()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L135):
 This is [start()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L135):
 
 
 ```rust
 ```rust
-{{#include ../../../../../src/net/p2p.rs:134:149}}
+{{#include ../../../../../src/net/p2p.rs:start}}
 ```
 ```
 
 
 `start()` changes the `P2pState` to `P2pState::Start` and runs a [seed
 `start()` changes the `P2pState` to `P2pState::Start` and runs a [seed
@@ -63,7 +67,7 @@ the channel from the channel list.
 This is [run()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L163):
 This is [run()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L163):
 
 
 ```rust
 ```rust
-{{#include ../../../../../src/net/p2p.rs:161:190}}
+{{#include ../../../../../src/net/p2p.rs:run}}
 ```
 ```
 
 
 `run()` changes the P2pState to `P2pState::Run`. It then calls `start()`
 `run()` changes the P2pState to `P2pState::Run`. It then calls `start()`
@@ -86,7 +90,7 @@ is received.
 This is [stop()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L306).
 This is [stop()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L306).
 
 
 ```rust
 ```rust
-    {{#include ../../../../../src/net/p2p.rs:306:308}}
+    {{#include ../../../../../src/net/p2p.rs:stop}}
 ```
 ```
 
 
 `stop()` transmits a shutdown signal to all channels subscribed to the
 `stop()` transmits a shutdown signal to all channels subscribed to the

+ 19 - 6
doc/src/learn/dchat/deployment/writing-a-daemon.md

@@ -6,15 +6,28 @@ start building `dchat` by configuring our main function into a daemon that
 can run the p2p network.
 can run the p2p network.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs::9}}
+{{#include ../../../../../example/dchat/src/main.rs:daemon_deps}}
 
 
-{{#include ../../../../../example/dchat/src/main.rs:25:26}}
+#[async_std::main]
+async fn main() -> Result<()> {
+    let ex = Arc::new(Executor::new());
+    let ex2 = ex.clone();
 
 
-{{#include ../../../../../example/dchat/src/main.rs:183:184}}
-{{#include ../../../../../example/dchat/src/main.rs:198:199}}
+    let nthreads = num_cpus::get();
+    let (signal, shutdown) = smol::channel::unbounded::<()>();
 
 
-{{#include ../../../../../example/dchat/src/main.rs:213:216}}
-{{#include ../../../../../example/dchat/src/main.rs:218:224}}
+    let (_, result) = Parallel::new()
+        .each(0..nthreads, |_| smol::future::block_on(ex2.run(shutdown.recv())))
+        .finish(|| {
+            smol::future::block_on(async move {
+                drop(signal);
+                Ok(())
+            })
+        });
+
+    result
+
+}
 ```
 ```
 
 
 We get the number of cpu cores using `num_cpus::get()` and spin up a
 We get the number of cpu cores using `num_cpus::get()` and spin up a

+ 19 - 15
doc/src/learn/dchat/network-tools/accept-addr.md

@@ -11,36 +11,40 @@ Let's define a new struct called `AppSettings` that has two fields,
 `Url` and `Settings`.
 `Url` and `Settings`.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:123:132}}
+{{#include ../../../../../example/dchat/src/main.rs:app_settings}}
 ```
 ```
 
 
 Next, we'll change our `alice()` method to return a `AppSettings`
 Next, we'll change our `alice()` method to return a `AppSettings`
 instead of a `Settings`.
 instead of a `Settings`.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:135}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:143:158}}
+{{#include ../../../../../example/dchat/src/main.rs:alice}}
 ```
 ```
 
 
 And the same for `bob()`:
 And the same for `bob()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:160}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:170:181}}
+{{#include ../../../../../example/dchat/src/main.rs:bob}}
 ```
 ```
 
 
 Update `main()` with the new type:
 Update `main()` with the new type:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:183:192}}
-
-{{#include ../../../../../example/dchat/src/main.rs:194}}
-
-{{#include ../../../../../example/dchat/src/main.rs:196}}
+#[async_std::main]
+async fn main() -> Result<()> {
+    let settings: Result<AppSettings> = match std::env::args().nth(1) {
+        Some(id) => match id.as_str() {
+            "a" => alice(),
+            "b" => bob(),
+            _ => Err(ErrorMissingSpecifier.into()),
+        },
+        None => Err(ErrorMissingSpecifier.into()),
+    };
+
+    let settings = settings?.clone();
+
+    let p2p = net::P2p::new(settings.net).await;
     //...
     //...
-{{#include ../../../../../example/dchat/src/main.rs:224}}
+    }
+}
 ```
 ```
-
-

+ 0 - 112
doc/src/learn/dchat/network-tools/darkfi-rpc.md

@@ -1,112 +0,0 @@
-# DarkFi RPC
-
-First, we'll need to connect dchat up to JSON-RPC using DarkFi's [rpc
-module](https://github.com/darkrenaissance/darkfi/tree/master/src/rpc).
-
-# AppSettings 
-
-We'll need to set an JSON-RPC `Url` that is specific to our nodes, Alice
-and Bob. To do that, let's return to our functions `alice()` and `bob()`
-that return the type `Settings`. To enable Alice and Bob to connect to
-JSON-RPC, we'll need to generalize this to include a RPC `Url`.
-
-Let's define a new struct called `AppSettings` that has two fields,
-a RPC `Url` and `Settings`.
-
-```rust
-{{#include ../../../../../example/dchat/src/main.rs:123:132}}
-```
-
-Next, we'll change our `alice()` method to return a `AppSettings`
-instead of a `Settings`.
-
-```rust
-{{#include ../../../../../example/dchat/src/main.rs:135}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:143:158}}
-```
-
-And the same for `bob()`:
-
-```rust
-{{#include ../../../../../example/dchat/src/main.rs:160}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:170:181}}
-```
-
-Update `main()` with the new type:
-
-```rust
-{{#include ../../../../../example/dchat/src/main.rs:183:192}}
-
-{{#include ../../../../../example/dchat/src/main.rs:194}}
-
-{{#include ../../../../../example/dchat/src/main.rs:197}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:225}}
-```
-
-# JsonRpcInterface
-
-Next, we'll define a new struct called `JsonRpcInterface` that takes
-two values, a `Url` that we'll connect the JSON-RPC to, and a pointer
-to the p2p network.
-
-```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:1:17}}
-```
-
-We'll need to implement a trait called `RequestHandler` for
-the `JsonRpcInterface`. `RequestHandler` exposes a method called
-`handle_request()` which is a handle for processes incoming
-JSON-RPC requests. `handle_request()` takes a `JsonRequest`
-and returns a `JsonResult`. These types are defined inside
-[jsonrpc.rs](https://github.com/darkrenaissance/darkfi/blob/master/src/rpc/jsonrpc.rs)
-
-This is `JsonResult`:
-```rust
-{{#include ../../../../../src/rpc/jsonrpc.rs:49:55}}
-```
-
-This is `JsonRequest`:
-
-```rust
-{{#include ../../../../../src/rpc/jsonrpc.rs:75:86}}
-```
-
-We'll use `handle_request()` to run a match statement on
-`JsonRequest.method`.
-
-Running a match on `method` will allow us to branch out to functions
-that handle respective methods.  We haven't implemented any methods yet,
-so for now let's just return a `JsonError`.
-
-```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:19:28}}
-{{#include ../../../../../example/dchat/src/rpc.rs:31:34}}
-```
-
-# Listen and serve
-
-Now let's implement some methods. We'll start with a simple `pong`
-method that replies to `ping`.
-
-```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:36:43}}
-{{#include ../../../../../example/dchat/src/rpc.rs:53}}
-```
-
-And add it to `handle_request()`:
-
-```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:19:21}}
-        //...
-{{#include ../../../../../example/dchat/src/rpc.rs:28:29}}
-{{#include ../../../../../example/dchat/src/rpc.rs:31:34}}
-```
-
-To deploy this, we'll need to invoke an `rpc::server` method,
-`listen_and_serve()`.  `listen_and_serve()` starts a JSON-RPC server that
-is bound to the provided accept URL and uses our previously implemented
-`RequestHandler` to handle incoming requests.
-

+ 4 - 6
doc/src/learn/dchat/network-tools/get-info.md

@@ -15,15 +15,13 @@ To use it, let's return to our `JsonRpcInterface` and add the following
 method:
 method:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:45:52}}
+{{#include ../../../../../example/dchat/src/rpc.rs:get_info}}
 ```
 ```
 
 
 And add it to `handle_request()`:
 And add it to `handle_request()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:21}}
-        //...
-{{#include ../../../../../example/dchat/src/rpc.rs:28:34}}
+{{#include ../../../../../example/dchat/src/rpc.rs:req_match}}
 ```
 ```
 
 
 This calls the p2p function `get_info()` and passes the returned data into a
 This calls the p2p function `get_info()` and passes the returned data into a
@@ -36,7 +34,7 @@ calls which deliver info specific to a node, its inbound or outbound
 Here's what happens:
 Here's what happens:
 
 
 ```rust
 ```rust
-{{#include ../../../../../src/net/p2p.rs:111:126}}
+{{#include ../../../../../src/net/p2p.rs:get_info}}
 ```
 ```
 
 
 Here we return two pieces of info that are unique to a node:
 Here we return two pieces of info that are unique to a node:
@@ -52,7 +50,7 @@ happens via a child struct called `ChannelInfo`.
 This is `ChannelInfo::get_info()`.
 This is `ChannelInfo::get_info()`.
 
 
 ```rust
 ```rust
-{{#include ../../../../../src/net/channel.rs:48:58}}
+{{#include ../../../../../src/net/channel.rs:get_info}}
 ```
 ```
 
 
 `dnetview` uses the info returned from `Channel` and `Session` and
 `dnetview` uses the info returned from `Channel` and `Session` and

+ 5 - 6
doc/src/learn/dchat/network-tools/pong.md

@@ -7,15 +7,14 @@ let's implement some methods.
 We'll start with a simple `pong` method that replies to `ping`.
 We'll start with a simple `pong` method that replies to `ping`.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:36:43}}
-{{#include ../../../../../example/dchat/src/rpc.rs:53}}
+{{#include ../../../../../example/dchat/src/rpc.rs:pong}}
 ```
 ```
 
 
 And add it to `handle_request()`:
 And add it to `handle_request()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:19:21}}
-        //...
-{{#include ../../../../../example/dchat/src/rpc.rs:28:29}}
-{{#include ../../../../../example/dchat/src/rpc.rs:31:34}}
+        match req.method.as_str() {
+            Some("ping") => self.pong(req.id, req.params).await,
+            Some(_) | None => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
+            }
 ```
 ```

+ 17 - 7
doc/src/learn/dchat/network-tools/jsonrpcinterface.md → doc/src/learn/dchat/network-tools/rpc.md

@@ -8,7 +8,7 @@ takes two values, an accept `Url` that will receive JSON-RPC requests,
 and a pointer to the p2p network.
 and a pointer to the p2p network.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:1:17}}
+{{#include ../../../../../example/dchat/src/rpc.rs:jsonrpc}}
 ```
 ```
 
 
 We'll need to implement a trait called `RequestHandler` for
 We'll need to implement a trait called `RequestHandler` for
@@ -20,13 +20,13 @@ and returns a `JsonResult`. These types are defined inside
 
 
 This is `JsonResult`:
 This is `JsonResult`:
 ```rust
 ```rust
-{{#include ../../../../../src/rpc/jsonrpc.rs:49:55}}
+{{#include ../../../../../src/rpc/jsonrpc.rs:jsonresult}}
 ```
 ```
 
 
 This is `JsonRequest`:
 This is `JsonRequest`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../src/rpc/jsonrpc.rs:75:86}}
+{{#include ../../../../../src/rpc/jsonrpc.rs:jsonrequest}}
 ```
 ```
 
 
 We'll use `handle_request()` to run a match statement on
 We'll use `handle_request()` to run a match statement on
@@ -37,8 +37,18 @@ that respond to methods received over JSON-RPC.  We haven't implemented
 any methods yet, so for now let's just return a `JsonError`.
 any methods yet, so for now let's just return a `JsonError`.
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/rpc.rs:19:28}}
-{{#include ../../../../../example/dchat/src/rpc.rs:31:34}}
+#[async_trait]
+impl RequestHandler for JsonRpcInterface {
+    async fn handle_request(&self, req: JsonRequest) -> JsonResult {
+        if req.params.as_array().is_none() {
+            return JsonError::new(ErrorCode::InvalidRequest, None, req.id).into()
+        }
+
+        debug!(target: "RPC", "--> {}", serde_json::to_string(&req).unwrap());
+
+        match req.method.as_str() {
+            Some(_) | None => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
+        }
+    }
+}
 ```
 ```
-
-

+ 2 - 7
doc/src/learn/dchat/network-tools/server.md

@@ -11,12 +11,7 @@ requests.
 Add the following lines to `main()`:
 Add the following lines to `main()`:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:183:184}}
-
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:209:212}}
-    //...
-{{#include ../../../../../example/dchat/src/main.rs:224}}
+{{#include ../../../../../example/dchat/src/main.rs:json_init}}
 ```
 ```
 
 
 We create a new `JsonRpcInterface` inside an `Arc` pointer and pass in our
 We create a new `JsonRpcInterface` inside an `Arc` pointer and pass in our
@@ -33,5 +28,5 @@ We have enabled JSON-RPC.
 Here's what our complete `main()` function looks like:
 Here's what our complete `main()` function looks like:
 
 
 ```rust
 ```rust
-{{#include ../../../../../example/dchat/src/main.rs:183:224}}
+{{#include ../../../../../example/dchat/src/main.rs:main}}
 ```
 ```

+ 4 - 0
example/dchat/Cargo.toml

@@ -8,10 +8,13 @@ repository = "https://github.com/darkrenaissance/darkfi"
 license = "AGPL-3.0-only"
 license = "AGPL-3.0-only"
 edition = "2021"
 edition = "2021"
 
 
+# ANCHOR: darkfi
 [dependencies]
 [dependencies]
 darkfi = {path = "../../", features = ["net", "rpc"]}
 darkfi = {path = "../../", features = ["net", "rpc"]}
 darkfi-serial = {path = "../../src/serial"}
 darkfi-serial = {path = "../../src/serial"}
+# ANCHOR_END: darkfi
 
 
+# ANCHOR: dependencies
 async-std = "1.12.0"
 async-std = "1.12.0"
 async-trait = "0.1.57"
 async-trait = "0.1.57"
 easy-parallel = "3.2.0"
 easy-parallel = "3.2.0"
@@ -25,3 +28,4 @@ url = "2.3.1"
 serde_json = "1.0.85"
 serde_json = "1.0.85"
 serde = {version = "1.0.145", features = ["derive"]}
 serde = {version = "1.0.145", features = ["derive"]}
 toml = "0.5.9"
 toml = "0.5.9"
+# ANCHOR_END: dependencies

+ 2 - 0
example/dchat/src/dchat_error.rs

@@ -1,3 +1,4 @@
+// ANCHOR: error
 use std::{error, fmt};
 use std::{error, fmt};
 
 
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
@@ -10,3 +11,4 @@ impl fmt::Display for ErrorMissingSpecifier {
 }
 }
 
 
 impl error::Error for ErrorMissingSpecifier {}
 impl error::Error for ErrorMissingSpecifier {}
+// ANCHOR_END: error

+ 2 - 0
example/dchat/src/dchatmsg.rs

@@ -1,3 +1,4 @@
+// ANCHOR: msg
 use async_std::sync::{Arc, Mutex};
 use async_std::sync::{Arc, Mutex};
 
 
 use darkfi::net;
 use darkfi::net;
@@ -15,3 +16,4 @@ impl net::Message for DchatMsg {
 pub struct DchatMsg {
 pub struct DchatMsg {
     pub msg: String,
     pub msg: String,
 }
 }
+// ANCHOR_END: msg

+ 28 - 4
example/dchat/src/main.rs

@@ -1,10 +1,12 @@
 use std::{error, fs::File, io::stdin};
 use std::{error, fs::File, io::stdin};
 
 
+// ANCHOR: daemon_deps
 use async_std::sync::{Arc, Mutex};
 use async_std::sync::{Arc, Mutex};
 use easy_parallel::Parallel;
 use easy_parallel::Parallel;
+use smol::Executor;
+// ANCHOR_END: daemon_deps
 use log::debug;
 use log::debug;
 use simplelog::WriteLogger;
 use simplelog::WriteLogger;
-use smol::Executor;
 use url::Url;
 use url::Url;
 
 
 use darkfi::{net, net::Settings, rpc::server::listen_and_serve};
 use darkfi::{net, net::Settings, rpc::server::listen_and_serve};
@@ -21,19 +23,24 @@ pub mod dchatmsg;
 pub mod protocol_dchat;
 pub mod protocol_dchat;
 pub mod rpc;
 pub mod rpc;
 
 
+// ANCHOR: error
 pub type Error = Box<dyn error::Error>;
 pub type Error = Box<dyn error::Error>;
 pub type Result<T> = std::result::Result<T, Error>;
 pub type Result<T> = std::result::Result<T, Error>;
+// ANCHOR_END: error
 
 
+// ANCHOR: dchat
 struct Dchat {
 struct Dchat {
     p2p: net::P2pPtr,
     p2p: net::P2pPtr,
     recv_msgs: DchatMsgsBuffer,
     recv_msgs: DchatMsgsBuffer,
 }
 }
+// ANCHOR_END: dchat
 
 
 impl Dchat {
 impl Dchat {
     fn new(p2p: net::P2pPtr, recv_msgs: DchatMsgsBuffer) -> Self {
     fn new(p2p: net::P2pPtr, recv_msgs: DchatMsgsBuffer) -> Self {
         Self { p2p, recv_msgs }
         Self { p2p, recv_msgs }
     }
     }
 
 
+    // ANCHOR: menu
     async fn menu(&self) -> Result<()> {
     async fn menu(&self) -> Result<()> {
         let mut buffer = String::new();
         let mut buffer = String::new();
         let stdin = stdin();
         let stdin = stdin();
@@ -81,7 +88,9 @@ impl Dchat {
             }
             }
         }
         }
     }
     }
+    // ANCHOR_END: menu
 
 
+    // ANCHOR: register_protocol
     async fn register_protocol(&self, msgs: DchatMsgsBuffer) -> Result<()> {
     async fn register_protocol(&self, msgs: DchatMsgsBuffer) -> Result<()> {
         debug!(target: "dchat", "Dchat::register_protocol() [START]");
         debug!(target: "dchat", "Dchat::register_protocol() [START]");
         let registry = self.p2p.protocol_registry();
         let registry = self.p2p.protocol_registry();
@@ -94,7 +103,9 @@ impl Dchat {
         debug!(target: "dchat", "Dchat::register_protocol() [STOP]");
         debug!(target: "dchat", "Dchat::register_protocol() [STOP]");
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: register_protocol
 
 
+    // ANCHOR: start
     async fn start(&mut self, ex: Arc<Executor<'_>>) -> Result<()> {
     async fn start(&mut self, ex: Arc<Executor<'_>>) -> Result<()> {
         debug!(target: "dchat", "Dchat::start() [START]");
         debug!(target: "dchat", "Dchat::start() [START]");
 
 
@@ -111,14 +122,18 @@ impl Dchat {
         debug!(target: "dchat", "Dchat::start() [STOP]");
         debug!(target: "dchat", "Dchat::start() [STOP]");
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: start
 
 
+    // ANCHOR: send
     async fn send(&self, msg: String) -> Result<()> {
     async fn send(&self, msg: String) -> Result<()> {
         let dchatmsg = DchatMsg { msg };
         let dchatmsg = DchatMsg { msg };
         self.p2p.broadcast(dchatmsg).await?;
         self.p2p.broadcast(dchatmsg).await?;
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: send
 }
 }
 
 
+// ANCHOR: app_settings
 #[derive(Clone, Debug)]
 #[derive(Clone, Debug)]
 struct AppSettings {
 struct AppSettings {
     accept_addr: Url,
     accept_addr: Url,
@@ -130,7 +145,9 @@ impl AppSettings {
         Self { accept_addr, net }
         Self { accept_addr, net }
     }
     }
 }
 }
+// ANCHOR_END: app_settings
 
 
+// ANCHOR: alice
 fn alice() -> Result<AppSettings> {
 fn alice() -> Result<AppSettings> {
     let log_level = simplelog::LevelFilter::Debug;
     let log_level = simplelog::LevelFilter::Debug;
     let log_config = simplelog::Config::default();
     let log_config = simplelog::Config::default();
@@ -156,7 +173,9 @@ fn alice() -> Result<AppSettings> {
 
 
     Ok(settings)
     Ok(settings)
 }
 }
+// ANCHOR_END: alice
 
 
+// ANCHOR: bob
 fn bob() -> Result<AppSettings> {
 fn bob() -> Result<AppSettings> {
     let log_level = simplelog::LevelFilter::Debug;
     let log_level = simplelog::LevelFilter::Debug;
     let log_config = simplelog::Config::default();
     let log_config = simplelog::Config::default();
@@ -180,7 +199,9 @@ fn bob() -> Result<AppSettings> {
 
 
     Ok(settings)
     Ok(settings)
 }
 }
+// ANCHOR_END: bob
 
 
+// ANCHOR: main
 #[async_std::main]
 #[async_std::main]
 async fn main() -> Result<()> {
 async fn main() -> Result<()> {
     let settings: Result<AppSettings> = match std::env::args().nth(1) {
     let settings: Result<AppSettings> = match std::env::args().nth(1) {
@@ -196,9 +217,6 @@ async fn main() -> Result<()> {
 
 
     let p2p = net::P2p::new(settings.net).await;
     let p2p = net::P2p::new(settings.net).await;
 
 
-    let nthreads = num_cpus::get();
-    let (signal, shutdown) = smol::channel::unbounded::<()>();
-
     let ex = Arc::new(Executor::new());
     let ex = Arc::new(Executor::new());
     let ex2 = ex.clone();
     let ex2 = ex.clone();
     let ex3 = ex2.clone();
     let ex3 = ex2.clone();
@@ -207,9 +225,14 @@ async fn main() -> Result<()> {
 
 
     let mut dchat = Dchat::new(p2p.clone(), msgs);
     let mut dchat = Dchat::new(p2p.clone(), msgs);
 
 
+    // ANCHOR: json_init
     let accept_addr = settings.accept_addr.clone();
     let accept_addr = settings.accept_addr.clone();
     let rpc = Arc::new(JsonRpcInterface { addr: accept_addr.clone(), p2p });
     let rpc = Arc::new(JsonRpcInterface { addr: accept_addr.clone(), p2p });
     ex.spawn(async move { listen_and_serve(accept_addr.clone(), rpc).await }).detach();
     ex.spawn(async move { listen_and_serve(accept_addr.clone(), rpc).await }).detach();
+    // ANCHOR_END: json_init
+
+    let nthreads = num_cpus::get();
+    let (signal, shutdown) = smol::channel::unbounded::<()>();
 
 
     let (_, result) = Parallel::new()
     let (_, result) = Parallel::new()
         .each(0..nthreads, |_| smol::future::block_on(ex2.run(shutdown.recv())))
         .each(0..nthreads, |_| smol::future::block_on(ex2.run(shutdown.recv())))
@@ -223,3 +246,4 @@ async fn main() -> Result<()> {
 
 
     result
     result
 }
 }
+// ANCHOR_END: main

+ 8 - 0
example/dchat/src/protocol_dchat.rs

@@ -1,3 +1,4 @@
+// ANCHOR: protocol_dchat
 use async_std::sync::Arc;
 use async_std::sync::Arc;
 use async_trait::async_trait;
 use async_trait::async_trait;
 use darkfi::{net, Result};
 use darkfi::{net, Result};
@@ -11,7 +12,9 @@ pub struct ProtocolDchat {
     msg_sub: net::MessageSubscription<DchatMsg>,
     msg_sub: net::MessageSubscription<DchatMsg>,
     msgs: DchatMsgsBuffer,
     msgs: DchatMsgsBuffer,
 }
 }
+// ANCHOR_END: protocol_dchat
 
 
+// ANCHOR: constructor
 impl ProtocolDchat {
 impl ProtocolDchat {
     pub async fn init(channel: net::ChannelPtr, msgs: DchatMsgsBuffer) -> net::ProtocolBasePtr {
     pub async fn init(channel: net::ChannelPtr, msgs: DchatMsgsBuffer) -> net::ProtocolBasePtr {
         debug!(target: "dchat", "ProtocolDchat::init() [START]");
         debug!(target: "dchat", "ProtocolDchat::init() [START]");
@@ -27,7 +30,9 @@ impl ProtocolDchat {
             msgs,
             msgs,
         })
         })
     }
     }
+    // ANCHOR_END: constructor
 
 
+    // ANCHOR: receive
     async fn handle_receive_msg(self: Arc<Self>) -> Result<()> {
     async fn handle_receive_msg(self: Arc<Self>) -> Result<()> {
         debug!(target: "dchat", "ProtocolDchat::handle_receive_msg() [START]");
         debug!(target: "dchat", "ProtocolDchat::handle_receive_msg() [START]");
         while let Ok(msg) = self.msg_sub.receive().await {
         while let Ok(msg) = self.msg_sub.receive().await {
@@ -37,10 +42,12 @@ impl ProtocolDchat {
 
 
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: receive
 }
 }
 
 
 #[async_trait]
 #[async_trait]
 impl net::ProtocolBase for ProtocolDchat {
 impl net::ProtocolBase for ProtocolDchat {
+    // ANCHOR: start
     async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
     async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
         debug!(target: "dchat", "ProtocolDchat::ProtocolBase::start() [START]");
         debug!(target: "dchat", "ProtocolDchat::ProtocolBase::start() [START]");
         self.jobsman.clone().start(executor.clone());
         self.jobsman.clone().start(executor.clone());
@@ -48,6 +55,7 @@ impl net::ProtocolBase for ProtocolDchat {
         debug!(target: "dchat", "ProtocolDchat::ProtocolBase::start() [STOP]");
         debug!(target: "dchat", "ProtocolDchat::ProtocolBase::start() [STOP]");
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: start
 
 
     fn name(&self) -> &'static str {
     fn name(&self) -> &'static str {
         "ProtocolDchat"
         "ProtocolDchat"

+ 8 - 0
example/dchat/src/rpc.rs

@@ -11,10 +11,12 @@ use darkfi::{
     },
     },
 };
 };
 
 
+// ANCHOR: jsonrpc
 pub struct JsonRpcInterface {
 pub struct JsonRpcInterface {
     pub addr: Url,
     pub addr: Url,
     pub p2p: net::P2pPtr,
     pub p2p: net::P2pPtr,
 }
 }
+// ANCHOR_END: jsonrpc
 
 
 #[async_trait]
 #[async_trait]
 impl RequestHandler for JsonRpcInterface {
 impl RequestHandler for JsonRpcInterface {
@@ -25,11 +27,13 @@ impl RequestHandler for JsonRpcInterface {
 
 
         debug!(target: "RPC", "--> {}", serde_json::to_string(&req).unwrap());
         debug!(target: "RPC", "--> {}", serde_json::to_string(&req).unwrap());
 
 
+        // ANCHOR: req_match
         match req.method.as_str() {
         match req.method.as_str() {
             Some("ping") => self.pong(req.id, req.params).await,
             Some("ping") => self.pong(req.id, req.params).await,
             Some("get_info") => self.get_info(req.id, req.params).await,
             Some("get_info") => self.get_info(req.id, req.params).await,
             Some(_) | None => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
             Some(_) | None => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
         }
         }
+        // ANCHOR_END: req_match
     }
     }
 }
 }
 
 
@@ -38,16 +42,20 @@ impl JsonRpcInterface {
     // Replies to a ping method.
     // Replies to a ping method.
     // --> {"jsonrpc": "2.0", "method": "ping", "params": [], "id": 42}
     // --> {"jsonrpc": "2.0", "method": "ping", "params": [], "id": 42}
     // <-- {"jsonrpc": "2.0", "result": "pong", "id": 42}
     // <-- {"jsonrpc": "2.0", "result": "pong", "id": 42}
+    // ANCHOR: pong
     async fn pong(&self, id: Value, _params: Value) -> JsonResult {
     async fn pong(&self, id: Value, _params: Value) -> JsonResult {
         JsonResponse::new(json!("pong"), id).into()
         JsonResponse::new(json!("pong"), id).into()
     }
     }
+    // ANCHOR_END: pong
 
 
     // RPCAPI:
     // RPCAPI:
     // Retrieves P2P network information.
     // Retrieves P2P network information.
     // --> {"jsonrpc": "2.0", "method": "get_info", "params": [], "id": 42}
     // --> {"jsonrpc": "2.0", "method": "get_info", "params": [], "id": 42}
     // <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
     // <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
+    // ANCHOR: get_info
     async fn get_info(&self, id: Value, _params: Value) -> JsonResult {
     async fn get_info(&self, id: Value, _params: Value) -> JsonResult {
         let resp = self.p2p.get_info().await;
         let resp = self.p2p.get_info().await;
         JsonResponse::new(resp, id).into()
         JsonResponse::new(resp, id).into()
     }
     }
+    // ANCHOR_END: get_info
 }
 }

+ 1 - 1
src/consensus/ouroboros/consts.rs

@@ -3,4 +3,4 @@ pub(crate) const LOG_T: &str = "stakeholder";
 pub(crate) const TREE_LEN: usize = 100;
 pub(crate) const TREE_LEN: usize = 100;
 pub(crate) const P: &str =
 pub(crate) const P: &str =
     "28948022309329048855892746252171976963363056481941560715954676764349967630337";
     "28948022309329048855892746252171976963363056481941560715954676764349967630337";
-pub(crate) const LOTTERY_HEAD_START : u64 = 1;
+pub(crate) const LOTTERY_HEAD_START: u64 = 1;

+ 26 - 20
src/consensus/ouroboros/epoch.rs

@@ -1,18 +1,8 @@
-use darkfi_sdk::crypto::{constants::MERKLE_DEPTH_ORCHARD, MerkleNode};
-use halo2_gadgets::poseidon::primitives as poseidon;
-use halo2_proofs::arithmetic::Field;
-use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
-use log::info;
-use pasta_curves::{
-    arithmetic::CurveAffine,
-    group::{ff::PrimeField, Curve},
-    pallas,
-};
-use rand::{thread_rng, Rng};
 use crate::{
 use crate::{
     consensus::ouroboros::{
     consensus::ouroboros::{
-        consts::{LOTTERY_HEAD_START},
-        EpochConsensus,
+        consts::{LOTTERY_HEAD_START, RADIX_BITS},
+        utils::{base2ibig, fbig2ibig},
+        EpochConsensus, Float10,
     },
     },
     crypto::{
     crypto::{
         coin::OwnCoin,
         coin::OwnCoin,
@@ -24,6 +14,17 @@ use crate::{
         util::{mod_r_p, pedersen_commitment_base, pedersen_commitment_u64},
         util::{mod_r_p, pedersen_commitment_base, pedersen_commitment_u64},
     },
     },
 };
 };
+use darkfi_sdk::crypto::{constants::MERKLE_DEPTH_ORCHARD, MerkleNode};
+use halo2_gadgets::poseidon::primitives as poseidon;
+use halo2_proofs::arithmetic::Field;
+use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
+use log::info;
+use pasta_curves::{
+    arithmetic::CurveAffine,
+    group::{ff::PrimeField, Curve},
+    pallas,
+};
+use rand::{thread_rng, Rng};
 
 
 const PRF_NULLIFIER_PREFIX: u64 = 0;
 const PRF_NULLIFIER_PREFIX: u64 = 0;
 const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
 const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
@@ -109,7 +110,9 @@ impl Epoch {
             let sk_y = *coord.y();
             let sk_y = *coord.y();
             let sk_coord_ar = [sk_x, sk_y];
             let sk_coord_ar = [sk_x, sk_y];
             let sk_base: pallas::Base =
             let sk_base: pallas::Base =
-                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(sk_coord_ar);
+                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+                )
+                .hash(sk_coord_ar);
             sks.push(SecretKey::from(sk_base));
             sks.push(SecretKey::from(sk_base));
             prev_sk_base = sk_base;
             prev_sk_base = sk_base;
             let sk_bytes = sk_base.to_repr();
             let sk_bytes = sk_base.to_repr();
@@ -295,9 +298,10 @@ impl Epoch {
         for (winning_idx, coin) in competing_coins.iter().enumerate() {
         for (winning_idx, coin) in competing_coins.iter().enumerate() {
             let y_exp = [coin.root_sk.unwrap(), coin.nonce.unwrap()];
             let y_exp = [coin.root_sk.unwrap(), coin.nonce.unwrap()];
             let y_exp_hash: pallas::Base =
             let y_exp_hash: pallas::Base =
-                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(y_exp);
-            let y_coordinates =
-                pedersen_commitment_base(coin.y_mu.unwrap(), mod_r_p(y_exp_hash))
+                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+                )
+                .hash(y_exp);
+            let y_coordinates = pedersen_commitment_base(coin.y_mu.unwrap(), mod_r_p(y_exp_hash))
                 .to_affine()
                 .to_affine()
                 .coordinates()
                 .coordinates()
                 .unwrap();
                 .unwrap();
@@ -306,11 +310,13 @@ impl Epoch {
             let y_y: pallas::Base = *y_coordinates.y();
             let y_y: pallas::Base = *y_coordinates.y();
             let y_coord_arr = [y_x, y_y];
             let y_coord_arr = [y_x, y_y];
             let y: pallas::Base =
             let y: pallas::Base =
-                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(y_coord_arr);
+                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+                )
+                .hash(y_coord_arr);
             //
             //
             let val_base = pallas::Base::from(coin.value.unwrap());
             let val_base = pallas::Base::from(coin.value.unwrap());
-            let target_base = coin.sigma1.unwrap() * val_base +
-                coin.sigma2.unwrap() * val_base * val_base;
+            let target_base =
+                coin.sigma1.unwrap() * val_base + coin.sigma2.unwrap() * val_base * val_base;
             info!("y: {:?}", y);
             info!("y: {:?}", y);
             info!("T: {:?}", target_base);
             info!("T: {:?}", target_base);
             let iam_leader = y < target_base;
             let iam_leader = y < target_base;

+ 1 - 1
src/consensus/ouroboros/mod.rs

@@ -1,7 +1,7 @@
 pub mod consts;
 pub mod consts;
+pub mod epochconsensus;
 pub mod types;
 pub mod types;
 pub mod utils;
 pub mod utils;
-pub mod epochconsensus;
 pub use epochconsensus::EpochConsensus;
 pub use epochconsensus::EpochConsensus;
 pub mod epoch;
 pub mod epoch;
 pub use epoch::Epoch;
 pub use epoch::Epoch;

+ 14 - 15
src/consensus/ouroboros/stakeholder.rs

@@ -1,13 +1,3 @@
-use std::{fmt, thread, time::Duration};
-use async_std::sync::Arc;
-use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode};
-use halo2_proofs::arithmetic::Field;
-use smol::Executor;
-use rand::rngs::OsRng;
-use incrementalmerkletree::bridgetree::BridgeTree;
-use log::{error, info};
-use pasta_curves::{group::ff::PrimeField, pallas};
-use url::Url;
 use crate::{
 use crate::{
     blockchain::Blockchain,
     blockchain::Blockchain,
     consensus::{
     consensus::{
@@ -16,7 +6,7 @@ use crate::{
             consts::{LOG_T, P, RADIX_BITS, TREE_LEN},
             consts::{LOG_T, P, RADIX_BITS, TREE_LEN},
             types::Float10,
             types::Float10,
             utils::fbig2base,
             utils::fbig2base,
-            EpochConsensus,Epoch, SlotWorkspace, StakeholderState,
+            Epoch, EpochConsensus, SlotWorkspace, StakeholderState,
         },
         },
         Block, BlockInfo, LeadProof, Metadata,
         Block, BlockInfo, LeadProof, Metadata,
     },
     },
@@ -40,6 +30,16 @@ use crate::{
     zk::circuit::{BurnContract, LeadContract, MintContract},
     zk::circuit::{BurnContract, LeadContract, MintContract},
     Result,
     Result,
 };
 };
+use async_std::sync::Arc;
+use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode};
+use halo2_proofs::arithmetic::Field;
+use incrementalmerkletree::bridgetree::BridgeTree;
+use log::{error, info};
+use pasta_curves::{group::ff::PrimeField, pallas};
+use rand::rngs::OsRng;
+use smol::Executor;
+use std::{fmt, thread, time::Duration};
+use url::Url;
 
 
 pub struct Stakeholder {
 pub struct Stakeholder {
     pub blockchain: Blockchain, // stakeholder view of the blockchain
     pub blockchain: Blockchain, // stakeholder view of the blockchain
@@ -324,9 +324,7 @@ impl Stakeholder {
         // let epoch_len = self.epoch_consensus.get_epoch_len();
         // let epoch_len = self.epoch_consensus.get_epoch_len();
         // let abs_sl = rel_sl + epochs * epoch_len;
         // let abs_sl = rel_sl + epochs * epoch_len;
         //
         //
-        let f = self.get_f()
-            .with_precision(RADIX_BITS)
-            .value();
+        let f = self.get_f().with_precision(RADIX_BITS).value();
         let total_stake = self.epoch.consensus.total_stake(e, sl);
         let total_stake = self.epoch.consensus.total_stake(e, sl);
         let one: Float10 =
         let one: Float10 =
             Float10::from_str_native("1").unwrap().with_precision(RADIX_BITS).value();
             Float10::from_str_native("1").unwrap().with_precision(RADIX_BITS).value();
@@ -345,7 +343,8 @@ impl Stakeholder {
 
 
         let sigma1: pallas::Base = fbig2base(sigma1_fbig);
         let sigma1: pallas::Base = fbig2base(sigma1_fbig);
         info!("sigma1 base: {:?}", sigma1);
         info!("sigma1 base: {:?}", sigma1);
-        let sigma2_fbig = (c.clone() / total_sigma.clone()).powf(two.clone()) * (field_p.clone() / two.clone());
+        let sigma2_fbig =
+            (c.clone() / total_sigma.clone()).powf(two.clone()) * (field_p.clone() / two.clone());
         info!("sigma2: {}", sigma2_fbig);
         info!("sigma2: {}", sigma2_fbig);
         let sigma2: pallas::Base = fbig2base(sigma2_fbig);
         let sigma2: pallas::Base = fbig2base(sigma2_fbig);
         info!("sigma2 base: {:?}", sigma2);
         info!("sigma2 base: {:?}", sigma2);

+ 4 - 8
src/consensus/ouroboros/utils.rs

@@ -1,7 +1,7 @@
-use dashu::integer::{IBig, Sign};
-use log::{info,debug};
-use pasta_curves::{pallas};
 use crate::consensus::ouroboros::types::Float10;
 use crate::consensus::ouroboros::types::Float10;
+use dashu::integer::{IBig, Sign};
+use log::{debug, info};
+use pasta_curves::pallas;
 //use pasta_curves::{group::ff::PrimeField};
 //use pasta_curves::{group::ff::PrimeField};
 //use dashu::integer::{UBig};
 //use dashu::integer::{UBig};
 
 
@@ -9,11 +9,7 @@ pub(crate) fn fbig2ibig(f: Float10) -> IBig {
     let rad = IBig::try_from(10).unwrap();
     let rad = IBig::try_from(10).unwrap();
     let sig = f.repr().significand();
     let sig = f.repr().significand();
     let exp = f.repr().exponent();
     let exp = f.repr().exponent();
-    let val: IBig = if exp >= 0 {
-        sig.clone() * rad.pow(exp as usize)
-    } else {
-        sig.clone()
-    };
+    let val: IBig = if exp >= 0 { sig.clone() * rad.pow(exp as usize) } else { sig.clone() };
     debug!("fbig2ibig (f): {}", f);
     debug!("fbig2ibig (f): {}", f);
     debug!("fbig2ibig (i): {}", val);
     debug!("fbig2ibig (i): {}", val);
     val
     val

+ 0 - 1
src/crypto/leadcoin.rs

@@ -12,7 +12,6 @@ use crate::{
     zk::circuit::lead_contract::LeadContract,
     zk::circuit::lead_contract::LeadContract,
 };
 };
 
 
-
 pub const LEAD_PUBLIC_INPUT_LEN: usize = 11;
 pub const LEAD_PUBLIC_INPUT_LEN: usize = 11;
 
 
 #[derive(Debug, Default, Clone, Copy)]
 #[derive(Debug, Default, Clone, Copy)]

+ 2 - 0
src/net/channel.rs

@@ -49,6 +49,7 @@ impl ChannelInfo {
         }
         }
     }
     }
 
 
+    // ANCHOR: get_info
     async fn get_info(&self) -> serde_json::Value {
     async fn get_info(&self) -> serde_json::Value {
         let log = match &self.log {
         let log = match &self.log {
             Some(l) => {
             Some(l) => {
@@ -68,6 +69,7 @@ impl ChannelInfo {
             "log": log,
             "log": log,
         })
         })
     }
     }
+    // ANCHOR_END: get_info
 }
 }
 
 
 /// Async channel for communication between nodes.
 /// Async channel for communication between nodes.

+ 10 - 0
src/net/p2p.rs

@@ -115,6 +115,7 @@ impl P2p {
         self_
         self_
     }
     }
 
 
+    // ANCHOR: get_info
     pub async fn get_info(&self) -> serde_json::Value {
     pub async fn get_info(&self) -> serde_json::Value {
         // Building ext_addr_vec string
         // Building ext_addr_vec string
         let mut ext_addr_vec = vec![];
         let mut ext_addr_vec = vec![];
@@ -130,8 +131,10 @@ impl P2p {
             "state": self.state.lock().await.to_string(),
             "state": self.state.lock().await.to_string(),
         })
         })
     }
     }
+    // ANCHOR_END: get_info
 
 
     /// Invoke startup and seeding sequence. Call from constructing thread.
     /// Invoke startup and seeding sequence. Call from constructing thread.
+    // ANCHOR: start
     pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
     pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
         debug!(target: "net", "P2p::start() [BEGIN]");
         debug!(target: "net", "P2p::start() [BEGIN]");
 
 
@@ -147,6 +150,7 @@ impl P2p {
         debug!(target: "net", "P2p::start() [END]");
         debug!(target: "net", "P2p::start() [END]");
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: start
 
 
     pub async fn session_manual(&self) -> Arc<ManualSession> {
     pub async fn session_manual(&self) -> Arc<ManualSession> {
         self.session_manual.lock().await.as_ref().unwrap().clone()
         self.session_manual.lock().await.as_ref().unwrap().clone()
@@ -160,6 +164,7 @@ impl P2p {
 
 
     /// Runs the network. Starts inbound, outbound and manual sessions.
     /// Runs the network. Starts inbound, outbound and manual sessions.
     /// Waits for a stop signal and stops the network if received.
     /// Waits for a stop signal and stops the network if received.
+    // ANCHOR: run
     pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
     pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
         debug!(target: "net", "P2p::run() [BEGIN]");
         debug!(target: "net", "P2p::run() [BEGIN]");
 
 
@@ -188,6 +193,7 @@ impl P2p {
         debug!(target: "net", "P2p::run() [END]");
         debug!(target: "net", "P2p::run() [END]");
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: run
 
 
     /// Wait for outbound connections to be established.
     /// Wait for outbound connections to be established.
     pub async fn wait_for_outbound(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
     pub async fn wait_for_outbound(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
@@ -303,11 +309,14 @@ impl P2p {
         Ok(())
         Ok(())
     }
     }
 
 
+    // ANCHOR: stop
     pub async fn stop(&self) {
     pub async fn stop(&self) {
         self.stop_subscriber.notify(()).await
         self.stop_subscriber.notify(()).await
     }
     }
+    // ANCHOR_END: stop
 
 
     /// Broadcasts a message concurrently across all channels.
     /// Broadcasts a message concurrently across all channels.
+    // ANCHOR: broadcast
     pub async fn broadcast<M: Message + Clone>(&self, message: M) -> Result<()> {
     pub async fn broadcast<M: Message + Clone>(&self, message: M) -> Result<()> {
         let chans = self.channels.lock().await;
         let chans = self.channels.lock().await;
         let iter = chans.values();
         let iter = chans.values();
@@ -336,6 +345,7 @@ impl P2p {
 
 
         Ok(())
         Ok(())
     }
     }
+    // ANCHOR_END: broadcast
 
 
     /// Broadcasts a message concurrently across all channels.
     /// Broadcasts a message concurrently across all channels.
     /// Excludes channels provided in `exclude_list`.
     /// Excludes channels provided in `exclude_list`.

+ 4 - 0
src/rpc/jsonrpc.rs

@@ -46,6 +46,7 @@ impl ErrorCode {
 }
 }
 
 
 /// Wrapping enum around the possible JSON-RPC object types.
 /// Wrapping enum around the possible JSON-RPC object types.
+// ANCHOR: jsonresult
 #[derive(Clone, Debug, Serialize, Deserialize)]
 #[derive(Clone, Debug, Serialize, Deserialize)]
 #[serde(untagged)]
 #[serde(untagged)]
 pub enum JsonResult {
 pub enum JsonResult {
@@ -53,6 +54,7 @@ pub enum JsonResult {
     Error(JsonError),
     Error(JsonError),
     Notification(JsonNotification),
     Notification(JsonNotification),
 }
 }
+// ANCHOR_END: jsonresult
 
 
 impl From<JsonResponse> for JsonResult {
 impl From<JsonResponse> for JsonResult {
     fn from(resp: JsonResponse) -> Self {
     fn from(resp: JsonResponse) -> Self {
@@ -73,6 +75,7 @@ impl From<JsonNotification> for JsonResult {
 }
 }
 
 
 /// A JSON-RPC request object.
 /// A JSON-RPC request object.
+// ANCHOR: jsonrequest
 #[derive(Clone, Debug, Serialize, Deserialize)]
 #[derive(Clone, Debug, Serialize, Deserialize)]
 pub struct JsonRequest {
 pub struct JsonRequest {
     /// JSON-RPC version
     /// JSON-RPC version
@@ -84,6 +87,7 @@ pub struct JsonRequest {
     /// Request parameters
     /// Request parameters
     pub params: Value,
     pub params: Value,
 }
 }
+// ANCHOR_END: jsonrequest
 
 
 impl JsonRequest {
 impl JsonRequest {
     pub fn new(method: &str, parameters: Value) -> Self {
     pub fn new(method: &str, parameters: Value) -> Self {

+ 4 - 4
src/zk/circuit/lead_contract.rs

@@ -474,7 +474,7 @@ impl Circuit<pallas::Base> for LeadContract {
                     coin_pk_y.clone(),
                     coin_pk_y.clone(),
                     coin_value.clone(),
                     coin_value.clone(),
                     coin2_nonce.clone(),
                     coin2_nonce.clone(),
-                    one.clone()
+                    one.clone(),
                 ];
                 ];
                 let poseidon_hasher = PoseidonHash::<
                 let poseidon_hasher = PoseidonHash::<
                     _,
                     _,
@@ -577,16 +577,16 @@ impl Circuit<pallas::Base> for LeadContract {
         let y_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         let y_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         let y_commit_base_y = y_commit.inner().x();
         let y_commit_base_y = y_commit.inner().x();
         let y_commit_base_x = y_commit.inner().x();
         let y_commit_base_x = y_commit.inner().x();
-        let y_commit_base : AssignedCell<Fp, Fp> = {
+        let y_commit_base: AssignedCell<Fp, Fp> = {
             let y_coord = [y_commit_base_y, y_commit_base_x];
             let y_coord = [y_commit_base_y, y_commit_base_x];
             let poseidon_hasher = PoseidonHash::<
             let poseidon_hasher = PoseidonHash::<
-                    _,
+                _,
                 _,
                 _,
                 poseidon::P128Pow5T3,
                 poseidon::P128Pow5T3,
                 poseidon::ConstantLength<2>,
                 poseidon::ConstantLength<2>,
                 3,
                 3,
                 2,
                 2,
-                >::init(
+            >::init(
                 config.poseidon_chip(), layouter.namespace(|| "Poseidon init")
                 config.poseidon_chip(), layouter.namespace(|| "Poseidon init")
             )?;
             )?;