Przeglądaj źródła

Merge branch 'master' into asset-id

Nym 5 lat temu
rodzic
commit
26290ac290

+ 4 - 4
Cargo.toml

@@ -84,10 +84,6 @@ path = "lisp/lisp.rs"
 name = "zkvm"
 path = "src/bin/zkvm.rs"
 
-[[bin]]
-name = "dfi"
-path = "src/bin/dfi.rs"
-
 [[bin]]
 name = "mimc"
 path = "src/old/mimc.rs"
@@ -112,6 +108,10 @@ path = "src/bin/gatewayd.rs"
 name = "darkfid"
 path = "src/bin/darkfid.rs"
 
+[[bin]]
+name = "cashier"
+path = "src/bin/cashier.rs"
+
 [profile.release]
 debug = 1
 

+ 22 - 0
examples/halo2/Cargo.toml

@@ -0,0 +1,22 @@
+[package]
+name = "halo2-examples"
+version = "0.1.0"
+authors = ["narodnik <x@x.org>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+group = "0.10"
+
+[dependencies.halo2]
+git = "https://github.com/zcash/halo2.git"
+rev = "93aabf26c67fcc7a1d5439c350afcf00f1399aa5"
+
+[[bin]]
+name = "simple3"
+path = "simple3.rs"
+
+[[bin]]
+name = "simple4"
+path = "simple4.rs"

+ 6 - 0
examples/halo2/README.md

@@ -0,0 +1,6 @@
+Always use the --release flag otherwise it's too slow:
+
+```
+cargo run --release --bin simple3
+```
+

+ 130 - 0
examples/halo2/simple3.rs

@@ -0,0 +1,130 @@
+use halo2::{
+    circuit::{SimpleFloorPlanner, Chip, Layouter},
+    pasta::{EqAffine, Fp},
+    plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Expression, Selector, create_proof, verify_proof, keygen_vk, keygen_pk},
+    poly::{commitment::Params, Rotation},
+    transcript::{Blake2bRead, Blake2bWrite, Challenge255},
+};
+use std::time::Instant;
+
+#[derive(Clone, Debug)]
+struct CoolConfig {
+    a_col: Column<Advice>,
+    s_range: Selector,
+}
+
+struct CoolChip {
+    config: CoolConfig
+}
+
+impl Chip<Fp> for CoolChip {
+    type Config = CoolConfig;
+    type Loaded = ();
+
+    fn config(&self) -> &Self::Config {
+        &self.config
+    }
+
+    fn loaded(&self) -> &Self::Loaded {
+        &()
+    }
+}
+
+impl CoolChip {
+    fn construct(config: CoolConfig) -> Self {
+        Self { config }
+    }
+
+    fn configure(cs: &mut ConstraintSystem<Fp>) -> CoolConfig {
+        let a_col = cs.advice_column();
+        let s_range = cs.selector();
+
+        cs.create_gate("check", |cs| {
+            let a = cs.query_advice(a_col, Rotation::cur());
+            let s_range = cs.query_selector(s_range);
+            vec![s_range * (a - Expression::Constant(Fp::from(2)))]
+        });
+
+        CoolConfig { a_col, s_range }
+    }
+
+    fn alloc_and_check(
+        &self,
+        layouter: &mut impl Layouter<Fp>,
+        a: Option<Fp>,
+    ) -> Result<(), Error> {
+        layouter.assign_region(
+            || "load private inputs",
+            |mut region| {
+                let row_offset = 0;
+                self.config.s_range.enable(&mut region, row_offset)?;
+                region.assign_advice(
+                    || "private input 'a'",
+                    self.config.a_col,
+                    row_offset,
+                    || a.ok_or(Error::SynthesisError),
+                )?;
+                Ok(())
+            },
+        )
+    }
+}
+
+#[derive(Clone)]
+struct CoolCircuit {
+    // Private input.
+    a: Option<Fp>,
+}
+
+impl Circuit<Fp> for CoolCircuit {
+    type Config = CoolConfig;
+    type FloorPlanner = SimpleFloorPlanner;
+
+    fn without_witnesses(&self) -> Self {
+        Self { a: None }
+    }
+
+    fn configure(cs: &mut ConstraintSystem<Fp>) -> Self::Config {
+        CoolChip::configure(cs)
+    }
+
+    fn synthesize(&self, config: Self::Config, mut layouter: impl Layouter<Fp>) -> Result<(), Error> {
+        let chip = CoolChip::construct(config);
+        chip.alloc_and_check(&mut layouter, self.a)
+    }
+}
+
+fn main() {
+    let start = Instant::now();
+    let params: Params<EqAffine> = Params::new(4);
+
+    let empty_circuit = CoolCircuit { a: None };
+    let vk = keygen_vk(&params, &empty_circuit).expect("keygen_vk should not fail");
+    let pk = keygen_pk(&params, vk, &empty_circuit).expect("keygen_pk should not fail");
+    println!("Setup: [{:?}]", start.elapsed());
+
+    let start = Instant::now();
+    let circuit = CoolCircuit {
+        a: Some(Fp::from(2)),
+    };
+
+    // Create a proof
+    let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
+    create_proof(&params, &pk, &[circuit], &[&[]], &mut transcript)
+        .expect("proof generation should not fail");
+    let proof = transcript.finalize();
+    println!("Prove: [{:?}]", start.elapsed());
+
+    let start = Instant::now();
+    let msm = params.empty_msm();
+    let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
+    let verification = verify_proof(&params, pk.get_vk(), msm, &[&[]], &mut transcript);
+    if let Err(err) = verification {
+        panic!("error {:?}", err);
+    }
+    let guard = verification.unwrap();
+    let msm = guard.clone().use_challenges();
+    assert!(msm.eval());
+    println!("Verify: [{:?}]", start.elapsed());
+}
+

+ 267 - 0
examples/halo2/simple4.rs

@@ -0,0 +1,267 @@
+use halo2::{
+    circuit::{SimpleFloorPlanner, Cell, Chip, Layouter},
+    pasta::{EqAffine, Fp},
+    plonk::{Advice, Any, Circuit, Column, ConstraintSystem, Error, Expression, Selector, create_proof, verify_proof, keygen_vk, keygen_pk, Permutation},
+    poly::{commitment::{Blind, Params}, Rotation},
+    transcript::{Blake2bRead, Blake2bWrite, Challenge255},
+};
+use group::Curve;
+use std::time::Instant;
+
+#[derive(Clone, Debug)]
+struct CoolConfig {
+    a_col: Column<Advice>,
+    b_col: Column<Advice>,
+    permute: Permutation,
+    s_range: Selector,
+    s_mul: Selector,
+    s_pub: Selector,
+}
+
+struct CoolChip {
+    config: CoolConfig
+}
+
+impl Chip<Fp> for CoolChip {
+    type Config = CoolConfig;
+    type Loaded = ();
+
+    fn config(&self) -> &Self::Config {
+        &self.config
+    }
+
+    fn loaded(&self) -> &Self::Loaded {
+        &()
+    }
+}
+
+#[derive(Clone, Debug)]
+struct Number {
+    cell: Cell,
+    value: Option<Fp>,
+}
+
+impl CoolChip {
+    fn construct(config: CoolConfig) -> Self {
+        Self { config }
+    }
+
+    fn configure(cs: &mut ConstraintSystem<Fp>) -> CoolConfig {
+        let a_col = cs.advice_column();
+        let b_col = cs.advice_column();
+
+        let instance = cs.instance_column();
+
+        let permute = {
+            // Convert advice columns into an "any" columns.
+            let cols: [Column<Any>; 2] = [a_col.into(), b_col.into()];
+            Permutation::new(cs, &cols)
+        };
+
+        let s_range = cs.selector();
+        let s_mul = cs.selector();
+        let s_pub = cs.selector();
+
+        cs.create_gate("check", |cs| {
+            let a = cs.query_advice(a_col, Rotation::cur());
+            let s_range = cs.query_selector(s_range);
+            vec![s_range * (a - Expression::Constant(Fp::from(2)))]
+        });
+
+        cs.create_gate("mul", |cs| {
+            let lhs = cs.query_advice(a_col, Rotation::cur());
+            let rhs = cs.query_advice(b_col, Rotation::cur());
+            let out = cs.query_advice(a_col, Rotation::next());
+            let s_mul = cs.query_selector(s_mul);
+
+            vec![s_mul * (lhs * rhs + out * -Fp::one())]
+        });
+
+        cs.create_gate("public input", |cs| {
+            let a = cs.query_advice(b_col, Rotation::cur());
+            let p = cs.query_instance(instance, Rotation::cur());
+            let s = cs.query_selector(s_pub);
+
+            vec![s * (p + a * -Fp::one())]
+        });
+
+        CoolConfig { a_col, b_col, permute, s_range, s_mul, s_pub }
+    }
+
+    fn alloc_left(
+        &self,
+        layouter: &mut impl Layouter<Fp>,
+        value: Option<Fp>
+    ) -> Result<Number, Error> {
+        layouter.assign_region(
+            || "load left private input",
+            |mut region| {
+                let cell = region.assign_advice(
+                    || "private input 'a'",
+                    self.config.a_col,
+                    0,
+                    || value.ok_or(Error::SynthesisError),
+                )?;
+                Ok(Number { cell, value })
+            }
+        )
+    }
+
+    fn check(
+        &self,
+        layouter: &mut impl Layouter<Fp>,
+        number: Number
+    ) -> Result<(), Error> {
+        layouter.assign_region(
+            || "load private inputs",
+            |mut region| {
+                self.config.s_range.enable(&mut region, 0)?;
+
+                let a = region.assign_advice(
+                    || "lhs",
+                    self.config.a_col,
+                    0,
+                    || number.value.ok_or(Error::SynthesisError),
+                )?;
+                region.constrain_equal(&self.config.permute, number.cell, a)?;
+
+                Ok(())
+            },
+        )
+    }
+
+    fn mul(
+        &self,
+        layouter: &mut impl Layouter<Fp>,
+        a: Number,
+        b: Number
+    ) -> Result<Number, Error> {
+        let mut out = None;
+        layouter.assign_region(
+            || "mul",
+            |mut region| {
+                self.config.s_mul.enable(&mut region, 0)?;
+
+                let lhs = region.assign_advice(
+                    || "lhs",
+                    self.config.a_col,
+                    0,
+                    || a.value.ok_or(Error::SynthesisError),
+                )?;
+                let rhs = region.assign_advice(
+                    || "rhs",
+                    self.config.b_col,
+                    0,
+                    || b.value.ok_or(Error::SynthesisError),
+                )?;
+                region.constrain_equal(&self.config.permute, a.cell, lhs)?;
+                region.constrain_equal(&self.config.permute, b.cell, rhs)?;
+
+                let value = a.value.and_then(|a| b.value.map(|b| a * b));
+                let cell = region.assign_advice(
+                    || "lhs * rhs",
+                    self.config.a_col,
+                    1,
+                    || value.ok_or(Error::SynthesisError),
+                )?;
+
+                out = Some(Number { cell, value });
+                Ok(())
+            },
+        )?;
+
+        Ok(out.unwrap())
+    }
+
+    fn expose_public(&self, layouter: &mut impl Layouter<Fp>, num: Number) -> Result<(), Error> {
+        layouter.assign_region(
+            || "expose public",
+            |mut region| {
+                self.config.s_pub.enable(&mut region, 0)?;
+
+                let out = region.assign_advice(
+                    || "public advice",
+                    self.config.b_col,
+                    0,
+                    || num.value.ok_or(Error::SynthesisError),
+                )?;
+                region.constrain_equal(&self.config.permute, num.cell, out)?;
+
+                Ok(())
+            },
+        )
+    }
+}
+
+#[derive(Clone)]
+struct CoolCircuit {
+    // Private input.
+    a: Option<Fp>,
+}
+
+impl Circuit<Fp> for CoolCircuit {
+    type Config = CoolConfig;
+    type FloorPlanner = SimpleFloorPlanner;
+
+    fn without_witnesses(&self) -> Self {
+        Self { a: None }
+    }
+
+    fn configure(cs: &mut ConstraintSystem<Fp>) -> Self::Config {
+        CoolChip::configure(cs)
+    }
+
+    fn synthesize(&self, config: Self::Config, mut layouter: impl Layouter<Fp>) -> Result<(), Error> {
+        let chip = CoolChip::construct(config);
+        let a = chip.alloc_left(&mut layouter, self.a)?;
+        chip.check(&mut layouter, a.clone())?;
+        let a2 = chip.mul(&mut layouter, a.clone(), a)?;
+        chip.expose_public(&mut layouter, a2)?;
+        Ok(())
+    }
+}
+
+fn main() {
+    let k = 6;
+
+    let start = Instant::now();
+    let params: Params<EqAffine> = Params::new(k);
+
+    let empty_circuit = CoolCircuit { a: None };
+    let vk = keygen_vk(&params, &empty_circuit).expect("keygen_vk should not fail");
+    let pk = keygen_pk(&params, vk, &empty_circuit).expect("keygen_pk should not fail");
+    println!("Setup: [{:?}]", start.elapsed());
+
+    let start = Instant::now();
+    let circuit = CoolCircuit {
+        a: Some(Fp::from(2)),
+    };
+
+    let mut public_inputs = pk.get_vk().get_domain().empty_lagrange();
+    public_inputs[4] = Fp::from(4);
+
+    // Create a proof
+    let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
+    create_proof(&params, &pk, &[circuit], &[&[public_inputs.clone()]], &mut transcript)
+        .expect("proof generation should not fail");
+    let proof = transcript.finalize();
+    println!("Prove: [{:?}]", start.elapsed());
+
+    let pubinput = params
+        .commit_lagrange(&public_inputs, Blind::default())
+        .to_affine();
+    let pubinput_slice = &[pubinput];
+
+    let start = Instant::now();
+    let msm = params.empty_msm();
+    let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
+    let verification = verify_proof(&params, pk.get_vk(), msm, &[pubinput_slice], &mut transcript);
+    if let Err(err) = verification {
+        panic!("error {:?}", err);
+    }
+    let guard = verification.unwrap();
+    let msm = guard.clone().use_challenges();
+    assert!(msm.eval());
+    println!("Verify: [{:?}]", start.elapsed());
+}
+

+ 5 - 0
scripts/dark_client/README.md

@@ -0,0 +1,5 @@
+# Dark Client 
+
+	$ python3 -m venv env
+	$ source env/bin/activate
+	$ pip install -r requirements.txt

+ 107 - 0
scripts/dark_client/drk.py

@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+
+from util import arg_parser
+
+import aiohttp
+import asyncio
+
+class DarkClient:
+    # TODO: generate random ID (4 byte unsigned int) (rand range 0 - max size
+    # uint32
+    def __init__(self, client_session):
+        self.url = "http://localhost:8000/"
+        self.client_session = client_session
+        self.payload = {
+                "method": [],
+                "params": [],
+                "jsonrpc": [],
+                "id": [],
+                }
+
+    #def ckeygen(self, payload):
+    #    payload['method'] = "cash_key_gen"
+    #    payload['jsonrpc'] = "2.0"
+    #    payload['id'] = "0"
+    #    ckeygen = self.__request(payload)
+    #    print(ckeygen)
+
+    #def cashkey(self, payload):
+    #    payload['method'] = "get_cash_key"
+    #    payload['jsonrpc'] = "2.0"
+    #    payload['id'] = "0"
+    #    cashk = self.__request(payload)
+    #    print(cashk)
+    #
+    #def test_path(self, payload):
+    #    payload['method'] = "test_path"
+    #    payload['jsonrpc'] = "2.0"
+    #    payload['id'] = "0"
+    #    test = self.__request(payload)
+    #    print(test)
+
+    async def key_gen(self, payload):
+        payload['method'] = "key_gen"
+        payload['jsonrpc'] = "2.0"
+        payload['id'] = "0"
+        key = await self.__request(payload)
+        print(key)
+
+    async def get_info(self, payload):
+        payload['method'] = "get_info"
+        payload['jsonrpc'] = "2.0"
+        payload['id'] = "0"
+        info = await self.__request(payload)
+        print(info)
+
+    async def stop(self, payload):
+        payload['method'] = "stop"
+        payload['jsonrpc'] = "2.0"
+        payload['id'] = "0"
+        stop = await self.__request(payload)
+        print(stop)
+
+    async def say_hello(self, payload):
+        payload['method'] = "say_hello"
+        payload['jsonrpc'] = "2.0"
+        payload['id'] = "0"
+        hello = await self.__request(payload)
+        print(hello)
+
+    async def create_wallet(self, payload):
+        payload['method'] = "create_wallet"
+        payload['jsonrpc'] = "2.0"
+        payload['id'] = "0"
+        wallet = await self.__request(payload)
+        print(wallet)
+
+    async def create_cashier_wallet(self, payload):
+        payload['method'] = "create_cashier_wallet"
+        payload['jsonrpc'] = "2.0"
+        payload['id'] = "0"
+        wallet = await self.__request(payload)
+        print(wallet)
+
+
+    async def __request(self, payload):
+        async with self.client_session.post(self.url, json=payload) as response:
+            resp = await response.text()
+            print(resp)
+
+
+
+
+async def main():
+    try:
+        async with aiohttp.ClientSession() as session:
+            client = DarkClient(session)
+            await arg_parser(client)
+    except aiohttp.ClientConnectorError as err:
+        print('CONNECTION ERROR:', str(err))
+    except Exception as err:
+        print("ERROR: ", str(err))
+
+if __name__ == "__main__":
+    loop = asyncio.get_event_loop()
+    loop.run_until_complete(main())
+
+

+ 14 - 0
scripts/dark_client/requirement.txt

@@ -0,0 +1,14 @@
+aiodns==3.0.0
+aiohttp==3.7.4.post0
+async-timeout==3.0.1
+attrs==21.2.0
+brotlipy==0.7.0
+cchardet==2.1.7
+cffi==1.14.5
+chardet==4.0.0
+idna==3.2
+multidict==5.1.0
+pycares==4.0.0
+pycparser==2.20
+typing-extensions==3.10.0.0
+yarl==1.6.3

+ 85 - 0
scripts/dark_client/util.py

@@ -0,0 +1,85 @@
+
+import argparse
+
+async def arg_parser(client):
+    parser = argparse.ArgumentParser(
+            prog='drk',
+            usage='%(prog)s [commands]',
+            description="""DarkFi wallet command-line tool"""
+            )
+
+    parser.add_argument('-c', '--cashier', action='store_true', help='Create a cashier wallet')
+    parser.add_argument('-w', '--wallet', action='store_true', help='Create a new wallet')
+    parser.add_argument('-k', '--key', action='store_true', help='Test key')
+    parser.add_argument('-i', '--info', action='store_true', help='Request info from daemon')
+    parser.add_argument('-hi', '--hello', action='store_true', help='Test hello')
+    parser.add_argument("-s", "--stop", action='store_true', help="Send a stop signal to the daemon")
+
+    try:
+        args = parser.parse_args()
+
+        if args.key:
+            print("Attemping to generate a create key pair...")
+            await client.key_gen(client.payload)
+
+        if args.wallet:
+            print("Attemping to generate a create wallet...")
+            await client.create_wallet(client.payload)
+
+        if args.info:
+            print("Info was entered")
+            await client.get_info(client.payload)
+            print("Requesting daemon info...")
+
+        if args.stop:
+            print("Stop was entered")
+            await client.stop(client.payload)
+            print("Sending a stop signal...")
+
+        if args.hello:
+            print("Hello was entered")
+            await client.say_hello(client.payload)
+
+        if args.cashier:
+            print("Cash was entered")
+            await client.create_cashier_wallet(client.payload)
+
+    except Exception:
+        raise
+
+    #subparser = parser.add_subparsers(help='All available commands', title="Commands", dest='cmd')
+    #subparser.metavar = 'subcommands';
+    #login = subparser.add_parser('login', help='wallet login')
+    ##test = subparser.add_parser('test', help='test wallet functions')
+    #new = subparser.add_parser('new', help='create something new')
+
+    #new.add_argument('-w', '--wallet', action='store_true', help='Create a new wallet')
+    #new.add_argument('-k', '--key', action='store_true', help='Create a new key')
+    #new.add_argument('-c', '--cashier', action='store_true', help='Create a cashier wallet')
+
+    #login.add_argument('-u', '--username', type=str, required=True)
+    #login.add_argument('-p', '--password', type=str, required=True)
+
+    ##test.add_argument('-k', '--key', dest='key', action='store_true', help='Test key')
+    ##test.add_argument('-p', '--path', dest='path', action='store_true', help='Test path')
+    ##test.add_argument('-pk', '--pkey', dest='pkey', action='store_true', help='Print test key')
+    ##test.add_argument('-ck', '--ckey', dest='ckey', action='store_true', help='Cashier test key')
+    ##test.add_argument('-w', '--wallet', dest='wallet', action='store_true', help='Create a new wallet')
+    ##test.add_argument('-c', '--cashier', dest='cashier',action='store_true', help='Create a cashier wallet')
+
+    #if args.path:
+    #    try:
+    #        print("Testing path...")
+    #        client.test_path(client.payload)
+    #    except Exception:
+    #        raise
+
+    #if args.pkey:
+    #    try:
+    #        print("Attempting to print cashier key...")
+    #        client.cashkey(client.payload)
+    #    except Exception:
+    #        raise
+
+
+

+ 0 - 202
scripts/drk

@@ -1,202 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-import requests
-import json
-
-def arg_parser(client):
-    parser = argparse.ArgumentParser(prog='drk',
-                                          usage='%(prog)s [commands]',
-                                          description="""DarkFi wallet
-                                          command-line tool""")
-    #subparser = parser.add_subparsers(help='All available commands', title="Commands", dest='cmd')
-    #subparser.metavar = 'subcommands';
-    #login = subparser.add_parser('login', help='wallet login')
-    ##test = subparser.add_parser('test', help='test wallet functions')
-    #new = subparser.add_parser('new', help='create something new')
-
-    #new.add_argument('-w', '--wallet', action='store_true', help='Create a new wallet')
-    #new.add_argument('-k', '--key', action='store_true', help='Create a new key')
-    #new.add_argument('-c', '--cashier', action='store_true', help='Create a cashier wallet')
-
-    #login.add_argument('-u', '--username', type=str, required=True)
-    #login.add_argument('-p', '--password', type=str, required=True)
-
-    ##test.add_argument('-k', '--key', dest='key', action='store_true', help='Test key')
-    ##test.add_argument('-p', '--path', dest='path', action='store_true', help='Test path')
-    ##test.add_argument('-pk', '--pkey', dest='pkey', action='store_true', help='Print test key')
-    ##test.add_argument('-ck', '--ckey', dest='ckey', action='store_true', help='Cashier test key')
-    ##test.add_argument('-w', '--wallet', dest='wallet', action='store_true', help='Create a new wallet')
-    ##test.add_argument('-c', '--cashier', dest='cashier',action='store_true', help='Create a cashier wallet')
-
-    parser.add_argument('-c', '--cashier', action='store_true', help='Create a cashier wallet')
-    parser.add_argument('-w', '--wallet', action='store_true', help='Create a new wallet')
-    parser.add_argument('-k', '--key', action='store_true', help='Test key')
-    parser.add_argument('-i', '--info', action='store_true', help='Request info from daemon')
-    parser.add_argument('-hi', '--hello', action='store_true', help='Test hello')
-    parser.add_argument("-s", "--stop", action='store_true', help="Send a stop signal to the daemon")
-    args = parser.parse_args()
-
-    #if args.path:
-    #    try:
-    #        print("Testing path...")
-    #        client.test_path(client.payload)
-    #    except Exception:
-    #        raise
-
-    #if args.pkey:
-    #    try:
-    #        print("Attempting to print cashier key...")
-    #        client.cashkey(client.payload)
-    #    except Exception:
-    #        raise
-
-    if args.key:
-        try:
-            print("Attemping to generate a create key pair...")
-            client.key_gen(client.payload)
-        except Exception:
-            raise
-
-    if args.wallet:
-        try:
-            print("Attemping to generate a create wallet...")
-            client.create_wallet(client.payload)
-        except Exception:
-            raise
-
-    if args.info:
-        try:
-            print("Info was entered")
-            client.get_info(client.payload)
-            print("Requesting daemon info...")
-        except Exception:
-            raise
-
-    if args.stop:
-        try:
-            print("Stop was entered")
-            client.stop(client.payload)
-            print("Sending a stop signal...")
-        except Exception:
-            raise
-
-    if args.hello:
-        try:
-            print("Hello was entered")
-            client.say_hello(client.payload)
-        except Exception:
-            raise
-
-    if args.cashier:
-        try:
-            print("Cash was entered")
-            client.create_cashier_wallet(client.payload)
-        except Exception:
-            raise
-
-# TODO: refactor into async
-class DarkClient:
-    # TODO: generate random ID (4 byte unsigned int) (rand range 0 - max size
-    # uint32
-    def __init__(self):
-        self.url = "http://localhost:8000/"
-        self.payload = {
-            "method": [],
-            "params": [],
-            "jsonrpc": [],
-            "id": [],
-        }
-
-    #def ckeygen(self, payload):
-    #    payload['method'] = "cash_key_gen"
-    #    payload['jsonrpc'] = "2.0"
-    #    payload['id'] = "0"
-    #    ckeygen = self.__request(payload)
-    #    print(ckeygen)
-
-    #def cashkey(self, payload):
-    #    payload['method'] = "get_cash_key"
-    #    payload['jsonrpc'] = "2.0"
-    #    payload['id'] = "0"
-    #    cashk = self.__request(payload)
-    #    print(cashk)
-    #    
-    #def test_path(self, payload):
-    #    payload['method'] = "test_path"
-    #    payload['jsonrpc'] = "2.0"
-    #    payload['id'] = "0"
-    #    test = self.__request(payload)
-    #    print(test)
-        
-    def key_gen(self, payload):
-        payload['method'] = "key_gen"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        key = self.__request(payload)
-        print(key)
-
-    def get_info(self, payload):
-        payload['method'] = "get_info"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        info = self.__request(payload)
-        print(info)
-
-    def stop(self, payload):
-        payload['method'] = "stop"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        stop = self.__request(payload)
-        print(stop)
-
-    def say_hello(self, payload):
-        payload['method'] = "say_hello"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        hello = self.__request(payload)
-        print(hello)
-    
-    def create_wallet(self, payload):
-        payload['method'] = "create_wallet"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        wallet = self.__request(payload)
-        print(wallet)
-
-    def create_cashier_wallet(self, payload):
-        payload['method'] = "create_cashier_wallet"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        wallet = self.__request(payload)
-        print(wallet)
-
-
-    def __request(self, payload):
-        response = requests.post(self.url, json=payload).json()
-        # print something better
-        # parse into data structure 
-        print(response)
-        assert response["jsonrpc"]
-
-    
-if __name__ == "__main__":
-    client = DarkClient()
-    arg_parser(client)
-
-    #rpc()
-    ## Example echo method
-    #payload = {
-    #    #"method:": args,
-    #    #"method": "stop",
-    #    "method": "get_info",
-    #    #"method": "say_hello",
-    #    #"params": [],
-    #    "jsonrpc": "2.0",
-    #    "id": 0,
-    #}
-    #response = requests.post(url, json=payload).json()
-
-    #print(response)
-    #assert response["result"] == "Hello World!"
-    #assert response["jsonrpc"]

+ 92 - 0
src/bin/cashier.rs

@@ -0,0 +1,92 @@
+extern crate clap;
+use drk::rpc::adapter::RpcAdapter;
+use drk::rpc::jsonserver;
+//use drk::rpc::options::ProgramOptions;
+use std::net::SocketAddr;
+
+use drk::blockchain::{rocks::columns, Rocks, RocksColumn};
+use drk::serial::Decodable;
+use drk::service::{ClientProgramOptions, GatewayClient, GatewaySlabsSubscriber};
+use drk::{tx, Result};
+
+use async_executor::Executor;
+use easy_parallel::Parallel;
+use std::sync::Arc;
+
+fn setup_addr(address: Option<SocketAddr>, default: SocketAddr) -> SocketAddr {
+    match address {
+        Some(addr) => addr,
+        None => default,
+    }
+}
+
+pub async fn subscribe(gateway_slabs_sub: GatewaySlabsSubscriber) -> Result<()> {
+    loop {
+        let slab = gateway_slabs_sub.recv().await?;
+        let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
+
+        //let update = state_transition(&state, tx)?;
+        //state.apply(update).await?;
+    }
+}
+async fn start(executor: Arc<Executor<'_>>, options: Arc<ClientProgramOptions>) -> Result<()> {
+    let connect_addr: SocketAddr = setup_addr(options.connect_addr, "127.0.0.1:3333".parse()?);
+    let sub_addr: SocketAddr = setup_addr(options.sub_addr, "127.0.0.1:4444".parse()?);
+    let database_path = options.database_path.as_path();
+
+    let rocks = Rocks::new(database_path)?;
+
+    let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
+
+    // create gateway client
+    let mut client = GatewayClient::new(connect_addr, slabstore)?;
+
+    // start subscribing
+    let gateway_slabs_sub: GatewaySlabsSubscriber =
+        client.start_subscriber(sub_addr, executor.clone()).await?;
+    let subscribe_task = executor.spawn(subscribe(gateway_slabs_sub));
+
+    // start gateway client
+    client.start().await?;
+
+    subscribe_task.cancel().await;
+    Ok(())
+}
+
+fn main() -> Result<()> {
+    use simplelog::*;
+
+    let options = Arc::new(ClientProgramOptions::load()?);
+
+    let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
+
+    CombinedLogger::init(vec![
+        TermLogger::new(LevelFilter::Debug, logger_config, TerminalMode::Mixed).unwrap(),
+        WriteLogger::new(
+            LevelFilter::Debug,
+            Config::default(),
+            std::fs::File::create(options.log_path.as_path()).unwrap(),
+        ),
+    ])
+    .unwrap();
+
+    //let adapter = RpcAdapter::new("wallet.db")?;
+    let ex = Arc::new(Executor::new());
+    let (signal, shutdown) = async_channel::unbounded::<()>();
+    let ex2 = ex.clone();
+
+    let (_, result) = Parallel::new()
+        // Run four executor threads.
+        .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv())))
+        // Run the main future on the current thread.
+        .finish(|| {
+            smol::future::block_on(async move {
+                //jsonserver::start(ex2, options, adapter).await?;
+                start(ex2, options).await?;
+                drop(signal);
+                Ok::<(), drk::Error>(())
+            })
+        });
+
+    result
+}

+ 10 - 11
src/bin/darkfid.rs

@@ -1,13 +1,12 @@
 use async_std::sync::Arc;
 use drk::rpc::adapter::RpcAdapter;
 use drk::rpc::jsonserver;
-use drk::rpc::options::ProgramOptions;
+//use drk::rpc::options::ProgramOptions;
 use rand::rngs::OsRng;
 use std::net::SocketAddr;
 
 use drk::blockchain::{rocks::columns, Rocks, RocksColumn};
 use drk::crypto::{
-    coin::Coin,
     load_params,
     merkle::{CommitmentTree, IncrementalWitness},
     merkle_node::MerkleNode,
@@ -15,11 +14,11 @@ use drk::crypto::{
     nullifier::Nullifier,
     save_params, setup_mint_prover, setup_spend_prover,
 };
-use drk::serial::{deserialize, Decodable};
+use drk::serial::Decodable;
 use drk::service::{ClientProgramOptions, GatewayClient, GatewaySlabsSubscriber};
 use drk::state::{state_transition, ProgramState, StateUpdate};
 use drk::wallet::WalletDB;
-use drk::{tx, Error, Result};
+use drk::{tx, Result};
 use rusqlite::Connection;
 
 use async_executor::Executor;
@@ -27,6 +26,7 @@ use bellman::groth16;
 use bls12_381::Bls12;
 use easy_parallel::Parallel;
 use ff::Field;
+use log::*;
 use std::path::Path;
 
 #[allow(dead_code)]
@@ -115,7 +115,7 @@ impl State {
                 let witness = IncrementalWitness::from_tree(&self.tree);
 
                 self.wallet.own_coins.push((coin, note, secret, witness));
-                self.wallet.put_own_coins();
+                self.wallet.put_own_coins().await?;
             }
         }
         Ok(())
@@ -157,7 +157,7 @@ pub async fn subscribe(gateway_slabs_sub: GatewaySlabsSubscriber, mut state: Sta
     }
 }
 
-async fn start(executor: Arc<Executor<'_>>, options: ClientProgramOptions) -> Result<()> {
+async fn start(executor: Arc<Executor<'_>>, options: Arc<ClientProgramOptions>) -> Result<()> {
     let connect_addr: SocketAddr = setup_addr(options.connect_addr, "127.0.0.1:3333".parse()?);
     let sub_addr: SocketAddr = setup_addr(options.sub_addr, "127.0.0.1:4444".parse()?);
     let database_path = options.database_path.as_path();
@@ -223,9 +223,7 @@ fn main() -> Result<()> {
     let ex = Arc::new(Executor::new());
     let (signal, shutdown) = async_channel::unbounded::<()>();
 
-    let rpc_options = ProgramOptions::load()?;
-
-    let options = ClientProgramOptions::load()?;
+    let options = Arc::new(ClientProgramOptions::load()?);
 
     let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
 
@@ -245,8 +243,9 @@ fn main() -> Result<()> {
     ])
     .unwrap();
 
-    let adapter = RpcAdapter::new("wallet.db")?;
+    debug!(target: "DARKFID", "main() [ADAPTER CREATED]");
     let ex2 = ex.clone();
+    let adapter = RpcAdapter::new("wallet.db")?;
 
     let (_, result) = Parallel::new()
         // Run four executor threads.
@@ -254,7 +253,7 @@ fn main() -> Result<()> {
         // Run the main future on the current thread.
         .finish(|| {
             smol::future::block_on(async move {
-                jsonserver::start(ex2.clone(), rpc_options, adapter).await?;
+                jsonserver::start(ex2.clone(), options.clone(), adapter).await?;
                 start(ex2, options).await?;
                 drop(signal);
                 Ok::<(), drk::Error>(())

+ 0 - 0
src/bin/dfi.rs → src/bin/old/dfi.rs


+ 11 - 27
src/crypto/merkle.rs

@@ -168,28 +168,16 @@ impl<Node: Hashable> CommitmentTree<Node> {
 impl<Node: Hashable> Encodable for CommitmentTree<Node> {
     fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
         let mut len = 0;
-        match self.left {
-            Some(v) => {
-                len += v.encode(&mut s)?;
-                1
-            }
-            None => 0,
-        };
-        match self.right {
-            Some(v) => {
+        if let Some(v) = self.left {
+            len += v.encode(&mut s)?;
+        }
+        if let Some(v) = self.right {
+            len += v.encode(&mut s)?;
+        }
+        for parent in self.parents.iter() {
+            if let Some(v) = parent {
                 len += v.encode(&mut s)?;
-                1
             }
-            None => 0,
-        };
-        for c in self.parents.iter() {
-            match c {
-                Some(v) => {
-                    len += v.encode(&mut s)?;
-                    1
-                }
-                None => 0,
-            };
         }
         Ok(len)
     }
@@ -258,13 +246,9 @@ impl<Node: Hashable> Encodable for IncrementalWitness<Node> {
             len += c.encode(&mut s)?;
         }
         len += self.cursor_depth.encode(&mut s)?;
-        match &self.cursor {
-            Some(v) => {
-                len += v.encode(&mut s)?;
-                1
-            }
-            None => 0,
-        };
+        if let Some(v) = &self.cursor {
+            len += v.encode(&mut s)?;
+        }
         Ok(len)
     }
 }

+ 1 - 0
src/rpc/adapter.rs

@@ -11,6 +11,7 @@ pub struct RpcAdapter {
 
 impl RpcAdapter {
     pub fn new(dbname: &str) -> Result<Self> {
+        debug!(target: "ADAPTER", "new() [CREATING NEW WALLET]");
         let wallet = WalletDB::new(dbname)?;
         Ok(Self { wallet })
     }

+ 8 - 16
src/rpc/jsonserver.rs

@@ -1,5 +1,5 @@
 use crate::rpc::adapter::RpcAdapter;
-use crate::rpc::options::ProgramOptions;
+use crate::service::ClientProgramOptions;
 use crate::{net, Error, Result};
 use async_executor::Executor;
 use async_native_tls::TlsAcceptor;
@@ -73,12 +73,10 @@ pub async fn listen(
 
 pub async fn start(
     executor: Arc<Executor<'_>>,
-    options: ProgramOptions,
-    _adapter: RpcAdapter,
+    options: Arc<ClientProgramOptions>,
+    adapter: RpcAdapter,
 ) -> Result<()> {
-    let p2p = net::P2p::new(options.network_settings);
-
-    let rpc = RpcInterface::new(p2p.clone())?;
+    let rpc = RpcInterface::new(adapter)?;
     let http = listen(
         executor.clone(),
         rpc.clone(),
@@ -90,10 +88,6 @@ pub async fn start(
 
     *rpc.started.lock().await = true;
 
-    p2p.clone().start(executor.clone()).await?;
-
-    p2p.run(executor).await?;
-
     rpc.wait_for_quit().await?;
 
     http_task.cancel().await;
@@ -103,7 +97,6 @@ pub async fn start(
 // json RPC server goes here
 #[allow(dead_code)]
 pub struct RpcInterface {
-    p2p: Arc<net::P2p>,
     pub started: Mutex<bool>,
     stop_send: async_channel::Sender<()>,
     stop_recv: async_channel::Receiver<()>,
@@ -111,11 +104,10 @@ pub struct RpcInterface {
 }
 
 impl RpcInterface {
-    pub fn new(p2p: Arc<net::P2p>) -> Result<Arc<Self>> {
+    pub fn new(adapter: RpcAdapter) -> Result<Arc<Self>> {
         let (stop_send, stop_recv) = async_channel::unbounded::<()>();
-        let adapter = RpcAdapter::new("wallet.db")?;
         Ok(Arc::new(Self {
-            p2p,
+            //p2p,
             started: Mutex::new(false),
             stop_send,
             stop_recv,
@@ -180,7 +172,7 @@ impl RpcInterface {
                 "Attempted wallet generation".into(),
             ))
         });
-        let self3 = self.clone();
+        //let self3 = self.clone();
         //io.add_method("key_gen", move |_| {
         //    let self4 = self3.clone();
         //    async move {
@@ -192,7 +184,7 @@ impl RpcInterface {
         //        ))
         //    }
         //});
-        let self5 = self.clone();
+        //let self5 = self.clone();
         //io.add_method("cash_key_gen", move |_| {
         //    let self6 = self5.clone();
         //    async move {

+ 0 - 1
src/rpc/mod.rs

@@ -1,4 +1,3 @@
 pub mod adapter;
 pub mod jsonserver;
-pub mod options;
 pub mod test;

+ 0 - 79
src/rpc/options.rs

@@ -1,79 +0,0 @@
-use crate::{net, Result};
-use std::net::SocketAddr;
-
-pub struct ProgramOptions {
-    pub network_settings: net::Settings,
-    pub log_path: Box<std::path::PathBuf>,
-    pub rpc_port: u16,
-}
-
-impl ProgramOptions {
-    pub fn load() -> Result<ProgramOptions> {
-        let app = clap_app!(dfi =>
-            (version: "0.1.0")
-            (author: "Amir Taaki <amir@dyne.org>")
-            (about: "Dark node")
-            (@arg ACCEPT: -a --accept +takes_value "Accept add//ress")
-            (@arg SEED_NODES: -s --seeds ... "Seed nodes")
-            (@arg CONNECTS: -c --connect ... "Manual connections")
-            (@arg CONNECT_SLOTS: --slots +takes_value "Connection slots")
-            (@arg LOG_PATH: --log +takes_value "Logfile path")
-            (@arg RPC_PORT: -r --rpc +takes_value "RPC port")
-        )
-        .get_matches();
-
-        let accept_addr = if let Some(accept_addr) = app.value_of("ACCEPT") {
-            Some(accept_addr.parse()?)
-        } else {
-            None
-        };
-
-        let mut seed_addrs: Vec<SocketAddr> = vec![];
-        if let Some(seeds) = app.values_of("SEED_NODES") {
-            for seed in seeds {
-                seed_addrs.push(seed.parse()?);
-            }
-        }
-
-        let mut manual_connects: Vec<SocketAddr> = vec![];
-        if let Some(connections) = app.values_of("CONNECTS") {
-            for connect in connections {
-                manual_connects.push(connect.parse()?);
-            }
-        }
-
-        let connection_slots = if let Some(connection_slots) = app.value_of("CONNECT_SLOTS") {
-            connection_slots.parse()?
-        } else {
-            0
-        };
-
-        let log_path = Box::new(
-            if let Some(log_path) = app.value_of("LOG_PATH") {
-                std::path::Path::new(log_path)
-            } else {
-                std::path::Path::new("/tmp/darkfid.log")
-            }
-            .to_path_buf(),
-        );
-
-        let rpc_port = if let Some(rpc_port) = app.value_of("RPC_PORT") {
-            rpc_port.parse()?
-        } else {
-            8000
-        };
-
-        Ok(ProgramOptions {
-            network_settings: net::Settings {
-                inbound: accept_addr,
-                outbound_connections: connection_slots,
-                external_addr: accept_addr,
-                peers: manual_connects,
-                seeds: seed_addrs,
-                ..Default::default()
-            },
-            log_path,
-            rpc_port,
-        })
-    }
-}

+ 9 - 0
src/service/options.rs

@@ -71,6 +71,7 @@ pub struct ClientProgramOptions {
     pub verbose: bool,
     pub database_path: Box<std::path::PathBuf>,
     pub log_path: Box<std::path::PathBuf>,
+    pub rpc_port: u16,
 }
 
 impl ClientProgramOptions {
@@ -84,6 +85,7 @@ impl ClientProgramOptions {
             (@arg VERBOSE: -v --verbose "Increase verbosity")
             (@arg DATABASE_PATH: --database +takes_value "database path")
             (@arg LOG_PATH: --log +takes_value "Logfile path")
+            (@arg RPC_PORT: -r --rpc +takes_value "RPC port")
         )
         .get_matches();
 
@@ -119,12 +121,19 @@ impl ClientProgramOptions {
             .to_path_buf(),
         );
 
+        let rpc_port = if let Some(rpc_port) = app.value_of("RPC_PORT") {
+            rpc_port.parse()?
+        } else {
+            8000
+        };
+
         Ok(ClientProgramOptions {
             connect_addr,
             sub_addr,
             verbose,
             database_path,
             log_path,
+            rpc_port,
         })
     }
 }

+ 3 - 0
src/wallet/walletdb.rs

@@ -21,8 +21,10 @@ pub struct WalletDB {
 
 impl WalletDB {
     pub fn new(wallet: &str) -> Result<Self> {
+        debug!(target: "walletdb", "new() Constructor called");
         let path = Self::create_path(wallet)?;
         let conn = Connection::open(&path)?;
+        debug!(target: "walletdb", "OPENED CONNECTION AT PATH {:?}", path);
         let contents = include_str!("../../res/schema.sql");
         let cashier_secret = jubjub::Fr::random(&mut OsRng);
         let secret = jubjub::Fr::random(&mut OsRng);
@@ -32,6 +34,7 @@ impl WalletDB {
             Ok(v) => println!("Database initalized successfully {:?}", v),
             Err(err) => println!("Error: {}", err),
         };
+        debug!(target: "walletdb", "new(): inititalized wallet");
         Ok(Self {
             path,
             own_coins: vec![],