GithubHelp home page GithubHelp logo

stacks-network / clarity-wasm Goto Github PK

View Code? Open in Web Editor NEW
11.0 11.0 9.0 3.17 MB

`clar2wasm` is a compiler for generating WebAssembly from Clarity.

License: GNU General Public License v3.0

Rust 82.12% WebAssembly 15.11% Clarity 2.77%
clarity stacks wasm webassembly

clarity-wasm's People

Contributors

acaccia avatar ameeratgithub avatar csgui avatar cylewitruk avatar hugocaillard avatar krl avatar obycode avatar zone117x avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clarity-wasm's Issues

[ ๐Ÿ’ป Clarity VM ] Cost tracking

Design how cost-tracking should work in this new system.

  • Should the cost be statically analyzed?
  • Should the cost tracking be inserted into the compiled Wasm?

Our "mul-uint" doesn't work

Working on #54 , I could see that our multiplication function doesn't work for now.

Here is a test to add to the unit tests to replicate the issue:

    mul.call(
        &mut store,
        &[Val::I64(1), 0i64.into(), Val::I64(4294967296), 0i64.into()],
        &mut result,
    )
    .expect("call to mul-uint failed");
    eprintln!("{:?}", result);
    assert_eq!(result[0].unwrap_i64(), 4294967296);
    assert_eq!(result[1].unwrap_i64(), 0);

Expected result should be 4294967296 but is actually 0.

Host interface functions

  • as-contract
  • ft-mint?
  • ft-transfer?
  • get-block-info?
  • map-delete
  • map-get?
  • map-insert
  • map-set
  • nft-get-owner?
  • nft-mint?
  • nft-transfer?
  • print
  • stx-account
  • stx-burn?
  • stx-get-balance
  • stx-transfer?

Investigate and document performance and pros/cons between Wasm runtimes

As Wasmtime and Wasmer are the two prominent runtime libraries for Rust, these are the two which will be focused on.

Performance
A fast initial comparison using add using externrefs, as well as a native add_i128 function which passes and returns two i64's (to achieve rust's i128 through bit manipulation) shows that the two frameworks perform, in general, relatively similar.

Benchmarks reveal that Wasmtime does have a slight performance edge at least in the above two tests, however the difference is for all purposes negligible when using Rust's default memory allocator. One interesting find is that Wasmtime's performance dramatically increased for more complex functions when I (out of random curiosity) swapped the default memory allocator out for mimalloc.

Documentation
Both frameworks provide relatively OK API documentation, however Wasmer's documentation in general is more complete and includes a much larger array of examples and tests.

API
A thing of taste, perhaps, but I do find the Wasmer API to be more natural and clean.

Community
Both frameworks seem to have relatively large communities across a multitude of language ports.

Replace the ASCII art in the README

The README has Hiro ASCII art that I took from a template. It should be replaced with some cool ASCII art representing the Clarity logo.

       /     /   โ–ถ clarity-wasm
      / --- /      Compile Clarity to Wasm.
     /     /       Generate WebAssembly from your Clarity code for fast and portable execution.

image

[ ๐Ÿ’ป Clarity VM ] Regression testing

Compare results from old VM and new VM. Note, that this may go into the Clarity VM work, not clar2wasm, but added here so it is not forgotten.

  • Boot from genesis and validate state
  • New tests

Property tests for standard functions generates mostly big ints

In the property tests in property_tests.rs, the generated i128 for the property tests are mostly big integers, and don't really test that functions still works for smaller ints.

We should split the int128() into several prop_compose, to have more control on the size we want to get.

I would propose at least:

  • small_uint128: i <= u64::MAX
  • big_uint128: i > u64::MAX
  • positive_int128
  • negative_int128

Tests in lib_test don't assert the correct return type

For now, all tests in lib_test.rs have this structure when we check for the result:

if let ClarityWasmResult::Int { high, low } = *ok_value.unwrap() {
	assert_eq!(high, 0);
    assert_eq!(low, 2);
}

This means that if the returned value was anything else (e.g. a UInt), nothing would fail.

RUSTSEC-2022-0093: Double Public Key Signing Function Oracle Attack on `ed25519-dalek`

Double Public Key Signing Function Oracle Attack on ed25519-dalek

Details
Package ed25519-dalek
Version 1.0.0-pre.3
URL https://github.com/MystenLabs/ed25519-unsafe-libs
Date 2022-06-11
Patched versions >=2

Versions of ed25519-dalek prior to v2.0 model private and public keys as
separate types which can be assembled into a Keypair, and also provide APIs
for serializing and deserializing 64-byte private/public keypairs.

Such APIs and serializations are inherently unsafe as the public key is one of
the inputs used in the deterministic computation of the S part of the signature,
but not in the R value. An adversary could somehow use the signing function as
an oracle that allows arbitrary public keys as input can obtain two signatures
for the same message sharing the same R and only differ on the S part.

Unfortunately, when this happens, one can easily extract the private key.

Revised public APIs in v2.0 of ed25519-dalek do NOT allow a decoupled
private/public keypair as signing input, except as part of specially labeled
"hazmat" APIs which are clearly labeled as being dangerous if misused.

See advisory page for additional details.

RUSTSEC-2020-0168: mach is unmaintained

mach is unmaintained

Details
Status unmaintained
Package mach
Version 0.3.2
URL fitzgen/mach#63
Date 2020-07-14

Last release was almost 4 years ago.

Maintainer(s) seem to be completely unreachable.

Possible Alternative(s)

These may or may not be suitable alternatives and have not been vetted in any way;

See advisory page for additional details.

[ ๐Ÿ’ป Clarity VM ] Eval hooks

In the existing Clarity VM, EvalHooks provide a way to hook into the execution. These are used to implement debugging, tracing, and code coverage in Clarinet. We'll need to provide a way to do all of these in the new VM.

RUSTSEC-2020-0071: Potential segfault in the time crate

Potential segfault in the time crate

Details
Package time
Version 0.1.45
URL time-rs/time#293
Date 2020-11-18
Patched versions >=0.2.23
Unaffected versions =0.2.0,=0.2.1,=0.2.2,=0.2.3,=0.2.4,=0.2.5,=0.2.6

Impact

Unix-like operating systems may segfault due to dereferencing a dangling pointer in specific circumstances. This requires an environment variable to be set in a different thread than the affected functions. This may occur without the user's knowledge, notably in a third-party library.

The affected functions from time 0.2.7 through 0.2.22 are:

  • time::UtcOffset::local_offset_at
  • time::UtcOffset::try_local_offset_at
  • time::UtcOffset::current_local_offset
  • time::UtcOffset::try_current_local_offset
  • time::OffsetDateTime::now_local
  • time::OffsetDateTime::try_now_local

The affected functions in time 0.1 (all versions) are:

  • at
  • at_utc
  • now

Non-Unix targets (including Windows and wasm) are unaffected.

Patches

Pending a proper fix, the internal method that determines the local offset has been modified to always return None on the affected operating systems. This has the effect of returning an Err on the try_* methods and UTC on the non-try_* methods.

Users and library authors with time in their dependency tree should perform cargo update, which will pull in the updated, unaffected code.

Users of time 0.1 do not have a patch and should upgrade to an unaffected version: time 0.2.23 or greater or the 0.3 series.

Workarounds

A possible workaround for crates affected through the transitive dependency in chrono, is to avoid using the default oldtime feature dependency of the chrono crate by disabling its default-features and manually specifying the required features instead.

Examples:

Cargo.toml:

chrono = { version = &quot;0.4&quot;, default-features = false, features = [&quot;serde&quot;] }
chrono = { version = &quot;0.4.22&quot;, default-features = false, features = [&quot;clock&quot;] }

Commandline:

cargo add chrono --no-default-features -F clock

Sources:

See advisory page for additional details.

Investigate Wasm options

There are various options that can be set in Wasmtime's Engine. See Config. We should review these and decide which we want to enable for the Clarity runtime, considering speed and safety.

Improve trait granularity of the visitors/compiler implementation

At the moment, the visitor trait is very large, over 3000 lines of mostly duplicated code.

Providing a proof of concept of a different approach, that uses more fine-grained traits to de-duplicate the code needed to compile Clarity to Wasm.

Additionally, adding type information to this layer, in the style of forth (which values are consumed from the stack, and which are put back on)

In a POC, there are two traits something like this

pub trait Procedure: Sync + Emit {
    fn input(&self) -> &'static [ValType];
    fn output(&self) -> &'static [ValType];
}

pub trait Emit {
    fn emit(&self, builder: &mut InstrSeqBuilder);
}

RUSTSEC-2022-0090: `libsqlite3-sys` via C SQLite CVE-2022-35737

libsqlite3-sys via C SQLite CVE-2022-35737

Details
Package libsqlite3-sys
Version 0.20.1
URL https://nvd.nist.gov/vuln/detail/CVE-2022-35737
Date 2022-08-03
Patched versions >=0.25.1

It was sometimes possible for SQLite versions >= 1.0.12, < 3.39.2 to allow an array-bounds overflow when large string were input into SQLite's printf function.

As libsqlite3-sys bundles SQLite, it is susceptible to the vulnerability. libsqlite3-sys was updated to bundle the patched version of SQLite here.

See advisory page for additional details.

[ ๐Ÿ’ป Clarity VM ] Drop unused values

Since Wasm is stack-based, when we have unused values, they need to be dropped if the Clarity value is not used. For example, in the var-set test, the true that is returned from var-set goes unused:

(define-data-var something int 123)

(define-public (simple)
    (begin
        (var-set something 5368002525449479521366)
        (ok (var-get something))
    )
)

To manage this, we'd need to keep track of how many values have been pushed to the stack, and then when processing a list of expressions, the result value(s) from all but the last expression in the list should be dropped.

Implement keywords

We also need to support the built-in keywords. The following subset is required for the boot contracts:

  • block-height
  • burn-block-height
  • contract-caller
  • false
  • none
  • stx-liquid-supply
  • true
  • tx-sender

[ ๐Ÿ’ป Clarity VM ] Support boot contracts

To support the boot contracts (see Clarity contracts in here), we need support for the following Clarity functions:

  • *
  • +
  • -
  • /
  • <
  • <=
  • >
  • >=
  • and
  • append
  • as-contract
  • as-max-len?
  • asserts!
  • begin
  • buff-to-uint-be
  • concat
  • default-to
  • define-constant
  • define-data-var
  • define-fungible-token
  • define-map
  • define-non-fungible-token
  • define-private
  • define-public
  • define-read-only
  • element-at
  • err
  • filter
  • fold
  • ft-mint?
  • ft-transfer?
  • get
  • get-block-info?
  • hash160
  • if
  • is-eq
  • is-none
  • is-some
  • len
  • let
  • list
  • log2
  • map-delete
  • map-get?
  • map-insert
  • map-set
  • match
  • merge
  • nft-get-owner?
  • nft-mint?
  • nft-transfer?
  • not
  • ok
  • or
  • pow
  • print
  • replace-at?
  • slice?
  • some
  • stx-account
  • stx-burn?
  • stx-get-balance
  • stx-transfer?
  • try!
  • tuple
  • unwrap!
  • unwrap-panic
  • var-get
  • var-set
  • xor

Reorder Int and Uint bytes passed to webassembly

For now, we pass our 128 bits-sized integers to webassembly as (high, low), respectively the most and the least significant bits.
This is the opposite of the order which would be natural for webassembly, which uses a little-endian representation. We should pass them as (low, high).

With the current representation, if we need to store those integers in the memory, the bytes would be stored as 89abcde,1234567.

This is not a big issue per se, but we should deal with it as soon as possible, while standard.wat isn't too big yet.

Define functions

  • define-constant
  • define-fungible-token
  • define-map
  • define-non-fungible-token

[ ๐Ÿ’ป Clarity VM ] General fuzz testing

The clar2wasm library needs to handle any random Clarity coming in from users (although it has passed through the parser and analysis passes before reaching here). It should be hardened to handle whatever comes in, handling errors gracefully.

Optional/Response functions

Implementation of Optional and Response types functions.

Functions to be implemented

Explore the feasibility of implementing an external memory allocator for Wasm memory

From discord:

I'm exploring a little now the feasibility of implementing an external memory allocator for wasm memory, partially thinking of @obycode 's concerns regarding return values of arbitrary length, while also trying to optimize how we use wasm memory instead of doing append-only. Something similar to malloc, only that it wouldn't actually allocate memory, just give you a valid offset that can hold the desired number of bytes. And then a host-function can be provided to the wasm-native stuff as well to retrieve an offset for desired length.

Decide on Wasm runtime

A placeholder issue for now, where we can document why a specific runtime was chosen (for the community).

[ ๐Ÿ’ป Clarity VM ] Epoch-gating across calls

The new VM should only be used for executing Clarity 3 epoch 3.0 contracts. When calling into Clarity 1 or 2 contracts deployed in previous epochs, the old interpreter should be used. The cross-contract calling needs to handle this.

Should we use the audit workflow in CI?

Potential unaligned read

Details
Status unsound
Package atty
Version 0.2.14
URL softprops/atty#50
Date 2021-07-04

On windows, atty dereferences a potentially unaligned pointer.

In practice however, the pointer won't be unaligned unless a custom global allocator is used.

In particular, the System allocator on windows uses HeapAlloc, which guarantees a large enough alignment.

atty is Unmaintained

A Pull Request with a fix has been provided over a year ago but the maintainer seems to be unreachable.

Last release of atty was almost 3 years ago.

Possible Alternative(s)

The below list has not been vetted in any way and may or may not contain alternatives;

See advisory page for additional details.

[ ๐Ÿ’ป Clarity VM ] Optimize stack pointer management

Currently, we are incrementing the stack pointer (a Wasm global) each time a new value needs to be pushed to the execution stack (the current function's stack frame in the linear memory). Instead, we should do a compilation pass that computes the total stack size needed for a function, and increments the stack pointer once, during the function prologue, and save the offsets for each local to use during the compilation pass.

Explore `externref` & `funcref` in both Walrus and runtime libraries

This issue is about exploring the passing of opaque host references through the Wasm runtime and back to host-functions for use.

It has been found that the use of ExternalRefs and all of the marshaling involved results in a relatively large performance hit. It should be noted, however, that this construct does allow a very seamless way of passing complex object references along in the Wasm function chain.

The use of FunctionRefs and the calling of host-functions from Wasm using Wasm-native types, however, reaches near-pure-Wasm-performance. When benchmarked using an add i128 function, accepting four i64's (a_low, a_high, b_low, b_high) and returning two i64s (c_low, c_high), the performance difference is in the order of 5-10 nanoseconds (higher for host-function call via funcref).

Wasm Tables have been extended now to allow the storage of externrefs in addition to funcrefs. One possible next task is comparing if accessing the values via tables affects performance of externrefs or not.

Buffer functions

  • buff-to-uint-be

Although not needed for boot contracts, this task may as well include these too:

  • buff-to-uint-le
  • buff-to-int-be
  • buff-to-int-le

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.