From 3ae60f10ebfb47e1bc970ceccbbb311f4a2df196 Mon Sep 17 00:00:00 2001 From: artifex11 <142263263+artifex11@users.noreply.github.com> Date: Mon, 28 Aug 2023 23:53:21 +0200 Subject: [PATCH] feat: refactor core into simplified WASM module (#79) --- .github/workflows/dusk_ci.yml | 60 +- .gitignore | 2 +- Cargo.toml | 37 +- Makefile | 30 + README.md | 43 +- assets/dusk-wallet-core-0.21.0.wasm | Bin 0 -> 303327 bytes assets/dusk_wallet_core.wasm | Bin 0 -> 388808 bytes assets/schema.json | 389 ++++++++++ asyncify.sh | 19 - build.rs | 57 ++ rust-toolchain | 2 +- src/ffi.rs | 949 +++++++++-------------- src/imp.rs | 1082 --------------------------- src/key.rs | 48 ++ src/lib.rs | 292 +------- src/tx.rs | 726 ++++++------------ src/types.rs | 143 ++++ src/utils.rs | 251 +++++++ tests/mock.rs | 350 --------- tests/wallet.rs | 466 ++++++++++-- 20 files changed, 2027 insertions(+), 2919 deletions(-) create mode 100644 Makefile create mode 100644 assets/dusk-wallet-core-0.21.0.wasm create mode 100755 assets/dusk_wallet_core.wasm create mode 100644 assets/schema.json delete mode 100755 asyncify.sh create mode 100644 build.rs delete mode 100644 src/imp.rs create mode 100644 src/key.rs create mode 100644 src/types.rs create mode 100644 src/utils.rs delete mode 100644 tests/mock.rs diff --git a/.github/workflows/dusk_ci.yml b/.github/workflows/dusk_ci.yml index 82853d5..8b208de 100644 --- a/.github/workflows/dusk_ci.yml +++ b/.github/workflows/dusk_ci.yml @@ -9,6 +9,7 @@ on: name: Dusk CI jobs: + analyze: name: Dusk Analyzer runs-on: ubuntu-latest @@ -33,7 +34,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: nightly-2023-05-22 - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 with: @@ -42,11 +43,12 @@ jobs: build_wasm: name: Build WASM + if: startsWith(github.ref, 'refs/tags/v') strategy: fail-fast: false matrix: toolchain: - - nightly + - nightly-2023-05-22 target: [ wasm32-unknown-unknown ] runs-on: ubuntu-latest steps: @@ -62,49 +64,45 @@ jobs: - name: Add target run: rustup target add ${{ matrix.target }} - - name: Run cargo check + - name: Run cargo build uses: actions-rs/cargo@v1 with: - command: check - args: --all-targets + command: build - - name: Build project - uses: actions-rs/cargo@v1 - with: - command: rustc - args: --release --target ${{ matrix.target }} -- -C link-args=-s + - name: Add rust-src + run: rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu + + - name: Install Binaryen + run: > + wget https://github.com/WebAssembly/binaryen/releases/download/version_105/binaryen-version_105-x86_64-linux.tar.gz && + tar -xvf binaryen-version_105-x86_64-linux.tar.gz -C ~/.local --strip-components 1 + + - run: make package - name: Set up node - if: startsWith(github.ref, 'refs/tags/v') uses: actions/setup-node@v2 with: node-version: 16 registry-url: https://npm.pkg.github.com - - name: Install Binaryen - if: startsWith(github.ref, 'refs/tags/v') - run: > - wget https://github.com/WebAssembly/binaryen/releases/download/version_105/binaryen-version_105-x86_64-linux.tar.gz && - tar -xvf binaryen-version_105-x86_64-linux.tar.gz -C ~/.local --strip-components 1 - - name: Publish package - if: startsWith(github.ref, 'refs/tags/v') # Move the compiled package to the root for better paths in the npm module. # We also automatically populate the version with the given tag. run: > - ./asyncify.sh && + make package && sed -i "/\"version\": \"0.0.1\"/s/\"0.0.1\"/\"${GITHUB_REF:11}\"/" package.json && npm publish env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + build_and_test: name: Test with all features strategy: fail-fast: false matrix: toolchain: - - nightly + - nightly-2023-05-22 os: - ubuntu-latest runs-on: ${{ matrix.os }} @@ -118,24 +116,28 @@ jobs: profile: minimal toolchain: ${{ matrix.toolchain }} + - name: Add target WASM + run: rustup target add wasm32-unknown-unknown + + - name: Add rust-src + run: rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu + + - run: make wasm + - name: Run cargo check uses: actions-rs/cargo@v1 with: command: check args: --all-targets - - name: Test project - if: ${{ matrix.os != 'ubuntu-latest' || matrix.toolchain != 'nightly' }} - uses: actions-rs/cargo@v1 - with: - command: test + - run: make test - name: Install kcov - if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain == 'nightly' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' }} run: sudo apt install -y kcov - name: Build test executable - if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain == 'nightly' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' }} uses: actions-rs/cargo@v1 env: RUSTFLAGS: '-Cdebuginfo=2 -Cinline-threshold=0 -Clink-dead-code' @@ -145,7 +147,7 @@ jobs: args: --no-run - name: Test with kcov - if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain == 'nightly' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' }} # Find every executable resulting from building the tests and run each # one of them with kcov. This ensures all the code we cover is measured. run: > @@ -153,7 +155,7 @@ jobs: xargs -n1 kcov --exclude-pattern=tests/,/.cargo,/usr/lib --verify target/cov - name: Upload coverage - if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain == 'nightly' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' }} uses: codecov/codecov-action@v1.0.2 with: token: ${{secrets.CODECOV_TOKEN}} diff --git a/.gitignore b/.gitignore index 6680449..e345084 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ target/ Cargo.lock **/*.rs.bk -*.wasm +mod.wasm diff --git a/Cargo.toml b/Cargo.toml index 48cedd9..aad3afe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,28 +1,39 @@ [package] name = "dusk-wallet-core" -version = "0.20.0-piecrust.0.6" +version = "0.21.0" edition = "2021" description = "The core functionality of the Dusk wallet" license = "MPL-2.0" +[lib] +crate-type = ["cdylib", "rlib"] + [dependencies] -rand_core = "^0.6" -rand_chacha = { version = "^0.3", default-features = false } -sha2 = { version = "^0.10", default-features = false } -phoenix-core = { version = "0.20.0-rc.0", default-features = false, features = ["alloc", "rkyv-impl"] } -dusk-pki = { version = "0.12", default-features = false } +bytecheck = { version = "0.6", default-features = false } +bs58 = { version = "0.5", default-features = false, features = ["alloc", "cb58"] } +dusk-bls12_381-sign = { version = "0.4", default-features = false } dusk-bytes = "^0.1" -dusk-schnorr = { version = "0.13", default-features = false } dusk-jubjub = { version = "0.12", default-features = false } -dusk-poseidon = { version = "0.30", default-features = false } +dusk-pki = { version = "0.12", default-features = false, features = ["rkyv-impl"] } +dusk-schnorr = { version = "0.13", default-features = false } +phoenix-core = { version = "0.20.0-rc.0", default-features = false, features = ["alloc", "rkyv-impl"] } poseidon-merkle = { version = "0.2.1-rc.0", features = ["rkyv-impl"] } -dusk-plonk = { version = "0.14", default-features = false } +rand_chacha = { version = "^0.3", default-features = false } +rand_core = "^0.6" +rkyv = { version = "^0.7", default-features = false, features = ["size_32"] } +serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +sha2 = { version = "^0.10", default-features = false } + +[target.'cfg(target_family = "wasm")'.dependencies] +rusk-abi = "0.10.0-piecrust.0.6" + +[target.'cfg(not(target_family = "wasm"))'.dependencies] rusk-abi = { version = "0.10.0-piecrust.0.6", default-features = false } -dusk-bls12_381-sign = { version = "0.4", default-features = false } -rkyv = { version = "0.7", default-features = false } [dev-dependencies] rand = "^0.8" +wasmer = "=3.1" -[lib] -crate-type = ["cdylib", "rlib"] +[build-dependencies] +schemafy_lib = "0.6" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a5b32d8 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +PROJECT := $(shell sed -n '0,/name\s*=\s*"\(.*\)"/s/name\s*=\s*"\(.*\)"/\1/p' Cargo.toml) +VERSION := $(shell sed -n '0,/version\s*=\s*"\(.*\)"/s/version\s*=\s*"\(.*\)"/\1/p' Cargo.toml) +FLAGS := RUSTFLAGS="$(RUSTFLAGS) --remap-path-prefix $(HOME)= -C link-args=-zstack-size=65536" +WASM := "target/wasm32-unknown-unknown/release/$(shell sed -n '0,/name\s*=\s*"\(.*\)"/s/name\s*=\s*"\(.*\)"/\1/p' Cargo.toml | sed 's/-/_/g').wasm" +NPM_WASM := "mod.wasm" +PACKAGE := "assets/$(PROJECT)-$(VERSION).wasm" + +help: ## Display this help screen + @grep -h \ + -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ + awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +test: wasm ## Run the wasmer tests + @cargo test + +wasm: ## Build the WASM files + @$(FLAGS) cargo build --release \ + --target wasm32-unknown-unknown \ + --color=always \ + -Z build-std=core,alloc,panic_abort \ + -Z build-std-features=panic_immediate_abort + @cp target/wasm32-unknown-unknown/release/dusk_wallet_core.wasm \ + assets/ + +package: wasm ## Prepare the WASM package + @wasm-opt -O3 $(WASM) -o $(NPM_WASM) + @cp $(NPM_WASM) $(PACKAGE) + @echo "Package created: $(PACKAGE)" + +.PHONY: test wasm package help diff --git a/README.md b/README.md index 0d5cb8b..ebda641 100644 --- a/README.md +++ b/README.md @@ -4,19 +4,46 @@ [![codecov](https://codecov.io/gh/dusk-network/wallet-core/branch/main/graph/badge.svg?token=9W3J09AWZG)](https://codecov.io/gh/dusk-network/wallet-core) [![documentation](https://img.shields.io/badge/docs-wallet-blue?logo=rust)](https://docs.rs/dusk-wallet-core/) -A library for generating and dealing with transactions. +A WASM library to provide business logic for Dusk wallet implementations. + +Check the available methods under the [FFI](src/ffi.rs) module. + +Every function expects a fat pointer to its arguments already allocated to the WASM memory. For the arguments definition, check the [JSON Schema](assets/schema.json). It will consume this pointer region and free it after execution. The return of the function will also be in accordance to the schema, and the user will have to free the memory himself after fetching the data. + +For maximum compatibility, every WASM function returns a `i64` with the status of the operation and an embedded pointer. The structure of the bytes in big-endian is as follows: + +[(pointer) x 4bytes (length) x 3bytes (status) x 1bit] + +The pointer will be a maximum `u32` number, and the length a `u24` number. The status of the operation is the least significant bit of the number, and will be `0` if the operation is successful. + +Here is an algorithm to split the result into meaningful parts: + +```rust,ignore +let ptr = (result >> 32) as u64; +let len = ((result << 32) >> 48) as u64; +let success = ((result << 63) >> 63) == 0; +``` + +For an example usage, check the [wallet-cli](https://github.com/dusk-network/wallet-cli) implementation that consumes this library. + +## Requirements + +- [Rust 1.71.0](https://www.rust-lang.org/) +- [target.wasm32-unknown-unknown](https://github.com/rustwasm/) +- [binaryen](https://github.com/WebAssembly/binaryen) to generate packages ## Build -To build and test the crate: +To build a distributable package: -```shell -cargo b -cargo t --all-features +```sh +make package ``` -To build the WASM module: +## Test + +To run the tests, there is an automated Makefile script -```shell -cargo b --release --target wasm32-unknown-unknown +```sh +make test ``` diff --git a/assets/dusk-wallet-core-0.21.0.wasm b/assets/dusk-wallet-core-0.21.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b00b491a4b89e92ae51e81cf73545853aa2bdd8d GIT binary patch literal 303327 zcmce<3z%I;b?3Vu=bV0>(|!7(R!c2QwYO!dWm~q4jU)_7v^##rHW+Y-F(kGD0qz#y zhhiWxRvU!r1ZPH>kclAVrjwAd?gY&!i30)*G{i}ijORunz7z47FPaY~Q8LVoa>I8& zW#SC?_g}Slo!u>&K=OT8cJEz#?b@rVR;^mK)~Z!?qI(~DTO37E{7k(5p5(xR_`p5s z0lV=KSvtBW7C7cn86Lf-K?WY0Tp#s$9`#QZ)V}AVNAHRFP}#}Q(pSpS?-NS)k$m(~ zr3@#T1@UMHc;o-6+#Uil4O%9<@RWi;H}Xg6H{-vKo6R&y8cD1C*X-}_Pvb_T(QG8O ze|<`)Ny@)wJ8d@mq9~2x2DDiHZ(tybI_WSO>|dg*Ap&U}$HJN>Q8Lm6J_^Q062(zE z7LBJoPym-CXnOSz-yh$6b2BAV>!QYixL8}Dy6JKxXcIYn$t6Sf%#>1_*?S0!j9(;Eawcd8` zzJ2d_W7O<_^MiZ$-VHcvH6Gf#_f1h>-y81TckkQZxHszW+xxD)Z~XE7d!vD&x9xrK zEqm{N`#bjUeJC1izxlp>`}aOrJ`RoE|Ko4ici$WDe(3(aZ-3L>^LyX@P}ClH_`bdG z^y$vv+kbrDzWd&M-`)owiiYDNjR)_(`%U-mzxQskr^(RWcfWP-z4zb!hI=2{o2CPA zjH4nRx@l@p@q@GXTz}nbfAkGMcGv4)cjp`Lo%)Ga-+J2*z5JGIc0C=xc=sz__3l57 ze{yQ-hMRA?aq5%t@%UB$G5){f=i>hq|8ac758XO-!>8lV#8Y30KOZm0Q{RZE{w)4- z{FQj>tMS+3{~Qnghp&$OHQX5=a8Ys1+)NVXabu5*W|AE)F1p?K$3wh08R?DaX&@jk zo9lie=6=H7_-~45?1Asv`-+DDbS7z32qRvk`}1hN=%05y%oU?^MZdBQy+4io8{}oD!tsy7QlqL8~&)O4c z?Df!d)5&EAl1DFwSK|3R-5j}84eZ{LH$<4G20cvZfGuV z6zK!JYGnFiM6dd@A@FuxgWk9qf>GQ}~3khyt1pa3deM%{6Jo1J~0p4L2~C z4bYrnYLpx>bRcWwqs1RS{-s!riKw7!sBQheZNs#Ux@LXt=8#KV9|aVBYFj_xM!PZO zMvJqJefh9qrwYyaTPSLnx2fJziFP)i8y`^pQB@>y&09JRsyJ|4Csr;4qyoI6lR6=B z!>NXe30b@KtQ|W1OoQSZuH(k9jbhg+l53;L^%nyI_7?}ApzC>douk%*<JNx#uVMR(^ms}hi_Uu-%^5eXbKmnCl0HRzJOabri_G?R1-q(I`v zZtT!z`b(YLcF;$?*L1^Fo&I%wDzjCjY8^}o+6Kt_x4~go@|sppaJzCBpH)2J2K_g5 zR3uh1&gs22f}f4VGU<>TV2n41GI4&NvQhyd1h04v6#9@#s4l}EuLO|VuExUT=}hw0 zyst=afY(XyP`et}cVbv>sOUo=Xs8!cb6ghVxoxRRX6&ci(gpaot8X63?Dnn<88?&c z&-h>_xgU<@wl5o*jj}5Yi=O(xLk%S4O8LfZW;V&LKsZf6e9EOIeEG6m@|nbLI)Mpc zYG2M!WAx1x1LfR6^(U04*daL_o2+r%m{v+T+@RZ#!-=3hIZOo*ToS;DRLxvF6Gx(d zF6+2HCz&;uP3X>;%0!7_hTU?T4zI?Yi;)e;l`-*AT%158-2%942tCj9j@~oFG%jYsGY_tM802Bk zd^vzMmU(8@3jjlf1`q&N)~Nt!lmB$@$s=HrU9)7G|>Z{12he2gVYFyhi(BS~;<7uh)Bs7}= z9jSppa|xhhH4tdF06HE(4K->jpi?yvAI<SmM7Rx8bGCHCp!YGo- zT7`&+7|iaX;`!77!)^=_>NZFWNC=R%d}9P~SE$K`(yghGn8bDKq$f?fVQCHdu#^R9 zL}&--QeN9YptpmX!R*#%){K%zHPQ7;-vqIyYxL+jH?9gq2rf&_rkZU0``Kj3=HZ!S zbB-ow6Yu4DpPw)t;-ATYR?}6p2i`xs@Ys6~E*@H1UO4c+>d7~reE$*;KG8WOuJe&Wd@eYn`aZ?0fAj3ABX+=hLq6sBP`+60lN&L)LOapu7+ zId{cu{2q4&Rd9XMGWw)S(d^BczdJQ`Uok#cyz7BHF3rGls`o8N>FDlCm2XD+$W%3M zBk2+wJZYx54M_{aJdhR?IrP3ZH`9V5>pN*QOdy-1p@-x2fS2u!Qk6!~_veXb_c$|x zCs;4FsXf6SWKvJjKS4tSH8Qf40!*d18w7Du`MfR?86D_QnVBPKm(kGgCvg*-)`~J> zp?#rZI5RB0MlWqM!4fS%X4EX={ZJZ>)HQCNM)ky`xosNjZDt=m-6)>=i)Yu}j18T& zl08nON1xf5Oi{%qSwtS{NcTV*5!1A=DczZuP%B7G%yqY@Kic5yaU(=jb4(kh#YyoP zX6n0ckV+#vIfYNbx?Zi~!9i4OS4LhH#|Ja}=JM2d(O6dcm}wZLD(R=r(3e8U`)<{@ zRzdM|IW2nhP=`@6^g445SZ9sMW{u1U_BK+o8TA(b&Y+9B?~T3b51#q$kt|--JuX1j zJrl22v!o8A)zPll_feNe$f#`I1Mo*1lF4%dT_~@(7v=8Z8SsTnd%$!DF-%$Dv zOaW@}+B#EK*+P76E_&GFX2$zUoj6GHD#0_~dmloKrx58zu?t^f` zvk^m748Wz)y${uvs%T6MXk5xcQBmkZcO=ADqZ_GJU-9>mn5_lMKgWIY{9}#o1pbYV ztew{OXv*xBYojSB-6*~tWA2yLQ{~bE(%hsv?M$w#DkV2e*YSj!sy3VPa(mVX2I_ii z@o zqvw-1-6I%1H){PnOg|5A#$B57|LT8rPy>!Vuj^wfKg5Lh4|Ee2ZpS7gi5^%%Lwf}` zAdY5|4c26uXn9v5gcFSgdsX`p_?XJli9kI6|>t-I68PB)oa1^g*k~^}ly11`{ABX<+7`_h%14CM@@zvk4s`?n& zGs!hp{gw(^mnU>l5o6`99Q{nhGSHLG0QiiZ@H?dPTBsA5YgbTZMrbb=S}H_$4>|k= z%&#Q_8v=2$m}SKfnbZ(rd@@2}MhKLl0dmz{-(mK334;+li5G2ZIu8gBc;9fwgaRFV99nWpXoQx#8%4kUO z3-7iGZ{LG*QmA93PPCPM#)`Cz=IXLC4M$a`{7ySG(K0Faiwj2FAigj;!bc<@<$|MF z^(B3`V)`XR1@|fX3@mMPzr!izjA%NO`Qppk(Oo6mfKV(ICUi=Zx&of&OmZsD8;wVm z`dSQ|az7nsF*7{Q4MhKAF?vF#86WRQ-iPZ5b-9V0DV7%+rDoEkX~pr{U ziX*khskvgQ_Sl^(4%Z(0=ZZtUN0mo4i^U2=rQ_n;(QWVxO-JFt3!#3fYR22Xhx5Lp z_8A%ax*v&s&SK%f15&WQ9ie3FvmsP;X33K=I1?s6`JikfYHkO}yCF?Im=u3s7KbnH zPk;L7f3>kQ5-IVH8V8V`D^4sl&_-Bu$Qx!zHC=OCx@R_iBp>$;5cL@MGB(CE7+1-l=58{)f&W97e+PRponce-kn{aCm@>V%# zXC6Q3ND9I16tASrfp@n5@qhGg zCL!0iqle5ns_|bSB)ty1_Fy*d*0{-o*#un~6=$P|iZ1$r2$9aY3D2^4I~<)M@`#dB zZa-ojXwSJH9WYB%J`8$7c!VDSMm$(VSujLPG7J3YL&5P0=?*1SgZpBF50(2u;z@cg z&erJpY)l)tGoGe&XPm9m{ZyQ-FP6m%2V-y3!XqO8cR>~M^s8G%Cel;2E}jWptlmAi zE80!9>1yk{f3!y@YIrAVcqe8nyq;^oy92yyg?DYQ7fDvVsAT9x^7QJvwuX0YzzZs0 z-x=^48?Nc$C0XHBvWIs~4ey#7-ZcR)s61W=-bvMWvWJ&sg;&WQ-pLx?$r|3tfEQFA zuMF@h;hpN?C0XHBvWIu7hIgulcPiiomB-r!?>gaK*TYM)!mDHt@46b^bv3-}0$xyg zy!cw&df{E)!%MQlt7H%F`WoK#HN5KsUQl_w5yQK*_L76mS%fn~s=;}c)2;l&Kms#v9ZX#ud-s9=irxhBe$%u%YT^(^$BKHtxI z)0B1T)lHk{sd=SWn=SN@TdSz-YOLE}bsTdWo+P9IeOEPWmfFJ*P@AK)&nHUHW_V&w9X<*l_%Evk&%Ue*2y1LQjyxmbnW!i-#B=kLc%w75`EH@fLJj(h>krA9Aj}Nmy{*(G932Yc0(*~*RY<>Z3kvKx692FNTQ3S!maJy zqon%Ht432QvwXCg)kbTxn)qLGOw*Yg)LH~)`LN9M32xN8%MJfno159{!!pu|9a2M? zon@=z5wQwRl)_WCIg8LK zMn6V8x0~pBZr2ex(Yh?t1X&Tn7>2|&n11z^Dt05KC406qiY zdH|fu09e-WInc!*Q^<}T41h(A@_W|bl-je(>7k)Vtzac;g;Ue2R=OJ+)CYiKC;UnZ zOF;rqwE%DeP_+QSA={AOI{@f9Pa-V<$}E&0g$os|01gMo9{+03JpJD6CKCGw&Ns}a zuQZyW-@t^7B(3_?hzzd7TUe}FxJ*ld-OFjVqSW9(mPqLn48HlSg&>U38TCly3^6{a zvS%Cf-47_v1{tD&n(kjxBa7bH1F&gi#nOtXvLdOw$h90)ez1Dr5n_hU!7ek;cBrT{MG4XS^E)Rc$8v zD_nJll%-jGlXcf9+8O=a7Kf9D$iF`MoMo3A`G^OC7^=r#T}i}ckt(jqq6YyjT&C^? zeT5vC-VBK4&FPQ?sgk&iu8q!I=@M{@(rO?EN+c>`9f z&EX4O_8}Iy27{DXDCFO3c$`9R3c7V4Q(B{f;*EZvoO2`R~zMpZpN zt1XQVARCaL)yIOjIl;PUS@b%6JYEwcyQ2DkB%e1mRxOlKS6oWUEI7Cdhd zvrzFyU-9Ju;|I?keTopP*rTsFWlm&q2wbXpgwdfPq>)2W#X4_xp@G3Z{q%JeQfgxPu%TV?#GZASDy(>q)xRF0>COV*1tdT}vhRPWr+3#bRAIPWt=Yo|Kq!u7Hc2J z<>&g?#p-kvGC3=wn^CzCU5YD48s1Dr)GcBK3Vc{2cK>{aDub5NF5(;Mns)KO73BQ@ z>Y{>c$V!YLDlAp+qvBK*ldu%n2q!UA2d8{$pT!T&>5F{K=Nz+2+LQ8OzvFyPBU5_FtDpo->HuigFQFt?t@qUZ~ zh9XJ$qYt04=|b9okfFbOxVjjHjLwi4MvSW0hs?yM%i*AOkLRjnk0b?Ac25H)4BL-DDlKG6~Rif%|gPpk<7b`vB*(@KC`OhWF*U<*RVmTN@ z;&kF>jRA3I%9;x<-$6HFZ~GkYBbH;KWGV?l*!=!%(uNy)xto|LfU-llf`aPht@C3N zniKxP&@>z1R_c!Nt{bjuB3a>JbcW(xg?hDr9?oK@GKws9(H;5Zw7Ms;47f$^;xTcP z(&ULni)+hv*V^;&TUXdry4xOVq1w)e~9a( zgx5^_;lO9S733~!KImUTQIQ~b7$kCZg)fdpS(j$m&-#S=%-ib3gt%#hLf4@HX{3#5 zN>PXSAtQ~Zh*3qc-c)h%c*{^G3a3FrizNn?=w6{#4G@Wzio@R@(>@7HLW+_{lSgOE zsl_J7^FxZ2tCB0+n^aGlJxVCZUspz$P|#FY=fV4Bj&8gZB#f34Tmt* zP{UJ5rI5-oogK{*3yyh%q?C!Gp6t@%4Ypl|{UC(m0NTL9nHY$*H7PWNS;d;}UNy~)eGU?yzz;$&*Js|Bm)zdiCk6f2pxnjfS0SinMPgj4UiU`72*Of<7eSx%ywNWzoZ-pNoryJthLqgb1a;}Q%EjMNHe*& z&nA)@+ckm6Q(4Uy+PUO5m2T-xrCWL}xIUlG6<>SIyQP^B*1EN2EK|$EiAtw*y+ZwN z?at&WiDorxb$eQB4-=DXh4wVTdcpQkM{5sVx}rU-|D)onJ+n#n3ES*M_`T1(GAFVf z`gZS=OzKsg;MXa)&R4yNv#aan2ZAt_stKrovnhoXk>5kHR*MuDL70Qg6dS`UD)MRN z*;M~NQR}T+HQk?NH$PBHY1bd|ts4+|R|DQpR}w6sm#kTl1UtR(Far zFA%yqKiodpY$9z8{nG3+&y98c+u zG4&emX6rRvKP!4|hqC!luhE|HG3M{}fN=g!Iy@M&^Sag7KQJgIW39QOr-gnD1@)W3 zEq{^bueI{SGj){R-hGS8>2&+cp?X#ud0whky}A61 zxHO}teZ@*m3%kN(aT^(O4QPHjpaI|;Md(*a8^m{=Ir3|+?^s+Iq`iXrT%s{`B}jff zG-{$kG7ylgrp%QJdi9OE79<@FwXGnDvrWA9t#tbo z%`-&x&!LYm?xh;b69szvbhb@gB&R%#0oLNZG-06oeHz*8_3S&_o^1)q_ZzD{su6#R z-efNOWNaPs%Dn5VwveDmDA1-uau;9r@6Myn_{@zzTZDzKBrgMmNKEkD*8J*5 zO?OpXifP?NxtA5W!|=o=8NI%P$JUKPW_o4R5AVFCJ_M$1?SA--R^cNELz@b^BW~3A zpU2XCz%paHP-JmwI}vn@k=(tHQR`M3Pb|f6D*m%p;*5P*&G|+zqz2c~wb609qMUL} zA2}x<1n4xM+Bbe&!6#Hb+e&7(wko-atxijFE%BI$S}9U*C65D9apA+g}NlXxhGHb*_3 z*33JzIuwc)$%WaUUm;JWJekm5K1-SZl)27bVOHR184J{CL>zXs>R%nyLP;NUoJ=s6 zGlKgOTUU6W03_EUymoD~`{O|p2yd2o|})-U?rhgMl$Vi*8^CKNu3Z6j#&^&nu>Jy`8M^;220(I0n+ypH+=Q{Halx zg!KwJRY(@$>I$Jlv@{;6*r*?|e2j%69E|rmj;?TMx5a84(8Gu~)_t=UXl6`Xg=$J0 z{ZyNw+H&-`Xg-852A`kLKv6?ltgoJ-=aAOw?OB5iY(#gc1AV8cNTLEf8@9aJ)`Pi37M+%xs_vJgI*)3Bw4F5 z(DY-VsWH$OFjH|8I~quzU5Uh%NJeT%Mm&-cA?d#$lFwfl2{x6+BHy`n9kkl&+adS) zm=HdR`w=W;FY7;Bftms2Eia-@q?cV)sZa7Tm`p5XQYjHWr8;;mbEVb`b){vZ6iL(e z#j>bS7K@1Tpi3%HrCOlep>R<5Z4OtuDRKt=F61GYBkn9hJ2WI6-t&3DonOk+@#2XntB5(!#}+A1}Ib)qn^hBQPYa;wq^B<;jl zobYpDHN%*k83L6-wkETr%y=BBihj1QDz(JBR`IZ^8Rjs-CB`J$i2MNh@tkzyAkMVVZz%KD~X7xT}S zAA*Xn08?xiuLZBINId7gA_42*3OVsv7ZG`5x5XU#Wle3Nmc~a;3o$Z}w)kq%A3g;g zarSp@hOKqH$p-8AYMfRb&$@<~qKENC3Oeut7i271AB*#4^)*_a`CKTquQ+Wdb>N2~ zeaiIv>;aM|J@^X(`y)Uk5c?{nZG>d0w0%Fx=lzF2K=L`Szp*&3^G2iy{1C}!eeyw) zCw%fElF#_$EhLwH@*$E>`{X8)oNFQsw~{QCK^97EyVz}N&~lu8kxH39w@v`|xqKRc zZFE5qB5^#Usus$MO*w8ZX);&PWwCL~FWsnj# z8RKr9yF|e`I+;)4qG4d7)h>bDt@2zxFyCbFFOgX3lcxDJLpYnJx`-E5usF42E?dt! z8LP1D@iuLl5gX+!s@z0~g)vD^NE7s7mj>&udDD%Qhw=e#Nlh1;#Ml9$mi{aO{rW3*>{F!_s<(Yg2NLeKw(V2Wg;u<=WPpcC`WoPn%s+;3h zm9&o)L$Th1bN#K&%|x>8_gSc&$w#Dxf^{vb8LqXp4adSV+(Lv&7N;D!<@sgUuX7HI znkmW@U5`*7 z!d0pb+%LQu7~1Y%o*u`jKD7g8((!R{p3^X2h6gcppwA^5QO27y$(bE+H*deO16CHh zB06`_HIcC^XqPo^{E)FbP6!PIB8bT2l+QkTHqKkH0G~4$aY5L@aAG=mt9CHlDhtu+ zlj7Ky?Z8eG2Lud?y%Ak@U}xmTK})i%Iw+2PK0A|-zt%R@CLiPOg}~Bl;X^Ir=P!mC zH6}HIzqt6s=U&258F~X}RB;l(#om#RYcn5g?1-$29cRpGYx}V=9pi?8y_|>??nk(@ zzo1y;K9Y*dA~=kqFQ0Rf#%H3SVsGp873T=1RDePNoHal=Ev2uF3OjQdq6fn%=^09P z4qOrpCCMqhC#KmWm(uU5ho=9y7dhONg_p>TDzodbF#x@|;U-VPO4AzK>5w<|d3%w{ zsmIofWwxUuIN3CO0s*$tb_j9ivN^&6EWXCiBv2CUB`6|+$0i4p959 ztyq|aQJIfzRfVIRMyqy|N75at0iYYFTLl0eyo7%XoCw!kdhn7*dx_hv&ZeI{gm(<3 zB?X|x#mD%bb6Jv)@mPF(R4BO`NWAxyLAVCU(+1%hAkP?tYk)j!5Uv68oI$t-$kz;=D@Rt6vhzuTk=AOydgf(8I)@zLz2EdU6? z@1_O-2m$bDQ&vg{fbVmY_VF=B(iCHLvhrzL#fX3`FqyUVL;dJ(t7XonVRHdcMT4ED z=SKoe0r*zeyxO2oMGb~NnYThd_=0@sl@``0p6FAght=6as61%5a#8EN3Y0fB?HI<$ z4#K)T@tQc&aYT43jPMYM*5Dx!Ol!=6SZtH*5sIj;9+4s*Y6R*A0*ynUE_)}uvaZ5K zAmVF1fsR00BT#7Kl0hI(fE+dmI(C2@GKg2TeTx?j0%1ZPhL)#GfG|KkSt^KEFn6W* z14cri_{-rdLV^XWC$oz6V^4zvaebmw^mQnR}H~V~yfbG!8PVvWobGc^vPH|>( zpXn@kDEgU5w6iRT*fL~4>cmVRnn>q-bOt8!2aiMq$)`W?EkYH6}?7azlBwx8<}ofNMx#2t|a#TT@xpAGu(G>yyC;^a^D zhKc4$b|jvtfsP2&D3*I5VzSa@O^U}$*peQWl+TgC5RSVaj$KxK{in3?PZi7vCoTT+ zryAQMyoQW37jZzv34PYNHd?%kyCf=~>&yY2s|m%w0=||%Z-XJJCoC0XP~DF6k?zOt zaydE_O;wJKT@EORBQxAh8t7VgmEm(2D;r82ze|xvU$uI%u=eLZ5xX41EZAuZ_zcko z*~l*ShgrgwmgH{LQVKO!nG09b0$euf*%y(JTjDecMkA(;5{Im^F7Lj{ZM3U%vD?`F z7gWJ!Bcy(dpj)fa(rblQVS?HXVeQiyXs!}xvF2ZnzboH38;6iOKxR0aAw1yc$ijmO zu2a3dxr@7pR0p_%D%fU?oSP9m(&S*HNF7NgW?MJSZjEG*_-yI5QolQHv(8U~kVjrC zRdiD0(@%lcgZ?vE*7qU)&Mj&s_O9*f=qtX(=9aj-O`zwuDCSe&+u^%28k9^;lgy%q zt2i|Y7CuJ_KRpQn)d8olZvDqpmnFF^Xn*T(?4(+-pO(pqPRZh~Yz?+I#6y^ZTd4P_ z+oD14qh@`5WW%C`S+S9dwU=7DWxfFy%c8P|A0++<%L~meoNkB&5-b+fw)6B2Mf^8= zK>y)7B~k#3dRl8hk^4gIz9>UGkES2Vp&0)kkMAg7;uBboZ(s33jC+9^7t-$VaBPuH zExyzo1jTR?UgpV_UCNN}%!=blY{T$d7@N+$ivjt*( zdlc$M5+eNRn7gx+y?r?G>U|uj{STX*9`?#^jti)g(P(8pF5ec26SB=CP?O>a8{#t* zgKRzG2@8<8Oi6moO!n&NKL|_%T7|;!@enL;7t4!;qi}}Oen*E^BW*{=h$6cuKt>h~ z2;TsiWI0>Y@W z?5wzw5DB-QxuWVnhEuh(0w-{}vjW=?$!I$(G}K9JOZWR@Z9edDm1c*Z(l+s{4azZF z{1~$?P4|>6iDmD`{LYFoLfrWfHsnlJZaM@g?5t?>rrcT4aHHq%tgv$D^UcB`44gcL z@96xU6|Hh-MZ-<#t-KTE&WcqSGGdfQ-9&F^#b(iFv)@^UH`zjfU-=Y=y6#HxqyE7%|a-Ta7v(R}g~@f~@K9TiZ) z=P|)_ClJoLo2CSHD_hRk_`n1EG(`&Apa3^bP!C3yYEUnqYHFuNqVlIGpU95s0F8G0kYRAQh5{xOPJw%vTMXsB;d!>d99uWG~@3>H4iupNNTsk`` zkNT(L+o>ML;eGpQuwB+tGXtuSZK18PnkV zquPq(2;-Z@9PQ>HY6y~URe40UNIAxa^(D_){-F2p&M+M_rC%o96+Ge?@ zR^$xGaV^-MS{6e+|ZF*@Es zc&VrBrEaU4H&TRh(e#H|XMo&SD0TBIbv@X5VIU zdQvr}JEsH&U`pP4X1H}4?i>r|l}EakE)l`KcF923S=_)pL_Ldl!|UXHLt1Z55?Cpy zs;QK0v2i*4P&$}KiD_npjn6J>+YJs>g$CF$gt&&(Q*HS|b$+5vTT{ic?R1Cr<*alo znhY_YzR@pAlYHt%WF!0G94`hkJkVW>14J^rI5+}Ep ziQ~^imilD;2>)cdaQM$xJpwdR&J~}Q*1;?!wvhDPC)cMG=(xhmxBf#(9#NboH|-;x z0z@6c?ps_Uew0b|OXM~di_7-$oNEU2*Th+<`%nl&Rhq0qCHe?L!V0>H#BC_y%JTrm zwC-P!Rip&#)#(`}zDVLUiQ+lfirZ;!T?C2=xz{iOqtm?DtJLN(_2UbDp6%zDGkrKr zx?jYI@E^Q~sbf})Ry^Lxe!Vk0yh+BAQlG-`pVz%C36qk7P+pf<;qWJGaWG@#EntNz zau8$B_?7#wX85)tSIy{c2V)nTPzJDrMW`XJMKg9;%OJ@v1zs1I&J|w?wr;yP^;3;2 zqv)ma46pdWuEweD0&k3Tg#v%f_K5S;<>b}QC$O**7^|^yIKhyIk#N2p51YyZ?nn+i z&NO1@kIB$&9My*$F9?lE=zu|P;erbmy=1R%*mT7r`-GdxdeR7 zxn(ZiSS|=Prtn9^0a=^9thnyWth}iZs+W+aNED z-c&i!GRZa3%QX>l@y2p3s*-Y{EF^R)gtEElFs>BF+0zIOCJqs?PnPdfH||Og$!&Dp zzyI2*_s{Vj&k&0$-kC8||2lQMQn{@3GY?B!x&IJRJi60KhjqV*C?4H!A&N)$hlt|Q zohYA0-ESp|NB5UgS?;#fI>TKqsO)7V>-tf)R!R zb1ZB-SR5bFK%k9-wpyp@>DT}dNZ%vG!$UvK?94ZV#Z&zD&o~27fz{yWl#Iq^7K?dv zge~Zb(q)R|bPSo4{9*HHHqq%ABSmvRDk==Ku;6Y+#mzLJn+#Trvv)c2NZr_*0RyiBvUe|I`e2x}yMptbAVLuFlG)Xzb~)`tVjj zOT%~u#UCgnP(K@^cS!WJJkPD2Pl%2~#Ukfdq}&f(fyadV8EG0LB>n`Afvx&|=wT=Y zoDy?tQeG7K?d*qzq!g4|mn>g2vTZC|L>wyNn%kl;Ps$xRRGh;-gZjrW(RddH2X3LQ z?20fZNkx51q2S$HXO^=1Pwe~orrnDTl23`ia zS-Wgw04R%&yVSL&IY%k*>~`-Q#RW=>ujn~FagYub3pD^dNu|w4q)(;{C3BcmI@4hZ zKP`(SFc%M`fGU!^*AVeLrd6HC?RELNS#eMwTR_T}c9!$|equCJRTNW7_mvENWPp_b zSo-4w*(-H_Y9QO`89jTIc-i>bv;6y{c#%9dkiD9IpP6$zYio^zj1d66)yP3Pf_K)| zD+k?9zm}<^!C)l!eQFAq{_fQruALqkP+$*g=!^w*75FvzQve6~(X0lGWBkU7|9zjH zT3A)GSmrdZYMcKcAFSa)f$dmN>S z(T+>UV0t@csWDQlpz#Ts;-G%a$*sW~Kd1=7GIgRgH*1RIaa^$7k1LyqIEK#CBcFQ6 zk4TuqlM28gOp`(VMpHhjK>@!}guzY%t33CEg-)>^)bBjyohqL?W?9?3pp%uC6w!_P zoO+QJlT(^4Nq+OGyGR1xc>?os|5l;_GgzEupLE*`$ar&P3}xOmv+7NuApl;oUq&{6 zh)2%5G1)KcY9I4Q)BlvFgnxo~nE)><5EA|fTIG>^M7M&_<9DqC(4s0Q&l zxCO;6^^{mp&wD|Gy}4kb_^05{#Ute!x}|wPcpa zm_jy(k-uW5^Vf+gc4X9@M@XZe5t9gHEhLYHh2&{w?Qyxq?<7^oWFl4|}W543XIa%aPsA}~c8CPIhFqEMolN`g|i1^N~al7!-~ z!@db6)$7kE*&PNdeJ-r@h&D}MGNfsGAMq5zLNne!uO9TnK^t}pbVyZvB@|cQ-43<) z{T4t!sPVCAKO1FY&Fw(`*ziF(xE*r$Adul%wy#U+DZcgr;;Nn+AfKHTmJN}b&=+We zJA#bcQA)N{WwlWWxJ_kajDCI{h;z~KM^Y{^YC0#Q(*7p5NBmMRi=qRNLi{_axsLEP z*vDiD&+SY)mX8he?^*p&>72UhOV6hzzjaa;XKUzZcUi{(gp&YeO}^-9z2f*5<!H!N;03@C|a*4ybj28l68( z{c+@s7;0jt^m^WncHc=;hS^KQ>|%$}u?0bO6>6)^ZB{!Wl&*=ABCQ2g%;rAOUKurC z8p#`t&;<{>{*^)Tbs{3Q1W<*#dH3*uU|MIM0Cm*U&+Aj%lpp5_jJPijfsW=NPGy=&H7e?#t4ut`VJIn<i%Kq6wt?jYVg#*HDqsyQ|S=s0^sC}!8x({xPjtuP5CYevLgC~|ODCwvc zET%YQh7<&Aa&tMAs^HaBpI@6Nst*)1YGxtAh`vXgip$0-Akruho@u=Of}C$`Vy3DT z!O(a#JX5yhQluguO3id7_0g10^z)B*-Lk0BtkhyCXh&YL4uHvEVhm#jy$3lCMvD|d zA;j{gXRN=Z_3>6@mgpCm(G9tZ%oPL;5{SrLK~5XwL=U3we@^qo8GCcG_eQ@1iZ8kR z5`yC+ATGyfQJAs2B4IeMQU_t93;oa=klMbYDDcah4#J#IjL=( zmm?@IXQG?6A}*&>tCWomh_bW%B=Pe~u(2uo*GdpanEiqh3TZg31RDu5BA_Uo#77Lmt6x-tHQtZv&SsVD zmz2Qenf)J1;N{GIS&46uSW*J7aP})ou&pBdRV9v-_%$VtkocGqA0zSWN*pHfZm;4K0dNCVX%y*qWf`9wT>@`S-+2j!{#3!>KQJUWu zLcU~oVl&yP6tBfaZHc?|RzIZhI&lr#VqRZ->yIA$ax44M;JjbuOJ+Icts$?Orr8m9C2Wci&hLTG`d^XDpRuv#yhm=ex5Xbd7v-eqF{v4*6t$Lq?EbzA3*cySc3V z-m)=oE*tljvaxS1-``ihpDW+bm+$wL@84Fwe|!1<9p(G`>7J|ITljhBqi)u{l?XjM zlg>>Xb)%MgzsO&7-``?+r$T@zzIpha&mE%~!t9|~9diC*)Q1rbs-zuNsrAOVB?pn7OQ~juW zse3a&i|s#o%~AK-S`k#(xp%6mw1Yxr33pFB;2wGfJ z%TI+bQ-yo@fn1~-miRaJnxF#%s6V*My3)KC)o@u|!Nn&NRoTG6Rg!ya50|>f$bIQt z{+9FV`c~gI>gsFZyOWx|)@_{2-+7c1Fa0nofPw#AmOp(p73dXI{A-W~cC$ZOQPpYUz@J$~)ESA=?33{p&Kq$MK7azRa2=vbS()9 zet$;f`?dI25<)gb-jxKKw3`c_v(7DYA*?p z|32{#y&`lB2b{9WT~_1zN%a@RDY<^!k9dP|(H+!p zTS<4?{&wG%^XdKu$FD*`!oZre??=Q9)|Nkr>qW4)Uv1g!ZgBJJ8h4Y!{p39AfunA{ zrGl*A=nm8cnVRArqu+cscLU$oKA`Rc>Lr@wD!Kv#vfUQ|z3P;qo~3B7as%1w)=QQf zC8<&wy4TezMV%R^>yNtkRD}RReVz10>^|zQ ztL3J;7pVzw*v2ZqZ$e2UB*;K5KNZeZVet1D2|q!=Pj^*KDA^wDrNEP$XjAL$gKN_U#8;`m-t?Y-)u?=RmlJj0b<+OX_ zQFn9gi;8P#RDG(Vr~gqcCkR*Se^p(}se0NU!bas88L)zBIX~#`u|{0)?hX^y>yNr0 zu2l(QJNJlnz@xPefIubV|KL$~eJwvt*eJ$l8mwzMK>Q5u&ew9bTtLg|F+LquHKAgb zP**to1+<(VGg*tt{Ec+a>n6#_jdi3Qu&6(2SD=2ln~>H8fc1@2H`{R)6~nG;a%N7Cf5Wpt;>)%I~XT z!Jwb7VZp4QTY=@ifMt)>=-puU)xJO5-oSNCGkl#+#4*3S0Z-z zS`xoR>i(eo8sEg2`~BY6xF}i-VwHlEf{o>t#7)71g(Y!Rr0x&PuW?q4xf8vw@maLo z4VDkLMZ>+xl6Wp+_eM+NyugKkac)nzFjCD*_JAK_3@=w`#~O2;x*P4~8rSnTAY2>r zD||nG1BcUN1X6^r@O>n1*1o~}F+w}TE1Vz++OC?08)Sq=gjXC$=x(w%YkA=Xh&^)p zi@VuUg&#xT&(~|*YY-{3-s!>1v*Obq5y<;K0MVE=?oNTc3k1;poP_k+I_@jnUFBG` z0K@)Ng}JH9C^4_5bZo% z!nMl4NraBKL0YFNoq(87{--ccEgiy;oU3WJObPN%U(`Lzq;wpf%XmmdZw%}2&lF;mh_FPp65e9h3dp_FYB#$*e?kOI7zTV1% zyQ}~cLK84nX^*dNSyr!Xxw;{tZww^}sM5=Kz5A{lcx^X{|c)E!^$nY`xSTytb2sNqGY#gc)>RioyT}W$ga!BL z%z1QCv;pcR7uoZCEE|~O7AgG#IAITyLK7(`r?nHT3?)uLSK|k)<6(vT3?*< za%Z^sXgY@&r^e9bFw0$H<651+BO6;(POg2G1eMtkBr1Si8ItsY2^j@qLQn4riA3u$ z3vQaw;)=MAR(i>|UiGj+{mXUELMm3A6|>DixS5fLt+S*o_KstTdt z+mNRs3UO2oZeiimODjmTqFGHx$?%J4ru}OSMpdIia5;S2VKpXnmWK>R_%88vhBS@Bz#;^LvdAi zge9>Czon&GA8~K1`T$Fb$1SrJQ$^h>XwU>9ZHHNX(?)b#rVJsy@!IH5l_ZGgOS&^J z|B3GG`#7mPmeSvS@!T)|?63Xy*{??L=a2#cF_Zq=|9bo@pZ}fz_Y0eVL6#AjSHFDf z@4o!SpZ&^vfAIi7^xqNLR)6yTkNnU7^~WFjz@O;rC4jSk^WVR9?$@9EhbMpi02>~Z z3%AQ>{;z-gZ%&>3Z@>K+eG1t}qzCqEyT`%V-#GiH-}?9e^{S32)huh=Pus=S*m0OMV1Ph_q_bF6qV2CFtr#=hbJf z!=_#Y5^mzz1GsQrPH%DZ|!ZR13CZK7(L)9DM{u zK(RpLx`JWgh=eZ|4sZY)LkiwdW$D)MqR>#7OODD&c!9!vTcMUeISoqi(`+0rK*QSl zog5vyCi?KlFIVzbqm(V=8ls||LQ#x%eotFPy9Vc>pDec)PEgxZHh(gnPJ=I{4^sv5 zb&$*c4bQ&-YIMR~2(46W;1+`dWl|{-p2t(&7820xVVw*tqp07oMNjV?l@i^lslB7p z^E)-IcNFml0FeOMrFOATL;yd$Jpd7Eq9o)%hIX{FUI84TjS?O3r12cl^)XAsbe;H& zqgsp`I^qU(E}7tk2wq5wU#4aJ;M#TudLJcxlcUQ!2eSO=%E8<9XrHpi=7$^`1VX_Af`hpg$rFko`0nM8|917Oq06Huy zMoh}gQaA;v0-Ryajf=Ha5Q>88{WL-g6v?8gKh^Xi1B7Qa-=Bh2k|ixR>2MGq!$MKp zqfNz#SzC&(QDB66or_srDsaXO10x$phnU^Pjv-|sR-we&QIToS?vl{wxw5-RqBeV} z@S*WiY?hHww40%)zz)Zu&laA7N`I0t6*1BY?gZdVsb>;;#-4E5=>AI1DJ-8A1nG9V z_xU3~EEJMw3|qlp#kL81&$bEOjm{jd;?qoNoTg7&k=YgudG<@?_6Z#a4cy{iyb&O3 z>QHE?8w`LUkxPnwspt)fcNIw$o}rcXQewSfCaU#L`CP``aA0?FVwZLvKsxq5ysY~Y zFEU|)q3zM>SJCgOw5*}x*al@Ib8&duq@lJAeB(>(YSI?uS34eOqW?m>Z>M0+3q(0U zz9}Sf%x_NxecO701aXopwjcNy!&pK1yd{Vm()(?cGM+Vg`x?~Bo{3()Gx`mF8dYE1 z4w*Mpu};O(v=8dH-xZNT!T0`4#5;rQumV5%>d1zj(T7PFADvd~!L}0_Gc>EsKHXi( zP2eVY={gWdkk=0CW}^n1x_T#dlhn3I^-9T`*g6KFhrBRhi-iH`q6$C=3!m7&0PACI zQ0d>5-VV_B3Eluz^I)uADf?rj(61d9pW2CJ9xDC|^k=6r78f&vZCSoxNBKjHj98=U zE?SNPQSPX@FmXi-!jO!*&?#Y(rYbi%3%?z*K%oi5EvDi4W&{THQ;0ru96!Dp6?o$i zAUPJXHgL5NeG1}dM$-`;?Cn{aR_J=C_}_ncN!a6*!e;E)Pz=A!C$j8JHjo4pHMSjG z_M7YM;If}-7v6Cn!_O8Nc5vC27x`)?v`dL|Atcix1?H{V>wp*-E}&P zwe330WW|T4=b>+49L}g@>UARuzBEcK#^M!5hq?$#8RvKkz%#dAs1K#_v$>ppvynwl z`u#YRd`C4fG8l|)lib7Ga$x9m|DkQkbqavApXMA=IG2$s(vU%*&??j% zo(8ug>cD_f^s!-`!eBv|OPu*BD*JIpR3NXH>@`v2+sG-gJ|h zL-Kr+1R2ih{<};T1pduf;9o?Q&JqVpNMdS&4^mJ`gAfraQD~6U202oLoHEE#4RX>T zhii}%207G&IEb>C?n;)MFgvtbPW={olFy{pf0`Jp2w!3wt>f4-qRii9)~nuWBaGz- z&aRQ_xCreuVDFP1lVK^bm(c0AuzYAKoKH7~Z4ZUE0S_r~SF*se`W*)Jx&PpwRZ}!s zbIC3C8v4Zf4TWa)h7wa-HI#h?XvJ*xr(t*aEg{Bh#%V7^0t#)~4?+z&S?N37t7_xn zm7?a9du12|w9ifnv3(47rZ*`caoy{Ta)W}AT$>O=1+{uY=OnDFE_AB={kl4PPEqzf4yd3v~XmdPoX>U7E4xOQ}_sjV#gp;NQ0B6ee9k# zLiLW8jj5iKx2txvtTe0&VgH=;B^6BMC|Bv*e%PfFM?f&l0^~U$@^M)CQr@cb;!Ih@ zV-{4qRHdf1GgM3cka@TiEvc&Tdh*!e)_1y8M;h#)S?M;G7Iq~svt)Xwubrma+a0^S zyE~;_-kFU+WD@t}NpaA&_BKRK8ZwjY#GJxpQ-_}eygfb zu9$`qqZU|O#3*=js0&bbEE2x%>%w#fU7-ubYKNEAjzd^w@#%C!m7O{M~I%Zk&K!=Oye00vk%r^5k!r!J@ zSz;t6OJOna9fiffcN7)_bz#BgA?zU5H@|0LF%X1>j*RodV!(vOKuuT-n6MbA35$WE zE-bVkCUue_l}wRI>v!yv|uxcm!=u@9S$I4h;RrKN;2~0QnN^!*nsTmfq{AJBbayTjMJ`t!uE~3KEvE$hIn!Pcb6TLUEGJz^5U;2# zr`bsmOZwP!j>1_B4PARE46AE1!-{(rz8tptH_G2AvWCglqMQ9p62e8n|D&KZPjfGn(49fIIc*TG0dmG5Tmxirowa>k53*not|8Ak`-*FToHYp706An|aSf2e z2H_eYO9tT@AV&5{71LUMZxCY26gK!Oya|YoWAZHE2H9*c7glmAD zHVD@eg8n{_{tg$SzoO-u7aGMBlRc7hTiPjFE3suA>pBxWTAlxmM>SYr%Iw z#_t`bzm`tuyg}HAStscFlw|G!86^$8OE~zXbn?c|`UPYsMaUfHtQ_4sPUnQmax$-` zFW^>r@|#Cp#{$S@>Bi0CeX=(6L(F*f%>Hl~cwN~Z3SDFI+FK%WB-=_rJJ|KS)JAt| zjggMteWwl*qWMEQmO-AOhR^ElEMzn>Z`gzfTUm2fcD7~i7EgG?kdVNejC%Hi?26#v zcd5W_xrSfJFdRP5FjQcIieG6M4zDl_hrMBl_sWEf(?%2%<{Fl-iwnw;zAn#9*|l26|8=W!3aO*$~VL5#4Q!WfcOI7J3!oyAYl6G9X0EPgu`tB|vRWfi8SRS2!jD&*i7S%sMW7|Q%W zD?uMCtU?YW#|)!4WEG~NuB8P#QT#&FTZL1VRmiUj$SPEuLuEP1RaPO^YR@Xftaa_u zhBd2@KzRcX6@Kj`QZI)cMf^b7C1SuB{4L3p@HJFpJv*2>V@GtY4A{mPZ}nC2=y zrdiWtcv&hjGo{+mT%mTzx5v4BH6=s3O!GWlrdiizOj+T0y4qJ#Ryatj203RCu0f(L zAn`c_v?lQv4Z=0#Ib;y70dm+NTmxjuAY23Fh(Wjp$T5R(4Uppo;Tj;z2H_eYCk(gKB1LUkhxCY1q@*Qdf`HtV*@^B4#7A+6g06An3t^sn` zAY21v$sk+<fIIc*TG0kVK1 zLfdPK$T`cyHRL&K5Uv4o#voh+WYO?&4Uj_y;Tj-^4Z<}*mJGr*K#mxMYk(Xx2-g5v zHVD@MIc^ZH0dm41Tm$5!LAVCUDT8ngkkba?8X#v3!Zkq78iZ?roHGd50MUF8ReNfg z9S+z$PnlzysO6C|$H8wk$dW<02Fy~vn?+suM#%=k6=_l$Sk1~ta&l^gZ*f*}+;0yT z&Mf_uUwDtztl#=8pP7&5nU8c5omNZi2UD1i^;_Q&x1is&a)@xyWX*gkU!Zo!Gm#UIGt{&j#rE+0 zRy^6<-jq%1_Ig~x9XS?fl6_LTx{y@C0H{C9&728KKm5k}xSB)+F_B~twDh6tMa zSY%$>VY&&T_9-~08-`mn6ebB^V3MWk5qB(ad)_?}CM?bs$xYcht(v@Q)__qr6> z#xR2&-C)NkkOTn^$ZY@>C>BgSqfSjxc>*X9rs^bNG&DRhjUfsIP$5taO*@_kgXi~O zYoGI;^WH04HiYT(Ont5QoU_k9d#}Cr+H0@1_S$Pp$dbrj>_Mo~dXgf}KE^73x z9X30bTFj9muOBqkQ-BOe6NIB~~a+evEr@P~nGnR6yk#d}gW~99o^;gF% zWwnvQTk?#jZ-eb3u&pu`$kB(lCmZ=sS;~n<3UA3nU3D$IC55``lrxsXw{^-{OQHNa z<(#FEvrc)&Qpj1SoVOHm)+rY(g`9QDMN1)Po${Qekh4zF)H6~%v^quB6Y$VTVX7sC zoOK>exZtyq!cT>yPS_Yn%fa%*MVZ>f{3N)LGaDC%Ok!uG zx*f_+9=2mr!?Ok+E}sLwL>(KA)iG&eJlAGrX<|IrW@Ra3JlAGr)2c`q+lfu{A_Xn1 zZklv7hIS(b!!arR)_KsyNEvHnri+m>*2ozCmS?PynJz}2)mq~~RzwGZI2$R)EQQ~? zuH%-%Z=G_&QuwV?PFf1Tb;>DA;kQmXZ7KZLDQ7H&-#X>2rSMzHnV`(L7{7I? z)>6(lQV>$v(beY&d;H!tGq14Nap&$L{9%=sjMGF=N)g8N+UtkZPWkr6Ps>c~{Y z?N5De@Y=y?_G`hE`+b^I&Ipt)^1+?iq9Tz8Z==_f5>E5=6t+g|j369&DzBg8!RzO7 zdHvw!gD}!BA7@CL+t1@)rgKDe97q71Pxn&!^>`2^@51GWSjg;ss|0BVquU81DrQ?7 z7Eo-xnPGocer7Y(M?JisZR=npfnNT977e{HSMOL}25i+Md63JMnmk#uT>iNk|M18- z6k&QbR|H9hJyoEC#BfoI%4h!x!V;qUf15?+?{MEoc$rz|v9~{(0jwT{s!l5I*kPnz zCly$oBwL+=OLhK*)oE`roT43QJL8^6(tL?WiP}j)Iu{kIoW6;yTSVe|EFw>5r>}-6 zE{zfDmqM)COF4m(1|as8+$%PjLz!&}99b!^PXb^-oI_dMiq+&I@)egZ4pTNB?$;ImI<6 zA9yLe4=CGFg^Mf6vp5;JS(0r-KN44SDnerKZfIHbeucaKacE`WeWN%hl+jS z-JQ{DFW4dZgqQ)?bW=Y)`jt6glRy76))fjNy zYRpzOX2I#O2PCeNKJd-CcHXmQ!;1 z8&7n~?&$Yp9=ded=|}W<6Ic*|jyB`d$fidd0{zi7UQ}X5$xqMrL*AWFE2wvO7SB?; z*h~0ZPU30FmO_D#MBf6RMIIL641Bt#Kf0>uVFH424n-Y}5p7IZ@ultPn6$)OQRSf# zw93QfPdoPLKIhnM`(Y^Iv#PPf!2_DrhNRf6Gz`pA6ELfjRJ&44+u+CDTP6U4&IkW# zRh;!S*;fOAJ-b_}dy8ymcF-0+x|y0;oj=L&O_`8&^*LOQ6_2xMmw2pUPT|U9R-?-R5c`Fl_F^rP-?0gcIaDejA95f zXKKgbpu|2YVC^#kt=z{w1CZPU{rDU<@6#~*E(3h+BHKq)h7l!jDTe-MN`Xh=EUMEx$>QlQ?AOH>RH`k!$6 z`jd5%{v`_|Ag(kErDi!I6s^cPy^@1sWPuf{nOYhu;LcPwl(jg5rLYn$nK4W9i0-18 z2=0WSjXe_}vFP)TMU!P-cO*UbU|a}6#U@1_b7mk>4Rm%#SgrS_TZ@fLsSeko`h^0! z1m{7S(RL3jE(X~Zppcspn^Ghoy*`)X{Lns0eboQ4=ThOip+DDO_aD#xT zu3*ur(nU>pA!m?1|Q<~$zknIc&YEjI5cI~v3aTAD;ssfXAl>Pg9Z zRH~iM=7`2^fdv4D#wrw2fg#F6{}gY5=pu9rjU8qIt>y?K4t#qB-npHU} z1v)qPB|rCRU8tBXF=v$jha&cIbRIgyJ}_d(0EseG1PCH{Mj6{N$9kkM5Y>@tFLqW& z-(v?bp+4|r!GXvQI;JgQ0s>pF$fywBzrzQbmbSJokFGQGg;>e-g)5VduI^C0bP%YY z7o5^C18^4`DvpkM7Uk)FzpwFrFKlkd3KG8V|!R&#Otd#@Nrjf=7V}8A@M(;-hBAGUA;l7 z=wzMsG=?TbxKC*}kQQ)E%c8uRcDMrdnLprO{az8 zTGKJ@ciuG}2O7?0nvUQ_(`kKHYdVQ+gdGj5O@R(v(-H9!;lMSWdl2O4$#;}!I!Ne= zDH`uAyRup)LP(3|ef* zCL&Y6R2*V(tGHVI0+DRO*EB3yO5%XchSb1bHYJ%#Q$Y)21CubVs)JV5rN??SpL~eL z+?a4|y3dgIhj#I{PsRz^&U6iv?Xbn#CzWg`%Bg^{GEfsuS5jlLiN<8=g`g|7*&wQF ztt)ZLIOeGLpf7TlG<+(%!mPoFzb0$6 zdU5lUreesX9QsJ`$}%n;tc7p&5ld}BPQ@;;PzWd7+(_I%E(gImm)GS}x*R}|;j+(Y zh?^0UCYPCFC~b_pK|W)X=1irH%~wsnt%DqaITe48TpHl^VZH_4>9i?QB8j1dz|AQUffJq!wR4FRDs~{j5CV*%n0Y_z^I`2(pq+iO8iomm@ z3Qk~(qXZxiR@p|BP+_b%#l?)KsaVScSc3LPv<-Rq3n&HzCW`);rcp-p?-7zN*gZjGSwqat zC!D!LkAHx&nGu1H3^sdQ=)8ds;JcIpAES^rP^`<|j9dXC?SdZB$)1s9aVSrschNT< z5BV#s-o*}TN;XByt7d|K5QZm$#8|LnlKuH9gdd39OSR%CI*-&s6WQ;TdaJ{LE72aU zi6;~7$&N(d0tz=BgJR%oXAr3<+YB2ZXLKF7XMRBsk=4%F-9U9i*PEw5xSNHISgU`> zP@R0WK}!d&?)pN<+Jz12jWj{$q^=S8r=YC$1%B<|H)$PJ;uQ=09LF|f-l*0!Iu)a% zY`4Xv#*~X`@h{DF`8;?fE}e;twyrT(aj>}t2O}PaI2arY2_u^pBV$I8(0@CK>%w$8 z7GyxOsi_slbpS;@OaFs%hMt6{OZ`DV?d1(5b6?&F@;||&Sm19gZzQ4;U*K@?1RPr6 zp$IQ7G0-uGotMURGUo_xzo(80DQX+pJXxvBb^XkfccmCFe;yu@zO1nvI2+d zO|s~Yu4Kl5ArTYht7d5;<1OX8IpKxX5AXug+o%CNSS6@Qm8}v(>@%X&R>ecG(h+)U zn*^~5+`DSf6aVi@N7OP1fM_P}rvka0N+UYr8X^?Vv*{Z=r^->MynyLXFzZflK ztWlHEms-@YRZV79h$buGvhq$8=&C^zwBqHHpv1>ky$4mVtoNzwF}4O$YX%*yfe2g# zwbo}4i3w_aCUdyxcT)h^sY_vZy0!*F#yg<^F1L&2THoGP;(;t}A&SaRKcTpAwj_dp z{fh|K9ace7ndZB;3W962jhXH!S1ETgO{*}8PQ20z%SfHvo7IT!g%Tu9Q$k0pAZh@r zO{)P1^raSYQclR`)m6k6?@Ibcq+s$P?6HJ0#y=xi(``CCMR}?~x-2Iid$9-*tzs8c ztk$vw5S@s4C7xN4uoWOWrpopp*`h(h$YP8z0SY%X0HK#>f`3RXjwnZV1MXaEByB7; zrq${M&<(SZI>Ffq7jv+otO^P%8xZR8hY-?gg^hbOa*&hA8hY8aOPcJOG m1klqh_o@R;A(KMZ`oq5t(VxEbzF< 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

mWmHeE>tD4Bu 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 G+J68xJt|TF literal 0 HcmV?d00001 diff --git a/assets/dusk_wallet_core.wasm b/assets/dusk_wallet_core.wasm new file mode 100755 index 0000000000000000000000000000000000000000..55e021186ad2ca0aead8198cf32bf0f56d3c0ddc GIT binary patch literal 388808 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 wZ&oIu<(7Dl8u)q>^$(UK8!KpK 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 AQUCw| literal 0 HcmV?d00001 diff --git a/assets/schema.json b/assets/schema.json new file mode 100644 index 0000000..7c418f1 --- /dev/null +++ b/assets/schema.json @@ -0,0 +1,389 @@ +{ + "$id": "https://json.schemastore.org/base.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "SeedArgs": { + "description": "The arguments of the seed function", + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "passphrase": { + "description": "An arbitrary sequence of bytes used to generate a secure seed", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + } + }, + "BalanceArgs": { + "description": "The arguments of the balance function", + "type": "object", + "required": [ + "notes", + "seed" + ], + "properties": { + "notes": { + "description": "A rkyv serialized [Vec]; all notes should have their keys derived from `seed`", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + }, + "seed": { + "description": "Seed used to derive the keys of the wallet", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "maxItems": 64, + "minItems": 64 + } + } + }, + "BalanceResponse": { + "description": "The response of the balance function", + "type": "object", + "required": [ + "maximum", + "value" + ], + "properties": { + "maximum": { + "description": "Maximum value per transaction", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "value": { + "description": "Total computed balance", + "type": "integer", + "format": "uint64", + "minimum": 0 + } + } + }, + "ExecuteCall": { + "description": "A call to a contract method", + "type": "object", + "required": [ + "contract", + "method", + "payload" + ], + "properties": { + "contract": { + "description": "The id of the contract to call in Base58 format", + "type": "string" + }, + "method": { + "description": "The name of the method to be called", + "type": "string" + }, + "payload": { + "description": "The payload of the call", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + } + }, + "OutputType": { + "description": "A note type variant", + "type": "string", + "enum": [ + "Transparent", + "Obfuscated" + ] + }, + "ExecuteOutput": { + "description": "The output of a transfer", + "type": "object", + "required": [ + "note_type", + "value", + "receiver" + ], + "properties": { + "note_type": { + "description": "The type of the note", + "$ref": "#/definitions/OutputType" + }, + "value": { + "description": "The value of the output", + "type": "integer", + "format": "uint64", + "minimum": 1 + }, + "receiver": { + "description": "The address of the receiver in Base58 format", + "type": "string" + }, + "ref_id": { + "description": "A reference id to be appended to the output", + "type": "integer", + "format": "uint64", + "minimum": 1 + } + } + }, + "ExecuteArgs": { + "description": "The arguments of the execute function", + "type": "object", + "required": [ + "gas_limit", + "gas_price", + "inputs", + "openings", + "refund", + "rng_seed", + "seed" + ], + "properties": { + "call": { + "description": "A call to a contract method", + "$ref": "#/definitions/ExecuteCall" + }, + "crossover": { + "description": "The [phoenix_core::Crossover] value", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "gas_limit": { + "description": "The gas limit of the transaction", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "gas_price": { + "description": "The gas price per unit for the transaction", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "inputs": { + "description": "A rkyv serialized [Vec] to be used as inputs", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + }, + "openings": { + "description": "A rkyv serialized [Vec] to open the inputs to a Merkle root", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + }, + "output": { + "description": "The transfer output note", + "$ref": "#/definitions/ExecuteOutput" + }, + "refund": { + "description": "The refund addressin Base58 format", + "type": "string" + }, + "rng_seed": { + "description": "Seed used to derive the entropy for the notes", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "maxItems": 64, + "minItems": 64 + }, + "seed": { + "description": "Seed used to derive the keys of the wallet", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "maxItems": 64, + "minItems": 64 + } + } + }, + "ExecuteResponse": { + "description": "The response of the execute function", + "type": "object", + "required": [ + "tx", + "unspent" + ], + "properties": { + "tx": { + "description": "A rkyv serialized [crate::tx::UnspentTransaction]", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + }, + "unspent": { + "description": "A rkyv serialized [Vec] containing the notes that weren't used", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + } + }, + "MergeNotesArgs": { + "description": "The arguments of the merge_notes function", + "type": "object", + "required": [ + "notes" + ], + "properties": { + "notes": { + "description": "All serialized list of notes to be merged", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + } + } + }, + "FilterNotesArgs": { + "description": "The arguments of the filter_notes function", + "type": "object", + "required": [ + "flags", + "notes" + ], + "properties": { + "flags": { + "description": "Boolean flags to be negative filtered", + "type": "array", + "items": { + "type": "boolean" + } + }, + "notes": { + "description": "A rkyv serialized [Vec] to be filtered", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + } + }, + "PublicSpendKeysArgs": { + "description": "The arguments of the public_spend_keys function", + "type": "object", + "required": [ + "seed" + ], + "properties": { + "seed": { + "description": "Seed used to derive the keys of the wallet", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "maxItems": 64, + "minItems": 64 + } + } + }, + "PublicSpendKeysResponse": { + "description": "The response of the public_spend_keys function", + "type": "object", + "required": [ + "keys" + ], + "properties": { + "keys": { + "description": "The Base58 public spend keys of the wallet.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ViewKeysArgs": { + "description": "The arguments of the view_keys function", + "type": "object", + "required": [ + "seed" + ], + "properties": { + "seed": { + "description": "Seed used to derive the keys of the wallet", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "maxItems": 64, + "minItems": 64 + } + } + }, + "NullifiersArgs": { + "description": "The arguments of the nullifiers function", + "type": "object", + "required": [ + "notes", + "seed" + ], + "properties": { + "notes": { + "description": "A rkyv serialized [Vec] to have nullifiers generated", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + }, + "seed": { + "description": "Seed used to derive the keys of the wallet", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "maxItems": 64, + "minItems": 64 + } + } + } + } +} diff --git a/asyncify.sh b/asyncify.sh deleted file mode 100755 index 75a821f..0000000 --- a/asyncify.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -arg_list=( - asyncify-import@env.compute_proof_and_propagate - asyncify-import@env.request_stct_proof - asyncify-import@env.request_wfct_proof - asyncify-import@env.fetch_anchor - asyncify-import@env.fetch_stake - asyncify-import@env.fetch_notes - asyncify-import@env.fetch_existing_nullifiers - asyncify-import@env.fetch_opening -) - -printf -v args '%s,' "${arg_list[@]}" - -wasm-opt --asyncify -O4 \ - --pass-arg "$args" \ - target/wasm32-unknown-unknown/release/dusk_wallet_core.wasm \ - -o mod.wasm diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..6651056 --- /dev/null +++ b/build.rs @@ -0,0 +1,57 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +use std::path::PathBuf; +use std::{env, fs}; + +fn main() { + if env::var("GITHUB_ACTIONS").is_ok() { + // CI doesn't build with schemafy deterministically + return (); + } + + println!("cargo:rerun-if-changed=assets/schema.json"); + + let schema = PathBuf::from("assets/schema.json").canonicalize().unwrap(); + let types = PathBuf::from("src/types.rs"); + + schemafy_lib::Generator::builder() + .with_input_file(&schema) + .build() + .generate_to_file(&types) + .unwrap(); + + let types = types.canonicalize().unwrap(); + let contents = fs::read_to_string(&types).unwrap(); + + // some limitations of schemafy will not allow it to parse the correct + // integer type as they incorrectly fallback any integer to `i64` + let contents = contents.replace("Vec", "Vec"); + let contents = contents.replace("i64", "u64"); + let contents = contents.replace("Vec", "Vec"); + + let header = r#"// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +//! Arguments and responses to the module requests + +// THIS FILE IS AUTO GENERATED!! + +#![allow(missing_docs)] + +use alloc::string::String; +use alloc::vec::Vec; +use serde::{Deserialize, Serialize}; + +"#; + + let contents = header.to_owned() + &contents; + + fs::write(&types, contents).unwrap(); +} diff --git a/rust-toolchain b/rust-toolchain index 67946b1..bf867e0 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2023-01-05 +nightly diff --git a/src/ffi.rs b/src/ffi.rs index 9eeaf75..6fb57b6 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -4,686 +4,419 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -//! The foreign function interface for the wallet. - -use alloc::string::String; -use alloc::vec::Vec; +//! FFI bindings exposed to WASM module. +use alloc::{vec, vec::Vec}; use core::mem; -use core::num::NonZeroU32; -use core::ptr; - -use dusk_bls12_381_sign::PublicKey; -use dusk_bytes::Write; -use dusk_bytes::{DeserializableSlice, Serializable}; -use dusk_jubjub::{BlsScalar, JubJubAffine, JubJubScalar}; -use dusk_pki::{PublicSpendKey, ViewKey}; -use dusk_plonk::prelude::Proof; -use dusk_schnorr::Signature; -use phoenix_core::{Crossover, Fee, Note}; -use poseidon_merkle::Opening as PoseidonOpening; -use rand_core::{ - impls::{next_u32_via_fill, next_u64_via_fill}, - CryptoRng, RngCore, -}; -use rusk_abi::ContractId; - -use crate::tx::UnprovenTransaction; -use crate::{ - BalanceInfo, EnrichedNote, Error, ProverClient, StakeInfo, StateClient, - Store, Transaction, Wallet, POSEIDON_TREE_DEPTH, -}; - -extern "C" { - /// Retrieves the seed from the store. - fn get_seed(seed: *mut [u8; 64]) -> u8; - - /// Fills a buffer with random numbers. - fn fill_random(buf: *mut u8, buf_len: u32) -> u8; - - /// Asks the node to finds the notes for a specific view key. - /// - /// An implementor should allocate - see [`malloc`] - a buffer large enough - /// to contain the serialized notes (and the corresponding block height) and - /// write them all in sequence. A pointer to the first element of the - /// buffer should then be written in `notes`, while the number of bytes - /// written should be put in `notes_len`. - /// - /// E.g: note1, block_height, note2, block_height, etc... - fn fetch_notes( - vk: *const [u8; ViewKey::SIZE], - notes: *mut *mut u8, - notes_len: *mut u32, - ) -> u8; - - /// Queries the node to find the opening for a specific note. - fn fetch_opening( - note: *const [u8; Note::SIZE], - opening: *mut u8, - opening_len: *mut u32, - ) -> u8; - - /// Asks the node to find the nullifiers that are already in the state and - /// returns them. - /// - /// The nullifiers are to be serialized in sequence and written to - /// `existing_nullifiers` and their number should be written to - /// `existing_nullifiers_len`. - fn fetch_existing_nullifiers( - nullifiers: *const u8, - nullifiers_len: u32, - existing_nullifiers: *mut u8, - existing_nullifiers_len: *mut u32, - ) -> u8; - - /// Fetches the current anchor. - fn fetch_anchor(anchor: *mut [u8; BlsScalar::SIZE]) -> u8; - - /// Fetches the current stake for a key. - /// - /// The value, eligibility, reward and counter should be written in - /// sequence, little endian, to the given buffer. If there is no value and - /// eligibility, the first 16 bytes should be zero. - fn fetch_stake( - pk: *const [u8; PublicKey::SIZE], - stake: *mut [u8; StakeInfo::SIZE], - ) -> u8; - - /// Request the node to prove the given unproven transaction. - fn compute_proof_and_propagate( - utx: *const u8, - utx_len: u32, - tx: *mut u8, - tx_len: *mut u32, - ) -> u8; - - /// Requests the node to prove STCT. - fn request_stct_proof( - inputs: *const [u8; STCT_INPUT_SIZE], - proof: *mut [u8; Proof::SIZE], - ) -> u8; - - /// Request the node to prove WFCT. - fn request_wfct_proof( - inputs: *const [u8; WFCT_INPUT_SIZE], - proof: *mut [u8; Proof::SIZE], - ) -> u8; -} -macro_rules! unwrap_or_bail { - ($e: expr) => { - match $e { - Ok(v) => v, - Err(e) => { - return Error::::from(e).into(); - } - } - }; -} +use dusk_bytes::Serializable; +use phoenix_core::Note; +use sha2::{Digest, Sha512}; -type FfiWallet = Wallet; -const WALLET: FfiWallet = - Wallet::new(FfiStore, FfiStateClient, FfiProverClient); +use crate::{key, tx, types, utils, MAX_KEY, MAX_LEN}; -/// Allocates memory with a given size. +/// Allocates a buffer of `len` bytes on the WASM memory. #[no_mangle] -pub unsafe extern "C" fn malloc(cap: u32) -> *mut u8 { - let mut buf = Vec::with_capacity(cap as usize); - let ptr = buf.as_mut_ptr(); - mem::forget(buf); - ptr +pub fn malloc(len: i32) -> i32 { + let bytes = vec![0u8; len as usize]; + let ptr = bytes.as_ptr(); + mem::forget(bytes); + ptr as i32 } -/// Free memory pointed to by the given `ptr`, and the given `cap`acity. +/// Frees a previously allocated buffer on the WASM memory. #[no_mangle] -pub unsafe extern "C" fn free(ptr: *mut u8, cap: u32) { - Vec::from_raw_parts(ptr, 0, cap as usize); -} - -/// Get the public spend key with the given index. -#[no_mangle] -pub unsafe extern "C" fn public_spend_key( - index: *const u64, - psk: *mut [u8; PublicSpendKey::SIZE], -) -> u8 { - let key = unwrap_or_bail!(WALLET.public_spend_key(*index)).to_bytes(); - ptr::copy_nonoverlapping(&key[0], &mut (*psk)[0], key.len()); - 0 +pub fn free_mem(ptr: i32, len: i32) { + let ptr = ptr as *mut u8; + let len = len as usize; + unsafe { + Vec::from_raw_parts(ptr, len, len); + } } -/// Execute a generic contract call +/// Computes a secure seed from the given passphrase. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::SeedArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to the seed. #[no_mangle] -pub unsafe extern "C" fn execute( - contract_id: *const [u8; 32], - call_name_ptr: *mut u8, - call_name_len: *const u32, - call_data_ptr: *mut u8, - call_data_len: *const u32, - sender_index: *const u64, - refund: *const [u8; PublicSpendKey::SIZE], - gas_limit: *const u64, - gas_price: *const u64, -) -> u8 { - let contract_id = ContractId::from_bytes(*contract_id); - - // SAFETY: these buffers are expected to have been allocated with the - // correct size. If this is not the case problems with the allocator - // *may* happen. - let call_name = Vec::from_raw_parts( - call_name_ptr, - call_name_len as usize, - call_name_len as usize, - ); - let call_name = unwrap_or_bail!(String::from_utf8(call_name)); - - let call_data = Vec::from_raw_parts( - call_data_ptr, - call_data_len as usize, - call_data_len as usize, - ); +pub fn seed(args: i32, len: i32) -> i64 { + let types::SeedArgs { passphrase } = match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; - let refund = unwrap_or_bail!(PublicSpendKey::from_bytes(&*refund)); + let mut hash = Sha512::new(); - unwrap_or_bail!(WALLET.execute( - &mut FfiRng, - contract_id, - call_name, - call_data, - *sender_index, - &refund, - *gas_price, - *gas_limit - )); + hash.update(passphrase); + hash.update(b"SEED"); - 0 -} + let seed = hash.finalize().to_vec(); + let ptr = seed.as_ptr() as u32; + let len = seed.len() as u32; -/// Creates a transfer transaction. -#[no_mangle] -pub unsafe extern "C" fn transfer( - sender_index: *const u64, - refund: *const [u8; PublicSpendKey::SIZE], - receiver: *const [u8; PublicSpendKey::SIZE], - value: *const u64, - gas_limit: *const u64, - gas_price: *const u64, - ref_id: Option<&u64>, -) -> u8 { - let refund = unwrap_or_bail!(PublicSpendKey::from_bytes(&*refund)); - let receiver = unwrap_or_bail!(PublicSpendKey::from_bytes(&*receiver)); - - let ref_id = - BlsScalar::from(ref_id.copied().unwrap_or_else(|| FfiRng.next_u64())); - - unwrap_or_bail!(WALLET.transfer( - &mut FfiRng, - *sender_index, - &refund, - &receiver, - *value, - *gas_price, - *gas_limit, - ref_id - )); - - 0 + mem::forget(seed); + utils::compose(true, ptr, len) } -/// Creates a stake transaction. +/// Computes the total balance of the given notes. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::BalanceArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to JSON string +/// representing [types::BalanceResult]. #[no_mangle] -pub unsafe extern "C" fn stake( - sender_index: *const u64, - staker_index: *const u64, - refund: *const [u8; PublicSpendKey::SIZE], - value: *const u64, - gas_limit: *const u64, - gas_price: *const u64, -) -> u8 { - let refund = unwrap_or_bail!(PublicSpendKey::from_bytes(&*refund)); - - unwrap_or_bail!(WALLET.stake( - &mut FfiRng, - *sender_index, - *staker_index, - &refund, - *value, - *gas_price, - *gas_limit - )); - - 0 -} - -/// Unstake the value previously staked using the [`stake`] function. -#[no_mangle] -pub unsafe extern "C" fn unstake( - sender_index: *const u64, - staker_index: *const u64, - refund: *const [u8; PublicSpendKey::SIZE], - gas_limit: *const u64, - gas_price: *const u64, -) -> u8 { - let refund = unwrap_or_bail!(PublicSpendKey::from_bytes(&*refund)); - - unwrap_or_bail!(WALLET.unstake( - &mut FfiRng, - *sender_index, - *staker_index, - &refund, - *gas_price, - *gas_limit - )); - - 0 -} - -/// Withdraw the rewards accumulated as a result of staking and taking part in -/// the consensus. -#[no_mangle] -pub unsafe extern "C" fn withdraw( - sender_index: *const u64, - staker_index: *const u64, - refund: *const [u8; PublicSpendKey::SIZE], - gas_limit: *const u64, - gas_price: *const u64, -) -> u8 { - let refund = unwrap_or_bail!(PublicSpendKey::from_bytes(&*refund)); - - unwrap_or_bail!(WALLET.withdraw( - &mut FfiRng, - *sender_index, - *staker_index, - &refund, - *gas_price, - *gas_limit - )); - - 0 -} - -/// Gets the balance of a secret spend key. -#[no_mangle] -pub unsafe extern "C" fn get_balance( - ssk_index: *const u64, - balance: *mut [u8; BalanceInfo::SIZE], -) -> u8 { - let b = unwrap_or_bail!(WALLET.get_balance(*ssk_index)).to_bytes(); - ptr::copy_nonoverlapping(&b[0], &mut (*balance)[0], b.len()); - 0 -} +pub fn balance(args: i32, len: i32) -> i64 { + let types::BalanceArgs { notes, seed } = match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; -/// Gets the stake of a key. The value, eligibility, reward, and counter are -/// written in sequence to the given buffer. If there is no value and -/// eligibility the first 16 bytes will be zero. -#[no_mangle] -pub unsafe extern "C" fn get_stake( - sk_index: *const u64, - stake: *mut [u8; StakeInfo::SIZE], -) -> u8 { - let s = unwrap_or_bail!(WALLET.get_stake(*sk_index)).to_bytes(); - ptr::copy_nonoverlapping(&s[0], &mut (*stake)[0], s.len()); - 0 -} + let seed = match utils::sanitize_seed(seed) { + Some(s) => s, + None => return utils::fail(), + }; -struct FfiStore; + let notes: Vec = match rkyv::from_bytes(¬es) { + Ok(n) => utils::sanitize_notes(n), + Err(_) => return utils::fail(), + }; -impl Store for FfiStore { - type Error = u8; + let mut keys = unsafe { [mem::zeroed(); MAX_KEY + 1] }; + let mut values = Vec::with_capacity(notes.len()); + let mut keys_len = 0; + let mut sum = 0u64; + + 'outer: for note in notes { + // we iterate all the available keys until one can successfully decrypt + // the note. if all fails, returns false + for idx in 0..=MAX_KEY { + if keys_len == idx { + keys[idx] = key::derive_vk(&seed, idx as u64); + keys_len += 1; + } - fn get_seed(&self) -> Result<[u8; 64], Self::Error> { - let mut seed = [0; 64]; - unsafe { - let r = get_seed(&mut seed); - if r != 0 { - return Err(r); + if let Ok(v) = note.value(Some(&keys[idx])) { + values.push(v); + sum = sum.saturating_add(v); + continue 'outer; } } - Ok(seed) + + return utils::fail(); } + + // the top 4 notes are the maximum value a transaction can have, given the + // circuit accepts up to 4 inputs + values.sort_by(|a, b| b.cmp(a)); + let maximum = values.iter().take(4).sum::(); + + utils::into_ptr(types::BalanceResponse { + maximum, + value: sum, + }) } -const STCT_INPUT_SIZE: usize = Fee::SIZE - + Crossover::SIZE - + u64::SIZE - + JubJubScalar::SIZE - + BlsScalar::SIZE - + Signature::SIZE; +/// Computes a serialized unproven transaction from the given arguments. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::ExecuteArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to JSON string +/// representing [types::ExecuteResponse]. +#[no_mangle] +pub fn execute(args: i32, len: i32) -> i64 { + let types::ExecuteArgs { + call, + crossover, + gas_limit, + gas_price, + inputs, + openings, + output, + refund, + rng_seed, + seed, + } = match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; -const WFCT_INPUT_SIZE: usize = - JubJubAffine::SIZE + u64::SIZE + JubJubScalar::SIZE; + let inputs: Vec = match rkyv::from_bytes(&inputs) { + Ok(n) => utils::sanitize_notes(n), + Err(_) => return utils::fail(), + }; -struct FfiStateClient; + let openings: Vec = match rkyv::from_bytes(&openings) { + Ok(n) => n, + Err(_) => return utils::fail(), + }; -impl StateClient for FfiStateClient { - type Error = u8; + let seed = match utils::sanitize_seed(seed) { + Some(s) => s, + None => return utils::fail(), + }; - fn fetch_notes( - &self, - vk: &ViewKey, - ) -> Result, Self::Error> { - let mut notes_ptr = ptr::null_mut(); - let mut notes_len = 0; + let rng_seed = match utils::sanitize_seed(rng_seed) { + Some(s) => s, + None => return utils::fail(), + }; - let notes_buf = unsafe { - let r = fetch_notes(&vk.to_bytes(), &mut notes_ptr, &mut notes_len); - if r != 0 { - return Err(r); + let value = output.as_ref().map(|o| o.value).unwrap_or(0); + let total_output = gas_limit + .saturating_mul(gas_price) + .saturating_add(value) + .saturating_add(crossover.unwrap_or_default()); + + let mut keys = unsafe { [mem::zeroed(); MAX_KEY + 1] }; + let mut keys_ssk = unsafe { [mem::zeroed(); MAX_KEY + 1] }; + let mut keys_len = 0; + let mut openings = openings.into_iter(); + let mut full_inputs = Vec::with_capacity(inputs.len()); + + 'outer: for input in inputs { + // we iterate all the available keys until one can successfully + // decrypt the note. if any fails, returns false + for idx in 0..=MAX_KEY { + if keys_len == idx { + keys_ssk[idx] = key::derive_ssk(&seed, idx as u64); + keys[idx] = keys_ssk[idx].view_key(); + keys_len += 1; } - // SAFETY: the buffer is expected to have been allocated with the - // correct size. If this is not the case problems with the allocator - // *may* happen. - Vec::from_raw_parts( - notes_ptr, - notes_len as usize, - notes_len as usize, - ) - }; + if let Ok(value) = input.value(Some(&keys[idx])) { + let opening = match openings.next() { + Some(o) => o, + None => return utils::fail(), + }; - let num_notes = notes_len as usize / (Note::SIZE + u64::SIZE); - let mut notes = Vec::with_capacity(num_notes); - - let mut buf = ¬es_buf[..]; - for _ in 0..num_notes { - let note = Note::from_reader(&mut buf).map_err( - Error::::from, - )?; - let block_height = u64::from_reader(&mut buf).map_err( - Error::::from, - )?; - notes.push((note, block_height)); + full_inputs.push((input, opening, value, idx)); + continue 'outer; + } } - Ok(notes) + return utils::fail(); } - fn fetch_anchor(&self) -> Result { - let mut scalar_buf = [0; BlsScalar::SIZE]; - unsafe { - let r = fetch_anchor(&mut scalar_buf); - if r != 0 { - return Err(r); - } - } - let scalar = BlsScalar::from_bytes(&scalar_buf).map_err( - Error::::from, - )?; + // optimizes the inputs given the total amount + let (unspent, inputs) = match utils::knapsack(full_inputs, total_output) { + Some(k) => k, + None => return utils::fail(), + }; - Ok(scalar) + let inputs: Vec<_> = inputs + .into_iter() + .map(|(note, opening, value, idx)| tx::PreInput { + note, + opening, + value, + ssk: &keys_ssk[idx], + }) + .collect(); + + let total_input: u64 = inputs.iter().map(|i| i.value).sum(); + let total_refund = total_input.saturating_sub(total_output); + + let mut outputs = Vec::with_capacity(2); + if let Some(o) = output { + outputs.push(o); + } + if total_refund > 0 { + outputs.push(types::ExecuteOutput { + note_type: types::OutputType::Obfuscated, + receiver: refund.clone(), + ref_id: None, + value: total_refund, + }); } - fn fetch_existing_nullifiers( - &self, - nullifiers: &[BlsScalar], - ) -> Result, Self::Error> { - let nullifiers_len = nullifiers.len(); - let mut nullifiers_buf = vec![0u8; BlsScalar::SIZE * nullifiers_len]; - - // If no nullifiers come in, then none of them exist in the state. - if nullifiers_len == 0 { - return Ok(vec![]); - } + let rng = &mut utils::rng(&rng_seed); + let tx = tx::UnprovenTransaction::new( + rng, inputs, outputs, refund, gas_limit, gas_price, crossover, call, + ); + let tx = match tx { + Some(t) => t, + None => return utils::fail(), + }; - let mut writer = &mut nullifiers_buf[..]; + let unspent = match rkyv::to_bytes::<_, MAX_LEN>(&unspent).ok() { + Some(t) => t.into_vec(), + None => return utils::fail(), + }; - for nullifier in nullifiers { - writer.write(&nullifier.to_bytes()).map_err( - Error::::from, - )?; - } + let tx = match rkyv::to_bytes::<_, MAX_LEN>(&tx).ok() { + Some(t) => t.into_vec(), + None => return utils::fail(), + }; - let mut existing_nullifiers_buf = - vec![0u8; BlsScalar::SIZE * nullifiers_len]; - let mut existing_nullifiers_len = 0; - - unsafe { - let r = fetch_existing_nullifiers( - &nullifiers_buf[0], - nullifiers_len as u32, - &mut existing_nullifiers_buf[0], - &mut existing_nullifiers_len, - ); - if r != 0 { - return Err(r); - } - }; + utils::into_ptr(types::ExecuteResponse { tx, unspent }) +} - let mut existing_nullifiers = - Vec::with_capacity(existing_nullifiers_len as usize); +/// Merges many lists of serialized notes into a unique, sanitized set. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::MergeNotesArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to the rkyv serialized +/// [Vec]. +#[no_mangle] +pub fn merge_notes(args: i32, len: i32) -> i64 { + let types::MergeNotesArgs { notes } = match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; - let mut reader = &existing_nullifiers_buf[..]; - for _ in 0..existing_nullifiers_len { - existing_nullifiers.push( - BlsScalar::from_reader(&mut reader).map_err( - Error::::from, - )?, - ); + let mut list = Vec::with_capacity(10); + for notes in notes { + if !notes.is_empty() { + match rkyv::from_bytes::>(¬es) { + Ok(n) => list.extend(n), + Err(_) => return utils::fail(), + }; } - - Ok(existing_nullifiers) } - fn fetch_opening( - &self, - note: &Note, - ) -> Result, Self::Error> { - const OPENING_BUF_SIZE: usize = 3000; - - let mut opening_buf = Vec::with_capacity(OPENING_BUF_SIZE); - let mut opening_len = 0; - - let note = note.to_bytes(); - unsafe { - let r = fetch_opening( - ¬e, - opening_buf.as_mut_ptr(), - &mut opening_len, - ); - if r != 0 { - return Err(r); - } - } - - let branch = rkyv::from_bytes(&opening_buf[..opening_len as usize]) - .map_err( - Error::::from, - )?; + let notes = utils::sanitize_notes(list); - Ok(branch) - } + utils::rkyv_into_ptr(notes) +} - fn fetch_stake(&self, pk: &PublicKey) -> Result { - let pk = pk.to_bytes(); - let mut stake_buf = [0u8; StakeInfo::SIZE]; +/// Filters a list of notes from a list of negative flags. The flags that are +/// `true` will represent a note that must be removed from the set. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::FilterNotesArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to the rkyv serialized +/// [Vec]. +#[no_mangle] +pub fn filter_notes(args: i32, len: i32) -> i64 { + let types::FilterNotesArgs { flags, notes } = + match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; - unsafe { - let r = fetch_stake(&pk, &mut stake_buf); - if r != 0 { - return Err(r); - } - } + let notes: Vec = match rkyv::from_bytes(¬es) { + Ok(n) => n, + Err(_) => return utils::fail(), + }; - let stake = StakeInfo::from_bytes(&stake_buf).map_err( - Error::::from, - )?; + let notes: Vec<_> = notes + .into_iter() + .zip(flags.into_iter()) + .filter_map(|(n, f)| (!f).then_some(n)) + .collect(); - Ok(stake) - } + let notes = utils::sanitize_notes(notes); + utils::rkyv_into_ptr(notes) } -struct FfiProverClient; - -impl ProverClient for FfiProverClient { - type Error = u8; - - fn compute_proof_and_propagate( - &self, - utx: &UnprovenTransaction, - ) -> Result { - let utx_bytes = utx.to_var_bytes(); - - // A transaction is always smaller than an unproven transaction - let mut tx_buf = vec![0; utx_bytes.len()]; - let mut tx_len = 0; - - unsafe { - let r = compute_proof_and_propagate( - &utx_bytes[0], - utx_bytes.len() as u32, - &mut tx_buf[0], - &mut tx_len, - ); - if r != 0 { - return Err(r); - } - } +/// Returns a list of [PublicSpendKey] that belongs to this wallet. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::PublicSpendKeysArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to JSON string +/// representing [types::PublicSpendKeysResponse]. +#[no_mangle] +pub fn public_spend_keys(args: i32, len: i32) -> i64 { + let types::PublicSpendKeysArgs { seed } = match utils::take_args(args, len) + { + Some(a) => a, + None => return utils::fail(), + }; + + let seed = match utils::sanitize_seed(seed) { + Some(s) => s, + None => return utils::fail(), + }; - let transaction = Transaction::from_slice(&tx_buf[..tx_len as usize]) - .map_err( - Error::::from, - )?; + let keys = (0..=MAX_KEY) + .map(|idx| key::derive_psk(&seed, idx as u64)) + .map(|psk| bs58::encode(psk.to_bytes()).into_string()) + .collect(); - Ok(transaction) - } + utils::into_ptr(types::PublicSpendKeysResponse { keys }) +} - fn request_stct_proof( - &self, - fee: &Fee, - crossover: &Crossover, - value: u64, - blinder: JubJubScalar, - address: BlsScalar, - signature: Signature, - ) -> Result { - let mut buf = [0; STCT_INPUT_SIZE]; - - let mut writer = &mut buf[..]; - writer.write(&fee.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&crossover.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&value.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&blinder.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&address.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&signature.to_bytes()).map_err( - Error::::from, - )?; - - let mut proof_buf = [0; Proof::SIZE]; - - unsafe { - let r = request_stct_proof(&buf, &mut proof_buf); - if r != 0 { - return Err(r); - } - } +/// Returns a list of [ViewKey] that belongs to this wallet. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::ViewKeysArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to the rkyv serialized +/// [Vec]. +#[no_mangle] +pub fn view_keys(args: i32, len: i32) -> i64 { + let types::ViewKeysArgs { seed } = match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; - let proof = Proof::from_bytes(&proof_buf).map_err( - Error::::from, - )?; - Ok(proof) - } + let seed = match utils::sanitize_seed(seed) { + Some(s) => s, + None => return utils::fail(), + }; - fn request_wfct_proof( - &self, - commitment: JubJubAffine, - value: u64, - blinder: JubJubScalar, - ) -> Result { - let mut buf = [0; WFCT_INPUT_SIZE]; - - let mut writer = &mut buf[..]; - writer.write(&commitment.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&value.to_bytes()).map_err( - Error::::from, - )?; - writer.write(&blinder.to_bytes()).map_err( - Error::::from, - )?; - - let mut proof_buf = [0; Proof::SIZE]; - - unsafe { - let r = request_wfct_proof(&buf, &mut proof_buf); - if r != 0 { - return Err(r); - } - } + let vks: Vec<_> = (0..=MAX_KEY) + .map(|idx| key::derive_vk(&seed, idx as u64)) + .collect(); - let proof = Proof::from_bytes(&proof_buf).map_err( - Error::::from, - )?; - Ok(proof) - } + utils::rkyv_into_ptr(vks) } -struct FfiRng; - -impl CryptoRng for FfiRng {} +/// Returns a list of [BlsScalar] nullifiers for the given [Vec] combined +/// with the keys of this wallet. +/// +/// Expects as argument a fat pointer to a JSON string representing +/// [types::NullifiersArgs]. +/// +/// Will return a triplet (status, ptr, len) pointing to the rkyv serialized +/// [Vec]. +#[no_mangle] +pub fn nullifiers(args: i32, len: i32) -> i64 { + let types::NullifiersArgs { notes, seed } = + match utils::take_args(args, len) { + Some(a) => a, + None => return utils::fail(), + }; -impl RngCore for FfiRng { - fn next_u32(&mut self) -> u32 { - next_u32_via_fill(self) - } + let notes: Vec = match rkyv::from_bytes(¬es) { + Ok(n) => n, + Err(_) => return utils::fail(), + }; - fn next_u64(&mut self) -> u64 { - next_u64_via_fill(self) - } + let seed = match utils::sanitize_seed(seed) { + Some(s) => s, + None => return utils::fail(), + }; - fn fill_bytes(&mut self, dest: &mut [u8]) { - self.try_fill_bytes(dest).ok(); - } + let mut nullifiers = Vec::with_capacity(notes.len()); + let mut keys = unsafe { [mem::zeroed(); MAX_KEY + 1] }; + let mut keys_ssk = unsafe { [mem::zeroed(); MAX_KEY + 1] }; + let mut keys_len = 0; + + 'outer: for note in notes { + // we iterate all the available keys until one can successfully + // decrypt the note. if any fails, returns false + for idx in 0..=MAX_KEY { + if keys_len == idx { + keys_ssk[idx] = key::derive_ssk(&seed, idx as u64); + keys[idx] = keys_ssk[idx].view_key(); + keys_len += 1; + } - fn try_fill_bytes( - &mut self, - dest: &mut [u8], - ) -> Result<(), rand_core::Error> { - let buf = dest.as_mut_ptr(); - let len = dest.len(); - - // SAFETY: this is unsafe since the passed function is not guaranteed to - // be a CSPRNG running in a secure context. We therefore consider it the - // responsibility of the user to pass a good generator. - unsafe { - match fill_random(buf, len as u32) { - 0 => Ok(()), - v => { - let nzu = NonZeroU32::new(v as u32).unwrap(); - Err(rand_core::Error::from(nzu)) - } + if keys[idx].owns(¬e) { + nullifiers.push(note.gen_nullifier(&keys_ssk[idx])); + continue 'outer; } } - } -} -impl From> - for u8 -{ - fn from(e: Error) -> Self { - match e { - Error::Store(_) => 255, - Error::Rng(_) => 254, - Error::Bytes(_) => 253, - Error::State(_) => 252, - Error::Prover(_) => 251, - Error::NotEnoughBalance => 250, - Error::NoteCombinationProblem => 249, - Error::Rkyv => 248, - Error::Phoenix(_) => 247, - Error::AlreadyStaked { .. } => 246, - Error::NotStaked { .. } => 245, - Error::NoReward { .. } => 244, - Error::Utf8(_) => 243, - } + return utils::fail(); } + + utils::rkyv_into_ptr(nullifiers) } diff --git a/src/imp.rs b/src/imp.rs deleted file mode 100644 index 916ae4e..0000000 --- a/src/imp.rs +++ /dev/null @@ -1,1082 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// Copyright (c) DUSK NETWORK. All rights reserved. - -use crate::tx::UnprovenTransaction; -use crate::{ - BalanceInfo, ProverClient, StakeInfo, StateClient, Store, MAX_CALL_SIZE, -}; - -use core::convert::Infallible; - -use alloc::string::{FromUtf8Error, String}; -use alloc::vec::Vec; - -use dusk_bls12_381_sign::{PublicKey, SecretKey, Signature}; -use dusk_bytes::{Error as BytesError, Serializable}; -use dusk_jubjub::{BlsScalar, JubJubScalar}; -use dusk_pki::{ - Ownable, PublicSpendKey, SecretKey as SchnorrKey, SecretSpendKey, - StealthAddress, -}; -use dusk_schnorr::Signature as SchnorrSignature; -use phoenix_core::transaction::*; -use phoenix_core::{Error as PhoenixError, Fee, Note, NoteType}; -use rand_core::{CryptoRng, Error as RngError, RngCore}; -use rkyv::ser::serializers::{ - AllocScratchError, AllocSerializer, CompositeSerializerError, - SharedSerializeMapError, -}; -use rkyv::validation::validators::CheckDeserializeError; -use rkyv::Serialize; -use rusk_abi::ContractId; - -const MAX_INPUT_NOTES: usize = 4; - -const TX_STAKE: &str = "stake"; -const TX_UNSTAKE: &str = "unstake"; -const TX_WITHDRAW: &str = "withdraw"; -const TX_ADD_ALLOWLIST: &str = "allow"; - -type SerializerError = CompositeSerializerError< - Infallible, - AllocScratchError, - SharedSerializeMapError, ->; - -/// The error type returned by this crate. -#[derive(Debug)] -#[allow(clippy::large_enum_variant)] -pub enum Error { - /// Underlying store error. - Store(S::Error), - /// Error originating from the state client. - State(SC::Error), - /// Error originating from the prover client. - Prover(PC::Error), - /// Rkyv serialization. - Rkyv, - /// Random number generator error. - Rng(RngError), - /// Serialization and deserialization of Dusk types. - Bytes(BytesError), - /// Bytes were meant to be utf8 but aren't. - Utf8(FromUtf8Error), - /// Originating from the transaction model. - Phoenix(PhoenixError), - /// Not enough balance to perform transaction. - NotEnoughBalance, - /// Note combination for the given value is impossible given the maximum - /// amount if inputs in a transaction. - NoteCombinationProblem, - /// The key is already staked. This happens when there already is an amount - /// staked for a key and the user tries to make a stake transaction. - AlreadyStaked { - /// The key that already has a stake. - key: PublicKey, - /// Information about the key's stake. - stake: StakeInfo, - }, - /// The key is not staked. This happens when a key doesn't have an amount - /// staked and the user tries to make an unstake transaction. - NotStaked { - /// The key that is not staked. - key: PublicKey, - /// Information about the key's stake. - stake: StakeInfo, - }, - /// The key has no reward. This happens when a key has no reward in the - /// stake contract and the user tries to make a withdraw transaction. - NoReward { - /// The key that has no reward. - key: PublicKey, - /// Information about the key's stake. - stake: StakeInfo, - }, -} - -impl Error { - /// Returns an error from the underlying store error. - pub fn from_store_err(se: S::Error) -> Self { - Self::Store(se) - } - /// Returns an error from the underlying state client. - pub fn from_state_err(se: SC::Error) -> Self { - Self::State(se) - } - /// Returns an error from the underlying prover client. - pub fn from_prover_err(pe: PC::Error) -> Self { - Self::Prover(pe) - } -} - -impl From - for Error -{ - fn from(_: SerializerError) -> Self { - Self::Rkyv - } -} - -impl - From> for Error -{ - fn from(_: CheckDeserializeError) -> Self { - Self::Rkyv - } -} - -impl From - for Error -{ - fn from(re: RngError) -> Self { - Self::Rng(re) - } -} - -impl From - for Error -{ - fn from(be: BytesError) -> Self { - Self::Bytes(be) - } -} - -impl From - for Error -{ - fn from(err: FromUtf8Error) -> Self { - Self::Utf8(err) - } -} - -impl From - for Error -{ - fn from(pe: PhoenixError) -> Self { - Self::Phoenix(pe) - } -} - -/// A wallet implementation. -/// -/// This is responsible for holding the keys, and performing operations like -/// creating transactions. -pub struct Wallet { - store: S, - state: SC, - prover: PC, -} - -impl Wallet { - /// Create a new wallet given the underlying store and node client. - pub const fn new(store: S, state: SC, prover: PC) -> Self { - Self { - store, - state, - prover, - } - } - - /// Return the inner Store reference - pub const fn store(&self) -> &S { - &self.store - } - - /// Return the inner State reference - pub const fn state(&self) -> &SC { - &self.state - } - - /// Return the inner Prover reference - pub const fn prover(&self) -> &PC { - &self.prover - } -} - -impl Wallet -where - S: Store, - SC: StateClient, - PC: ProverClient, -{ - /// Retrieve the public spend key with the given index. - pub fn public_spend_key( - &self, - index: u64, - ) -> Result> { - self.store - .retrieve_ssk(index) - .map(|ssk| ssk.public_spend_key()) - .map_err(Error::from_store_err) - } - - /// Retrieve the public key with the given index. - pub fn public_key( - &self, - index: u64, - ) -> Result> { - self.store - .retrieve_sk(index) - .map(|sk| From::from(&sk)) - .map_err(Error::from_store_err) - } - - /// Fetches the notes and nullifiers in the state and returns the notes that - /// are still available for spending. - fn unspent_notes( - &self, - ssk: &SecretSpendKey, - ) -> Result, Error> { - let vk = ssk.view_key(); - - let notes = - self.state.fetch_notes(&vk).map_err(Error::from_state_err)?; - - let nullifiers: Vec<_> = - notes.iter().map(|(n, _)| n.gen_nullifier(ssk)).collect(); - - let existing_nullifiers = self - .state - .fetch_existing_nullifiers(&nullifiers) - .map_err(Error::from_state_err)?; - - let unspent_notes = notes - .into_iter() - .zip(nullifiers.into_iter()) - .filter(|(_, nullifier)| !existing_nullifiers.contains(nullifier)) - .map(|((note, _), _)| note) - .collect(); - - Ok(unspent_notes) - } - - /// Here we fetch the notes and perform a "minimum number of notes - /// required" algorithm to select which ones to use for this TX. This is - /// done by picking notes largest to smallest until they combined have - /// enough accumulated value. - /// - /// We also return the outputs with a possible change note (if applicable). - #[allow(clippy::type_complexity)] - fn inputs_and_change_output( - &self, - rng: &mut Rng, - sender: &SecretSpendKey, - refund: &PublicSpendKey, - value: u64, - ) -> Result< - ( - Vec<(Note, u64, JubJubScalar)>, - Vec<(Note, u64, JubJubScalar)>, - ), - Error, - > { - let notes = self.unspent_notes(sender)?; - let mut notes_and_values = Vec::with_capacity(notes.len()); - - let sender_vk = sender.view_key(); - - let mut accumulated_value = 0; - for note in notes.into_iter() { - let val = note.value(Some(&sender_vk))?; - let blinder = note.blinding_factor(Some(&sender_vk))?; - - accumulated_value += val; - notes_and_values.push((note, val, blinder)); - } - - if accumulated_value < value { - return Err(Error::NotEnoughBalance); - } - - let inputs = pick_notes(value, notes_and_values); - - if inputs.is_empty() { - return Err(Error::NoteCombinationProblem); - } - - let change = inputs.iter().map(|v| v.1).sum::() - value; - - let mut outputs = vec![]; - if change > 0 { - let nonce = BlsScalar::random(rng); - let (change_note, change_blinder) = - generate_obfuscated_note(rng, refund, change, nonce); - - outputs.push((change_note, change, change_blinder)) - } - - Ok((inputs, outputs)) - } - - /// Execute a generic contract call - #[allow(clippy::too_many_arguments)] - pub fn execute( - &self, - rng: &mut Rng, - contract_id: ContractId, - call_name: String, - call_data: C, - sender_index: u64, - refund: &PublicSpendKey, - gas_limit: u64, - gas_price: u64, - ) -> Result> - where - Rng: RngCore + CryptoRng, - C: Serialize>, - { - let sender = self - .store - .retrieve_ssk(sender_index) - .map_err(Error::from_store_err)?; - - let (inputs, outputs) = self.inputs_and_change_output( - rng, - &sender, - refund, - gas_limit * gas_price, - )?; - - let fee = Fee::new(rng, gas_limit, gas_price, refund); - - let call_data = rkyv::to_bytes(&call_data)?.to_vec(); - let call = (contract_id, call_name, call_data); - - let utx = UnprovenTransaction::new( - rng, - &self.state, - &sender, - inputs, - outputs, - fee, - None, - Some(call), - ) - .map_err(Error::from_state_err)?; - - self.prover - .compute_proof_and_propagate(&utx) - .map_err(Error::from_prover_err) - } - - /// Transfer Dusk from one key to another. - #[allow(clippy::too_many_arguments)] - pub fn transfer( - &self, - rng: &mut Rng, - sender_index: u64, - refund: &PublicSpendKey, - receiver: &PublicSpendKey, - value: u64, - gas_limit: u64, - gas_price: u64, - ref_id: BlsScalar, - ) -> Result> { - let sender = self - .store - .retrieve_ssk(sender_index) - .map_err(Error::from_store_err)?; - - let (inputs, mut outputs) = self.inputs_and_change_output( - rng, - &sender, - refund, - value + gas_limit * gas_price, - )?; - - let (output_note, output_blinder) = - generate_obfuscated_note(rng, receiver, value, ref_id); - - outputs.push((output_note, value, output_blinder)); - - let crossover = None; - let fee = Fee::new(rng, gas_limit, gas_price, refund); - - let utx = UnprovenTransaction::new( - rng, - &self.state, - &sender, - inputs, - outputs, - fee, - crossover, - None, - ) - .map_err(Error::from_state_err)?; - - self.prover - .compute_proof_and_propagate(&utx) - .map_err(Error::from_prover_err) - } - - /// Stakes an amount of Dusk. - #[allow(clippy::too_many_arguments)] - pub fn stake( - &self, - rng: &mut Rng, - sender_index: u64, - staker_index: u64, - refund: &PublicSpendKey, - value: u64, - gas_limit: u64, - gas_price: u64, - ) -> Result> { - let sender = self - .store - .retrieve_ssk(sender_index) - .map_err(Error::from_store_err)?; - - let sk = self - .store - .retrieve_sk(staker_index) - .map_err(Error::from_store_err)?; - let pk = PublicKey::from(&sk); - - let (inputs, outputs) = self.inputs_and_change_output( - rng, - &sender, - refund, - value + gas_limit * gas_price, - )?; - - let stake = - self.state.fetch_stake(&pk).map_err(Error::from_state_err)?; - if stake.amount.is_some() { - return Err(Error::AlreadyStaked { key: pk, stake }); - } - - let blinder = JubJubScalar::random(rng); - let note = Note::obfuscated(rng, refund, value, blinder); - let (mut fee, crossover) = note - .try_into() - .expect("Obfuscated notes should always yield crossovers"); - - fee.gas_limit = gas_limit; - fee.gas_price = gas_price; - - let contract_id = rusk_abi::STAKE_CONTRACT; - let address = rusk_abi::contract_to_scalar(&contract_id); - - let contract_id = rusk_abi::contract_to_scalar(&contract_id); - - let stct_message = - stct_signature_message(&crossover, value, contract_id); - let stct_message = dusk_poseidon::sponge::hash(&stct_message); - - let sk_r = *sender.sk_r(fee.stealth_address()).as_ref(); - let secret = SchnorrKey::from(sk_r); - - let stct_signature = SchnorrSignature::new(&secret, rng, stct_message); - - let spend_proof = self - .prover - .request_stct_proof( - &fee, - &crossover, - value, - blinder, - address, - stct_signature, - ) - .map_err(Error::from_prover_err)? - .to_bytes() - .to_vec(); - - let signature = stake_sign(&sk, &pk, stake.counter, value); - - let stake = Stake { - public_key: pk, - signature, - value, - proof: spend_proof, - }; - - let call_data = rkyv::to_bytes::<_, MAX_CALL_SIZE>(&stake)?.to_vec(); - let call = - (rusk_abi::STAKE_CONTRACT, String::from(TX_STAKE), call_data); - - let utx = UnprovenTransaction::new( - rng, - &self.state, - &sender, - inputs, - outputs, - fee, - Some((crossover, value, blinder)), - Some(call), - ) - .map_err(Error::from_state_err)?; - - self.prover - .compute_proof_and_propagate(&utx) - .map_err(Error::from_prover_err) - } - - /// Unstake a key from the stake contract. - pub fn unstake( - &self, - rng: &mut Rng, - sender_index: u64, - staker_index: u64, - refund: &PublicSpendKey, - gas_limit: u64, - gas_price: u64, - ) -> Result> { - let sender = self - .store - .retrieve_ssk(sender_index) - .map_err(Error::from_store_err)?; - - let sk = self - .store - .retrieve_sk(staker_index) - .map_err(Error::from_store_err)?; - let pk = PublicKey::from(&sk); - - let (inputs, outputs) = self.inputs_and_change_output( - rng, - &sender, - refund, - gas_limit * gas_price, - )?; - - let stake = - self.state.fetch_stake(&pk).map_err(Error::from_state_err)?; - let (value, _) = - stake.amount.ok_or(Error::NotStaked { key: pk, stake })?; - - let blinder = JubJubScalar::random(rng); - - // Since we're not transferring value *to* the contract the crossover - // shouldn't contain a value. As such the note used to create it should - // be valueless as well. - let note = Note::obfuscated(rng, refund, 0, blinder); - let (mut fee, crossover) = note - .try_into() - .expect("Obfuscated notes should always yield crossovers"); - - fee.gas_limit = gas_limit; - fee.gas_price = gas_price; - - let unstake_note = - Note::transparent(rng, &sender.public_spend_key(), value); - let unstake_blinder = unstake_note - .blinding_factor(None) - .expect("Note is transparent so blinding factor is unencrypted"); - - let unstake_proof = self - .prover - .request_wfct_proof( - unstake_note.value_commitment().into(), - value, - unstake_blinder, - ) - .map_err(Error::from_prover_err)? - .to_bytes() - .to_vec(); - - let signature = unstake_sign(&sk, &pk, stake.counter, unstake_note); - - let unstake = Unstake { - public_key: pk, - signature, - note: unstake_note, - proof: unstake_proof, - }; - - let call_data = rkyv::to_bytes::<_, MAX_CALL_SIZE>(&unstake)?.to_vec(); - let call = ( - rusk_abi::STAKE_CONTRACT, - String::from(TX_UNSTAKE), - call_data, - ); - - let utx = UnprovenTransaction::new( - rng, - &self.state, - &sender, - inputs, - outputs, - fee, - Some((crossover, 0, blinder)), - Some(call), - ) - .map_err(Error::from_state_err)?; - - self.prover - .compute_proof_and_propagate(&utx) - .map_err(Error::from_prover_err) - } - - /// Withdraw the reward a key has reward if accumulated by staking and - /// taking part in operating the network. - pub fn withdraw( - &self, - rng: &mut Rng, - sender_index: u64, - staker_index: u64, - refund: &PublicSpendKey, - gas_limit: u64, - gas_price: u64, - ) -> Result> { - let sender = self - .store - .retrieve_ssk(sender_index) - .map_err(Error::from_store_err)?; - let sender_psk = sender.public_spend_key(); - - let sk = self - .store - .retrieve_sk(staker_index) - .map_err(Error::from_store_err)?; - let pk = PublicKey::from(&sk); - - let (inputs, outputs) = self.inputs_and_change_output( - rng, - &sender, - refund, - gas_limit * gas_price, - )?; - - let stake = - self.state.fetch_stake(&pk).map_err(Error::from_state_err)?; - if stake.reward == 0 { - return Err(Error::NoReward { key: pk, stake }); - } - - let withdraw_r = JubJubScalar::random(rng); - let address = sender_psk.gen_stealth_address(&withdraw_r); - let nonce = BlsScalar::random(rng); - - let signature = withdraw_sign(&sk, &pk, stake.counter, address, nonce); - - // Since we're not transferring value *to* the contract the crossover - // shouldn't contain a value. As such the note used to created it should - // be valueless as well. - let blinder = JubJubScalar::random(rng); - let note = Note::obfuscated(rng, refund, 0, blinder); - let (mut fee, crossover) = note - .try_into() - .expect("Obfuscated notes should always yield crossovers"); - - fee.gas_limit = gas_limit; - fee.gas_price = gas_price; - - let withdraw = Withdraw { - public_key: pk, - signature, - address, - nonce, - }; - let call_data = rkyv::to_bytes::<_, MAX_CALL_SIZE>(&withdraw)?.to_vec(); - - let contract_id = rusk_abi::STAKE_CONTRACT; - let call = (contract_id, String::from(TX_WITHDRAW), call_data); - - let utx = UnprovenTransaction::new( - rng, - &self.state, - &sender, - inputs, - outputs, - fee, - Some((crossover, 0, blinder)), - Some(call), - ) - .map_err(Error::from_state_err)?; - - self.prover - .compute_proof_and_propagate(&utx) - .map_err(Error::from_prover_err) - } - - /// Allow a `staker` public key. - #[allow(clippy::too_many_arguments)] - pub fn allow( - &self, - rng: &mut Rng, - sender_index: u64, - owner_index: u64, - refund: &PublicSpendKey, - staker: &PublicKey, - gas_limit: u64, - gas_price: u64, - ) -> Result> { - let sender = self - .store - .retrieve_ssk(sender_index) - .map_err(Error::from_store_err)?; - - let owner_sk = self - .store - .retrieve_sk(owner_index) - .map_err(Error::from_store_err)?; - let owner_pk = PublicKey::from(&owner_sk); - - let (inputs, outputs) = self.inputs_and_change_output( - rng, - &sender, - refund, - gas_limit * gas_price, - )?; - - let stake = self - .state - .fetch_stake(&owner_pk) - .map_err(Error::from_state_err)?; - - let signature = allow_sign(&owner_sk, &owner_pk, stake.counter, staker); - - // Since we're not transferring value *to* the contract the crossover - // shouldn't contain a value. As such the note used to created it should - // be valueless as well. - let blinder = JubJubScalar::random(rng); - let note = Note::obfuscated(rng, refund, 0, blinder); - let (mut fee, crossover) = note - .try_into() - .expect("Obfuscated notes should always yield crossovers"); - - fee.gas_limit = gas_limit; - fee.gas_price = gas_price; - - let allow = Allow { - public_key: *staker, - owner: owner_pk, - signature, - }; - let call_data = rkyv::to_bytes::<_, MAX_CALL_SIZE>(&allow)?.to_vec(); - - let contract_id = rusk_abi::STAKE_CONTRACT; - let call = (contract_id, String::from(TX_ADD_ALLOWLIST), call_data); - - let utx = UnprovenTransaction::new( - rng, - &self.state, - &sender, - inputs, - outputs, - fee, - Some((crossover, 0, blinder)), - Some(call), - ) - .map_err(Error::from_state_err)?; - - self.prover - .compute_proof_and_propagate(&utx) - .map_err(Error::from_prover_err) - } - - /// Gets the balance of a key. - pub fn get_balance( - &self, - ssk_index: u64, - ) -> Result> { - let sender = self - .store - .retrieve_ssk(ssk_index) - .map_err(Error::from_store_err)?; - let vk = sender.view_key(); - - let notes = self.unspent_notes(&sender)?; - let mut values = Vec::with_capacity(notes.len()); - - for note in notes.into_iter() { - values.push(note.value(Some(&vk))?); - } - values.sort_by(|a, b| b.cmp(a)); - - let spendable = values.iter().take(MAX_INPUT_NOTES).sum(); - let value = - spendable + values.iter().skip(MAX_INPUT_NOTES).sum::(); - - Ok(BalanceInfo { value, spendable }) - } - - /// Gets the stake and the expiration of said stake for a key. - pub fn get_stake( - &self, - sk_index: u64, - ) -> Result> { - let sk = self - .store - .retrieve_sk(sk_index) - .map_err(Error::from_store_err)?; - - let pk = PublicKey::from(&sk); - - let s = self.state.fetch_stake(&pk).map_err(Error::from_state_err)?; - - Ok(s) - } -} - -/// Pick the notes to be used in a transaction from a vector of notes. -/// -/// The notes are picked in a way to maximize the number of notes used, while -/// minimizing the value employed. To do this we sort the notes in ascending -/// value order, and go through each combination in a lexicographic order -/// until we find the first combination whose sum is larger or equal to -/// the given value. If such a slice is not found, an empty vector is returned. -/// -/// Note: it is presupposed that the input notes contain enough balance to cover -/// the given `value`. -fn pick_notes( - value: u64, - notes_and_values: Vec<(Note, u64, JubJubScalar)>, -) -> Vec<(Note, u64, JubJubScalar)> { - let mut notes_and_values = notes_and_values; - let len = notes_and_values.len(); - - if len <= MAX_INPUT_NOTES { - return notes_and_values; - } - - notes_and_values.sort_by(|(_, aval, _), (_, bval, _)| aval.cmp(bval)); - - pick_lexicographic(notes_and_values.len(), |indices| { - indices - .iter() - .map(|index| notes_and_values[*index].1) - .sum::() - >= value - }) - .map(|indices| { - indices - .into_iter() - .map(|index| notes_and_values[index]) - .collect() - }) - .unwrap_or_default() -} - -fn pick_lexicographic bool>( - max_len: usize, - is_valid: F, -) -> Option<[usize; MAX_INPUT_NOTES]> { - let mut indices = [0; MAX_INPUT_NOTES]; - indices - .iter_mut() - .enumerate() - .for_each(|(i, index)| *index = i); - - loop { - if is_valid(&indices) { - return Some(indices); - } - - let mut i = MAX_INPUT_NOTES - 1; - - while indices[i] == i + max_len - MAX_INPUT_NOTES { - if i > 0 { - i -= 1; - } else { - break; - } - } - - indices[i] += 1; - for j in i + 1..MAX_INPUT_NOTES { - indices[j] = indices[j - 1] + 1; - } - - if indices[MAX_INPUT_NOTES - 1] == max_len { - break; - } - } - - None -} - -/// Creates a signature compatible with what the stake contract expects for a -/// stake transaction. -/// -/// The counter is the number of transactions that have been sent to the -/// transfer contract by a given key, and is reported in `StakeInfo`. -fn stake_sign( - sk: &SecretKey, - pk: &PublicKey, - counter: u64, - value: u64, -) -> Signature { - let mut msg = Vec::with_capacity(u64::SIZE + u64::SIZE); - - msg.extend(counter.to_bytes()); - msg.extend(value.to_bytes()); - - sk.sign(pk, &msg) -} - -/// Creates a signature compatible with what the stake contract expects for a -/// unstake transaction. -/// -/// The counter is the number of transactions that have been sent to the -/// transfer contract by a given key, and is reported in `StakeInfo`. -fn unstake_sign( - sk: &SecretKey, - pk: &PublicKey, - counter: u64, - note: Note, -) -> Signature { - let mut msg = Vec::with_capacity(u64::SIZE + Note::SIZE); - - msg.extend(counter.to_bytes()); - msg.extend(note.to_bytes()); - - sk.sign(pk, &msg) -} - -/// Creates a signature compatible with what the stake contract expects for a -/// withdraw transaction. -/// -/// The counter is the number of transactions that have been sent to the -/// transfer contract by a given key, and is reported in `StakeInfo`. -fn withdraw_sign( - sk: &SecretKey, - pk: &PublicKey, - counter: u64, - address: StealthAddress, - nonce: BlsScalar, -) -> Signature { - let mut msg = - Vec::with_capacity(u64::SIZE + StealthAddress::SIZE + BlsScalar::SIZE); - - msg.extend(counter.to_bytes()); - msg.extend(address.to_bytes()); - msg.extend(nonce.to_bytes()); - - sk.sign(pk, &msg) -} - -/// Creates a signature compatible with what the stake contract expects for a -/// ADD_ALLOWLIST transaction. -/// -/// The counter is the number of transactions that have been sent to the -/// transfer contract by a given key, and is reported in `StakeInfo`. -fn allow_sign( - sk: &SecretKey, - pk: &PublicKey, - counter: u64, - staker: &PublicKey, -) -> Signature { - let mut msg = Vec::with_capacity(u64::SIZE + PublicKey::SIZE); - - msg.extend(counter.to_bytes()); - msg.extend(staker.to_bytes()); - - sk.sign(pk, &msg) -} - -/// Generates an obfuscated note for the given public spend key. -fn generate_obfuscated_note( - rng: &mut Rng, - psk: &PublicSpendKey, - value: u64, - nonce: BlsScalar, -) -> (Note, JubJubScalar) { - let r = JubJubScalar::random(rng); - let blinder = JubJubScalar::random(rng); - - ( - Note::deterministic( - NoteType::Obfuscated, - &r, - nonce, - psk, - value, - blinder, - ), - blinder, - ) -} - -#[cfg(test)] -mod tests { - use rand::rngs::StdRng; - use rand_core::SeedableRng; - - use super::*; - - fn gen_notes(values: &[u64]) -> Vec<(Note, u64, JubJubScalar)> { - let mut rng = StdRng::seed_from_u64(0xbeef); - - let ssk = SecretSpendKey::random(&mut rng); - let psk = ssk.public_spend_key(); - - let mut notes_and_values = Vec::with_capacity(values.len()); - - for value in values { - let note = Note::transparent(&mut rng, &psk, *value); - let blinder = JubJubScalar::random(&mut rng); - - notes_and_values.push((note, *value, blinder)); - } - - notes_and_values - } - - #[test] - fn note_picking_none() { - let values = [2, 1, 4, 3, 5, 7, 6]; - - let notes_and_values = gen_notes(&values); - - let picked = pick_notes(100, notes_and_values); - - assert_eq!(picked.len(), 0); - } - - #[test] - fn note_picking_1() { - let values = [1]; - - let notes_and_values = gen_notes(&values); - - let picked = pick_notes(1, notes_and_values); - assert_eq!(picked.len(), 1); - } - - #[test] - fn note_picking_2() { - let values = [1, 2]; - - let notes_and_values = gen_notes(&values); - - let picked = pick_notes(2, notes_and_values); - assert_eq!(picked.len(), 2); - } - - #[test] - fn note_picking_3() { - let values = [1, 3, 2]; - - let notes_and_values = gen_notes(&values); - - let picked = pick_notes(2, notes_and_values); - assert_eq!(picked.len(), 3); - } - - #[test] - fn note_picking_4() { - let values = [4, 2, 1, 3]; - - let notes_and_values = gen_notes(&values); - - let picked = pick_notes(2, notes_and_values); - assert_eq!(picked.len(), 4); - } - - #[test] - fn note_picking_4_plus() { - let values = [2, 1, 4, 3, 5, 7, 6]; - - let notes_and_values = gen_notes(&values); - - let picked = pick_notes(20, notes_and_values); - - assert_eq!(picked.len(), 4); - assert_eq!(picked.iter().map(|v| v.1).sum::(), 20); - } -} diff --git a/src/key.rs b/src/key.rs new file mode 100644 index 0000000..d6fb81f --- /dev/null +++ b/src/key.rs @@ -0,0 +1,48 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +//! Utilities to derive keys from the seed. + +use crate::{utils, RNG_SEED}; + +use dusk_bls12_381_sign::SecretKey; +use dusk_pki::{PublicSpendKey, SecretSpendKey, ViewKey}; + +/// Generates a secret spend key from its seed and index. +/// +/// First the `seed` and then the little-endian representation of the key's +/// `index` are passed through SHA-256. A constant is then mixed in and the +/// resulting hash is then used to seed a `ChaCha12` CSPRNG, which is +/// subsequently used to generate the key. +pub fn derive_ssk(seed: &[u8; RNG_SEED], index: u64) -> SecretSpendKey { + SecretSpendKey::random(&mut utils::rng_with_index(seed, index)) +} + +/// Generates a secret key from its seed and index. +/// +/// First the `seed` and then the little-endian representation of the key's +/// `index` are passed through SHA-256. A constant is then mixed in and the +/// resulting hash is then used to seed a `ChaCha12` CSPRNG, which is +/// subsequently used to generate the key. +pub fn derive_sk(seed: &[u8; RNG_SEED], index: u64) -> SecretKey { + SecretKey::random(&mut utils::rng_with_index(seed, index)) +} + +/// Generates a public spend key from its seed and index. +/// +/// The secret spend key is derived from [derive_ssk], and then the key is +/// generated via [SecretSpendKey::public_spend_key]. +pub fn derive_psk(seed: &[u8; RNG_SEED], index: u64) -> PublicSpendKey { + derive_ssk(seed, index).public_spend_key() +} + +/// Generates a view key from its seed and index. +/// +/// The secret spend key is derived from [derive_ssk], and then the key is +/// generated via [SecretSpendKey::view_key]. +pub fn derive_vk(seed: &[u8; RNG_SEED], index: u64) -> ViewKey { + derive_ssk(seed, index).view_key() +} diff --git a/src/lib.rs b/src/lib.rs index 8269f65..df998c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,287 +4,27 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -//! The wallet specification. - +#![cfg_attr(target_family = "wasm", no_std)] #![deny(missing_docs)] -#![deny(clippy::all)] -#![allow(clippy::result_large_err)] -// #![no_std] +#![doc = include_str!("../README.md")] -#[macro_use] extern crate alloc; -#[cfg(target_family = "wasm")] -mod ffi; - -mod imp; -mod tx; - -use alloc::vec::Vec; -use dusk_bls12_381_sign::{PublicKey, SecretKey}; -use dusk_bytes::{DeserializableSlice, Serializable, Write}; -use dusk_jubjub::{BlsScalar, JubJubAffine, JubJubScalar}; -use dusk_pki::{SecretSpendKey, ViewKey}; -use dusk_plonk::proof_system::Proof; -use dusk_schnorr::Signature; -use phoenix_core::{Crossover, Fee, Note}; -use poseidon_merkle::Opening as PoseidonOpening; -use rand_chacha::ChaCha12Rng; -use rand_core::SeedableRng; -use sha2::{Digest, Sha256}; - -pub use imp::*; -pub use phoenix_core::Transaction; -pub use tx::{UnprovenTransaction, UnprovenTransactionInput}; - -use phoenix_core::transaction::*; -pub use rusk_abi::POSEIDON_TREE_DEPTH; - -/// The maximum size of call data. -pub const MAX_CALL_SIZE: usize = rusk_abi::ARGBUF_LEN; - -/// Stores the cryptographic material necessary to derive cryptographic keys. -pub trait Store { - /// The error type returned from the store. - type Error; - - /// Retrieves the seed used to derive keys. - fn get_seed(&self) -> Result<[u8; 64], Self::Error>; - - /// Retrieves a derived secret spend key from the store. - /// - /// The provided implementation simply gets the seed and regenerates the key - /// every time with [`generate_ssk`]. It may be reimplemented to - /// provide a cache for keys, or implement a different key generation - /// algorithm. - fn retrieve_ssk(&self, index: u64) -> Result { - let seed = self.get_seed()?; - Ok(derive_ssk(&seed, index)) - } - - /// Retrieves a derived secret key from the store. - /// - /// The provided implementation simply gets the seed and regenerates the key - /// every time with [`generate_sk`]. It may be reimplemented to - /// provide a cache for keys, or implement a different key generation - /// algorithm. - fn retrieve_sk(&self, index: u64) -> Result { - let seed = self.get_seed()?; - Ok(derive_sk(&seed, index)) - } -} - -/// Generates a secret spend key from its seed and index. -/// -/// First the `seed` and then the little-endian representation of the key's -/// `index` are passed through SHA-256. A constant is then mixed in and the -/// resulting hash is then used to seed a `ChaCha12` CSPRNG, which is -/// subsequently used to generate the key. -pub fn derive_ssk(seed: &[u8; 64], index: u64) -> SecretSpendKey { - let mut hash = Sha256::new(); - - hash.update(seed); - hash.update(index.to_le_bytes()); - hash.update(b"SSK"); - - let hash = hash.finalize().into(); - let mut rng = ChaCha12Rng::from_seed(hash); - - SecretSpendKey::random(&mut rng) -} - -/// Generates a secret key from its seed and index. -/// -/// First the `seed` and then the little-endian representation of the key's -/// `index` are passed through SHA-256. A constant is then mixed in and the -/// resulting hash is then used to seed a `ChaCha12` CSPRNG, which is -/// subsequently used to generate the key. -pub fn derive_sk(seed: &[u8; 64], index: u64) -> SecretKey { - let mut hash = Sha256::new(); - - hash.update(seed); - hash.update(index.to_le_bytes()); - hash.update(b"SK"); - - let hash = hash.finalize().into(); - let mut rng = ChaCha12Rng::from_seed(hash); - - SecretKey::random(&mut rng) -} - -/// Types that are client of the prover. -pub trait ProverClient { - /// Error returned by the node client. - type Error; - - /// Requests that a node prove the given transaction and later propagates it - fn compute_proof_and_propagate( - &self, - utx: &UnprovenTransaction, - ) -> Result; - - /// Requests an STCT proof. - fn request_stct_proof( - &self, - fee: &Fee, - crossover: &Crossover, - value: u64, - blinder: JubJubScalar, - address: BlsScalar, - signature: Signature, - ) -> Result; - - /// Request a WFCT proof. - fn request_wfct_proof( - &self, - commitment: JubJubAffine, - value: u64, - blinder: JubJubScalar, - ) -> Result; -} - -/// Block height representation -pub type BlockHeight = u64; - -/// Tuple containing Note and Block height -pub type EnrichedNote = (Note, BlockHeight); - -/// Types that are clients of the state API. -pub trait StateClient { - /// Error returned by the node client. - type Error; - - /// Find notes for a view key. - fn fetch_notes( - &self, - vk: &ViewKey, - ) -> Result, Self::Error>; - - /// Fetch the current anchor of the state. - fn fetch_anchor(&self) -> Result; - - /// Asks the node to return the nullifiers that already exist from the given - /// nullifiers. - fn fetch_existing_nullifiers( - &self, - nullifiers: &[BlsScalar], - ) -> Result, Self::Error>; - - /// Queries the node to find the opening for a specific note. - fn fetch_opening( - &self, - note: &Note, - ) -> Result, Self::Error>; - - /// Queries the node for the stake of a key. If the key has no stake, a - /// `Default` stake info should be returned. - fn fetch_stake(&self, pk: &PublicKey) -> Result; -} - -/// Information about the balance of a particular key. -#[derive(Debug, Default, Hash, Clone, Copy, PartialEq, Eq)] -pub struct BalanceInfo { - /// The total value of the balance. - pub value: u64, - /// The maximum _spendable_ value in a single transaction. This is - /// different from `value` since there is a maximum number of notes one can - /// spend. - pub spendable: u64, -} - -impl Serializable<16> for BalanceInfo { - type Error = dusk_bytes::Error; - - fn from_bytes(buf: &[u8; Self::SIZE]) -> Result - where - Self: Sized, - { - let mut reader = &buf[..]; - - let value = u64::from_reader(&mut reader)?; - let spendable = u64::from_reader(&mut reader)?; - - Ok(Self { value, spendable }) - } - - #[allow(unused_must_use)] - fn to_bytes(&self) -> [u8; Self::SIZE] { - let mut buf = [0u8; Self::SIZE]; - let mut writer = &mut buf[..]; - - writer.write(&self.value.to_bytes()); - writer.write(&self.spendable.to_bytes()); - - buf - } -} - -/// The stake of a particular key. -#[derive(Debug, Default, Hash, Clone, Copy, PartialEq, Eq)] -pub struct StakeInfo { - /// The value and eligibility of the stake, in that order. - pub amount: Option<(u64, u64)>, - /// The reward available for withdrawal. - pub reward: u64, - /// Signature counter. - pub counter: u64, -} - -impl From for StakeInfo { - fn from(data: StakeData) -> Self { - StakeInfo { - amount: data.amount, - reward: data.reward, - counter: data.counter, - } - } -} - -impl Serializable<32> for StakeInfo { - type Error = dusk_bytes::Error; - - /// Deserializes in the same order as defined in [`to_bytes`]. If the - /// deserialized value is 0, then `amount` will be `None`. This means that - /// the eligibility value is left loose, and could be any number when value - /// is 0. - fn from_bytes(buf: &[u8; Self::SIZE]) -> Result - where - Self: Sized, - { - let mut reader = &buf[..]; - - let value = u64::from_reader(&mut reader)?; - let eligibility = u64::from_reader(&mut reader)?; - let reward = u64::from_reader(&mut reader)?; - let counter = u64::from_reader(&mut reader)?; - - let amount = match value > 0 { - true => Some((value, eligibility)), - false => None, - }; - - Ok(Self { - amount, - reward, - counter, - }) - } +pub mod ffi; +pub mod key; +pub mod tx; +pub mod types; +pub mod utils; - /// Serializes the amount and the eligibility first, and then the reward and - /// the counter. If `amount` is `None`, and since a stake of no value should - /// not be possible, the first 16 bytes are filled with zeros. - #[allow(unused_must_use)] - fn to_bytes(&self) -> [u8; Self::SIZE] { - let mut buf = [0u8; Self::SIZE]; - let mut writer = &mut buf[..]; +/// The maximum number of keys (inclusive) to derive when attempting to decrypt +/// a note. +pub const MAX_KEY: usize = 24; - let (value, eligibility) = self.amount.unwrap_or_default(); +/// The maximum allocated buffer for rkyv serialization. +pub const MAX_LEN: usize = rusk_abi::ARGBUF_LEN; - writer.write(&value.to_bytes()); - writer.write(&eligibility.to_bytes()); - writer.write(&self.reward.to_bytes()); - writer.write(&self.counter.to_bytes()); +/// Length of the seed of the generated rng. +pub const RNG_SEED: usize = 64; - buf - } -} +/// The length of the allocated response. +pub const RESPONSE_LEN: usize = 3 * i32::BITS as usize / 8; diff --git a/src/tx.rs b/src/tx.rs index 578c1ed..8c89930 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -4,221 +4,284 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -use crate::StateClient; +//! Unspent transaction definition. use alloc::string::String; use alloc::vec::Vec; +use core::mem; -use dusk_bytes::{ - DeserializableSlice, Error as BytesError, Serializable, Write, +use bytecheck::CheckBytes; +use dusk_jubjub::{ + BlsScalar, JubJubExtended, JubJubScalar, GENERATOR_NUMS_EXTENDED, }; -use dusk_jubjub::{BlsScalar, JubJubAffine, JubJubExtended}; -use dusk_pki::{Ownable, SecretSpendKey}; -use dusk_plonk::prelude::{JubJubScalar, Proof}; +use dusk_pki::{Ownable, PublicSpendKey, SecretSpendKey}; use dusk_schnorr::Proof as SchnorrSig; -use phoenix_core::transaction::Transaction; -use phoenix_core::{Crossover, Fee, Note}; -use poseidon_merkle::Opening as PoseidonOpening; +use phoenix_core::{ + Crossover as PhoenixCrossover, Fee, Note, NoteType, Transaction, +}; use rand_core::{CryptoRng, RngCore}; +use rkyv::{Archive, Deserialize, Serialize}; use rusk_abi::hash::Hasher; -use rusk_abi::{ContractId, CONTRACT_ID_BYTES, POSEIDON_TREE_DEPTH}; +use rusk_abi::{ContractId, POSEIDON_TREE_DEPTH}; + +use crate::{types, utils}; + +/// Chosen arity for the Notes tree implementation. +pub const POSEIDON_TREE_ARITY: usize = 4; + +/// The Merkle Opening used in Rusk. +pub type Opening = + poseidon_merkle::Opening<(), POSEIDON_TREE_DEPTH, POSEIDON_TREE_ARITY>; + +/// A preliminary input to a transaction that is yet to be proven. +pub struct PreInput<'a> { + /// Input note to be used in the transaction. + pub note: Note, + /// Opening from the `input` to the Merkle root of the state. + pub opening: Opening, + /// Decrypted value of the input note. + pub value: u64, + /// Secret key to generate the nullifier of the input note. + pub ssk: &'a SecretSpendKey, +} /// An input to a transaction that is yet to be proven. -#[derive(Debug, Clone)] -pub struct UnprovenTransactionInput { - nullifier: BlsScalar, - opening: PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4>, - note: Note, - value: u64, - blinder: JubJubScalar, - pk_r_prime: JubJubExtended, - sig: SchnorrSig, +#[derive(Debug, Clone, Archive, Serialize, Deserialize)] +#[archive_attr(derive(CheckBytes))] +pub struct Input { + /// Nulifier generated from the input note. + pub nullifier: BlsScalar, + /// Opening from the `input` to the Merkle root of the state. + pub opening: Opening, + /// Input note to be used in the transaction. + pub note: Note, + /// Decrypted value of the input note. + pub value: u64, + /// Blinding factor used to construct the note. + pub blinder: JubJubScalar, + /// Stealth address derived from the key of the owner of the note. + pub pk_r_prime: JubJubExtended, + /// Schnorr signature to prove the ownership of the note. + pub sig: SchnorrSig, } -impl UnprovenTransactionInput { - fn new( - rng: &mut Rng, - ssk: &SecretSpendKey, - note: Note, - value: u64, - blinder: JubJubScalar, - opening: PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4>, - tx_hash: BlsScalar, - ) -> Self { - let nullifier = note.gen_nullifier(ssk); - let sk_r = ssk.sk_r(note.stealth_address()); - let sig = SchnorrSig::new(&sk_r, rng, tx_hash); - - let pk_r_prime = dusk_jubjub::GENERATOR_NUMS_EXTENDED * sk_r.as_ref(); - - Self { - note, - value, - blinder, - sig, - nullifier, - opening, - pk_r_prime, - } - } - - /// Serialize the input to a variable size byte buffer. - pub fn to_var_bytes(&self) -> Vec { - let affine_pkr = JubJubAffine::from(&self.pk_r_prime); - - let opening_bytes = rkyv::to_bytes::<_, 256>(&self.opening) - .expect("Rkyv serialization should always succeed for an opening") - .to_vec(); - - let mut bytes = Vec::with_capacity( - BlsScalar::SIZE - + Note::SIZE - + JubJubAffine::SIZE - + SchnorrSig::SIZE - + u64::SIZE - + JubJubScalar::SIZE - + opening_bytes.len(), - ); - - bytes.extend_from_slice(&self.nullifier.to_bytes()); - bytes.extend_from_slice(&self.note.to_bytes()); - bytes.extend_from_slice(&self.value.to_bytes()); - bytes.extend_from_slice(&self.blinder.to_bytes()); - bytes.extend_from_slice(&affine_pkr.to_bytes()); - bytes.extend_from_slice(&self.sig.to_bytes()); - bytes.extend(opening_bytes); - - bytes - } - - /// Deserializes the the input from bytes. - pub fn from_slice(buf: &[u8]) -> Result { - let mut bytes = buf; - - let nullifier = BlsScalar::from_reader(&mut bytes)?; - let note = Note::from_reader(&mut bytes)?; - let value = u64::from_reader(&mut bytes)?; - let blinder = JubJubScalar::from_reader(&mut bytes)?; - let pk_r_prime = - JubJubExtended::from(JubJubAffine::from_reader(&mut bytes)?); - let sig = SchnorrSig::from_reader(&mut bytes)?; - - // `to_vec` is required here otherwise `rkyv` will throw an alignment - // error - #[allow(clippy::unnecessary_to_owned)] - let opening = rkyv::from_bytes(&bytes.to_vec()) - .map_err(|_| BytesError::InvalidData)?; - - Ok(Self { - note, - value, - blinder, - sig, - nullifier, - opening, - pk_r_prime, - }) - } - - /// Returns the nullifier of the input. - pub fn nullifier(&self) -> BlsScalar { - self.nullifier - } - - /// Returns the opening of the input. - pub fn opening(&self) -> &PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4> { - &self.opening - } - - /// Returns the note of the input. - pub fn note(&self) -> &Note { - &self.note - } - - /// Returns the value of the input. - pub fn value(&self) -> u64 { - self.value - } +/// A preliminary output to a transaction that is yet to be proven. +#[derive(Debug, Clone, Archive, Serialize, Deserialize)] +#[archive_attr(derive(CheckBytes))] +pub struct OutputValue { + /// Type of the output note to be used in the transaction. + pub r#type: NoteType, + /// Value of the output. + pub value: u64, + /// Public key that will receive the note as spendable input. + pub receiver: PublicSpendKey, + /// Nonce/reference to be attached to the note. + pub ref_id: u64, +} - /// Returns the blinding factor of the input. - pub fn blinding_factor(&self) -> JubJubScalar { - self.blinder - } +/// An output to a transaction that is yet to be proven. +#[derive(Debug, Clone, Archive, Serialize, Deserialize)] +#[archive_attr(derive(CheckBytes))] +pub struct Output { + /// Computed output note to be used in the transaction. + pub note: Note, + /// Decrypted value of the output note. + pub value: u64, + /// Blinding factor used to construct the note. + pub blinder: JubJubScalar, +} - /// Returns the input's pk_r'. - pub fn pk_r_prime(&self) -> JubJubExtended { - self.pk_r_prime - } +/// A crossover to a transaction that is yet to be proven. +#[derive(Debug, Clone, Archive, Serialize, Deserialize)] +#[archive_attr(derive(CheckBytes))] +pub struct Crossover { + /// Crossover value to be used in inter-contract calls. + pub crossover: PhoenixCrossover, + /// Value of the crossover. + pub value: u64, + /// Blinding factor used to construct the crossover. + pub blinder: JubJubScalar, +} - /// Returns the input's signature. - pub fn signature(&self) -> &SchnorrSig { - &self.sig - } +/// A call data payload to a transaction that is yet to be proven. +#[derive(Debug, Clone, Archive, Serialize, Deserialize)] +#[archive_attr(derive(CheckBytes))] +pub struct CallData { + /// Contract ID to be called. + pub contract: ContractId, + /// Name of the method to be called. + pub method: String, + /// Payload of the call to be sent to the contract module. + pub payload: Vec, } -/// A transaction that is yet to be proven. The purpose of this is solely to -/// send to the node to perform a circuit proof. -#[derive(Debug, Clone)] +/// A transaction that is yet to be proven. +#[derive(Debug, Clone, Archive, Serialize, Deserialize)] +#[archive_attr(derive(CheckBytes))] pub struct UnprovenTransaction { - inputs: Vec, - outputs: Vec<(Note, u64, JubJubScalar)>, - anchor: BlsScalar, - fee: Fee, - crossover: Option<(Crossover, u64, JubJubScalar)>, - call: Option<(ContractId, String, Vec)>, + /// Inputs to the transaction. + pub inputs: Vec, + /// Outputs to the transaction. + pub outputs: Vec, + /// Merkle root of the state for the inputs openings. + pub anchor: BlsScalar, + /// Fee setup for the transaction. + pub fee: Fee, + /// Crossover value for inter-contract calls. + pub crossover: Option, + /// Call data payload for contract calls. + pub call: Option, } impl UnprovenTransaction { - /// Creates a transaction that conforms to the transfer contract. - #[allow(clippy::too_many_arguments)] - pub(crate) fn new( + /// Creates a new unproven transaction from the arguments. + /// + /// The transaction can be sent to a prover service and it contains all the + /// data required to generate a ZK proof of validity. + pub fn new<'a, Rng, I, O>( rng: &mut Rng, - state: &SC, - sender: &SecretSpendKey, - inputs: Vec<(Note, u64, JubJubScalar)>, - outputs: Vec<(Note, u64, JubJubScalar)>, - fee: Fee, - crossover: Option<(Crossover, u64, JubJubScalar)>, - call: Option<(ContractId, String, Vec)>, - ) -> Result { - let nullifiers: Vec = inputs - .iter() - .map(|(note, _, _)| note.gen_nullifier(sender)) - .collect(); + inputs: I, + outputs: O, + refund: String, + gas_limit: u64, + gas_price: u64, + crossover: Option, + call: Option, + ) -> Option + where + Rng: RngCore + CryptoRng, + I: IntoIterator>, + O: IntoIterator, + { + let (nullifiers, inputs): (Vec<_>, Vec<_>) = inputs + .into_iter() + .map(|i| { + let nullifier = i.note.gen_nullifier(i.ssk); + (nullifier, i) + }) + .unzip(); - let mut openings = Vec::with_capacity(inputs.len()); - for (note, _, _) in &inputs { - let opening = state.fetch_opening(note)?; - openings.push(opening); - } + let anchor = inputs.first().map(|i| i.opening.root().hash)?; + let refund = utils::bs58_to_psk(&refund)?; - let anchor = state.fetch_anchor()?; + let mut output_notes = Vec::with_capacity(4); + let mut outputs_values = Vec::with_capacity(4); - let hash_outputs: Vec = outputs.iter().map(|o| o.0).collect(); - let hash_crossover = crossover.map(|c| c.0); + for types::ExecuteOutput { + note_type, + receiver, + ref_id, + value, + } in outputs.into_iter() + { + let r#type = match note_type { + types::OutputType::Transparent => NoteType::Transparent, + types::OutputType::Obfuscated => NoteType::Obfuscated, + }; + + let r = JubJubScalar::random(rng); + let blinder = JubJubScalar::random(rng); + let nonce = BlsScalar::from(ref_id.unwrap_or_default()); + let receiver = utils::bs58_to_psk(&receiver)?; + let note = Note::deterministic( + r#type, &r, nonce, &receiver, value, blinder, + ); + + output_notes.push(note); + outputs_values.push(Output { + note, + value, + blinder, + }); + } - let hash_call = call.clone().map(|c| (c.0.to_bytes(), c.1, c.2)); - let hash_bytes = Transaction::hash_input_bytes_from_components( + let outputs = outputs_values; + + let call = match call { + Some(types::ExecuteCall { + contract, + method, + payload, + }) => { + let decoded = bs58::decode(contract).into_vec().ok()?; + if decoded.len() != mem::size_of::() { + return None; + } + let mut contract = ContractId::uninitialized(); + contract.as_bytes_mut().copy_from_slice(&decoded); + Some(CallData { + contract, + method, + payload, + }) + } + None => None, + }; + let call_phoenix = call.as_ref().map(|c| { + (c.contract.to_bytes(), c.method.clone(), c.payload.clone()) + }); + + let fee = Fee::new(rng, gas_limit, gas_price, &refund); + + let crossover = crossover.map(|crossover| { + let blinder = JubJubScalar::random(rng); + let (_, crossover_note) = + Note::obfuscated(rng, &refund, crossover, blinder) + .try_into() + .expect("Obfuscated notes should always yield crossovers"); + Crossover { + crossover: crossover_note, + value: crossover, + blinder, + } + }); + + let tx_hash = Transaction::hash_input_bytes_from_components( &nullifiers, - &hash_outputs, + &output_notes, &anchor, &fee, - &hash_crossover, - &hash_call, + &crossover.as_ref().map(|c| c.crossover), + &call_phoenix, ); - let hash = Hasher::digest(hash_bytes); + let tx_hash = Hasher::digest(tx_hash); - let inputs: Vec = inputs + let inputs = inputs .into_iter() - .zip(openings.into_iter()) - .map(|((note, value, blinder), opening)| { - UnprovenTransactionInput::new( - rng, sender, note, value, blinder, opening, hash, - ) - }) - .collect(); - - Ok(Self { + .zip(nullifiers.into_iter()) + .map( + |( + PreInput { + note, + opening, + value, + ssk, + }, + nullifier, + )| { + let vk = ssk.view_key(); + let sk_r = ssk.sk_r(note.stealth_address()); + + let blinder = + note.blinding_factor(Some(&vk)).map_err(|_| ())?; + let pk_r_prime = GENERATOR_NUMS_EXTENDED * sk_r.as_ref(); + let sig = SchnorrSig::new(&sk_r, rng, tx_hash); + + Ok(Input { + nullifier, + opening, + note, + value, + blinder, + pk_r_prime, + sig, + }) + }, + ) + .collect::, ()>>() + .ok()?; + + Some(UnprovenTransaction { inputs, outputs, anchor, @@ -227,301 +290,4 @@ impl UnprovenTransaction { call, }) } - - /// Consumes self and a proof to generate a transaction. - pub fn prove(self, proof: Proof) -> Transaction { - Transaction { - anchor: self.anchor, - nullifiers: self - .inputs - .into_iter() - .map(|input| input.nullifier) - .collect(), - outputs: self - .outputs - .into_iter() - .map(|(note, _, _)| note) - .collect(), - fee: self.fee, - crossover: self.crossover.map(|c| c.0), - proof: proof.to_bytes().to_vec(), - call: self.call.map(|c| (c.0.to_bytes(), c.1, c.2)), - } - } - - /// Serialize the transaction to a variable length byte buffer. - #[allow(unused_must_use)] - pub fn to_var_bytes(&self) -> Vec { - let serialized_inputs: Vec> = self - .inputs - .iter() - .map(UnprovenTransactionInput::to_var_bytes) - .collect(); - let num_inputs = self.inputs.len(); - let total_input_len = serialized_inputs - .iter() - .fold(0, |len, input| len + input.len()); - - let serialized_outputs: Vec< - [u8; Note::SIZE + u64::SIZE + JubJubScalar::SIZE], - > = self - .outputs - .iter() - .map(|(note, value, blinder)| { - let mut buf = [0; Note::SIZE + u64::SIZE + JubJubScalar::SIZE]; - - buf[..Note::SIZE].copy_from_slice(¬e.to_bytes()); - buf[Note::SIZE..Note::SIZE + u64::SIZE] - .copy_from_slice(&value.to_bytes()); - buf[Note::SIZE + u64::SIZE - ..Note::SIZE + u64::SIZE + JubJubScalar::SIZE] - .copy_from_slice(&blinder.to_bytes()); - - buf - }) - .collect(); - let num_outputs = self.outputs.len(); - let total_output_len = serialized_outputs - .iter() - .fold(0, |len, output| len + output.len()); - - let size = u64::SIZE - + num_inputs * u64::SIZE - + total_input_len - + u64::SIZE - + total_output_len - + BlsScalar::SIZE - + Fee::SIZE - + u64::SIZE - + self.crossover.map_or(0, |_| { - Crossover::SIZE + u64::SIZE + JubJubScalar::SIZE - }) - + u64::SIZE - + self - .call - .as_ref() - .map(|(_, cname, cdata)| { - CONTRACT_ID_BYTES + u64::SIZE + cname.len() + cdata.len() - }) - .unwrap_or(0); - - let mut buf = vec![0; size]; - let mut writer = &mut buf[..]; - - writer.write(&(num_inputs as u64).to_bytes()); - for sinput in serialized_inputs { - writer.write(&(sinput.len() as u64).to_bytes()); - writer.write(&sinput); - } - - writer.write(&(num_outputs as u64).to_bytes()); - for soutput in serialized_outputs { - writer.write(&soutput); - } - - writer.write(&self.anchor.to_bytes()); - writer.write(&self.fee.to_bytes()); - - write_crossover_value_blinder(&mut writer, self.crossover); - write_optional_call(&mut writer, &self.call); - - buf - } - - /// Deserialize the transaction from a bytes buffer. - pub fn from_slice(buf: &[u8]) -> Result { - let mut buffer = buf; - - let num_inputs = u64::from_reader(&mut buffer)?; - let mut inputs = Vec::with_capacity(num_inputs as usize); - for _ in 0..num_inputs { - let size = u64::from_reader(&mut buffer)? as usize; - inputs.push(UnprovenTransactionInput::from_slice(&buffer[..size])?); - buffer = &buffer[size..]; - } - - let num_outputs = u64::from_reader(&mut buffer)?; - let mut outputs = Vec::with_capacity(num_outputs as usize); - for _ in 0..num_outputs { - let note = Note::from_reader(&mut buffer)?; - let value = u64::from_reader(&mut buffer)?; - let blinder = JubJubScalar::from_reader(&mut buffer)?; - - outputs.push((note, value, blinder)); - } - - let anchor = BlsScalar::from_reader(&mut buffer)?; - let fee = Fee::from_reader(&mut buffer)?; - - let crossover = read_crossover_value_blinder(&mut buffer)?; - - let call = read_optional_call(&mut buffer)?; - - Ok(Self { - inputs, - outputs, - anchor, - fee, - crossover, - call, - }) - } - - /// Returns the hash of the transaction. - pub fn hash(&self) -> BlsScalar { - let nullifiers: Vec = - self.inputs.iter().map(|input| input.nullifier).collect(); - - let hash_outputs: Vec = - self.outputs.iter().map(|(note, _, _)| *note).collect(); - let hash_crossover = self.crossover.map(|c| c.0); - let hash_bytes = self.call.clone().map(|c| (c.0.to_bytes(), c.1, c.2)); - - Hasher::digest(Transaction::hash_input_bytes_from_components( - &nullifiers, - &hash_outputs, - &self.anchor, - &self.fee, - &hash_crossover, - &hash_bytes, - )) - } - - /// Returns the inputs to the transaction. - pub fn inputs(&self) -> &[UnprovenTransactionInput] { - &self.inputs - } - - /// Returns the outputs of the transaction. - pub fn outputs(&self) -> &[(Note, u64, JubJubScalar)] { - &self.outputs - } - - /// Returns the anchor of the transaction. - pub fn anchor(&self) -> BlsScalar { - self.anchor - } - - /// Returns the fee of the transaction. - pub fn fee(&self) -> &Fee { - &self.fee - } - - /// Returns the crossover of the transaction. - pub fn crossover(&self) -> Option<&(Crossover, u64, JubJubScalar)> { - self.crossover.as_ref() - } - - /// Returns the call of the transaction. - pub fn call(&self) -> Option<&(ContractId, String, Vec)> { - self.call.as_ref() - } -} - -/// Writes an optional call into the writer, prepending it with a `u64` denoting -/// if it is present or not. This should be called at the end of writing other -/// fields since it doesn't write any information about the length of the call -/// data. -fn write_optional_call( - writer: &mut W, - call: &Option<(ContractId, String, Vec)>, -) -> Result<(), BytesError> { - match call { - Some((cid, cname, cdata)) => { - writer.write(&1_u64.to_bytes())?; - - writer.write(cid.as_bytes())?; - - let cname_len = cname.len() as u64; - writer.write(&cname_len.to_bytes())?; - writer.write(cname.as_bytes())?; - - writer.write(cdata)?; - } - None => { - writer.write(&0_u64.to_bytes())?; - } - }; - - Ok(()) -} - -/// Reads an optional call from the given buffer. This should be called at the -/// end of parsing other fields since it consumes the entirety of the buffer. -fn read_optional_call( - buffer: &mut &[u8], -) -> Result)>, BytesError> { - let mut call = None; - - if u64::from_reader(buffer)? != 0 { - let buf_len = buffer.len(); - - // needs to be at least the size of a contract ID and have some call - // data. - if buf_len < CONTRACT_ID_BYTES { - return Err(BytesError::BadLength { - found: buf_len, - expected: CONTRACT_ID_BYTES, - }); - } - let (mid_buffer, mut buffer_left) = { - let (buf, left) = buffer.split_at(CONTRACT_ID_BYTES); - - let mut mid_buf = [0u8; CONTRACT_ID_BYTES]; - mid_buf.copy_from_slice(buf); - - (mid_buf, left) - }; - - let contract_id = ContractId::from(mid_buffer); - - let buffer = &mut buffer_left; - - let cname_len = u64::from_reader(buffer)?; - let (cname_bytes, buffer_left) = buffer.split_at(cname_len as usize); - - let cname = String::from_utf8(cname_bytes.to_vec()) - .map_err(|_| BytesError::InvalidData)?; - - let call_data = Vec::from(buffer_left); - call = Some((contract_id, cname, call_data)); - } - - Ok(call) -} - -fn write_crossover_value_blinder( - writer: &mut W, - crossover: Option<(Crossover, u64, JubJubScalar)>, -) -> Result<(), BytesError> { - match crossover { - Some((crossover, value, blinder)) => { - writer.write(&1_u64.to_bytes())?; - writer.write(&crossover.to_bytes())?; - writer.write(&value.to_bytes())?; - writer.write(&blinder.to_bytes())?; - } - None => { - writer.write(&0_u64.to_bytes())?; - } - } - - Ok(()) -} - -/// Reads an optional crossover from the given buffer. -fn read_crossover_value_blinder( - buffer: &mut &[u8], -) -> Result, BytesError> { - let ser = match u64::from_reader(buffer)? { - 0 => None, - _ => { - let crossover = Crossover::from_reader(buffer)?; - let value = u64::from_reader(buffer)?; - let blinder = JubJubScalar::from_reader(buffer)?; - Some((crossover, value, blinder)) - } - }; - - Ok(ser) } diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..f58ac56 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,143 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +//! Arguments and responses to the module requests + +// THIS FILE IS AUTO GENERATED!! + +#![allow(missing_docs)] + +use alloc::string::String; +use alloc::vec::Vec; +use serde::{Deserialize, Serialize}; + +#[doc = " The arguments of the balance function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct BalanceArgs { + #[doc = " A rkyv serialized [Vec]; all notes should have their keys derived from "] + #[doc = " `seed`"] + pub notes: Vec, + #[doc = " Seed used to derive the keys of the wallet"] + pub seed: Vec, +} +#[doc = " The response of the balance function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct BalanceResponse { + #[doc = " Maximum value per transaction"] + pub maximum: u64, + #[doc = " Total computed balance"] + pub value: u64, +} +#[doc = " The arguments of the execute function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ExecuteArgs { + #[doc = " A call to a contract method"] + #[serde(skip_serializing_if = "Option::is_none")] + pub call: Option, + #[doc = " The [phoenix_core::Crossover] value"] + #[serde(skip_serializing_if = "Option::is_none")] + pub crossover: Option, + #[doc = " The gas limit of the transaction"] + pub gas_limit: u64, + #[doc = " The gas price per unit for the transaction"] + pub gas_price: u64, + #[doc = " A rkyv serialized [Vec] to be used as inputs"] + pub inputs: Vec, + #[doc = " A rkyv serialized [Vec] to open the inputs to a Merkle root"] + pub openings: Vec, + #[doc = " The transfer output note"] + #[serde(skip_serializing_if = "Option::is_none")] + pub output: Option, + #[doc = " The refund addressin Base58 format"] + pub refund: String, + #[doc = " Seed used to derive the entropy for the notes"] + pub rng_seed: Vec, + #[doc = " Seed used to derive the keys of the wallet"] + pub seed: Vec, +} +#[doc = " A call to a contract method"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ExecuteCall { + #[doc = " The id of the contract to call in Base58 format"] + pub contract: String, + #[doc = " The name of the method to be called"] + pub method: String, + #[doc = " The payload of the call"] + pub payload: Vec, +} +#[doc = " The output of a transfer"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ExecuteOutput { + #[doc = " The type of the note"] + pub note_type: OutputType, + #[doc = " The address of the receiver in Base58 format"] + pub receiver: String, + #[doc = " A reference id to be appended to the output"] + #[serde(skip_serializing_if = "Option::is_none")] + pub ref_id: Option, + #[doc = " The value of the output"] + pub value: u64, +} +#[doc = " The response of the execute function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ExecuteResponse { + #[doc = " A rkyv serialized [crate::tx::UnspentTransaction]"] + pub tx: Vec, + #[doc = " A rkyv serialized [Vec] containing the notes that weren't used"] + pub unspent: Vec, +} +#[doc = " The arguments of the filter_notes function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct FilterNotesArgs { + #[doc = " Boolean flags to be negative filtered"] + pub flags: Vec, + #[doc = " A rkyv serialized [Vec] to be filtered"] + pub notes: Vec, +} +#[doc = " The arguments of the merge_notes function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct MergeNotesArgs { + #[doc = " All serialized list of notes to be merged"] + pub notes: Vec>, +} +#[doc = " The arguments of the nullifiers function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct NullifiersArgs { + #[doc = " A rkyv serialized [Vec] to have nullifiers generated"] + pub notes: Vec, + #[doc = " Seed used to derive the keys of the wallet"] + pub seed: Vec, +} +#[doc = " A note type variant"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub enum OutputType { + Transparent, + Obfuscated, +} +#[doc = " The arguments of the public_spend_keys function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct PublicSpendKeysArgs { + #[doc = " Seed used to derive the keys of the wallet"] + pub seed: Vec, +} +#[doc = " The response of the public_spend_keys function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct PublicSpendKeysResponse { + #[doc = " The Base58 public spend keys of the wallet."] + pub keys: Vec, +} +#[doc = " The arguments of the seed function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct SeedArgs { + #[doc = " An arbitrary sequence of bytes used to generate a secure seed"] + pub passphrase: Vec, +} +#[doc = " The arguments of the view_keys function"] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ViewKeysArgs { + #[doc = " Seed used to derive the keys of the wallet"] + pub seed: Vec, +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..b6b4608 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,251 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +//! Misc utilities required by the library implementation. + +use crate::{tx, MAX_LEN, RNG_SEED}; + +use alloc::vec::Vec; +use core::mem; + +use dusk_bytes::DeserializableSlice; +use dusk_pki::PublicSpendKey; +use phoenix_core::Note; +use rand_chacha::ChaCha12Rng; +use rand_core::SeedableRng; +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; + +/// Composes a `i64` from the provided arguments. This will be returned from the +/// WASM module functions. +pub const fn compose(success: bool, ptr: u32, len: u32) -> i64 { + let success = (!success) as u64; + let ptr = (ptr as u64) << 32; + let len = ((len as u64) << 48) >> 32; + (success | ptr | len) as i64 +} + +/// Decomposes a `i64` into its inner arguments, being: +/// +/// - status: a boolean indicating the success of the operation +/// - ptr: a pointer to the underlying data +/// - len: the length of the underlying data +pub const fn decompose(result: i64) -> (bool, u64, u64) { + let ptr = (result >> 32) as u64; + let len = ((result << 32) >> 48) as u64; + let success = ((result << 63) >> 63) == 0; + + (success, ptr, len) +} + +/// Takes a JSON string from the memory slice and deserializes it into the +/// provided type. +pub fn take_args(args: i32, len: i32) -> Option +where + T: for<'a> Deserialize<'a>, +{ + let args = args as *mut u8; + let len = len as usize; + let args = unsafe { Vec::from_raw_parts(args, len, len) }; + let args = alloc::string::String::from_utf8(args).ok()?; + serde_json::from_str(&args).ok() +} + +/// Sanitizes arbitrary bytes into well-formed seed. +pub fn sanitize_seed(bytes: Vec) -> Option<[u8; RNG_SEED]> { + (bytes.len() == RNG_SEED).then(|| { + let mut seed = [0u8; RNG_SEED]; + seed.copy_from_slice(&bytes); + seed + }) +} + +/// Fails the operation +pub const fn fail() -> i64 { + compose(false, 0, 0) +} + +/// Converts the provided response into an allocated pointer and returns the +/// composed success value. +pub fn into_ptr(response: T) -> i64 +where + T: Serialize, +{ + let response = serde_json::to_string(&response).unwrap_or_default(); + let ptr = response.as_ptr() as u32; + let len = response.len() as u32; + let result = compose(true, ptr, len); + + mem::forget(response); + + result +} + +/// Returns the provided bytes as a pointer +pub fn rkyv_into_ptr(value: T) -> i64 +where + T: rkyv::Serialize>, +{ + let bytes = match rkyv::to_bytes(&value) { + Ok(t) => t.into_vec(), + Err(_) => return fail(), + }; + + let ptr = bytes.as_ptr() as u32; + let len = bytes.len() as u32; + + mem::forget(bytes); + compose(true, ptr, len) +} + +/// Creates a secure RNG from a seed. +pub fn rng(seed: &[u8; RNG_SEED]) -> ChaCha12Rng { + let mut hash = Sha256::new(); + + hash.update(seed); + hash.update(b"RNG"); + + let hash = hash.finalize().into(); + ChaCha12Rng::from_seed(hash) +} + +/// Creates a secure RNG from a seed with embedded index. +pub fn rng_with_index(seed: &[u8; RNG_SEED], index: u64) -> ChaCha12Rng { + let mut hash = Sha256::new(); + + hash.update(seed); + hash.update(index.to_le_bytes()); + hash.update(b"INDEX"); + + let hash = hash.finalize().into(); + ChaCha12Rng::from_seed(hash) +} + +/// Sanitize a notes input into a consumable notes set +pub fn sanitize_notes(mut notes: Vec) -> Vec { + notes.sort_by_key(|n| n.hash()); + notes.dedup(); + notes +} + +/// Converts a Base58 string into a [PublicSpendKey]. +pub fn bs58_to_psk(psk: &str) -> Option { + // TODO this should be defined in dusk-pki + let bytes = bs58::decode(psk).into_vec().ok()?; + PublicSpendKey::from_reader(&mut &bytes[..]).ok() +} + +/// Perform a knapsack algorithm to define the notes to be used as input. +/// +/// Returns a tuple containing (unspent, inputs). `unspent` contains the notes +/// that are not used. +pub fn knapsack( + mut nodes: Vec<(Note, tx::Opening, u64, usize)>, + target_sum: u64, +) -> Option<(Vec, Vec<(Note, tx::Opening, u64, usize)>)> { + if nodes.is_empty() { + return None; + } + + // TODO implement a knapsack algorithm + // here we do a naive, desc order pick. optimally, we should maximize the + // number of smaller inputs that fits the target sum so we reduce the number + // of available small notes on the wallet. a knapsack implementation is + // optimal for such problems as it can deliver high confidence results + // with moderate memory space. + nodes.sort_by(|a, b| b.2.cmp(&a.2)); + + let mut i = 0; + let mut sum = 0; + while sum < target_sum && i < nodes.len() { + sum = sum.saturating_add(nodes[i].2); + i += 1; + } + + if sum < target_sum { + return None; + } + let unspent = nodes.split_off(i).into_iter().map(|n| n.0).collect(); + + Some((unspent, nodes)) +} + +#[test] +fn compose_works() { + assert_eq!(decompose(compose(true, 0, 0)), (true, 0, 0)); + assert_eq!(decompose(compose(false, 0, 0)), (false, 0, 0)); + assert_eq!(decompose(compose(false, 1, 0)), (false, 1, 0)); + assert_eq!(decompose(compose(false, 0, 1)), (false, 0, 1)); + assert_eq!(decompose(compose(false, 4837, 383)), (false, 4837, 383)); +} + +#[test] +fn knapsack_works() { + use core::mem; + use dusk_jubjub::JubJubScalar; + use dusk_pki::SecretSpendKey; + use rand::{rngs::StdRng, SeedableRng}; + + // openings are not checked here; no point in setting them up properly + let o = unsafe { mem::zeroed() }; + let rng = &mut StdRng::seed_from_u64(0xbeef); + + // sanity check + assert_eq!(knapsack(vec![], 70), None); + + // basic check + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note = Note::obfuscated(rng, &key.public_spend_key(), 100, blinder); + let available = vec![(note, o, 100, 0)]; + let unspent = vec![]; + let inputs = available.clone(); + assert_eq!(knapsack(available, 70), Some((unspent, inputs))); + + // out of balance basic check + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note = Note::obfuscated(rng, &key.public_spend_key(), 100, blinder); + let available = vec![(note, o, 100, 0)]; + assert_eq!(knapsack(available, 101), None); + + // multiple inputs check + // note: this test is checking a naive, simple order-based output + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note1 = Note::obfuscated(rng, &key.public_spend_key(), 100, blinder); + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note2 = Note::obfuscated(rng, &key.public_spend_key(), 500, blinder); + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note3 = Note::obfuscated(rng, &key.public_spend_key(), 300, blinder); + let available = vec![ + (note1.clone(), o, 100, 0), + (note2.clone(), o, 500, 1), + (note3.clone(), o, 300, 2), + ]; + let unspent = vec![note1]; + let inputs = vec![(note2.clone(), o, 500, 1), (note3.clone(), o, 300, 2)]; + assert_eq!(knapsack(available, 600), Some((unspent, inputs))); + + // multiple inputs, out of balance check + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note1 = Note::obfuscated(rng, &key.public_spend_key(), 100, blinder); + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note2 = Note::obfuscated(rng, &key.public_spend_key(), 500, blinder); + let key = SecretSpendKey::random(rng); + let blinder = JubJubScalar::random(rng); + let note3 = Note::obfuscated(rng, &key.public_spend_key(), 300, blinder); + let available = vec![ + (note1.clone(), o, 100, 0), + (note2.clone(), o, 500, 1), + (note3.clone(), o, 300, 2), + ]; + assert_eq!(knapsack(available, 901), None); +} diff --git a/tests/mock.rs b/tests/mock.rs deleted file mode 100644 index 1e5c8d8..0000000 --- a/tests/mock.rs +++ /dev/null @@ -1,350 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// Copyright (c) DUSK NETWORK. All rights reserved. - -//! Mocks of the traits supplied by the user of the crate.. - -use dusk_bls12_381_sign::PublicKey; -use dusk_jubjub::{BlsScalar, JubJubAffine, JubJubScalar}; -use dusk_pki::{PublicSpendKey, ViewKey}; -use dusk_plonk::prelude::Proof; -use dusk_schnorr::Signature; -use dusk_wallet_core::{ - EnrichedNote, ProverClient, StakeInfo, StateClient, Store, Transaction, - UnprovenTransaction, Wallet, POSEIDON_TREE_DEPTH, -}; -use phoenix_core::{Crossover, Fee, Note, NoteType}; -use poseidon_merkle::{Item, Opening as PoseidonOpening, Tree}; -use rand_core::{CryptoRng, RngCore}; - -fn default_opening() -> PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4> { - // Build a "default" opening - const POS: u64 = 42; - let mut tree = Tree::new(); - tree.insert( - POS, - Item { - hash: BlsScalar::zero(), - data: (), - }, - ); - tree.opening(POS).unwrap() -} - -/// Create a new wallet meant for tests. It includes a client that will always -/// return a random anchor (same every time), and the default opening. -/// -/// The number of notes available is determined by `note_values`. -pub fn mock_wallet( - rng: &mut Rng, - note_values: &[u64], -) -> Wallet { - let store = TestStore::new(rng); - let psk = store.retrieve_ssk(0).unwrap().public_spend_key(); - - let notes = new_notes(rng, &psk, note_values); - let anchor = BlsScalar::random(rng); - let opening = default_opening(); - - let state = TestStateClient::new(notes, anchor, opening); - let prover = TestProverClient; - - Wallet::new(store, state, prover) -} - -/// Create a new wallet equivalent in all ways to `mock_wallet`, but serializing -/// and deserializing a `Transaction` using `rkyv`. -pub fn mock_canon_wallet( - rng: &mut Rng, - note_values: &[u64], -) -> Wallet { - let store = TestStore::new(rng); - let psk = store.retrieve_ssk(0).unwrap().public_spend_key(); - - let notes = new_notes(rng, &psk, note_values); - let anchor = BlsScalar::random(rng); - let opening = default_opening(); - - let state = TestStateClient::new(notes, anchor, opening); - let prover = RkyvProverClient { - prover: TestProverClient, - }; - - Wallet::new(store, state, prover) -} - -/// Create a new wallet equivalent in all ways to `mock_wallet`, but serializing -/// and deserializing an `UnprovenTransaction` using `dusk::bytes`. -pub fn mock_serde_wallet( - rng: &mut Rng, - note_values: &[u64], -) -> Wallet { - let store = TestStore::new(rng); - let psk = store.retrieve_ssk(0).unwrap().public_spend_key(); - - let notes = new_notes(rng, &psk, note_values); - let anchor = BlsScalar::random(rng); - let opening = default_opening(); - - let state = TestStateClient::new(notes, anchor, opening); - let prover = SerdeProverClient { - prover: TestProverClient, - }; - - Wallet::new(store, state, prover) -} - -/// Returns obfuscated notes with the given value. -fn new_notes( - rng: &mut Rng, - psk: &PublicSpendKey, - note_values: &[u64], -) -> Vec { - note_values - .iter() - .map(|val| { - let blinder = JubJubScalar::random(rng); - (Note::new(rng, NoteType::Obfuscated, psk, *val, blinder), 0) - }) - .collect() -} - -/// An in-memory seed store. -#[derive(Debug)] -pub struct TestStore { - seed: [u8; 64], -} - -impl TestStore { - /// Instantiate a new in-memory store with a random seed. - fn new(rng: &mut Rng) -> Self { - let mut seed = [0; 64]; - rng.fill_bytes(&mut seed); - Self { seed } - } -} - -impl Store for TestStore { - type Error = (); - - fn get_seed(&self) -> Result<[u8; 64], Self::Error> { - Ok(self.seed) - } -} - -/// A state client that always returns the same notes, anchor, and opening. -#[derive(Debug, Clone)] -pub struct TestStateClient { - notes: Vec, - anchor: BlsScalar, - opening: PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4>, -} - -impl TestStateClient { - /// Create a new node given the notes, anchor, and opening we will return. - fn new( - notes: Vec, - anchor: BlsScalar, - opening: PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4>, - ) -> Self { - Self { - notes, - anchor, - opening, - } - } -} - -impl StateClient for TestStateClient { - type Error = (); - - fn fetch_notes( - &self, - _: &ViewKey, - ) -> Result, Self::Error> { - Ok(self.notes.clone()) - } - - fn fetch_anchor(&self) -> Result { - Ok(self.anchor) - } - - fn fetch_existing_nullifiers( - &self, - _: &[BlsScalar], - ) -> Result, Self::Error> { - Ok(vec![]) - } - - fn fetch_opening( - &self, - _: &Note, - ) -> Result, Self::Error> { - Ok(self.opening) - } - - fn fetch_stake(&self, _pk: &PublicKey) -> Result { - Ok(StakeInfo { - amount: Some((100, 0)), - reward: 0, - counter: 0, - }) - } -} - -#[derive(Debug)] -pub struct TestProverClient; - -impl ProverClient for TestProverClient { - type Error = (); - fn compute_proof_and_propagate( - &self, - utx: &UnprovenTransaction, - ) -> Result { - Ok(utx.clone().prove(Proof::default())) - } - - fn request_stct_proof( - &self, - _fee: &Fee, - _crossover: &Crossover, - _value: u64, - _blinder: JubJubScalar, - _address: BlsScalar, - _signature: Signature, - ) -> Result { - Ok(Proof::default()) - } - - fn request_wfct_proof( - &self, - _commitment: JubJubAffine, - _value: u64, - _blinder: JubJubScalar, - ) -> Result { - Ok(Proof::default()) - } -} - -#[derive(Debug)] -pub struct RkyvProverClient { - prover: TestProverClient, -} - -impl ProverClient for RkyvProverClient { - type Error = (); - - fn compute_proof_and_propagate( - &self, - utx: &UnprovenTransaction, - ) -> Result { - let utx_clone = utx.clone(); - - let tx = utx_clone.prove(Proof::default()); - - let bytes = rkyv::to_bytes::<_, 65536>(&tx) - .expect("Encoding a tx should succeed") - .to_vec(); - - let decoded_tx: Transaction = rkyv::from_bytes(&bytes) - .expect("Deserializing a transaction should succeed"); - - assert_eq!( - tx, decoded_tx, - "Encoded and decoded transaction should be equal" - ); - - self.prover.compute_proof_and_propagate(utx) - } - - fn request_stct_proof( - &self, - fee: &Fee, - crossover: &Crossover, - value: u64, - blinder: JubJubScalar, - address: BlsScalar, - signature: Signature, - ) -> Result { - self.prover.request_stct_proof( - fee, crossover, value, blinder, address, signature, - ) - } - - fn request_wfct_proof( - &self, - commitment: JubJubAffine, - value: u64, - blinder: JubJubScalar, - ) -> Result { - self.prover.request_wfct_proof(commitment, value, blinder) - } -} - -#[derive(Debug)] -pub struct SerdeProverClient { - prover: TestProverClient, -} - -impl ProverClient for SerdeProverClient { - type Error = (); - - fn compute_proof_and_propagate( - &self, - utx: &UnprovenTransaction, - ) -> Result { - let utx_bytes = utx.to_var_bytes(); - let utx_clone = UnprovenTransaction::from_slice(&utx_bytes) - .expect("Successful deserialization"); - - for (input, cinput) in - utx.inputs().iter().zip(utx_clone.inputs().iter()) - { - assert_eq!(input.nullifier(), cinput.nullifier()); - // assert_eq!(input.opening(), cinput.opening()); - assert_eq!(input.note(), cinput.note()); - assert_eq!(input.value(), cinput.value()); - assert_eq!(input.blinding_factor(), cinput.blinding_factor()); - assert_eq!(input.pk_r_prime(), cinput.pk_r_prime()); - // assert_eq!(input.signature(), cinput.signature()); - } - - for (output, coutput) in - utx.outputs().iter().zip(utx_clone.outputs().iter()) - { - assert_eq!(output, coutput); - } - - assert_eq!(utx.anchor(), utx_clone.anchor()); - assert_eq!(utx.fee(), utx_clone.fee()); - assert_eq!(utx.crossover(), utx_clone.crossover()); - assert_eq!(utx.call(), utx_clone.call()); - - self.prover.compute_proof_and_propagate(utx) - } - - fn request_stct_proof( - &self, - fee: &Fee, - crossover: &Crossover, - value: u64, - blinder: JubJubScalar, - address: BlsScalar, - signature: Signature, - ) -> Result { - self.prover.request_stct_proof( - fee, crossover, value, blinder, address, signature, - ) - } - - fn request_wfct_proof( - &self, - commitment: JubJubAffine, - value: u64, - blinder: JubJubScalar, - ) -> Result { - self.prover.request_wfct_proof(commitment, value, blinder) - } -} diff --git a/tests/wallet.rs b/tests/wallet.rs index 55ef628..cdce6b9 100644 --- a/tests/wallet.rs +++ b/tests/wallet.rs @@ -6,82 +6,444 @@ //! Wallet library tests. -mod mock; - use dusk_bytes::Serializable; -use dusk_plonk::prelude::BlsScalar; -use dusk_wallet_core::StakeInfo; -use mock::{mock_canon_wallet, mock_serde_wallet, mock_wallet}; +use dusk_pki::PublicSpendKey; +use dusk_wallet_core::{tx, types, utils, MAX_KEY, MAX_LEN, RNG_SEED}; +use rusk_abi::ContractId; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use wasmer::{imports, Instance, Module, Store, Value}; + +#[test] +fn seed_works() { + let mut wallet = Wallet::default(); + + let seed = wallet.call("seed", json!({ + "passphrase": b"Taking a new step, uttering a new word, is what people fear most.".to_vec() + })).take_memory(); + + assert_eq!(seed.len(), RNG_SEED); +} + +#[test] +fn balance_works() { + let seed = [0xfa; RNG_SEED]; + let values = [10, 250, 15, 39, 55]; + let mut wallet = Wallet::default(); + + let types::BalanceResponse { maximum, value } = wallet + .call( + "balance", + json!({ + "notes": node::notes(&seed, values), + "seed": seed.to_vec(), + }), + ) + .take_contents(); + + assert_eq!(value, values.into_iter().sum::()); + assert_eq!(maximum, 359); +} + +#[test] +fn execute_works() { + let seed = [0xfa; RNG_SEED]; + let rng_seed = [0xfb; RNG_SEED]; + let values = [10, 250, 15, 7500]; + + let mut wallet = Wallet::default(); + + let types::PublicSpendKeysResponse { keys } = wallet + .call( + "public_spend_keys", + json!({ + "seed": seed.to_vec(), + }), + ) + .take_contents(); + let psk = &keys[0]; + + let mut contract = ContractId::uninitialized(); + contract.as_bytes_mut().iter_mut().for_each(|b| *b = 0xfa); + let contract = bs58::encode(contract.as_bytes()).into_string(); + + let (inputs, openings) = node::notes_and_openings(&seed, values); + let args = json!({ + "call": { + "contract": contract, + "method": "commit", + "payload": b"We lost because we told ourselves we lost.".to_vec(), + }, + "crossover": 25, + "gas_limit": 100, + "gas_price": 2, + "inputs": inputs, + "openings": openings, + "output": { + "note_type": "Transparent", + "receiver": psk, + "ref_id": 15, + "value": 10, + }, + "refund": psk, + "rng_seed": rng_seed.to_vec(), + "seed": seed.to_vec() + }); + let types::ExecuteResponse { tx, unspent } = + wallet.call("execute", args).take_contents(); + + rkyv::from_bytes::(&tx).unwrap(); + rkyv::from_bytes::>(&unspent).unwrap(); +} #[test] -fn serde_stake() { - let stake = StakeInfo { - amount: Some((1000, 0)), - reward: 100, - counter: 1, - }; - - let stake_bytes = stake.to_bytes(); - let des_stake = - StakeInfo::from_bytes(&stake_bytes).expect("serde to go correctly"); - - assert_eq!(stake.amount, des_stake.amount); - assert_eq!(stake.reward, des_stake.reward); - assert_eq!(stake.counter, des_stake.counter); +fn merge_notes_works() { + let seed = [0xfa; RNG_SEED]; + + let notes1 = node::raw_notes(&seed, [10, 250, 15, 39, 55]); + let notes2 = vec![notes1[1].clone(), notes1[3].clone()]; + let notes3: Vec<_> = node::raw_notes(&seed, [10, 250, 15, 39, 55]) + .into_iter() + .chain([notes1[4].clone()]) + .collect(); + + let notes_unmerged: Vec<_> = notes1 + .iter() + .chain(notes2.iter()) + .chain(notes3.iter()) + .cloned() + .collect(); + + let mut notes_merged = notes_unmerged.clone(); + notes_merged.sort_by_key(|n| n.hash()); + notes_merged.dedup(); + + assert_ne!(notes_unmerged, notes_merged); + + let notes1 = rkyv::to_bytes::<_, MAX_LEN>(¬es1).unwrap().into_vec(); + let notes2 = rkyv::to_bytes::<_, MAX_LEN>(¬es2).unwrap().into_vec(); + let notes3 = rkyv::to_bytes::<_, MAX_LEN>(¬es3).unwrap().into_vec(); + let notes4 = vec![]; + let notes = vec![notes1, notes2, notes3, notes4]; + + let mut wallet = Wallet::default(); + + let notes = wallet + .call("merge_notes", json!({ "notes": notes })) + .take_memory(); + + let notes = rkyv::from_bytes::>(¬es).unwrap(); + + assert_eq!(notes, notes_merged); } #[test] -fn serde() { - let mut rng = rand::thread_rng(); +fn filter_notes_works() { + let seed = [0xfa; RNG_SEED]; + + let notes = node::raw_notes(&seed, [10, 250, 15, 39, 55]); + let flags = vec![true, true, false, true, false]; + let filtered = vec![notes[2].clone(), notes[4].clone()]; + let filtered = utils::sanitize_notes(filtered); + + let notes = rkyv::to_bytes::<_, MAX_LEN>(¬es).unwrap().into_vec(); - let wallet = mock_serde_wallet(&mut rng, &[2500, 2500, 5000]); + let mut wallet = Wallet::default(); - let send_psk = wallet.public_spend_key(0).unwrap(); - let recv_psk = wallet.public_spend_key(1).unwrap(); + let notes = wallet + .call("filter_notes", json!({ "flags": flags, "notes": notes })) + .take_memory(); - let ref_id = BlsScalar::random(&mut rng); - wallet - .transfer(&mut rng, 0, &send_psk, &recv_psk, 100, 100, 1, ref_id) - .expect("Transaction creation to be successful"); + let notes = rkyv::from_bytes::>(¬es).unwrap(); + + assert_eq!(notes, filtered); } #[test] -fn canon() { - let mut rng = rand::thread_rng(); +fn public_spend_keys_works() { + let seed = [0xfa; RNG_SEED]; + + let mut wallet = Wallet::default(); - let wallet = mock_canon_wallet(&mut rng, &[2500, 2500, 5000]); + let types::PublicSpendKeysResponse { keys } = wallet + .call( + "public_spend_keys", + json!({ + "seed": seed.to_vec(), + }), + ) + .take_contents(); - let send_psk = wallet.public_spend_key(0).unwrap(); - let recv_psk = wallet.public_spend_key(1).unwrap(); + for key in &keys { + let key = bs58::decode(key).into_vec().unwrap(); + let mut key_array = [0u8; PublicSpendKey::SIZE]; + key_array.copy_from_slice(&key); + PublicSpendKey::from_bytes(&key_array).unwrap(); + } - let ref_id = BlsScalar::random(&mut rng); - wallet - .transfer(&mut rng, 0, &send_psk, &recv_psk, 100, 100, 1, ref_id) - .expect("Transaction creation to be successful"); + assert_eq!(keys.len(), MAX_KEY + 1); } #[test] -fn transfer() { - let mut rng = rand::thread_rng(); +fn view_keys_works() { + let seed = [0xfa; RNG_SEED]; - let wallet = mock_wallet(&mut rng, &[2500, 2500, 5000]); + let mut wallet = Wallet::default(); - let send_psk = wallet.public_spend_key(0).unwrap(); - let recv_psk = wallet.public_spend_key(1).unwrap(); + let vk = wallet + .call( + "view_keys", + json!({ + "seed": seed.to_vec() + }), + ) + .take_memory(); - let ref_id = BlsScalar::random(&mut rng); - wallet - .transfer(&mut rng, 0, &send_psk, &recv_psk, 100, 100, 1, ref_id) - .expect("Transaction creation to be successful"); + rkyv::from_bytes::>(&vk).unwrap(); } #[test] -fn get_balance() { - let mut rng = rand::thread_rng(); +fn nullifiers_works() { + let seed = [0xfa; RNG_SEED]; + + let (notes, nullifiers): (Vec<_>, Vec<_>) = + node::raw_notes_and_nulifiers(&seed, [10, 250, 15, 39, 55]) + .into_iter() + .unzip(); + + let notes = rkyv::to_bytes::<_, MAX_LEN>(¬es).unwrap().into_vec(); + + let mut wallet = Wallet::default(); + + let response = wallet + .call( + "nullifiers", + json!({ + "seed": seed.to_vec(), + "notes": notes + }), + ) + .take_memory(); + + let response = + rkyv::from_bytes::>(&response).unwrap(); + + assert_eq!(nullifiers, response); +} + +/// A node interface. It will encapsulate all the phoenix core functionality. +mod node { + use core::mem; + + use dusk_jubjub::{BlsScalar, JubJubScalar}; + use dusk_wallet_core::{key, tx, utils, MAX_KEY, MAX_LEN, RNG_SEED}; + use phoenix_core::Note; + use rand::RngCore; + + pub fn raw_notes(seed: &[u8; RNG_SEED], values: Values) -> Vec + where + Values: IntoIterator, + { + let rng = &mut utils::rng(seed); + values + .into_iter() + .map(|value| { + let obfuscated = (rng.next_u32() & 1) == 1; + let idx = rng.next_u64() % MAX_KEY as u64; + let psk = key::derive_ssk(seed, idx).public_spend_key(); + + if obfuscated { + let blinder = JubJubScalar::random(rng); + Note::obfuscated(rng, &psk, value, blinder) + } else { + Note::transparent(rng, &psk, value) + } + }) + .collect() + } + + pub fn notes(seed: &[u8; RNG_SEED], values: Values) -> Vec + where + Values: IntoIterator, + { + rkyv::to_bytes::<_, MAX_LEN>(&raw_notes(seed, values)) + .expect("failed to serialize notes") + .into_vec() + } + + pub fn notes_and_openings( + seed: &[u8; RNG_SEED], + values: Values, + ) -> (Vec, Vec) + where + Values: IntoIterator, + { + let values: Vec<_> = values.into_iter().collect(); + let len = values.len(); + let notes = notes(seed, values); + let openings: Vec<_> = (0..len) + .map(|_| unsafe { mem::zeroed::() }) + .collect(); + + let openings = rkyv::to_bytes::<_, MAX_LEN>(&openings) + .expect("failed to serialize openings") + .into_vec(); + + (notes, openings) + } + + pub fn raw_notes_and_nulifiers( + seed: &[u8; RNG_SEED], + values: Values, + ) -> Vec<(Note, BlsScalar)> + where + Values: IntoIterator, + { + let rng = &mut utils::rng(seed); + values + .into_iter() + .map(|value| { + let obfuscated = (rng.next_u32() & 1) == 1; + let idx = rng.next_u64() % MAX_KEY as u64; + let ssk = key::derive_ssk(seed, idx); + let psk = ssk.public_spend_key(); + + let note = if obfuscated { + let blinder = JubJubScalar::random(rng); + Note::obfuscated(rng, &psk, value, blinder) + } else { + Note::transparent(rng, &psk, value) + }; + + let nullifier = note.gen_nullifier(&ssk); + (note, nullifier) + }) + .collect() + } +} + +pub struct Wallet { + pub store: Store, + pub module: Module, + pub instance: Instance, +} + +pub struct CallResult<'a> { + pub status: bool, + pub val: u64, + pub aux: u64, + pub wallet: &'a mut Wallet, +} + +impl<'a> CallResult<'a> { + pub fn new(wallet: &'a mut Wallet, value: i64) -> Self { + let (status, val, aux) = utils::decompose(value); + Self { + status, + val, + aux, + wallet, + } + } + + pub fn take_memory(self) -> Vec { + assert!(self.status); + + let mut bytes = vec![0u8; self.aux as usize]; + + self.wallet + .instance + .exports + .get_memory("memory") + .unwrap() + .view(&self.wallet.store) + .read(self.val, &mut bytes) + .unwrap(); + + self.wallet + .instance + .exports + .get_function("free_mem") + .unwrap() + .call( + &mut self.wallet.store, + &[Value::I32(self.val as i32), Value::I32(self.aux as i32)], + ) + .unwrap(); + + bytes + } + + pub fn take_contents(self) -> T + where + T: for<'b> Deserialize<'b>, + { + assert!(self.status); + let bytes = self.take_memory(); + let json = String::from_utf8(bytes).unwrap(); + serde_json::from_str(&json).unwrap() + } + + pub fn take_val(self) -> u64 { + assert!(self.status); + self.val + } +} + +impl Wallet { + pub fn call(&mut self, f: &str, args: T) -> CallResult + where + T: Serialize, + { + let bytes = serde_json::to_string(&args).unwrap(); + let len = Value::I32(bytes.len() as i32); + let ptr = self + .instance + .exports + .get_function("malloc") + .unwrap() + .call(&mut self.store, &[len.clone()]) + .unwrap()[0] + .unwrap_i32(); + + self.instance + .exports + .get_memory("memory") + .unwrap() + .view(&self.store) + .write(ptr as u64, bytes.as_bytes()) + .unwrap(); + + let ptr = Value::I32(ptr); + let result = self + .instance + .exports + .get_function(f) + .unwrap() + .call(&mut self.store, &[ptr, len]) + .unwrap()[0] + .unwrap_i64(); + + CallResult::new(self, result) + } +} + +impl Default for Wallet { + fn default() -> Self { + const WALLET: &[u8] = include_bytes!("../assets/dusk_wallet_core.wasm"); + + let mut store = Store::default(); + let module = + Module::new(&store, WALLET).expect("failed to create wasm module"); - let wallet = mock_wallet(&mut rng, &[2500, 5000, 2500, 5000, 5000]); - let info = wallet.get_balance(0).expect("Valid balance call"); + let import_object = imports! {}; + let instance = Instance::new(&mut store, &module, &import_object) + .expect("failed to instanciate the wasm module"); - assert_eq!(info.value, 20000); - assert_eq!(info.spendable, 17500); + Self { + store, + module, + instance, + } + } }