Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor core into simplified WASM module #79

Merged
merged 29 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dac4f1c
feat: refactor core into simplified WASM module
artifex11 Aug 23, 2023
61487fc
fix CI
artifex11 Aug 24, 2023
7b7e3e7
add maximum value to balance
artifex11 Aug 24, 2023
8484753
fix CI
artifex11 Aug 24, 2023
060d6ea
add `merge_notes` and `view_keys` methods
artifex11 Aug 24, 2023
f0e236b
add `filter_notes` and `nullifiers` methods
artifex11 Aug 24, 2023
7a5c925
remove failing kcov
artifex11 Aug 24, 2023
6ae98df
add `seed` method
artifex11 Aug 24, 2023
7b117e6
refactor wasm module input into json schema
artifex11 Aug 25, 2023
8753b50
missing header
artifex11 Aug 25, 2023
8a647da
tweak makefile to generate asset package
artifex11 Aug 25, 2023
ce2703b
integrate with wallet-cli tests
artifex11 Aug 26, 2023
0ec45f1
ignore minimal readme example in tests
artifex11 Aug 26, 2023
e7f8dc8
remove unused public spend key wallet method
artifex11 Aug 27, 2023
6f5b25c
fix cargo fmt
artifex11 Aug 27, 2023
b8130ab
upd toolchain on ci
artifex11 Aug 27, 2023
7d81ec5
run build manually on ci to satisfy build script
artifex11 Aug 27, 2023
06bb508
upd build wasm ci
artifex11 Aug 27, 2023
ffc689f
add rustup stdlib for wasm ci
artifex11 Aug 27, 2023
b62addd
fix ci
artifex11 Aug 27, 2023
75524f8
fix ci wasm version
artifex11 Aug 27, 2023
42f384b
add ci fix for schemafy non-deterministic build
artifex11 Aug 27, 2023
3e864e3
change order of schemafy fix
artifex11 Aug 27, 2023
bc627e5
remove build script from ci
artifex11 Aug 27, 2023
232a58a
explicitly build wasm for tests in ci
artifex11 Aug 27, 2023
58e8115
reord ci
artifex11 Aug 27, 2023
9f27a73
run ci build wasm only if going to publish
artifex11 Aug 27, 2023
4617bef
reactivate kcov
artifex11 Aug 27, 2023
aeacba6
run coverage only from main
artifex11 Aug 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 31 additions & 29 deletions .github/workflows/dusk_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
name: Dusk CI

jobs:

analyze:
name: Dusk Analyzer
runs-on: ubuntu-latest
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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 }}
Expand All @@ -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'
Expand All @@ -145,15 +147,15 @@ 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: >
find target/debug/deps -type f -executable ! -name "*.*" |
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}}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ target/
Cargo.lock
**/*.rs.bk

*.wasm
mod.wasm
37 changes: 24 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
30 changes: 30 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
43 changes: 35 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Binary file added assets/dusk-wallet-core-0.21.0.wasm
Binary file not shown.
Binary file added assets/dusk_wallet_core.wasm
Binary file not shown.
Loading
Loading