stacks-network / clarity-wasm Goto Github PK
View Code? Open in Web Editor NEW`clar2wasm` is a compiler for generating WebAssembly from Clarity.
License: GNU General Public License v3.0
`clar2wasm` is a compiler for generating WebAssembly from Clarity.
License: GNU General Public License v3.0
and
asserts!
filter
if
match
or
try!
unwrap!
unwrap-panic
Design how cost-tracking should work in this new system.
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.
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?
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 externref
s, 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.
append
as-max-len?
concat
element-at
len
replace-at?
slice?
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.
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:
Setup the CI jobs to run our tests, then enable the appropriate checks on PRs.
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.
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.
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.
These may or may not be suitable alternatives and have not been vetted in any way;
See advisory page for additional details.
What does the interface look like when one contract calls another? Think about efficiency. This might require importing host functionality like #2, or we may be able to load all of the dependencies and link them together. Clarinet could be a good place to prototype this.
is-eq
not
xor
In the existing Clarity VM, EvalHook
s 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.
We should add unit tests as we build out the library, but it would also make sense to do some fuzz and/or property testing.
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 |
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.
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.
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.
Cargo.toml
:
chrono = { version = "0.4", default-features = false, features = ["serde"] }
chrono = { version = "0.4.22", default-features = false, features = ["clock"] }
Commandline:
cargo add chrono --no-default-features -F clock
Sources:
See advisory page for additional details.
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.
We need to add cost tracking into the generated Wasm, similar to the way it is done in the existing interpreter.
stdweb is unmaintained
Details | |
---|---|
Status | unmaintained |
Package | stdweb |
Version | 0.4.20 |
URL | koute/stdweb#403 |
Date | 2020-05-04 |
The author of the stdweb
crate is unresponsive.
Maintained alternatives:
See advisory page for additional details.
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);
}
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.
Get an initial proof-of-concept in place to execute the compiled wasm in Clarinet's simulation environment.
Once everything is functional, measure performance, compare with previous implementation, and analyze for areas to further improve speed.
Since Wasm is stack-based, when we have unused values, they need to be drop
ped 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.
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
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
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-constant
define-fungible-token
define-map
define-non-fungible-token
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.
Implementation of Optional
and Response
types functions.
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.
Define and implement the stack management for placing sequence values on stack.
A placeholder issue for now, where we can document why a specific runtime was chosen (for the community).
Add support in clar2wasm for the bitwise functions:
See Clarity docs for details.
Setup tests for the generated Wasm.
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.
hash160
pow
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.
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.
The below list has not been vetted in any way and may or may not contain alternatives;
See advisory page for additional details.
TBD
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.
get
merge
tuple
This includes defining an AST visitor in WasmGenerator
and potentially any supporting functions in the standard library.
This task can be broken down further if multiple developers will work on it in parallel.
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 ExternalRef
s 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 FunctionRef
s 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 i64
s (c_low
, c_high
), the performance difference is in the order of 5-10 nanoseconds (higher for host-function call via funcref
).
Wasm Table
s have been extended now to allow the storage of externref
s in addition to funcref
s. One possible next task is comparing if accessing the values via tables affects performance of externref
s or not.
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
These functions require interfacing with the VM. They likely should be implemented by importing host functionality to call into functions defined in the VM. For flexibility, this functionality should be defined as a trait, so that it can be implemented in memory for simple testing outside of the stacks node.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.