hexresearch / hschain

Other
4 stars 0 forks source link

BLS for GHCjs and WASM #542

Closed dmalkr closed 4 years ago

dmalkr commented 4 years ago

Overview

Here are Haskell bindings for GHCJS for using bls-signatures.

To use this bindings, we need to compile bls-signatures for JavaScript environment. As a result, we get two files: blsjs.wasm -- WASM module of bls-signatures, and bundle.js -- JavaScript bindings for bls-signatures and all its dependencies. It is need to load both of this files before use bls-signatures in GHCjs-compiled haskell modules.

Current structure of bls-signatures support

Using WASM/JS-modules

At first, we need to load bundle.js (see building instuctions below). For example, we can load it in <head> section of index.html file:

<!DOCTYPE html>
<html>
  <head>
    <script language="javascript" src="bundle.js"></script>
    <!-- other scripts -->
    <script language="javascript" src="rts.js"></script>
  </head>
  <body>
      Your c001 site here
  </body>
  <!-- And THAN we load main Haskell file -->
  <script language="javascript" src="runmain.js" defer></script>
</html>

Then in Haskell files we need to call initBls function before using bls-signatures. This call load up blsjs.wasm and setup bls-signatures environment.

See example of main unittest file:

import Test.Tasty
import qualified TM.BLS
import Crypto.Bls -- It is need to import just `Crypto.Bls`

main :: IO ()
main = do
    initBls -- Then it is need to call `initBls` BEFORE we do something with `bls-signatures`
    defaultMain $ testGroup "BLS test suite" [ TM.BLS.tests ]

Building instructions

Building WASM image for bls-signatures

At first, it is need to build WASM image for bls-signatures. But only once! After image is ready it is not necessary to constanly rebuild them.

We need fresh bls-signatures copy of repo. So let's clone and cd to it and update submodules:

local:~ $ git clone https://github.com/Chia-Network/bls-signatures
local:~ $ cd bls-signatures
local:~ $ git submodule update --init --recursive

Next we need installed Emscripted C++ (https://emscripten.org/) to build from C++ to WASM. I prefer to use Docker image wasm/toolchain which contains everything we need to build. So we download image and enter into it:

local:~ $ docker pull wasm/toolchain
local:~ $ # Note that we in `bls-signatures` directory
local:~ $ docker run -it --rm --mount type=bind,src=$PWD,target=/project --workdir /project wasm/toolchain:latest /bin/bash --login

That docker image contain Emscripted C++ but outdated Node JS (which also need to build). So let's install fresh NodeJS in Docker session:

DOCKER:/project  # curl -sL https://deb.nodesource.com/setup_10.x | bash -
DOCKER:/project  # apt install nodejs
DOCKER:/project  # npm --version
6.13.14

bls-signatures repo contains file ./js_build.sh for simply build. But it contains error, so let's repeat correct commands by yourself:

DOCKER:/project # export PATH=/emsdk/emscripten/incoming:$PATH
DOCKER:/project # mkdir js_build
DOCKER:/project # cd js_build
DOCKER:/project/js_build # cmake ../ -DCMAKE_TOOLCHAIN_FILE=/emsdk/emscripten/incoming/cmake/Modules/Platform/Emscripten.cmake 
DOCKER:/project/js_build # cmake --build . --target blsjs

Now main part of BLS-Signatures is compiled: ./js_build/js-bindings/blsjs.wasm and ./js_build/js-bindings/blsjs.wasm. Now we need to pack all dependencies into one NodeJS package:

DOCKER:/project/js_build # cd js-bindings
DOCKER:/project/js_build/js-bindings # npm install browserify
DOCKER:/project/js_build/js-bindings # node_modules/.bin/browserify -r ./blsjs.js:blsjs -o bundle.js

Result

Now we have two files:

Shimuuar commented 4 years ago

Nix build is partially complete. So far problem is closurecompiler fails with:

/tmp/tmpAkGIfe.cl.js:7461: ERROR - This language feature is only supported for ECMASCRIPT6 mode or better: block-scoped function declaration.
    function doBrowserLoad() {
    ^

/tmp/tmpAkGIfe.cl.js:7468: ERROR - This language feature is only supported for ECMASCRIPT6 mode or better: block-scoped function declaration.
      function useRequest() {

Relevant issues:

Shimuuar commented 4 years ago

To be more exact. 1.37.36 (from snapshot used by hschain atm) gives error above, while 1.38.28 gives different and completely inscrutable error