From 220c4f91dddaa9c023d503d6bead5537c2c4d1b6 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Sat, 14 Dec 2019 02:22:57 +0200 Subject: [PATCH 01/10] Add basic substrate interface. --- nimplay/substrate_runtime.nim | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 nimplay/substrate_runtime.nim diff --git a/nimplay/substrate_runtime.nim b/nimplay/substrate_runtime.nim new file mode 100644 index 0000000..fb17b42 --- /dev/null +++ b/nimplay/substrate_runtime.nim @@ -0,0 +1,24 @@ +import utils + +{.push cdecl, importc.} + +proc ext_block_number*() +proc ext_get_storage*(key_ptr: pointer): int32 +proc ext_println*(str_ptr: pointer, str_len: int32) +proc ext_scratch_read*(dest_ptr: pointer, offset: int32, len: int32) +proc ext_scratch_size*(): int32 +proc ext_scratch_write(src_ptr: pointer, len: int32) +proc ext_set_rent_allowance*(value_ptr: pointer, value_len: int32) +proc ext_set_storage*(key_ptr: pointer, value_non_null: int32, value_ptr: int32, value_len: int32) + +{.pop.} + +macro exportwasm*(p: untyped): untyped = + expectKind(p, nnkProcDef) + result = p + result.addPragma(newIdentNode("exportc")) + result.addPragma( + newColonExpr( + newIdentNode("codegenDecl"), newLit("__attribute__ ((visibility (\"default\"))) $# $#$#") + ) + ) From df1cd5a336abb6a204669e421a267fcf2eec9062 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Thu, 19 Dec 2019 13:31:20 +0200 Subject: [PATCH 02/10] Ignore *.wasm files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b95ad4b..f4c784d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ tools/wabt/* tools/abi_gen examples/*.wasm .priv_key_hex +*.wasm From 5de34f913cf792fd2872beaf27dc089d05ea79a9 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Thu, 19 Dec 2019 13:36:25 +0200 Subject: [PATCH 03/10] Add EE tests as well; update to echo_block example. --- .gitignore | 1 + Makefile | 2 +- examples/ee/bazaar.nim | 17 --------------- examples/ee/block_echo.nim | 24 +++++++++++++++++++++ tests/ee/test.sh | 41 ++++++++++++++++++++++++++++++++++++ tests/ee/test_block_echo.yml | 13 ++++++++++++ 6 files changed, 80 insertions(+), 18 deletions(-) delete mode 100644 examples/ee/bazaar.nim create mode 100644 examples/ee/block_echo.nim create mode 100755 tests/ee/test.sh create mode 100644 tests/ee/test_block_echo.yml diff --git a/.gitignore b/.gitignore index f4c784d..c2e9577 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ tools/abi_gen examples/*.wasm .priv_key_hex *.wasm +tests/ee/ewasm-scout/ diff --git a/Makefile b/Makefile index ffc7124..b58d06a 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ examples: king_of_the_hill .PHONY: ee-examples ee-examples: $(WASM32_NIMC) --out:examples/ee/helloworld.wasm examples/ee/helloworld.nim - $(WASM32_NIMC) --out:examples/ee/bazaar.wasm examples/ee/bazaar.nim + $(WASM32_NIMC) --out:examples/ee/block_echo.wasm examples/ee/block_echo.nim .PHONY: test-ee diff --git a/examples/ee/bazaar.nim b/examples/ee/bazaar.nim deleted file mode 100644 index 2695dfe..0000000 --- a/examples/ee/bazaar.nim +++ /dev/null @@ -1,17 +0,0 @@ -import system/alloc - -import ../../nimplay/ee_runtime - - -proc main() {.exportwasm.} = - var - pre_state_root {.noinit.}: array[32, byte] - post_state_root {.noinit.}: array[32, byte] - - eth2_loadPreStateRoot(addr pre_state_root) - var - block_data_size = eth2_blockDataSize() - block_data = alloc(block_data_size) - - eth2_blockDataCopy(addr block_data, 0, block_data_size) - eth2_savePostStateRoot(addr post_state_root) diff --git a/examples/ee/block_echo.nim b/examples/ee/block_echo.nim new file mode 100644 index 0000000..18820fe --- /dev/null +++ b/examples/ee/block_echo.nim @@ -0,0 +1,24 @@ +import ../../nimplay/ee_runtime + +{.compile: "malloc.c".} +proc malloc(n: int): pointer {.importc.} + + +proc copy_into_ba(to_ba: var auto, offset: int, from_ba: auto) = + for i, x in from_ba: + if offset + i > sizeof(to_ba) - 1: + break + to_ba[offset + i] = x + + +proc main() {.exportwasm.} = + var + pre_state_root {.noinit.}: array[32, byte] + post_state_root {.noinit.}: array[32, byte] + eth2_loadPreStateRoot(addr pre_state_root) + var + block_data_size = eth2_blockDataSize() + block_data = malloc(block_data_size.int) + eth2_blockDataCopy(block_data, 0, block_data_size) + copyMem(addr post_state_root, block_data, 32) + eth2_savePostStateRoot(addr post_state_root[0]) diff --git a/tests/ee/test.sh b/tests/ee/test.sh new file mode 100755 index 0000000..d1a224d --- /dev/null +++ b/tests/ee/test.sh @@ -0,0 +1,41 @@ +#!/bin/bash +CARGO_HOME="${CARGO_HOME:-$HOME/.cargo}" +RUST_VERSION="nightly" +REPO_DIR="ewasm-scout" +REPO_URL="https://github.com/ewasm/scout.git" +SCOUT_TEST_FILES=./*.yml + + +if [[ -e $REPO_DIR ]]; then + rm -v $REPO_DIR/*.yml + cp $SCOUT_TEST_FILES $REPO_DIR/ + cd $REPO_DIR + git pull +else + git clone $REPO_URL $REPO_DIR + rm -v $REPO_DIR/*.yml + cp $SCOUT_TEST_FILES $REPO_DIR/ + cd $REPO_DIR +fi + + +if [[ ! -e $CARGO_HOME ]]; then + echo "Fetching rustup" + curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain $RUST_VERSION +fi + +rustup target add wasm32-unknown-unknown +rustup component add rustfmt +rustup update +cargo install chisel +# make build +cargo build --release +# make test +# target/release/phase2-scout $SCOUT_TEST_FILE + +for testfile in $SCOUT_TEST_FILES +do + echo $testfile + RUST_LOG=debug target/release/phase2-scout $testfile || exit + break +done diff --git a/tests/ee/test_block_echo.yml b/tests/ee/test_block_echo.yml new file mode 100644 index 0000000..9658939 --- /dev/null +++ b/tests/ee/test_block_echo.yml @@ -0,0 +1,13 @@ + +beacon_state: + execution_scripts: + - ../../../examples/ee/block_echo.wasm +shard_pre_state: + exec_env_states: + - "0000000000000000000000000000000000000000000000000000000000000000" +shard_blocks: + - env: 0 + data: "fafbfcfdfef0f0f0f0f0ffffffffffffffffffffffffffffffffe6e5e4e3e2e1" +shard_post_state: + exec_env_states: + - "fafbfcfdfef0f0f0f0f0ffffffffffffffffffffffffffffffffe6e5e4e3e2e1" From 0a3990465cb9bedd72f9ee05ca63182661c73940 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Sat, 21 Dec 2019 00:37:40 +0200 Subject: [PATCH 04/10] Add basic test layout. --- Makefile | 10 +- nimplay/substrate_runtime.nim | 12 +- tests/substrate/test.sh | 22 ++++ tests/substrate/tests/consts.ts | 9 ++ .../substrate/tests/contract-nimplay.spec.ts | 98 ++++++++++++++++ tests/substrate/tests/utils.ts | 109 ++++++++++++++++++ tests/substrate/tsconfig.js | 24 ++++ tests/substrate/utils.ts | 9 ++ 8 files changed, 289 insertions(+), 4 deletions(-) create mode 100755 tests/substrate/test.sh create mode 100644 tests/substrate/tests/consts.ts create mode 100644 tests/substrate/tests/contract-nimplay.spec.ts create mode 100644 tests/substrate/tests/utils.ts create mode 100644 tests/substrate/tsconfig.js create mode 100644 tests/substrate/utils.ts diff --git a/Makefile b/Makefile index b58d06a..7b73ccd 100644 --- a/Makefile +++ b/Makefile @@ -81,8 +81,16 @@ ee-examples: $(WASM32_NIMC) --out:examples/ee/helloworld.wasm examples/ee/helloworld.nim $(WASM32_NIMC) --out:examples/ee/block_echo.wasm examples/ee/block_echo.nim - .PHONY: test-ee test-ee: ee-examples cd tests/ee/; \ ./test.sh + +.PHONY: substrate-examples +substrate-examples: + $(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim + +.PHONY: test-substrate +test-substrate: substrate-examples + cd tests/substrate; \ + SUBSTRATE_PATH="${HOME}/.cargo/bin/substrate" ./test.sh diff --git a/nimplay/substrate_runtime.nim b/nimplay/substrate_runtime.nim index fb17b42..72309b3 100644 --- a/nimplay/substrate_runtime.nim +++ b/nimplay/substrate_runtime.nim @@ -1,15 +1,21 @@ -import utils +import macros {.push cdecl, importc.} +proc ext_address*() proc ext_block_number*() +proc ext_gas_left*() +proc ext_gas_price*() proc ext_get_storage*(key_ptr: pointer): int32 -proc ext_println*(str_ptr: pointer, str_len: int32) +proc ext_now*() +proc ext_println*(str_ptr: pointer, str_len: int32) # experimental; will be removed. +proc ext_random_seed*() proc ext_scratch_read*(dest_ptr: pointer, offset: int32, len: int32) proc ext_scratch_size*(): int32 -proc ext_scratch_write(src_ptr: pointer, len: int32) +proc ext_scratch_write*(src_ptr: pointer, len: int32) proc ext_set_rent_allowance*(value_ptr: pointer, value_len: int32) proc ext_set_storage*(key_ptr: pointer, value_non_null: int32, value_ptr: int32, value_len: int32) +proc ext_value_transferred*() {.pop.} diff --git a/tests/substrate/test.sh b/tests/substrate/test.sh new file mode 100755 index 0000000..dee896c --- /dev/null +++ b/tests/substrate/test.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +if [ -z "$SUBSTRATE_PATH" ]; then + echo "Please specify the path to substrate in the SUBSTRATE_PATH environment variable" + exit 1 +fi + +if [ ! -f "$SUBSTRATE_PATH" ]; then + echo "$SUBSTRATE_PATH doesn't exist" + exit 2 +fi + +# Purge dev chain and then spin up the substrate node in background +$SUBSTRATE_PATH purge-chain --dev -y +$SUBSTRATE_PATH --dev & +SUBSTRATE_PID=$! + +# # Execute tests +yarn && yarn test --verbose + +# # Kill the spawned substrate node +kill -9 $SUBSTRATE_PID diff --git a/tests/substrate/tests/consts.ts b/tests/substrate/tests/consts.ts new file mode 100644 index 0000000..6a6ef86 --- /dev/null +++ b/tests/substrate/tests/consts.ts @@ -0,0 +1,9 @@ +import BN from "bn.js"; + +export const WSURL = "ws://127.0.0.1:9944"; +export const DOT: BN = new BN("1000000000000000"); +export const CREATION_FEE: BN = DOT.muln(200); +export const GAS_REQUIRED = 50000; +export const ALICE = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"; +export const BOB = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"; + diff --git a/tests/substrate/tests/contract-nimplay.spec.ts b/tests/substrate/tests/contract-nimplay.spec.ts new file mode 100644 index 0000000..727028d --- /dev/null +++ b/tests/substrate/tests/contract-nimplay.spec.ts @@ -0,0 +1,98 @@ +// Adapted from https://github.com/paritytech/srml-contracts-waterfall/ + +import { ApiPromise, SubmittableResult, WsProvider } from "@polkadot/api"; +import { Abi } from '@polkadot/api-contract'; +import testKeyring from "@polkadot/keyring/testing"; +import { u8aToHex } from "@polkadot/util"; +import { randomAsU8a } from "@polkadot/util-crypto"; +import { KeyringPair } from "@polkadot/keyring/types"; +import { Option } from "@polkadot/types"; +import { Address, ContractInfo, Hash } from "@polkadot/types/interfaces"; + +import { ALICE, CREATION_FEE, WSURL } from "./consts"; +import { + callContract, + instantiate, + getContractStorage, + putCode +} from "./utils"; + +// This is a test account that is going to be created and funded each test. +const keyring = testKeyring({ type: "sr25519" }); +const alicePair = keyring.getPair(ALICE); +let testAccount: KeyringPair; +let api: ApiPromise; + +beforeAll((): void => { + jest.setTimeout(30000); +}); + +beforeEach( + async (done): Promise<() => void> => { + api = await ApiPromise.create({ provider: new WsProvider(WSURL) }); + testAccount = keyring.addFromSeed(randomAsU8a(32)); + + return api.tx.balances + .transfer(testAccount.address, CREATION_FEE.muln(3)) + .signAndSend(alicePair, (result: SubmittableResult): void => { + if ( + result.status.isFinalized && + result.findRecord("system", "ExtrinsicSuccess") + ) { + console.log("New test account has been created."); + done(); + } + }); + } +); + + + +describe("Nimplay Hello World", () => { + test("Raw Flipper contract", async (done): Promise => { + // See https://github.com/paritytech/srml-contracts-waterfall/issues/6 for info about + // how to get the STORAGE_KEY of an instantiated contract + + const STORAGE_KEY = (new Uint8Array(32)).fill(2); + // Deploy contract code on chain and retrieve the code hash + const codeHash = await putCode( + api, + testAccount, + "../../../examples/substrate/hello_world.wasm" + ); + expect(codeHash).toBeDefined(); + + // Instantiate a new contract instance and retrieve the contracts address + // Call contract with Action: 0x00 = Action::Flip() + const address: Address = await instantiate( + api, + testAccount, + codeHash, + "0x00", + CREATION_FEE + ); + expect(address).toBeDefined(); + + const initialValue: Uint8Array = await getContractStorage( + api, + address, + STORAGE_KEY + ); + expect(initialValue).toBeDefined(); + expect(initialValue.toString()).toEqual("0x00"); + + await callContract(api, testAccount, address, "0x00"); + + const newValue = await getContractStorage(api, address, STORAGE_KEY); + expect(newValue.toString()).toEqual("0x01"); + + await callContract(api, testAccount, address, "0x00"); + + const flipBack = await getContractStorage(api, address, STORAGE_KEY); + expect(flipBack.toString()).toEqual("0x00"); + + done(); + }); + + +}); diff --git a/tests/substrate/tests/utils.ts b/tests/substrate/tests/utils.ts new file mode 100644 index 0000000..0119fd6 --- /dev/null +++ b/tests/substrate/tests/utils.ts @@ -0,0 +1,109 @@ +import { ApiPromise, SubmittableResult } from "@polkadot/api"; +import { KeyringPair } from "@polkadot/keyring/types"; +import { Option, StorageData } from "@polkadot/types"; +import { Address, ContractInfo, Hash } from "@polkadot/types/interfaces"; +import BN from "bn.js"; +import fs from "fs"; +import path from "path"; +const blake = require('blakejs') + +import { GAS_REQUIRED } from "./consts"; + +export async function sendAndReturnFinalized(signer: KeyringPair, tx: any) { + return new Promise(function(resolve, reject) { + tx.signAndSend(signer, (result: SubmittableResult) => { + if (result.status.isFinalized) { + // Return result of the submittable extrinsic after the transfer is finalized + resolve(result as SubmittableResult); + } + if ( + result.status.isDropped || + result.status.isInvalid || + result.status.isUsurped + ) { + reject(result as SubmittableResult); + console.error("ERROR: Transaction could not be finalized."); + } + }); + }); +} + +export async function putCode( + api: ApiPromise, + signer: KeyringPair, + fileName: string, + gasRequired: number = GAS_REQUIRED +): Promise { + const wasmCode = fs + .readFileSync(path.join(__dirname, fileName)) + .toString("hex"); + const tx = api.tx.contracts.putCode(gasRequired, `0x${wasmCode}`); + const result: any = await sendAndReturnFinalized(signer, tx); + console.log('result', result) + const record = result.findRecord("contracts", "CodeStored"); + + if (!record) { + console.error("ERROR: No code stored after executing putCode()"); + } + // Return code hash. + console.log(record); + return record.event.data[0]; +} + +export async function instantiate( + api: ApiPromise, + signer: KeyringPair, + codeHash: Hash, + inputData: any, + endowment: BN, + gasRequired: number = GAS_REQUIRED +): Promise
{ + const tx = api.tx.contracts.instantiate( + endowment, + gasRequired, + codeHash, + inputData + ); + const result: any = await sendAndReturnFinalized(signer, tx); + const record = result.findRecord("contracts", "Instantiated"); + + if (!record) { + console.error("ERROR: No new instantiated contract"); + } + // Return the address of instantiated contract. + return record.event.data[1]; +} + +export async function callContract( + api: ApiPromise, + signer: KeyringPair, + contractAddress: Address, + inputData: any, + gasRequired: number = GAS_REQUIRED, + endowment: number = 0 +): Promise { + const tx = api.tx.contracts.call( + contractAddress, + endowment, + gasRequired, + inputData + ); + await sendAndReturnFinalized(signer, tx); +} + +export async function getContractStorage( + api: ApiPromise, + contractAddress: Address, + storageKey: Uint8Array +): Promise { + const contractInfo = await api.query.contracts.contractInfoOf( + contractAddress + ); + // Return the value of the contracts storage + const storageKeyBlake2b = blake.blake2bHex(storageKey, null, 32); + return await api.rpc.state.getChildStorage( + (contractInfo as Option).unwrap().asAlive.trieId, + '0x' + storageKeyBlake2b + ); +} + diff --git a/tests/substrate/tsconfig.js b/tests/substrate/tsconfig.js new file mode 100644 index 0000000..14b7763 --- /dev/null +++ b/tests/substrate/tsconfig.js @@ -0,0 +1,24 @@ +{ + + "compilerOptions": { + "target": "esnext", + "module": "commonjs", + "lib": ["dom", "es2018"], + "resolveJsonModule": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "allowJs": true, + "esModuleInterop": true + }, + "exclude": [ + "contracts/rust", + "lib", + "node_modules", + ] +} diff --git a/tests/substrate/utils.ts b/tests/substrate/utils.ts new file mode 100644 index 0000000..6a6ef86 --- /dev/null +++ b/tests/substrate/utils.ts @@ -0,0 +1,9 @@ +import BN from "bn.js"; + +export const WSURL = "ws://127.0.0.1:9944"; +export const DOT: BN = new BN("1000000000000000"); +export const CREATION_FEE: BN = DOT.muln(200); +export const GAS_REQUIRED = 50000; +export const ALICE = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"; +export const BOB = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"; + From 1465125f576425e2279e6525f236d9b29774347a Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Thu, 9 Jan 2020 10:44:44 +0200 Subject: [PATCH 05/10] Add Basic print example. --- Makefile | 8 +++++++- examples/panicoverride.nim | 8 ++++++++ tests/substrate/test.sh | 2 +- tests/substrate/tests/contract-nimplay.spec.ts | 10 +--------- tests/substrate/tests/utils.ts | 1 - tools/eth_postprocess.sh | 2 -- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 7b73ccd..0c4c743 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ DOCKER_NLVM_C=$(DOCKER_NLVM) $(PATH_PARAMS) $(NLVM_WAMS32_FLAGS) c # Use nim + clang DOCKER_NIM_CLANG=docker run -e HOME='/tmp/' --user $(user_id):$(user_id) -w /code/ -v $(pwd):/code/ --entrypoint="/usr/bin/nim" jacqueswww/nimclang --verbosity:2 DOCKER_NIM_CLANG_PASS_FLAGS = --passC:"--target=wasm32-unknown-unknown-wasm" \ ---passL:"--target=wasm32-unknown-unknown-wasm" --passC:"-I./include" --clang.options.linker:"-nostdlib -Wl,--no-entry,--allow-undefined,--strip-all,--export-dynamic" +--passL:"--target=wasm32-unknown-unknown-wasm" --passC:"-I./include" --clang.options.linker:"-nostdlib -Wl,--no-entry,--allow-undefined,--strip-all,--export-dynamic,--import-memory,--max-memory=131072" DOCKER_NIM_CLANG_FLAGS=$(DOCKER_NIM_CLANG_PASS_FLAGS) --os:standalone --cpu:i386 --cc:clang --gc:none --nomain -d:release DOCKER_NIM_CLANG_C=$(DOCKER_NIM_CLANG) --cc:clang $(PATH_PARAMS) c DOCKER_NIM_CLANG_WASM32_C=$(DOCKER_NIM_CLANG) $(DOCKER_NIM_CLANG_FLAGS) $(PATH_PARAMS) c @@ -86,11 +86,17 @@ test-ee: ee-examples cd tests/ee/; \ ./test.sh + + +SUBSTRATE_POSTPROCESS=tools/substrate_postprocess.sh + .PHONY: substrate-examples substrate-examples: $(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim + $(SUBSTRATE_POSTPROCESS) examples/substrate/hello_world.wasm .PHONY: test-substrate test-substrate: substrate-examples cd tests/substrate; \ SUBSTRATE_PATH="${HOME}/.cargo/bin/substrate" ./test.sh + diff --git a/examples/panicoverride.nim b/examples/panicoverride.nim index c122d82..527f050 100644 --- a/examples/panicoverride.nim +++ b/examples/panicoverride.nim @@ -4,3 +4,11 @@ proc rawoutput(s: string) = revert(cstring(s), s.len.int32) proc panic(s: string) = rawoutput(s) {.pop.} + + +# Try LLVm builtin unreachable: +# void myabort(void) __attribute__((noreturn)); +# void myabort(void) { +# asm("int3"); +# __builtin_unreachable(); +# } diff --git a/tests/substrate/test.sh b/tests/substrate/test.sh index dee896c..53706be 100755 --- a/tests/substrate/test.sh +++ b/tests/substrate/test.sh @@ -12,7 +12,7 @@ fi # Purge dev chain and then spin up the substrate node in background $SUBSTRATE_PATH purge-chain --dev -y -$SUBSTRATE_PATH --dev & +$SUBSTRATE_PATH --dev -l debug & SUBSTRATE_PID=$! # # Execute tests diff --git a/tests/substrate/tests/contract-nimplay.spec.ts b/tests/substrate/tests/contract-nimplay.spec.ts index 727028d..030af14 100644 --- a/tests/substrate/tests/contract-nimplay.spec.ts +++ b/tests/substrate/tests/contract-nimplay.spec.ts @@ -79,18 +79,10 @@ describe("Nimplay Hello World", () => { STORAGE_KEY ); expect(initialValue).toBeDefined(); - expect(initialValue.toString()).toEqual("0x00"); + expect(initialValue.toString()).toEqual(""); await callContract(api, testAccount, address, "0x00"); - const newValue = await getContractStorage(api, address, STORAGE_KEY); - expect(newValue.toString()).toEqual("0x01"); - - await callContract(api, testAccount, address, "0x00"); - - const flipBack = await getContractStorage(api, address, STORAGE_KEY); - expect(flipBack.toString()).toEqual("0x00"); - done(); }); diff --git a/tests/substrate/tests/utils.ts b/tests/substrate/tests/utils.ts index 0119fd6..d4be1ab 100644 --- a/tests/substrate/tests/utils.ts +++ b/tests/substrate/tests/utils.ts @@ -39,7 +39,6 @@ export async function putCode( .toString("hex"); const tx = api.tx.contracts.putCode(gasRequired, `0x${wasmCode}`); const result: any = await sendAndReturnFinalized(signer, tx); - console.log('result', result) const record = result.findRecord("contracts", "CodeStored"); if (!record) { diff --git a/tools/eth_postprocess.sh b/tools/eth_postprocess.sh index b0d063d..59d9fc5 100755 --- a/tools/eth_postprocess.sh +++ b/tools/eth_postprocess.sh @@ -10,9 +10,7 @@ set -ex wasm2wat="docker run --entrypoint=wasm2wat -w /code/ -v $(pwd):/code/ jacqueswww/nimclang " wat2wasm="docker run --entrypoint=wat2wasm -w /code/ -v $(pwd):/code/ jacqueswww/nimclang " -# Replace "env" with "ethereum" $wasm2wat "$WASM_FILE" | - sed 's/(import "env" /(import "ethereum" /g' | sed '/(export.*memory\|main.*/! s/(export.*//g' > ./wasm.tmp $wat2wasm -o "$WASM_FILE" ./wasm.tmp From 1a82f47a4e3c4f9d320c7be1d5ce92bde236bb21 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Thu, 9 Jan 2020 20:51:06 +0200 Subject: [PATCH 06/10] Add ext_scratch_read example. --- Makefile | 2 + examples/substrate/flipper.nim | 54 +++++++++++++++++++ examples/substrate/hello_world.nim | 14 +++++ examples/substrate/panicoverride.nim | 6 +++ .../substrate/tests/contract-nimplay.spec.ts | 10 ++-- tools/substrate_postprocess.sh | 19 +++++++ 6 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 examples/substrate/flipper.nim create mode 100644 examples/substrate/hello_world.nim create mode 100644 examples/substrate/panicoverride.nim create mode 100755 tools/substrate_postprocess.sh diff --git a/Makefile b/Makefile index 0c4c743..2d9ebc0 100644 --- a/Makefile +++ b/Makefile @@ -94,6 +94,8 @@ SUBSTRATE_POSTPROCESS=tools/substrate_postprocess.sh substrate-examples: $(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim $(SUBSTRATE_POSTPROCESS) examples/substrate/hello_world.wasm + $(WASM32_NIMC) --out:examples/substrate/flipper.wasm examples/substrate/flipper.nim + $(SUBSTRATE_POSTPROCESS) examples/substrate/flipper.wasm .PHONY: test-substrate test-substrate: substrate-examples diff --git a/examples/substrate/flipper.nim b/examples/substrate/flipper.nim new file mode 100644 index 0000000..bd6589a --- /dev/null +++ b/examples/substrate/flipper.nim @@ -0,0 +1,54 @@ +import ../../nimplay/substrate_runtime + +{.compile: "malloc.c".} +proc malloc(n: int): pointer {.importc.} + +type + Action = enum + Flip = 0'u8, Get = 1'u8, SelfEvict = 2'u8 + +# Init function. +proc deploy(): uint32 {.exportwasm.} = + 0 + +proc get_scratch(): (pointer, int32) = + var + scratch_size = ext_scratch_size() + mem_ptr = malloc(scratch_size.int) + ext_scratch_read(mem_ptr, 0, scratch_size) + (mem_ptr, scratch_size) + +proc print(s: cstring) = + ext_println(s, s.len.int32) + +# Main function. +proc call(): uint32 {.exportwasm.} = + var + selector: uint8 + (scratch_ptr, scratch_size) = get_scratch() + + copyMem(addr selector, scratch_ptr, 1) + + case selector + of Action.Flip.ord: + print("Flip".cstring) + of Action.Get.ord: + print("Get".cstring) + of Action.SelfEvict.ord: + print("SelfEvict".cstring) + else: + print("Unknown".cstring) + + 0 # return + +# sys::ext_set_storage( +# key.as_ptr() as u32, +# 1, +# value.as_ptr() as u32, +# value.len() as u32, +# ) + + +# block_data = malloc(block_data_size.int) +# eth2_blockDataCopy(block_data, 0, block_data_size) +# copyMem(addr post_state_root, block_data, 32) diff --git a/examples/substrate/hello_world.nim b/examples/substrate/hello_world.nim new file mode 100644 index 0000000..1700fb0 --- /dev/null +++ b/examples/substrate/hello_world.nim @@ -0,0 +1,14 @@ +import ../../nimplay/substrate_runtime + + +# Init function. +proc deploy(): uint32 {.exportwasm.} = + 0 + +# Main function. +proc call(): uint32 {.exportwasm.} = + var + s = cstring("Hello world!") + ext_println(s, s.len.int32) + ext_scratch_write(s, s.len.int32) + 0 # return diff --git a/examples/substrate/panicoverride.nim b/examples/substrate/panicoverride.nim new file mode 100644 index 0000000..3af3ae5 --- /dev/null +++ b/examples/substrate/panicoverride.nim @@ -0,0 +1,6 @@ +{.push stack_trace: off, profiler:off.} +proc ext_println*(offset: pointer, length: uint32) {.noreturn, cdecl, importc.} +proc rawoutput(s: string) = + ext_println(cstring(s), s.len.uint32) +proc panic(s: string) = rawoutput(s) +{.pop.} diff --git a/tests/substrate/tests/contract-nimplay.spec.ts b/tests/substrate/tests/contract-nimplay.spec.ts index 030af14..c73eeeb 100644 --- a/tests/substrate/tests/contract-nimplay.spec.ts +++ b/tests/substrate/tests/contract-nimplay.spec.ts @@ -47,9 +47,8 @@ beforeEach( ); - -describe("Nimplay Hello World", () => { - test("Raw Flipper contract", async (done): Promise => { +describe("Nimplay Flipper", () => { + test("Can deploy and execute", async (done): Promise => { // See https://github.com/paritytech/srml-contracts-waterfall/issues/6 for info about // how to get the STORAGE_KEY of an instantiated contract @@ -58,7 +57,7 @@ describe("Nimplay Hello World", () => { const codeHash = await putCode( api, testAccount, - "../../../examples/substrate/hello_world.wasm" + "../../../examples/substrate/flipper.wasm" ); expect(codeHash).toBeDefined(); @@ -82,9 +81,10 @@ describe("Nimplay Hello World", () => { expect(initialValue.toString()).toEqual(""); await callContract(api, testAccount, address, "0x00"); + await callContract(api, testAccount, address, "0x01"); + await callContract(api, testAccount, address, "0x74657374"); done(); }); - }); diff --git a/tools/substrate_postprocess.sh b/tools/substrate_postprocess.sh new file mode 100755 index 0000000..2066124 --- /dev/null +++ b/tools/substrate_postprocess.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +WASM_FILE=$1 + +set -ex + +#wasm2wat="tools/wabt/build/wasm2wat" +#wat2wasm="tools/wabt/build/wat2wasm" + +wasm2wat="docker run --entrypoint=wasm2wat -w /code/ -v $(pwd):/code/ jacqueswww/nimclang " +wat2wasm="docker run --entrypoint=wat2wasm -w /code/ -v $(pwd):/code/ jacqueswww/nimclang " + +# Replace "env" with "ethereum" +$wasm2wat "$WASM_FILE" | + sed '/(export.*deploy\|call.*/! s/(export.*//g' > ./wasm.tmp + +$wat2wasm -o "$WASM_FILE" ./wasm.tmp + +rm ./wasm.tmp From f5059e5826bc2ef1c819ae4e25dd0912f9353400 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Tue, 14 Jan 2020 17:43:24 +0200 Subject: [PATCH 07/10] Add storage set example for Substrate. --- Makefile | 4 +-- examples/substrate/malloc.c | 13 +++++++ .../substrate/{flipper.nim => setter.nim} | 31 ++++++++++++---- nimplay/substrate_runtime.nim | 2 +- .../substrate/tests/contract-nimplay.spec.ts | 35 +++++++++++++++---- tests/substrate/tests/utils.ts | 1 - 6 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 examples/substrate/malloc.c rename examples/substrate/{flipper.nim => setter.nim} (54%) diff --git a/Makefile b/Makefile index 2d9ebc0..a947a98 100644 --- a/Makefile +++ b/Makefile @@ -94,8 +94,8 @@ SUBSTRATE_POSTPROCESS=tools/substrate_postprocess.sh substrate-examples: $(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim $(SUBSTRATE_POSTPROCESS) examples/substrate/hello_world.wasm - $(WASM32_NIMC) --out:examples/substrate/flipper.wasm examples/substrate/flipper.nim - $(SUBSTRATE_POSTPROCESS) examples/substrate/flipper.wasm + $(WASM32_NIMC) --out:examples/substrate/setter.wasm examples/substrate/setter.nim + $(SUBSTRATE_POSTPROCESS) examples/substrate/setter.wasm .PHONY: test-substrate test-substrate: substrate-examples diff --git a/examples/substrate/malloc.c b/examples/substrate/malloc.c new file mode 100644 index 0000000..797df27 --- /dev/null +++ b/examples/substrate/malloc.c @@ -0,0 +1,13 @@ +extern unsigned char __heap_base; + +unsigned int bump_pointer = &__heap_base; + +void* malloc(int n) { + unsigned int r = bump_pointer ; + bump_pointer += n; + return (void *)r; +} + +void free(void* p) { + // lol +} diff --git a/examples/substrate/flipper.nim b/examples/substrate/setter.nim similarity index 54% rename from examples/substrate/flipper.nim rename to examples/substrate/setter.nim index bd6589a..5190d96 100644 --- a/examples/substrate/flipper.nim +++ b/examples/substrate/setter.nim @@ -5,7 +5,7 @@ proc malloc(n: int): pointer {.importc.} type Action = enum - Flip = 0'u8, Get = 1'u8, SelfEvict = 2'u8 + Set = 0'u8, Get = 1'u8, SelfEvict = 2'u8 # Init function. proc deploy(): uint32 {.exportwasm.} = @@ -21,6 +21,25 @@ proc get_scratch(): (pointer, int32) = proc print(s: cstring) = ext_println(s, s.len.int32) + +proc incr_pointer(oldp: pointer): pointer = + var newp = cast[pointer](cast[uint](oldp) + 1u) + newp + + +proc set_val_in_store(scratch_ptr: pointer, scratch_size: int32) = + print("Set".cstring) + var + key: array[32, byte] = [ + 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, + 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, + 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, + 2'u8, 2'u8, 2'u8, 2'u8, 2'u8 + ] + offset_ptr = incr_pointer(scratch_ptr) + + ext_set_storage(addr key, 1.int32 , offset_ptr, scratch_size - 1) + # Main function. proc call(): uint32 {.exportwasm.} = var @@ -30,14 +49,14 @@ proc call(): uint32 {.exportwasm.} = copyMem(addr selector, scratch_ptr, 1) case selector - of Action.Flip.ord: - print("Flip".cstring) + of Action.Set.ord: + set_val_in_store(scratch_ptr, scratch_size) of Action.Get.ord: - print("Get".cstring) + print("Get: Todo".cstring) of Action.SelfEvict.ord: - print("SelfEvict".cstring) + print("SelfEvict: Todo".cstring) else: - print("Unknown".cstring) + print("Unknown action passed".cstring) 0 # return diff --git a/nimplay/substrate_runtime.nim b/nimplay/substrate_runtime.nim index 72309b3..5f0c672 100644 --- a/nimplay/substrate_runtime.nim +++ b/nimplay/substrate_runtime.nim @@ -14,7 +14,7 @@ proc ext_scratch_read*(dest_ptr: pointer, offset: int32, len: int32) proc ext_scratch_size*(): int32 proc ext_scratch_write*(src_ptr: pointer, len: int32) proc ext_set_rent_allowance*(value_ptr: pointer, value_len: int32) -proc ext_set_storage*(key_ptr: pointer, value_non_null: int32, value_ptr: int32, value_len: int32) +proc ext_set_storage*(key_ptr: pointer, value_non_null: int32, value_ptr: pointer, value_len: int32) proc ext_value_transferred*() {.pop.} diff --git a/tests/substrate/tests/contract-nimplay.spec.ts b/tests/substrate/tests/contract-nimplay.spec.ts index c73eeeb..a37efc6 100644 --- a/tests/substrate/tests/contract-nimplay.spec.ts +++ b/tests/substrate/tests/contract-nimplay.spec.ts @@ -46,9 +46,29 @@ beforeEach( } ); - -describe("Nimplay Flipper", () => { +describe("Nimplay Hellow World", () => { test("Can deploy and execute", async (done): Promise => { + const codeHash = await putCode( + api, + testAccount, + "../../../examples/substrate/hello_world.wasm" + ); + expect(codeHash).toBeDefined(); + const address: Address = await instantiate( + api, + testAccount, + codeHash, + "0x00", + CREATION_FEE + ); + expect(address).toBeDefined(); + await callContract(api, testAccount, address, "0x00"); + done(); + }); +}); + +describe("Nimplay Storage Setter", () => { + test("Setter: Can deploy and execute", async (done): Promise => { // See https://github.com/paritytech/srml-contracts-waterfall/issues/6 for info about // how to get the STORAGE_KEY of an instantiated contract @@ -57,12 +77,11 @@ describe("Nimplay Flipper", () => { const codeHash = await putCode( api, testAccount, - "../../../examples/substrate/flipper.wasm" + "../../../examples/substrate/setter.wasm" ); expect(codeHash).toBeDefined(); // Instantiate a new contract instance and retrieve the contracts address - // Call contract with Action: 0x00 = Action::Flip() const address: Address = await instantiate( api, testAccount, @@ -81,10 +100,12 @@ describe("Nimplay Flipper", () => { expect(initialValue.toString()).toEqual(""); await callContract(api, testAccount, address, "0x00"); - await callContract(api, testAccount, address, "0x01"); - await callContract(api, testAccount, address, "0x74657374"); + var val_hex = "03".repeat(32); + // "0x00" indicates calling "Set" Action + await callContract(api, testAccount, address, "0x00" + val_hex); + const newValue = await getContractStorage(api, address, STORAGE_KEY); + expect(newValue.toString()).toEqual("0x" + val_hex); done(); }); - }); diff --git a/tests/substrate/tests/utils.ts b/tests/substrate/tests/utils.ts index d4be1ab..e3295a4 100644 --- a/tests/substrate/tests/utils.ts +++ b/tests/substrate/tests/utils.ts @@ -45,7 +45,6 @@ export async function putCode( console.error("ERROR: No code stored after executing putCode()"); } // Return code hash. - console.log(record); return record.event.data[0]; } From fdf52f9b0bc227a4c9e44678124b3b16e0055e3d Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Thu, 16 Jan 2020 12:22:24 +0200 Subject: [PATCH 08/10] Fix separate ld parameters for ewasm & substrate. --- Makefile | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index a947a98..8b77ba2 100644 --- a/Makefile +++ b/Makefile @@ -9,18 +9,28 @@ NLVM_WAMS32_FLAGS= --nlvm.target=wasm32 --gc:none -l:--no-entry -l:--allow-undef DOCKER_NLVM_C=$(DOCKER_NLVM) $(PATH_PARAMS) $(NLVM_WAMS32_FLAGS) c # Use nim + clang DOCKER_NIM_CLANG=docker run -e HOME='/tmp/' --user $(user_id):$(user_id) -w /code/ -v $(pwd):/code/ --entrypoint="/usr/bin/nim" jacqueswww/nimclang --verbosity:2 -DOCKER_NIM_CLANG_PASS_FLAGS = --passC:"--target=wasm32-unknown-unknown-wasm" \ ---passL:"--target=wasm32-unknown-unknown-wasm" --passC:"-I./include" --clang.options.linker:"-nostdlib -Wl,--no-entry,--allow-undefined,--strip-all,--export-dynamic,--import-memory,--max-memory=131072" -DOCKER_NIM_CLANG_FLAGS=$(DOCKER_NIM_CLANG_PASS_FLAGS) --os:standalone --cpu:i386 --cc:clang --gc:none --nomain -d:release +CLANG_OPTIONS_LINKER=-nostdlib -Wl,--no-entry,--allow-undefined,--strip-all,--export-dynamic + +# Ewasm DOCKER_NIM_CLANG_C=$(DOCKER_NIM_CLANG) --cc:clang $(PATH_PARAMS) c -DOCKER_NIM_CLANG_WASM32_C=$(DOCKER_NIM_CLANG) $(DOCKER_NIM_CLANG_FLAGS) $(PATH_PARAMS) c +DOCKER_NIM_CLANG_PASS_FLAGS_EWASM = --passC:"--target=wasm32-unknown-unknown-wasm" \ +--passL:"--target=wasm32-unknown-unknown-wasm" --passC:"-I./include" --clang.options.linker:"$(CLANG_OPTIONS_LINKER)" +DOCKER_NIM_CLANG_FLAGS_EWASM=$(DOCKER_NIM_CLANG_PASS_FLAGS_EWASM) --os:standalone --cpu:i386 --cc:clang --gc:none --nomain -d:release +DOCKER_NIM_CLANG_EWASM_C=$(DOCKER_NIM_CLANG) $(DOCKER_NIM_CLANG_FLAGS_EWASM) $(PATH_PARAMS) c + +# Substrate +DOCKER_NIM_CLANG_PASS_FLAGS_SUBSTRATE = --passC:"--target=wasm32-unknown-unknown-wasm" \ +--passL:"--target=wasm32-unknown-unknown-wasm" --passC:"-I./include" \ +--clang.options.linker:"$(CLANG_OPTIONS_LINKER),--import-memory,--max-memory=131072" +DOCKER_NIM_CLANG_FLAGS_SUBSTRATE=$(DOCKER_NIM_CLANG_PASS_FLAGS_SUBSTRATE) --os:standalone --cpu:i386 --cc:clang --gc:none --nomain -d:release +SUBSTRATE_NIMC=$(DOCKER_NIM_CLANG) $(DOCKER_NIM_CLANG_FLAGS_SUBSTRATE) $(PATH_PARAMS) c ifdef USE_NLVM NIMC=$(DOCKER_NLVM_C) - WASM32_NIMC=$(DOCKER_NLVM_C) + EWASM_NIMC=$(DOCKER_NLVM_C) else NIMC=$(DOCKER_NIM_CLANG_C) - WASM32_NIMC=$(DOCKER_NIM_CLANG_WASM32_C) + EWASM_NIMC=$(DOCKER_NIM_CLANG_EWASM_C) endif .PHONY: all @@ -59,46 +69,42 @@ vendors: cd vendors git submodule update --init -.PHONY: king_of_the_hill -king_of_the_hill: - $(WASM32_NIMC) --out:examples/king_of_the_hill.wasm examples/king_of_the_hill.nim +.PHONY: ewasm_king_of_the_hill +ewasm_king_of_the_hill: + $(EWASM_NIMC) --out:examples/king_of_the_hill.wasm examples/king_of_the_hill.nim $(POSTPROCESS) examples/king_of_the_hill.wasm .PHONY: examples -examples: king_of_the_hill - $(WASM32_NIMC) --out:examples/registry.wasm examples/registry.nim +ewasm-examples: ewasm_king_of_the_hill + $(EWASM_NIMC) --out:examples/registry.wasm examples/registry.nim $(POSTPROCESS) examples/registry.wasm - $(WASM32_NIMC) --out:examples/balances.wasm examples/balances.nim + $(EWASM_NIMC) --out:examples/balances.wasm examples/balances.nim $(POSTPROCESS) examples/balances.wasm - $(WASM32_NIMC) --out:examples/erc20.wasm examples/erc20.nim + $(EWASM_NIMC) --out:examples/erc20.wasm examples/erc20.nim $(POSTPROCESS) examples/erc20.wasm - $(WASM32_NIMC) --out:examples/default_func.wasm examples/default_func.nim + $(EWASM_NIMC) --out:examples/default_func.wasm examples/default_func.nim $(POSTPROCESS) examples/default_func.wasm - .PHONY: ee-examples ee-examples: - $(WASM32_NIMC) --out:examples/ee/helloworld.wasm examples/ee/helloworld.nim - $(WASM32_NIMC) --out:examples/ee/block_echo.wasm examples/ee/block_echo.nim + $(EWASM_NIMC) --out:examples/ee/helloworld.wasm examples/ee/helloworld.nim + $(EWASM_NIMC) --out:examples/ee/block_echo.wasm examples/ee/block_echo.nim .PHONY: test-ee test-ee: ee-examples cd tests/ee/; \ ./test.sh - - SUBSTRATE_POSTPROCESS=tools/substrate_postprocess.sh .PHONY: substrate-examples substrate-examples: - $(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim + $(SUBSTRATE_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim $(SUBSTRATE_POSTPROCESS) examples/substrate/hello_world.wasm - $(WASM32_NIMC) --out:examples/substrate/setter.wasm examples/substrate/setter.nim + $(SUBSTRATE_NIMC) --out:examples/substrate/setter.wasm examples/substrate/setter.nim $(SUBSTRATE_POSTPROCESS) examples/substrate/setter.wasm .PHONY: test-substrate test-substrate: substrate-examples cd tests/substrate; \ SUBSTRATE_PATH="${HOME}/.cargo/bin/substrate" ./test.sh - From 4d9dbbbbaf9d927d83df645436ec1cdc151328b6 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Thu, 16 Jan 2020 13:05:15 +0200 Subject: [PATCH 09/10] Add missing substrate test files. --- .gitignore | 1 + tests/substrate/package.json | 33 +++++++++++++++++++++++++++++++++ tests/substrate/tsconfig.json | 24 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/substrate/package.json create mode 100644 tests/substrate/tsconfig.json diff --git a/.gitignore b/.gitignore index c2e9577..aef75b3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ examples/*.wasm .priv_key_hex *.wasm tests/ee/ewasm-scout/ +tests/substrate/node_modules/ diff --git a/tests/substrate/package.json b/tests/substrate/package.json new file mode 100644 index 0000000..e56d1d3 --- /dev/null +++ b/tests/substrate/package.json @@ -0,0 +1,33 @@ +{ + "name": "srml-contract-waterfall-nimplay", + "version": "1.0.0", + "main": "index.js", + "author": "Sergey Shulepov ", + "contributors": [ + "Stefanie Doll " + ], + "license": "MIT", + "dependencies": { + "@polkadot/api": "^0.97.0-beta.39", + "@polkadot/api-contract": "^0.97.0-beta.39", + "blakejs": "^1.1.0", + "typescript": "^3.6.4" + }, + "devDependencies": { + "@types/jest": "^24.0.18", + "@types/node": "^10.12.18", + "@typescript-eslint/eslint-plugin": "^2.6.0", + "@typescript-eslint/parser": "^2.6.0", + "bn.js": "^5.0.0", + "eslint": "^6.6.0", + "jest": "^24.9.0", + "ts-jest": "^24.1.0", + "ts-loader": "^5.3.2" + }, + "jest": { + "preset": "ts-jest/presets/js-with-ts" + }, + "scripts": { + "test": "NODE_ENV=abc jest" + } +} \ No newline at end of file diff --git a/tests/substrate/tsconfig.json b/tests/substrate/tsconfig.json new file mode 100644 index 0000000..14b7763 --- /dev/null +++ b/tests/substrate/tsconfig.json @@ -0,0 +1,24 @@ +{ + + "compilerOptions": { + "target": "esnext", + "module": "commonjs", + "lib": ["dom", "es2018"], + "resolveJsonModule": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "allowJs": true, + "esModuleInterop": true + }, + "exclude": [ + "contracts/rust", + "lib", + "node_modules", + ] +} From 934aadfcb9923e6c7db1ce6a00eb84db47feb068 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Tue, 21 Jan 2020 12:15:21 +0200 Subject: [PATCH 10/10] Revert regression in eth_postprocess.sh --- tools/eth_postprocess.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/eth_postprocess.sh b/tools/eth_postprocess.sh index 59d9fc5..b0d063d 100755 --- a/tools/eth_postprocess.sh +++ b/tools/eth_postprocess.sh @@ -10,7 +10,9 @@ set -ex wasm2wat="docker run --entrypoint=wasm2wat -w /code/ -v $(pwd):/code/ jacqueswww/nimclang " wat2wasm="docker run --entrypoint=wat2wasm -w /code/ -v $(pwd):/code/ jacqueswww/nimclang " +# Replace "env" with "ethereum" $wasm2wat "$WASM_FILE" | + sed 's/(import "env" /(import "ethereum" /g' | sed '/(export.*memory\|main.*/! s/(export.*//g' > ./wasm.tmp $wat2wasm -o "$WASM_FILE" ./wasm.tmp