Skip to content

Commit

Permalink
feat: refactor core into simplified WASM module (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
artifex11 committed Aug 28, 2023
1 parent 3c02311 commit 3ae60f1
Show file tree
Hide file tree
Showing 20 changed files with 2,027 additions and 2,919 deletions.
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

0 comments on commit 3ae60f1

Please sign in to comment.