diff --git a/package.json b/package.json index 85e4db60..594166fa 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ }, "homepage": "https://github.com/warp-contracts/warp#readme", "dependencies": { - "@assemblyscript/loader": "^0.19.23", "@idena/vrf-js": "^1.0.1", "archiver": "^5.3.0", "arweave": "^1.12.4", diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/decrement.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/decrement.ts deleted file mode 100644 index 3a7dd900..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/decrement.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {ContractResultSchema} from '../contract'; - -export function decrement(state: StateSchema, action: ActionSchema): ContractResultSchema { - state.counter -= 555; - - return { - state, - result: null - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/evolve.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/evolve.ts deleted file mode 100644 index 630d25c7..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/evolve.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {Transaction} from '../imports/smartweave/transaction'; -import {Contract} from '../imports'; -import {ContractResultSchema} from '../contract'; - -export function evolve( - state: StateSchema, - action: ActionSchema -): ContractResultSchema { - const evolve = action.value; - const contractOwner = Contract.owner(); - const sender = Transaction.owner(); - - if (sender != contractOwner) { - throw new Error( - '[CE:EPE] Evolve permissions error - only contract owner can evolve' - ); - } - - if (!state.canEvolve) { - throw new Error('[CE:ECE] Evolve not allowed'); - } - - state.evolve = evolve; - - return { - state, - result: null, - }; -} \ No newline at end of file diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/fullName.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/fullName.ts deleted file mode 100644 index c02e413e..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/fullName.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {ContractResultSchema} from '../contract'; -import {ActionSchema, StateSchema} from '../schemas'; -import {console} from '../imports'; - -export function fullName(state: StateSchema, action: ActionSchema): ContractResultSchema { - console.log(`fullName called: "${action.function}"`); - console.log(`${state.firstName} ${state.lastName}`); - return { - state, - result: { - fullName: `${state.firstName} ${state.lastName}` - } - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/increment.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/increment.ts deleted file mode 100644 index 351d1f70..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/increment.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {ContractResultSchema} from '../contract'; - -export function increment(state: StateSchema, action: ActionSchema): ContractResultSchema { - state.counter += 2; - - return { - state, - result: null, - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/infLoop.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/infLoop.ts deleted file mode 100644 index 1d14fb5b..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/actions/infLoop.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {ContractResultSchema} from '../contract'; - -export function infLoop(state: StateSchema, action: ActionSchema): ContractResultSchema { - while (true) {} - - return { - state, - result: null - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/arrays.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/arrays.ts deleted file mode 100644 index f13a5fc0..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/arrays.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const UINT8ARRAY_ID = idof(); -export const INT16ARRAY_ID = idof(); -export const UINT16ARRAY_ID = idof(); -export const INT32ARRAY_ID = idof(); -export const UINT32ARRAY_ID = idof(); -export const FLOAT32ARRAY_ID = idof(); -export const ARRAYI32_ID = idof>(); -export const STATICARRAYI32_ID = idof>(); -export const STATICARRAYU32_ID = idof>(); -export const STATICARRAYU8_ID = idof>(); -export const STATICARRAYI16_ID = idof>(); -export const STATICARRAYF32_ID = idof>(); diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/contract.d.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/contract.d.ts deleted file mode 100644 index 05fa6bde..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/contract.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare function contract(a: any): any; diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/contract.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/contract.ts deleted file mode 100644 index 2f196772..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/contract.ts +++ /dev/null @@ -1,65 +0,0 @@ -// common imports - do not remove (even if IDE reports as non-used)! -import { - Block, - console, - Contract, - ContractFn, - HandlerResultSchema, - SmartWeaveSchema, - stringify, - Transaction -} from "./imports"; - -// contract specific imports -import {increment} from "./actions/increment"; -import {decrement} from "./actions/decrement"; -import {fullName} from "./actions/fullName"; -import {infLoop} from "./actions/infLoop"; -import {evolve} from "./actions/evolve"; -import {ActionSchema, ResultSchema, StateSchema} from "./schemas"; - -const functions: Map> = new Map(); -functions.set("increment", increment); -functions.set("decrement", decrement); -functions.set("fullName", fullName); -functions.set("infLoop", infLoop); -functions.set("evolve", evolve); - -export type ContractResultSchema = HandlerResultSchema; - -let contractState: StateSchema; - -@contract -function handle(state: StateSchema, action: ActionSchema): ResultSchema | null { - console.log(`Function called: "${action.function}"`); - console.logO(`SmartWeave:`, stringify({ - contract: { - id: Contract.id(), - owner: Contract.owner() - }, - block: { - height: Block.height(), - indep_hash: Block.indep_hash(), - timestamp: Block.timestamp() - }, - transaction: { - id: Transaction.id(), - owner: Transaction.owner(), - target: Transaction.target() - } - })); - - const fn = action.function; - if (functions.has(fn)) { - const handlerResult = functions.get(fn)(state, action); - if (handlerResult.state != null) { - contractState = handlerResult.state!; - } - if (handlerResult.result != null) { - console.logO(`Result:`, stringify(handlerResult.result!)) - } - return handlerResult.result; - } else { - throw new Error(`[RE:WTF] Unknown function ${action.function}`); - } -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/AbstractERC20.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/AbstractERC20.ts deleted file mode 100644 index fd6ec126..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/AbstractERC20.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {ContractError, ERC20} from './ERC20'; -import {console} from '../imports/console'; -import {msg} from '../imports/smartweave/msg'; - -export abstract class AbstractERC20 implements ERC20 { - private _name: string; - private _symbol: string; - protected _totalSupply: u64; - protected readonly _balances: Map = new Map(); - protected readonly _allowances: Map> = new Map>(); - - protected constructor(name_: string, symbol_: string) { - this._name = name_; - this._symbol = symbol_; - this._totalSupply = 0; - } - - abstract mint(account: string, amount: u64): void; - abstract burn(account: string, amount: u64): void; - - transfer(recipient: string, amount: u64): void { - console.log(`transfer called ${recipient}: ${amount}`); - this._transfer(msg.sender(), recipient, amount); - } - - approve(spender: string, amount: u64): void { - const msgSender = msg.sender(); - if (!this._allowances.has(msgSender)) { - this._allowances.set(msgSender, new Map()); - } - if (!this._allowances.get(msgSender).has(spender)) { - this._allowances.get(msgSender).set(spender, amount); - } else { - let spenderAllowance: u64 = this._allowances.get(msgSender).get(spender); - spenderAllowance += amount; - this._allowances.get(msgSender).set(spender, spenderAllowance); - } - } - - protected _transfer(sender: string, recipient: string, amount: u64): void { - if (amount <= 0 || sender === recipient) { - throw new ContractError('Invalid token transfer'); - } - - let senderBalance = this._balances.get(sender); - if (senderBalance < amount) { - throw new ContractError(`Caller balance not high enough to send ${amount} token(s)!`); - } - senderBalance -= amount; - this._balances.set(sender, senderBalance); - - if (!this._balances.has(recipient)) { - this._balances.set(recipient, amount); - } else { - let recipientBalance = this._balances.get(sender); - recipientBalance += amount; - this._balances.set(recipient, recipientBalance); - } - } - - balanceOf(account: string): u64 { - console.log(`balanceOf called ${account}`); - if (this._balances.has(account)) { - return this._balances.get(account); - } else { - return 0; - } - } - - allowance(owner: string, spender: string): u64 { - console.log(`allowance called ${owner}: ${spender}`); - let result: u64 = 0; - if (this._allowances.has(owner) && this._allowances.get(owner).has(spender)) { - const ownerAllowances: Map = this._allowances.get(owner); - result = ownerAllowances.get(spender); - } - - return result; - } - - get totalSupply(): u64 { - return this._totalSupply; - } - - transferFrom(sender: string, recipient: string, amount: u64): void { - const msgSender = msg.sender(); - console.log(`transferFrom called ${sender}[${msgSender}] -> ${recipient}:${amount}`); - - if (!this._allowances.has(sender) || !this._allowances.get(sender).has(msgSender)) { - throw new ContractError(`No allowance for ${msgSender} from ${sender}`); - } - - let currentAllowance = this._allowances.get(sender).get(msgSender); - if (currentAllowance < amount) { - throw new ContractError(`Transfer amount exceeds allowance`); - } - currentAllowance -= amount; - this._allowances.get(sender).set(msgSender, currentAllowance); - this._transfer(sender, recipient, amount); - } - - get name(): string { - return this._name; - } - - get symbol(): string { - return this._symbol; - } - - set name(value: string) { - this._name = value; - } - - set symbol(value: string) { - this._symbol = value; - } -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/ERC20.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/ERC20.ts deleted file mode 100644 index f73799c1..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/ERC20.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface ERC20 { - // view functions - totalSupply: u64; - balanceOf(account: string): u64; - allowance(owner: string, spender: string): u64; - - // state changing functions - transfer(recipient: string, amount: u64): void; - approve(spender: string, amount: u64): void; - transferFrom(sender: string, recipient: string, amount: u64): void; -} - -// no custom exceptions support - throwing Exception -// effectively calls "abort" -export class ContractError extends Error { - constructor(message: string) { - super(message); - this.name = 'ContractError'; - } -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/RedStoneToken.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/RedStoneToken.ts deleted file mode 100644 index 4f7afc61..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/RedStoneToken.ts +++ /dev/null @@ -1,125 +0,0 @@ -import {AbstractERC20} from './AbstractERC20'; -import {console} from '../imports/console'; -import {ContractError} from './ERC20'; -import {setTimeout} from '../imports/api'; -import {msg} from '../imports/smartweave/msg'; - -export class RedStoneToken extends AbstractERC20 { - constructor(name_: string, symbol_: string) { - super(name_, symbol_); - } - - burn(account: string, amount: u64): void { - console.log(`burn called ${account}: ${amount}`); - const msgSender = msg.sender(); - if (account != msgSender) { - throw new ContractError('Only account owner can burn his tokens'); - } - if (!this._balances.has(account)) { - throw new ContractError('Account has no balance'); - } - - if (this._balances.get(account) < amount) { - throw new ContractError('Account has not enough balance'); - } - - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance - amount); - this._totalSupply -= amount; - } - - mint(account: string, amount: u64): void { - console.log(`mint called ${account}: ${amount}`); - - if (this._balances.has(account)) { - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance + amount); - } else { - this._balances.set(account, amount); - } - this._totalSupply += amount; - } - - // just for tests. - private _structField: ProviderData = new ProviderData( - 'RedStone Provider', - 'RedStone Provider desc', - 'RedStone Provider manifest' - ); - - private _arrayField: Uint16Array = new Uint16Array(10); - - /** - * WASM testing BEGIN - */ - testTimeout(milliseconds: f32): void { - let timeout: i32 = 0; - - timeout = setTimeout((providerData: ProviderData) => { - console.log('After timeout: ' + providerData.name); - // no closures support - // clearTimeout(timeout); - }, milliseconds); - } - - get structField(): ProviderData { - return this._structField; - } - - get arrayField(): Uint16Array { - return this._arrayField; - } - - set arrayField(value: Uint16Array) { - console.log(`arrayField called ${value}`); - this._arrayField = value; - } - - modifyProviderDataArray(data: ProviderData[]): ProviderData[] { - console.log('modifyProviderDataArray'); - return data.map((pd) => { - pd.name += ' WASM'; - return pd; - }); - } - - /** - * WASM testing END - */ -} - -export const UINT16ARRAY_ID = idof(); -export const ProviderData_ID = idof(); -/** - * WASM testing BEGIN - */ -export function getToken(): RedStoneToken { - return new RedStoneToken('RedStone', 'RDST'); -} - -/** - * Some test class to verify wasm-js interoperability - */ -export class ProviderData { - name: string; - description: string; - manifestTxId: string; - - constructor(name: string, description: string, manifestTxId: string) { - this.name = name; - this.description = description; - this.manifestTxId = manifestTxId; - } - - toString(): string { - return ` - ProviderData - #name: ${this.name} - #description: ${this.description} - #manifestTxId: ${this.manifestTxId} - `; - } -} -/** - * WASM testing END - */ diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/RedStoneToken_old.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/RedStoneToken_old.ts deleted file mode 100644 index 560eed40..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/fancy/RedStoneToken_old.ts +++ /dev/null @@ -1,242 +0,0 @@ -import {ContractError, ERC20} from './ERC20'; -import {console} from '../imports/console'; -import {Block} from '../imports/smartweave/block'; -import {Transaction} from '../imports/smartweave/transaction'; -import {Contract} from '../imports/smartweave/contract'; -import {msg} from '../imports/smartweave/msg'; -import {setTimeout} from '../imports/api'; - -export class RedStoneToken_old implements ERC20 { - private readonly _name: string; - - private readonly _symbol: string; - - private _totalSupply: u64; - - private readonly _balances: Map = new Map(); - - private readonly _allowances: Map> = new Map>(); - - // just for tests. - private _structField: ProviderData = new ProviderData( - 'RedStone Provider', - 'RedStone Provider desc', - 'RedStone Provider manifest' - ); - - private _arrayField: Uint16Array = new Uint16Array(10); - - constructor(name_: string, symbol_: string) { - this._name = name_; - this._symbol = symbol_; - this._totalSupply = 0; - - /** - * WASM testing BEGIN - */ - console.log(`Constructor: ${this._structField.toString()}`); - console.log(`Block#height: ${Block.height()}`); - console.log(`Block#indep_hash: ${Block.indep_hash()}`); - console.log(`Block#timestamp: ${Block.timestamp()}`); - - console.log(`Transaction#id: ${Transaction.id()}`); - console.log(`Transaction#owner: ${Transaction.owner()}`); - console.log(`Transaction#target: ${Transaction.target()}`); - - console.log(`Contract#id: ${Contract.id()}`); - console.log(`Contract#owner: ${Contract.owner()}`); - - console.log(`msg#sender: ${msg.sender()}`); - /** - * WASM testing END - */ - } - - get totalSupply(): u64 { - return this._totalSupply; - } - - balanceOf(account: string): u64 { - console.log(`balanceOf called ${account}`); - if (this._balances.has(account)) { - return this._balances.get(account); - } else { - return 0; - } - } - - allowance(owner: string, spender: string): u64 { - console.log(`allowance called ${owner}: ${spender}`); - let result: u64 = 0; - if (this._allowances.has(owner) && this._allowances.get(owner).has(spender)) { - const ownerAllowances: Map = this._allowances.get(owner); - result = ownerAllowances.get(spender); - } - - return result; - } - - transfer(recipient: string, amount: u64): void { - console.log(`transfer called ${recipient}: ${amount}`); - this._transfer(msg.sender(), recipient, amount); - } - - approve(spender: string, amount: u64): void { - const msgSender = msg.sender(); - if (!this._allowances.has(msgSender)) { - this._allowances.set(msgSender, new Map()); - } - if (!this._allowances.get(msgSender).has(spender)) { - this._allowances.get(msgSender).set(spender, amount); - } - } - - transferFrom(sender: string, recipient: string, amount: u64): void { - const msgSender = msg.sender(); - console.log(`transferFrom called ${sender}[${msgSender}] -> ${recipient}:${amount}`); - - if (!this._allowances.has(sender) || !this._allowances.get(sender).has(msgSender)) { - throw new ContractError(`No allowance for ${msgSender} from ${sender}`); - } - - let currentAllowance = this._allowances.get(sender).get(msgSender); - if (currentAllowance < amount) { - throw new ContractError(`Transfer amount exceeds allowance`); - } - currentAllowance -= amount; - this._allowances.get(sender).set(msgSender, currentAllowance); - this._transfer(sender, recipient, amount); - } - - // TODO: ownership - mint(account: string, amount: u64): void { - console.log(`mint called ${account}: ${amount}`); - - if (this._balances.has(account)) { - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance + amount); - } else { - this._balances.set(account, amount); - } - this._totalSupply += amount; - } - - // TODO: ownership - burn(account: string, amount: u64): void { - console.log(`burn called ${account}: ${amount}`); - if (!this._balances.has(account)) { - throw new ContractError('Account has no balance'); - } - - if (this._balances.get(account) < amount) { - throw new ContractError('Account has not enough balance'); - } - - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance - amount); - this._totalSupply -= amount; - } - - get name(): string { - return this._name; - } - - get symbol(): string { - return this._symbol; - } - - private _transfer(sender: string, recipient: string, amount: u64): void { - if (amount <= 0 || sender === recipient) { - throw new ContractError('Invalid token transfer'); - } - - let senderBalance = this._balances.get(sender); - if (senderBalance < amount) { - throw new ContractError(`Caller balance not high enough to send ${amount} token(s)!`); - } - senderBalance -= amount; - this._balances.set(sender, senderBalance); - - if (!this._balances.has(recipient)) { - this._balances.set(recipient, amount); - } else { - let recipientBalance = this._balances.get(sender); - recipientBalance += amount; - this._balances.set(recipient, recipientBalance); - } - } - - /** - * WASM testing BEGIN - */ - testTimeout(milliseconds: f32): void { - let timeout: i32 = 0; - - timeout = setTimeout((providerData: ProviderData) => { - console.log('After timeout: ' + providerData.name); - // no closures support - // clearTimeout(timeout); - }, milliseconds); - } - - get structField(): ProviderData { - return this._structField; - } - - get arrayField(): Uint16Array { - return this._arrayField; - } - - set arrayField(value: Uint16Array) { - console.log(`arrayField called ${value}`); - this._arrayField = value; - } - - modifyProviderDataArray(data: ProviderData[]): ProviderData[] { - console.log('modifyProviderDataArray'); - return data.map((pd) => { - pd.name += ' WASM'; - return pd; - }); - } - /** - * WASM testing END - */ -} - -/** - * WASM testing BEGIN - */ -export function getToken(): RedStoneToken_old { - return new RedStoneToken_old('RedStone', 'RDST'); -} - -export const UINT16ARRAY_ID = idof(); -export const ProviderData_ID = idof(); - -/** - * Some test class to verify wasm-js interoperability - */ -export class ProviderData { - name: string; - description: string; - manifestTxId: string; - - constructor(name: string, description: string, manifestTxId: string) { - this.name = name; - this.description = description; - this.manifestTxId = manifestTxId; - } - - toString(): string { - return ` - ProviderData - #name: ${this.name} - #description: ${this.description} - #manifestTxId: ${this.manifestTxId} - `; - } -} -/** - * WASM testing END - */ diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/api.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/api.ts deleted file mode 100644 index 3fc15dca..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/api.ts +++ /dev/null @@ -1,34 +0,0 @@ -export type ContractFn = (state: S, action: A) => HandlerResultSchema; - -@serializable -export class HandlerResultSchema { - state: S | null; - result: R | null; -} - -@serializable -export class SmartWeaveSchema { - contract: ContractSchema; - block: BlockSchema; - transaction: TransactionSchema; -} - -@serializable -export class BlockSchema { - height: i32; - indep_hash: string; - timestamp: i32; -} - -@serializable -export class TransactionSchema { - id: string; - owner: string; - target: string; -} - -@serializable -export class ContractSchema { - id: string; - owner: string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/console.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/console.ts deleted file mode 100644 index bdbf42a8..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/console.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare namespace console { - function logO(msg: string, data: string /* stringified json */): void; - function log(msg: string): void; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/index.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/index.ts deleted file mode 100644 index a676300b..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './console'; -export * from './api'; - -export { parse, stringify } from '@serial-as/json'; -export * from './smartweave/block'; -export * from './smartweave/contract'; -export * from './smartweave/msg'; -export * from './smartweave/transaction'; diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/block.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/block.ts deleted file mode 100644 index 89a8d6d5..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/block.ts +++ /dev/null @@ -1,5 +0,0 @@ -export declare namespace Block { - function height(): i32; - function indep_hash(): string; - function timestamp(): i32; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/contract.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/contract.ts deleted file mode 100644 index 7ed6cbc5..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/contract.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare namespace Contract { - function id(): string; - function owner(): string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/msg.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/msg.ts deleted file mode 100644 index e99330d2..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/msg.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare namespace msg { - function sender(): string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/transaction.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/transaction.ts deleted file mode 100644 index 571d7f07..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/imports/smartweave/transaction.ts +++ /dev/null @@ -1,8 +0,0 @@ -export declare namespace Transaction { - function id(): string; - function owner(): string; - function target(): string; - function tags(): Tag[]; -} - -export interface Tag {} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/schemas.ts b/src/__tests__/integration/data/wasm/as/assembly-evolve/schemas.ts deleted file mode 100644 index 1f76c283..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/schemas.ts +++ /dev/null @@ -1,20 +0,0 @@ -@serializable -export class StateSchema { - firstName: string; - lastName: string; - counter: i32; - canEvolve: boolean; - evolve: string; -} - -@serializable -export class ActionSchema { - function: string; - contractTxId: string | null; - value: string; -} - -@serializable -export class ResultSchema { - fullName: string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly-evolve/tsconfig.json b/src/__tests__/integration/data/wasm/as/assembly-evolve/tsconfig.json deleted file mode 100644 index 6911eafc..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly-evolve/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "assemblyscript/std/assembly.json", - "include": [ - "./**/*.ts", - "./contract.d.ts", - "../node_modules/@serial-as/core/assembly/as_types.d.ts" - ] -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/actions/decrement.ts b/src/__tests__/integration/data/wasm/as/assembly/actions/decrement.ts deleted file mode 100644 index 3a7dd900..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/actions/decrement.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {ContractResultSchema} from '../contract'; - -export function decrement(state: StateSchema, action: ActionSchema): ContractResultSchema { - state.counter -= 555; - - return { - state, - result: null - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/actions/evolve.ts b/src/__tests__/integration/data/wasm/as/assembly/actions/evolve.ts deleted file mode 100644 index 630d25c7..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/actions/evolve.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {Transaction} from '../imports/smartweave/transaction'; -import {Contract} from '../imports'; -import {ContractResultSchema} from '../contract'; - -export function evolve( - state: StateSchema, - action: ActionSchema -): ContractResultSchema { - const evolve = action.value; - const contractOwner = Contract.owner(); - const sender = Transaction.owner(); - - if (sender != contractOwner) { - throw new Error( - '[CE:EPE] Evolve permissions error - only contract owner can evolve' - ); - } - - if (!state.canEvolve) { - throw new Error('[CE:ECE] Evolve not allowed'); - } - - state.evolve = evolve; - - return { - state, - result: null, - }; -} \ No newline at end of file diff --git a/src/__tests__/integration/data/wasm/as/assembly/actions/fullName.ts b/src/__tests__/integration/data/wasm/as/assembly/actions/fullName.ts deleted file mode 100644 index c02e413e..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/actions/fullName.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {ContractResultSchema} from '../contract'; -import {ActionSchema, StateSchema} from '../schemas'; -import {console} from '../imports'; - -export function fullName(state: StateSchema, action: ActionSchema): ContractResultSchema { - console.log(`fullName called: "${action.function}"`); - console.log(`${state.firstName} ${state.lastName}`); - return { - state, - result: { - fullName: `${state.firstName} ${state.lastName}` - } - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/actions/increment.ts b/src/__tests__/integration/data/wasm/as/assembly/actions/increment.ts deleted file mode 100644 index 76d9ca87..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/actions/increment.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {ContractResultSchema} from '../contract'; - -export function increment(state: StateSchema, action: ActionSchema): ContractResultSchema { - state.counter++; - - return { - state, - result: null - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/actions/infLoop.ts b/src/__tests__/integration/data/wasm/as/assembly/actions/infLoop.ts deleted file mode 100644 index 1d14fb5b..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/actions/infLoop.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {ActionSchema, StateSchema} from '../schemas'; -import {ContractResultSchema} from '../contract'; - -export function infLoop(state: StateSchema, action: ActionSchema): ContractResultSchema { - while (true) {} - - return { - state, - result: null - }; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/arrays.ts b/src/__tests__/integration/data/wasm/as/assembly/arrays.ts deleted file mode 100644 index f13a5fc0..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/arrays.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const UINT8ARRAY_ID = idof(); -export const INT16ARRAY_ID = idof(); -export const UINT16ARRAY_ID = idof(); -export const INT32ARRAY_ID = idof(); -export const UINT32ARRAY_ID = idof(); -export const FLOAT32ARRAY_ID = idof(); -export const ARRAYI32_ID = idof>(); -export const STATICARRAYI32_ID = idof>(); -export const STATICARRAYU32_ID = idof>(); -export const STATICARRAYU8_ID = idof>(); -export const STATICARRAYI16_ID = idof>(); -export const STATICARRAYF32_ID = idof>(); diff --git a/src/__tests__/integration/data/wasm/as/assembly/contract.d.ts b/src/__tests__/integration/data/wasm/as/assembly/contract.d.ts deleted file mode 100644 index 05fa6bde..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/contract.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare function contract(a: any): any; diff --git a/src/__tests__/integration/data/wasm/as/assembly/contract.ts b/src/__tests__/integration/data/wasm/as/assembly/contract.ts deleted file mode 100644 index 2f196772..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/contract.ts +++ /dev/null @@ -1,65 +0,0 @@ -// common imports - do not remove (even if IDE reports as non-used)! -import { - Block, - console, - Contract, - ContractFn, - HandlerResultSchema, - SmartWeaveSchema, - stringify, - Transaction -} from "./imports"; - -// contract specific imports -import {increment} from "./actions/increment"; -import {decrement} from "./actions/decrement"; -import {fullName} from "./actions/fullName"; -import {infLoop} from "./actions/infLoop"; -import {evolve} from "./actions/evolve"; -import {ActionSchema, ResultSchema, StateSchema} from "./schemas"; - -const functions: Map> = new Map(); -functions.set("increment", increment); -functions.set("decrement", decrement); -functions.set("fullName", fullName); -functions.set("infLoop", infLoop); -functions.set("evolve", evolve); - -export type ContractResultSchema = HandlerResultSchema; - -let contractState: StateSchema; - -@contract -function handle(state: StateSchema, action: ActionSchema): ResultSchema | null { - console.log(`Function called: "${action.function}"`); - console.logO(`SmartWeave:`, stringify({ - contract: { - id: Contract.id(), - owner: Contract.owner() - }, - block: { - height: Block.height(), - indep_hash: Block.indep_hash(), - timestamp: Block.timestamp() - }, - transaction: { - id: Transaction.id(), - owner: Transaction.owner(), - target: Transaction.target() - } - })); - - const fn = action.function; - if (functions.has(fn)) { - const handlerResult = functions.get(fn)(state, action); - if (handlerResult.state != null) { - contractState = handlerResult.state!; - } - if (handlerResult.result != null) { - console.logO(`Result:`, stringify(handlerResult.result!)) - } - return handlerResult.result; - } else { - throw new Error(`[RE:WTF] Unknown function ${action.function}`); - } -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/fancy/AbstractERC20.ts b/src/__tests__/integration/data/wasm/as/assembly/fancy/AbstractERC20.ts deleted file mode 100644 index fd6ec126..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/fancy/AbstractERC20.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {ContractError, ERC20} from './ERC20'; -import {console} from '../imports/console'; -import {msg} from '../imports/smartweave/msg'; - -export abstract class AbstractERC20 implements ERC20 { - private _name: string; - private _symbol: string; - protected _totalSupply: u64; - protected readonly _balances: Map = new Map(); - protected readonly _allowances: Map> = new Map>(); - - protected constructor(name_: string, symbol_: string) { - this._name = name_; - this._symbol = symbol_; - this._totalSupply = 0; - } - - abstract mint(account: string, amount: u64): void; - abstract burn(account: string, amount: u64): void; - - transfer(recipient: string, amount: u64): void { - console.log(`transfer called ${recipient}: ${amount}`); - this._transfer(msg.sender(), recipient, amount); - } - - approve(spender: string, amount: u64): void { - const msgSender = msg.sender(); - if (!this._allowances.has(msgSender)) { - this._allowances.set(msgSender, new Map()); - } - if (!this._allowances.get(msgSender).has(spender)) { - this._allowances.get(msgSender).set(spender, amount); - } else { - let spenderAllowance: u64 = this._allowances.get(msgSender).get(spender); - spenderAllowance += amount; - this._allowances.get(msgSender).set(spender, spenderAllowance); - } - } - - protected _transfer(sender: string, recipient: string, amount: u64): void { - if (amount <= 0 || sender === recipient) { - throw new ContractError('Invalid token transfer'); - } - - let senderBalance = this._balances.get(sender); - if (senderBalance < amount) { - throw new ContractError(`Caller balance not high enough to send ${amount} token(s)!`); - } - senderBalance -= amount; - this._balances.set(sender, senderBalance); - - if (!this._balances.has(recipient)) { - this._balances.set(recipient, amount); - } else { - let recipientBalance = this._balances.get(sender); - recipientBalance += amount; - this._balances.set(recipient, recipientBalance); - } - } - - balanceOf(account: string): u64 { - console.log(`balanceOf called ${account}`); - if (this._balances.has(account)) { - return this._balances.get(account); - } else { - return 0; - } - } - - allowance(owner: string, spender: string): u64 { - console.log(`allowance called ${owner}: ${spender}`); - let result: u64 = 0; - if (this._allowances.has(owner) && this._allowances.get(owner).has(spender)) { - const ownerAllowances: Map = this._allowances.get(owner); - result = ownerAllowances.get(spender); - } - - return result; - } - - get totalSupply(): u64 { - return this._totalSupply; - } - - transferFrom(sender: string, recipient: string, amount: u64): void { - const msgSender = msg.sender(); - console.log(`transferFrom called ${sender}[${msgSender}] -> ${recipient}:${amount}`); - - if (!this._allowances.has(sender) || !this._allowances.get(sender).has(msgSender)) { - throw new ContractError(`No allowance for ${msgSender} from ${sender}`); - } - - let currentAllowance = this._allowances.get(sender).get(msgSender); - if (currentAllowance < amount) { - throw new ContractError(`Transfer amount exceeds allowance`); - } - currentAllowance -= amount; - this._allowances.get(sender).set(msgSender, currentAllowance); - this._transfer(sender, recipient, amount); - } - - get name(): string { - return this._name; - } - - get symbol(): string { - return this._symbol; - } - - set name(value: string) { - this._name = value; - } - - set symbol(value: string) { - this._symbol = value; - } -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/fancy/ERC20.ts b/src/__tests__/integration/data/wasm/as/assembly/fancy/ERC20.ts deleted file mode 100644 index f73799c1..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/fancy/ERC20.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface ERC20 { - // view functions - totalSupply: u64; - balanceOf(account: string): u64; - allowance(owner: string, spender: string): u64; - - // state changing functions - transfer(recipient: string, amount: u64): void; - approve(spender: string, amount: u64): void; - transferFrom(sender: string, recipient: string, amount: u64): void; -} - -// no custom exceptions support - throwing Exception -// effectively calls "abort" -export class ContractError extends Error { - constructor(message: string) { - super(message); - this.name = 'ContractError'; - } -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/fancy/RedStoneToken.ts b/src/__tests__/integration/data/wasm/as/assembly/fancy/RedStoneToken.ts deleted file mode 100644 index 4f7afc61..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/fancy/RedStoneToken.ts +++ /dev/null @@ -1,125 +0,0 @@ -import {AbstractERC20} from './AbstractERC20'; -import {console} from '../imports/console'; -import {ContractError} from './ERC20'; -import {setTimeout} from '../imports/api'; -import {msg} from '../imports/smartweave/msg'; - -export class RedStoneToken extends AbstractERC20 { - constructor(name_: string, symbol_: string) { - super(name_, symbol_); - } - - burn(account: string, amount: u64): void { - console.log(`burn called ${account}: ${amount}`); - const msgSender = msg.sender(); - if (account != msgSender) { - throw new ContractError('Only account owner can burn his tokens'); - } - if (!this._balances.has(account)) { - throw new ContractError('Account has no balance'); - } - - if (this._balances.get(account) < amount) { - throw new ContractError('Account has not enough balance'); - } - - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance - amount); - this._totalSupply -= amount; - } - - mint(account: string, amount: u64): void { - console.log(`mint called ${account}: ${amount}`); - - if (this._balances.has(account)) { - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance + amount); - } else { - this._balances.set(account, amount); - } - this._totalSupply += amount; - } - - // just for tests. - private _structField: ProviderData = new ProviderData( - 'RedStone Provider', - 'RedStone Provider desc', - 'RedStone Provider manifest' - ); - - private _arrayField: Uint16Array = new Uint16Array(10); - - /** - * WASM testing BEGIN - */ - testTimeout(milliseconds: f32): void { - let timeout: i32 = 0; - - timeout = setTimeout((providerData: ProviderData) => { - console.log('After timeout: ' + providerData.name); - // no closures support - // clearTimeout(timeout); - }, milliseconds); - } - - get structField(): ProviderData { - return this._structField; - } - - get arrayField(): Uint16Array { - return this._arrayField; - } - - set arrayField(value: Uint16Array) { - console.log(`arrayField called ${value}`); - this._arrayField = value; - } - - modifyProviderDataArray(data: ProviderData[]): ProviderData[] { - console.log('modifyProviderDataArray'); - return data.map((pd) => { - pd.name += ' WASM'; - return pd; - }); - } - - /** - * WASM testing END - */ -} - -export const UINT16ARRAY_ID = idof(); -export const ProviderData_ID = idof(); -/** - * WASM testing BEGIN - */ -export function getToken(): RedStoneToken { - return new RedStoneToken('RedStone', 'RDST'); -} - -/** - * Some test class to verify wasm-js interoperability - */ -export class ProviderData { - name: string; - description: string; - manifestTxId: string; - - constructor(name: string, description: string, manifestTxId: string) { - this.name = name; - this.description = description; - this.manifestTxId = manifestTxId; - } - - toString(): string { - return ` - ProviderData - #name: ${this.name} - #description: ${this.description} - #manifestTxId: ${this.manifestTxId} - `; - } -} -/** - * WASM testing END - */ diff --git a/src/__tests__/integration/data/wasm/as/assembly/fancy/RedStoneToken_old.ts b/src/__tests__/integration/data/wasm/as/assembly/fancy/RedStoneToken_old.ts deleted file mode 100644 index 560eed40..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/fancy/RedStoneToken_old.ts +++ /dev/null @@ -1,242 +0,0 @@ -import {ContractError, ERC20} from './ERC20'; -import {console} from '../imports/console'; -import {Block} from '../imports/smartweave/block'; -import {Transaction} from '../imports/smartweave/transaction'; -import {Contract} from '../imports/smartweave/contract'; -import {msg} from '../imports/smartweave/msg'; -import {setTimeout} from '../imports/api'; - -export class RedStoneToken_old implements ERC20 { - private readonly _name: string; - - private readonly _symbol: string; - - private _totalSupply: u64; - - private readonly _balances: Map = new Map(); - - private readonly _allowances: Map> = new Map>(); - - // just for tests. - private _structField: ProviderData = new ProviderData( - 'RedStone Provider', - 'RedStone Provider desc', - 'RedStone Provider manifest' - ); - - private _arrayField: Uint16Array = new Uint16Array(10); - - constructor(name_: string, symbol_: string) { - this._name = name_; - this._symbol = symbol_; - this._totalSupply = 0; - - /** - * WASM testing BEGIN - */ - console.log(`Constructor: ${this._structField.toString()}`); - console.log(`Block#height: ${Block.height()}`); - console.log(`Block#indep_hash: ${Block.indep_hash()}`); - console.log(`Block#timestamp: ${Block.timestamp()}`); - - console.log(`Transaction#id: ${Transaction.id()}`); - console.log(`Transaction#owner: ${Transaction.owner()}`); - console.log(`Transaction#target: ${Transaction.target()}`); - - console.log(`Contract#id: ${Contract.id()}`); - console.log(`Contract#owner: ${Contract.owner()}`); - - console.log(`msg#sender: ${msg.sender()}`); - /** - * WASM testing END - */ - } - - get totalSupply(): u64 { - return this._totalSupply; - } - - balanceOf(account: string): u64 { - console.log(`balanceOf called ${account}`); - if (this._balances.has(account)) { - return this._balances.get(account); - } else { - return 0; - } - } - - allowance(owner: string, spender: string): u64 { - console.log(`allowance called ${owner}: ${spender}`); - let result: u64 = 0; - if (this._allowances.has(owner) && this._allowances.get(owner).has(spender)) { - const ownerAllowances: Map = this._allowances.get(owner); - result = ownerAllowances.get(spender); - } - - return result; - } - - transfer(recipient: string, amount: u64): void { - console.log(`transfer called ${recipient}: ${amount}`); - this._transfer(msg.sender(), recipient, amount); - } - - approve(spender: string, amount: u64): void { - const msgSender = msg.sender(); - if (!this._allowances.has(msgSender)) { - this._allowances.set(msgSender, new Map()); - } - if (!this._allowances.get(msgSender).has(spender)) { - this._allowances.get(msgSender).set(spender, amount); - } - } - - transferFrom(sender: string, recipient: string, amount: u64): void { - const msgSender = msg.sender(); - console.log(`transferFrom called ${sender}[${msgSender}] -> ${recipient}:${amount}`); - - if (!this._allowances.has(sender) || !this._allowances.get(sender).has(msgSender)) { - throw new ContractError(`No allowance for ${msgSender} from ${sender}`); - } - - let currentAllowance = this._allowances.get(sender).get(msgSender); - if (currentAllowance < amount) { - throw new ContractError(`Transfer amount exceeds allowance`); - } - currentAllowance -= amount; - this._allowances.get(sender).set(msgSender, currentAllowance); - this._transfer(sender, recipient, amount); - } - - // TODO: ownership - mint(account: string, amount: u64): void { - console.log(`mint called ${account}: ${amount}`); - - if (this._balances.has(account)) { - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance + amount); - } else { - this._balances.set(account, amount); - } - this._totalSupply += amount; - } - - // TODO: ownership - burn(account: string, amount: u64): void { - console.log(`burn called ${account}: ${amount}`); - if (!this._balances.has(account)) { - throw new ContractError('Account has no balance'); - } - - if (this._balances.get(account) < amount) { - throw new ContractError('Account has not enough balance'); - } - - const currentBalance = this._balances.get(account); - this._balances.set(account, currentBalance - amount); - this._totalSupply -= amount; - } - - get name(): string { - return this._name; - } - - get symbol(): string { - return this._symbol; - } - - private _transfer(sender: string, recipient: string, amount: u64): void { - if (amount <= 0 || sender === recipient) { - throw new ContractError('Invalid token transfer'); - } - - let senderBalance = this._balances.get(sender); - if (senderBalance < amount) { - throw new ContractError(`Caller balance not high enough to send ${amount} token(s)!`); - } - senderBalance -= amount; - this._balances.set(sender, senderBalance); - - if (!this._balances.has(recipient)) { - this._balances.set(recipient, amount); - } else { - let recipientBalance = this._balances.get(sender); - recipientBalance += amount; - this._balances.set(recipient, recipientBalance); - } - } - - /** - * WASM testing BEGIN - */ - testTimeout(milliseconds: f32): void { - let timeout: i32 = 0; - - timeout = setTimeout((providerData: ProviderData) => { - console.log('After timeout: ' + providerData.name); - // no closures support - // clearTimeout(timeout); - }, milliseconds); - } - - get structField(): ProviderData { - return this._structField; - } - - get arrayField(): Uint16Array { - return this._arrayField; - } - - set arrayField(value: Uint16Array) { - console.log(`arrayField called ${value}`); - this._arrayField = value; - } - - modifyProviderDataArray(data: ProviderData[]): ProviderData[] { - console.log('modifyProviderDataArray'); - return data.map((pd) => { - pd.name += ' WASM'; - return pd; - }); - } - /** - * WASM testing END - */ -} - -/** - * WASM testing BEGIN - */ -export function getToken(): RedStoneToken_old { - return new RedStoneToken_old('RedStone', 'RDST'); -} - -export const UINT16ARRAY_ID = idof(); -export const ProviderData_ID = idof(); - -/** - * Some test class to verify wasm-js interoperability - */ -export class ProviderData { - name: string; - description: string; - manifestTxId: string; - - constructor(name: string, description: string, manifestTxId: string) { - this.name = name; - this.description = description; - this.manifestTxId = manifestTxId; - } - - toString(): string { - return ` - ProviderData - #name: ${this.name} - #description: ${this.description} - #manifestTxId: ${this.manifestTxId} - `; - } -} -/** - * WASM testing END - */ diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/api.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/api.ts deleted file mode 100644 index 3fc15dca..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/api.ts +++ /dev/null @@ -1,34 +0,0 @@ -export type ContractFn = (state: S, action: A) => HandlerResultSchema; - -@serializable -export class HandlerResultSchema { - state: S | null; - result: R | null; -} - -@serializable -export class SmartWeaveSchema { - contract: ContractSchema; - block: BlockSchema; - transaction: TransactionSchema; -} - -@serializable -export class BlockSchema { - height: i32; - indep_hash: string; - timestamp: i32; -} - -@serializable -export class TransactionSchema { - id: string; - owner: string; - target: string; -} - -@serializable -export class ContractSchema { - id: string; - owner: string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/console.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/console.ts deleted file mode 100644 index bdbf42a8..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/console.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare namespace console { - function logO(msg: string, data: string /* stringified json */): void; - function log(msg: string): void; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/index.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/index.ts deleted file mode 100644 index a676300b..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './console'; -export * from './api'; - -export { parse, stringify } from '@serial-as/json'; -export * from './smartweave/block'; -export * from './smartweave/contract'; -export * from './smartweave/msg'; -export * from './smartweave/transaction'; diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/block.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/block.ts deleted file mode 100644 index 89a8d6d5..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/block.ts +++ /dev/null @@ -1,5 +0,0 @@ -export declare namespace Block { - function height(): i32; - function indep_hash(): string; - function timestamp(): i32; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/contract.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/contract.ts deleted file mode 100644 index 7ed6cbc5..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/contract.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare namespace Contract { - function id(): string; - function owner(): string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/msg.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/msg.ts deleted file mode 100644 index e99330d2..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/msg.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare namespace msg { - function sender(): string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/transaction.ts b/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/transaction.ts deleted file mode 100644 index 571d7f07..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/imports/smartweave/transaction.ts +++ /dev/null @@ -1,8 +0,0 @@ -export declare namespace Transaction { - function id(): string; - function owner(): string; - function target(): string; - function tags(): Tag[]; -} - -export interface Tag {} diff --git a/src/__tests__/integration/data/wasm/as/assembly/schemas.ts b/src/__tests__/integration/data/wasm/as/assembly/schemas.ts deleted file mode 100644 index 1f76c283..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/schemas.ts +++ /dev/null @@ -1,20 +0,0 @@ -@serializable -export class StateSchema { - firstName: string; - lastName: string; - counter: i32; - canEvolve: boolean; - evolve: string; -} - -@serializable -export class ActionSchema { - function: string; - contractTxId: string | null; - value: string; -} - -@serializable -export class ResultSchema { - fullName: string; -} diff --git a/src/__tests__/integration/data/wasm/as/assembly/tsconfig.json b/src/__tests__/integration/data/wasm/as/assembly/tsconfig.json deleted file mode 100644 index 6911eafc..00000000 --- a/src/__tests__/integration/data/wasm/as/assembly/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "assemblyscript/std/assembly.json", - "include": [ - "./**/*.ts", - "./contract.d.ts", - "../node_modules/@serial-as/core/assembly/as_types.d.ts" - ] -} diff --git a/src/__tests__/integration/data/wasm/as/assemblyscript-counter-evolve.wasm b/src/__tests__/integration/data/wasm/as/assemblyscript-counter-evolve.wasm deleted file mode 100644 index 03e5137b..00000000 Binary files a/src/__tests__/integration/data/wasm/as/assemblyscript-counter-evolve.wasm and /dev/null differ diff --git a/src/__tests__/integration/data/wasm/as/assemblyscript-counter.wasm b/src/__tests__/integration/data/wasm/as/assemblyscript-counter.wasm deleted file mode 100644 index be8165c8..00000000 Binary files a/src/__tests__/integration/data/wasm/as/assemblyscript-counter.wasm and /dev/null differ diff --git a/src/__tests__/integration/data/wasm/go/go-pst-evolve.wasm b/src/__tests__/integration/data/wasm/go/go-pst-evolve.wasm deleted file mode 100755 index fcbbcfea..00000000 Binary files a/src/__tests__/integration/data/wasm/go/go-pst-evolve.wasm and /dev/null differ diff --git a/src/__tests__/integration/data/wasm/go/go-pst.wasm b/src/__tests__/integration/data/wasm/go/go-pst.wasm deleted file mode 100755 index 10a894a0..00000000 Binary files a/src/__tests__/integration/data/wasm/go/go-pst.wasm and /dev/null differ diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/async.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/async.go deleted file mode 100644 index 295228ff..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/async.go +++ /dev/null @@ -1,43 +0,0 @@ -package common - -import ( - "math/rand" - "syscall/js" -) - -func Await(awaitable js.Value) ([]js.Value, []js.Value) { - then := make(chan []js.Value) - defer close(then) - thenFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - then <- args - return nil - }) - defer thenFunc.Release() - - catch := make(chan []js.Value) - defer close(catch) - catchFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - catch <- args - return nil - }) - defer catchFunc.Release() - - awaitable.Call("then", thenFunc).Call("catch", catchFunc) - - select { - case result := <-then: - return result, nil - case err := <-catch: - return nil, err - } -} - -var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -func RandSeq(n int) string { - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] - } - return string(b) -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/block/imports.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/block/imports.go deleted file mode 100644 index 401aaf12..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/block/imports.go +++ /dev/null @@ -1,22 +0,0 @@ -package block - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func IndepHash() string { - return importBlock().Call("indep_hash").String() -} - -func Height() int { - return importBlock().Call("height").Int() -} - -func Timestamp() int { - return importBlock().Call("timestamp").Int() -} - -func importBlock() js.Value { - return imports.RedStone().Get("Block") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/console/imports.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/console/imports.go deleted file mode 100644 index a6bf7e49..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/console/imports.go +++ /dev/null @@ -1,14 +0,0 @@ -package console - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func Log(args ...interface{}) { - importConsole().Call("log", args[0], args[1:]) -} - -func importConsole() js.Value { - return imports.RedStone().Get("console") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/contract/imports.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/contract/imports.go deleted file mode 100644 index 6510a55c..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/contract/imports.go +++ /dev/null @@ -1,18 +0,0 @@ -package contract - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func Id() string { - return importContract().Call("id").String() -} - -func Owner() string { - return importContract().Call("owner").String() -} - -func importContract() js.Value { - return imports.RedStone().Get("Contract") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/global.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/global.go deleted file mode 100644 index 085baed7..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/global.go +++ /dev/null @@ -1,14 +0,0 @@ -package imports - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common" - "syscall/js" -) - -func RedStone() js.Value { - return js.Global(). - Get("redstone"). - Get("go"). - Get(common.GetWasmInstance().ModuleId). - Get("imports") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/smartweave/imports.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/smartweave/imports.go deleted file mode 100644 index 431be094..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/smartweave/imports.go +++ /dev/null @@ -1,18 +0,0 @@ -package smartweave - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func ReadContractState(contractTxId string) js.Value { - promise := importSmartWeave().Call("readContractState", contractTxId).JSValue() - result, _ := common.Await(promise) - - return result[0] -} - -func importSmartWeave() js.Value { - return imports.RedStone().Get("SmartWeave") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/transaction/imports.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/transaction/imports.go deleted file mode 100644 index 88ecf7b6..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/transaction/imports.go +++ /dev/null @@ -1,22 +0,0 @@ -package transaction - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func Id() string { - return importTransaction().Call("id").String() -} - -func Owner() string { - return importTransaction().Call("owner").String() -} - -func Target() string { - return importTransaction().Call("target").String() -} - -func importTransaction() js.Value { - return imports.RedStone().Get("Transaction") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/wasm_module/imports.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/wasm_module/imports.go deleted file mode 100644 index 4c768794..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/imports/wasm_module/imports.go +++ /dev/null @@ -1,13 +0,0 @@ -package wasm_module - -import ( - "syscall/js" -) - -func RegisterWasmModule(wasmModuleId string) { - importModule().Call("registerWasmModule", wasmModuleId) -} - -func importModule() js.Value { - return js.Global().Get("redstone").Get("go").Get("WasmModule") -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common/wasm.go b/src/__tests__/integration/data/wasm/go/src-evolve/common/wasm.go deleted file mode 100644 index 50003512..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common/wasm.go +++ /dev/null @@ -1,134 +0,0 @@ -package common - -import ( - "encoding/json" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/wasm_module" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common_types" - "math/rand" - "syscall/js" - "time" -) - -type WasmInstance struct { - ModuleId string -} - -var singleton *WasmInstance - -func GetWasmInstance() *WasmInstance { - // it is not thread safe, but wasm is single-threaded - // alternatively could use sync.Once - but it would increase the binary size. - if singleton == nil { - singleton = &WasmInstance{} - } - return singleton -} - -func Run(contract common_types.SwContract) { - // generating random module id and registering it on host - // a workaround for potential wasm modules collision - rand.Seed(time.Now().UnixNano()) - moduleId := RandSeq(20) - - js.Global().Set(moduleId, make(map[string]interface{})) - wasmModule := js.Global().Get(moduleId) - // the Go way of defining WASM exports... - // standard "exports" from the wasm module do not work here... - // that's kinda ugly TBH - wasmModule.Set("handle", handle(contract)) - wasmModule.Set("initState", initState(contract)) - wasmModule.Set("currentState", currentState(contract)) - wasmModule.Set("lang", lang()) - wasmModule.Set("version", version()) - - GetWasmInstance().ModuleId = moduleId - wasm_module.RegisterWasmModule(moduleId) - - // Prevent the function from returning, which is required in a wasm module - // i.e. "Error: Go program has already exited" is thrown otherwise on host - <-make(chan bool) -} - -func handle(contract common_types.SwContract) js.Func { - // note: each 'exported' function has to be wrapped into - // js.FuncOf(func(this js.Value, args []js.Value) interface{} - // - that's kinda ugly too... - return js.FuncOf(func(this js.Value, handleArgs []js.Value) interface{} { - - // exception handling - promisifiedHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - resolve := args[0] - reject := args[1] - - go func() { - actionJson := handleArgs[0].String() - var action common_types.Action - err := action.UnmarshalJSON([]byte(actionJson)) - if err != nil { - doReject(err, reject) - } - - _, err = json.Marshal(action) - if err != nil { - doReject(err, reject) - } - - state, result, err := contract.Handle(action, []byte(actionJson)) - - if err != nil { - // err should be an instance of `error`, eg `errors.New("some error")` - doReject(err, reject) - } else { - if state != nil { - contract.UpdateState(state) - } - resultMarshalled, _ := json.Marshal(result) - resolve.Invoke(string(resultMarshalled)) - } - }() - - return nil - }) - - promiseConstructor := js.Global().Get("Promise") - return promiseConstructor.New(promisifiedHandler) - }) -} - -func doReject(err error, reject js.Value) { - errorConstructor := js.Global().Get("Error") - errorObject := errorConstructor.New(err.Error()) - reject.Invoke(errorObject) -} - -func currentState(contract common_types.SwContract) interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - data, _ := json.Marshal(contract.CurrentState()) - return string(data) - }) -} - -func initState(contract common_types.SwContract) interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - contract.InitState(args[0].String()) - return nil - }) -} - -func version() interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - return 1 - }) -} - -// Lang workaround for now to simplify type reading without as/loader or wasm-bindgen -// 1 = assemblyscript -// 2 = rust -// 3 = go -// 4 = swift -// 5 = c -func lang() interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - return 3 - }) -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common_types/types.go b/src/__tests__/integration/data/wasm/go/src-evolve/common_types/types.go deleted file mode 100644 index a329bace..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common_types/types.go +++ /dev/null @@ -1,20 +0,0 @@ -package common_types - -type Action struct { - Function string `json:"function"` -} - -type ActionResult = interface{} - -// SwContract We need to use "any" (interface{}) type here for the state - as this is -// a common interface for all contracts implemented in Go WASM. -// Version with generics is available on branch ppe/go-generics (but to use it real life -// we need to wait for the official release of Go 1.18 and tinygo compiler with generics -// support added - https://github.com/tinygo-org/tinygo/issues/2158) -//easyjson:skip -type SwContract interface { - Handle(action Action, actionBytes []byte) (interface{}, ActionResult, error) - InitState(stateJson string) - UpdateState(newState interface{}) - CurrentState() interface{} -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/common_types/types_easyjson.go b/src/__tests__/integration/data/wasm/go/src-evolve/common_types/types_easyjson.go deleted file mode 100644 index de04b869..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/common_types/types_easyjson.go +++ /dev/null @@ -1,85 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package common_types - -import ( - json "encoding/json" - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(in *jlexer.Lexer, out *Action) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(out *jwriter.Writer, in Action) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"function\":" - out.RawString(prefix[1:]) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v Action) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v Action) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *Action) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Action) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(l, v) -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/impl/actions.go b/src/__tests__/integration/data/wasm/go/src-evolve/impl/actions.go deleted file mode 100644 index 2e58c56a..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/impl/actions.go +++ /dev/null @@ -1,75 +0,0 @@ -package impl - -import ( - "errors" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/smartweave" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/transaction" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/types" -) - -func Transfer(state types.PstState, action types.TransferAction) (*types.PstState, error) { - if action.Qty == 0 { - return nil, errors.New("[CE:ITQ] invalid transfer qty") - } - - caller := transaction.Owner() - - if callerBalance, ok := state.Balances[caller]; ok { - if callerBalance < action.Qty { - return nil, errors.New("[CE:CBNE] caller balance not enough: " + string(state.Balances[caller])) - } - - callerBalance -= action.Qty - state.Balances[caller] = callerBalance - - if targetBalance, ok := state.Balances[action.Target]; ok { - targetBalance += (action.Qty + 200) - state.Balances[action.Target] = targetBalance - } else { - state.Balances[action.Target] = action.Qty - } - - } else { - return nil, errors.New("[CE:CNF] caller not found: " + caller) - } - - return &state, nil -} - -func Balance(state types.PstState, action types.BalanceAction) (*types.BalanceResult, error) { - if targetBalance, ok := state.Balances[action.Target]; ok { - return &types.BalanceResult{ - Balance: targetBalance, - }, nil - } else { - return nil, errors.New("[CE:TNF] target not found: " + action.Target) - } -} - -func ForeignCall(state types.PstState, action types.ForeignCallAction) (*types.PstState, error) { - if action.ContractTxId == "bad_contract" { - return nil, errors.New("[CE:WFC] Wrong foreign contract") - } - - result := smartweave.ReadContractState(action.ContractTxId) - if result.Get("ticker").String() == "FOREIGN_PST" { - for key, _ := range state.Balances { - state.Balances[key] += 1000 - } - } - - return &state, nil -} - -func Evolve(state types.PstState, action types.EvolveAction) (*types.PstState, error) { - if !state.CanEvolve { - return nil, errors.New("[CE:ENA] Evolve not allowed") - } - if state.Owner != transaction.Owner() { - return nil, errors.New("[CE:OOE] Only owner can evolve") - } - - state.Evolve = action.Value - - return &state, nil -} \ No newline at end of file diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/impl/pst-contract.go b/src/__tests__/integration/data/wasm/go/src-evolve/impl/pst-contract.go deleted file mode 100644 index 7da21a52..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/impl/pst-contract.go +++ /dev/null @@ -1,99 +0,0 @@ -package impl - -import ( - "errors" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/block" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/console" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common_types" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/types" -) - -type PstContract struct { - state types.PstState -} - -// Handle the function that contract developers actually need to implement -func (c *PstContract) Handle(action common_types.Action, actionBytes []byte) (interface{}, common_types.ActionResult, error) { - fn := action.Function - console.Log("Calling", fn) - - console.Log("Block height", block.Height()) - console.Log("Block indep_hash", block.IndepHash()) - console.Log("Block timestamp", block.Timestamp()) - - clonedState := c.CloneState().(types.PstState) - - switch fn { - case "transfer": - // not sure how to "automatically" handle casting to concrete action impl in Go. - // https://eagain.net/articles/go-json-kind/ - // https://eagain.net/articles/go-dynamic-json/ - var transfer types.TransferAction - err := transfer.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - state, err := Transfer(clonedState, transfer) - return state, nil, err - case "evolve": - var evolve types.EvolveAction - err := evolve.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - state, err := Evolve(clonedState, evolve) - return state, nil, err - case "balance": - var balance types.BalanceAction - err := balance.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - result, err := Balance(clonedState, balance) - return nil, result, err - case "foreignCall": - var foreignCall types.ForeignCallAction - err := foreignCall.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - state, err := ForeignCall(clonedState, foreignCall) - return state, nil, err - default: - return nil, nil, errors.New("[RE:WTF] unknown function: " + fn) - } -} - -func (c *PstContract) InitState(stateJson string) { - var state types.PstState - err := state.UnmarshalJSON([]byte(stateJson)) - if err != nil { - return // TODO: throw in a similar way as in handle - } - c.UpdateState(&state) -} - -func (c *PstContract) UpdateState(newState interface{}) { - // note: we're first type asserting here to the pointer to types.PstState - // - and the retrieving value from the pointer - c.state = *(newState.(*types.PstState)) -} - -func (c *PstContract) CurrentState() interface{} { - return c.state -} - -// CloneState TODO: discuss whether it is necessary -// it allows to make the given action transactional, but -// at the cost of performance -func (c *PstContract) CloneState() interface{} { - json, _ := c.state.MarshalJSON() - state := types.PstState{} - err := state.UnmarshalJSON(json) - if err != nil { - // TODO: return error - return types.PstState{} - } - - return state -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/main.go b/src/__tests__/integration/data/wasm/go/src-evolve/main.go deleted file mode 100644 index f2f6ed79..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/impl" -) - -// contract - implementation of the SwContract interface -var contract = impl.PstContract{} - -// handles all the WASM-JS related trickery... -func main() { - common.Run(&contract) -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/types/types.go b/src/__tests__/integration/data/wasm/go/src-evolve/types/types.go deleted file mode 100644 index b43c81b8..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/types/types.go +++ /dev/null @@ -1,39 +0,0 @@ -package types - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common_types" -) - -type PstState struct { - Ticker string `json:"ticker"` - Name string `json:"name"` - Owner string `json:"owner"` - Evolve string `json:"evolve"` - CanEvolve bool `json:"canEvolve"` - Balances map[string]uint64 `json:"balances"` -} - -type TransferAction struct { - common_types.Action - Target string `json:"target"` - Qty uint64 `json:"qty"` -} - -type EvolveAction struct { - common_types.Action - Value string `json:"value"` -} - -type BalanceAction struct { - common_types.Action - Target string `json:"target"` -} - -type ForeignCallAction struct { - common_types.Action - ContractTxId string `json:"contractTxId"` -} - -type BalanceResult struct { - Balance uint64 `json:"balance"` -} diff --git a/src/__tests__/integration/data/wasm/go/src-evolve/types/types_easyjson.go b/src/__tests__/integration/data/wasm/go/src-evolve/types/types_easyjson.go deleted file mode 100644 index f6462484..00000000 --- a/src/__tests__/integration/data/wasm/go/src-evolve/types/types_easyjson.go +++ /dev/null @@ -1,515 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package types - -import ( - json "encoding/json" - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(in *jlexer.Lexer, out *TransferAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "target": - out.Target = string(in.String()) - case "qty": - out.Qty = uint64(in.Uint64()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(out *jwriter.Writer, in TransferAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"target\":" - out.RawString(prefix[1:]) - out.String(string(in.Target)) - } - { - const prefix string = ",\"qty\":" - out.RawString(prefix) - out.Uint64(uint64(in.Qty)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v TransferAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v TransferAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *TransferAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *TransferAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(in *jlexer.Lexer, out *PstState) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "ticker": - out.Ticker = string(in.String()) - case "name": - out.Name = string(in.String()) - case "owner": - out.Owner = string(in.String()) - case "evolve": - out.Evolve = string(in.String()) - case "canEvolve": - out.CanEvolve = bool(in.Bool()) - case "balances": - if in.IsNull() { - in.Skip() - } else { - in.Delim('{') - out.Balances = make(map[string]uint64) - for !in.IsDelim('}') { - key := string(in.String()) - in.WantColon() - var v1 uint64 - v1 = uint64(in.Uint64()) - (out.Balances)[key] = v1 - in.WantComma() - } - in.Delim('}') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(out *jwriter.Writer, in PstState) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"ticker\":" - out.RawString(prefix[1:]) - out.String(string(in.Ticker)) - } - { - const prefix string = ",\"name\":" - out.RawString(prefix) - out.String(string(in.Name)) - } - { - const prefix string = ",\"owner\":" - out.RawString(prefix) - out.String(string(in.Owner)) - } - { - const prefix string = ",\"evolve\":" - out.RawString(prefix) - out.String(string(in.Evolve)) - } - { - const prefix string = ",\"canEvolve\":" - out.RawString(prefix) - out.Bool(bool(in.CanEvolve)) - } - { - const prefix string = ",\"balances\":" - out.RawString(prefix) - if in.Balances == nil && (out.Flags&jwriter.NilMapAsEmpty) == 0 { - out.RawString(`null`) - } else { - out.RawByte('{') - v2First := true - for v2Name, v2Value := range in.Balances { - if v2First { - v2First = false - } else { - out.RawByte(',') - } - out.String(string(v2Name)) - out.RawByte(':') - out.Uint64(uint64(v2Value)) - } - out.RawByte('}') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v PstState) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v PstState) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *PstState) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *PstState) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(in *jlexer.Lexer, out *ForeignCallAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "contractTxId": - out.ContractTxId = string(in.String()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(out *jwriter.Writer, in ForeignCallAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"contractTxId\":" - out.RawString(prefix[1:]) - out.String(string(in.ContractTxId)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v ForeignCallAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v ForeignCallAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *ForeignCallAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *ForeignCallAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(in *jlexer.Lexer, out *EvolveAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "value": - out.Value = string(in.String()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(out *jwriter.Writer, in EvolveAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"value\":" - out.RawString(prefix[1:]) - out.String(string(in.Value)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v EvolveAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v EvolveAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *EvolveAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *EvolveAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(in *jlexer.Lexer, out *BalanceResult) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "balance": - out.Balance = uint64(in.Uint64()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(out *jwriter.Writer, in BalanceResult) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"balance\":" - out.RawString(prefix[1:]) - out.Uint64(uint64(in.Balance)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v BalanceResult) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v BalanceResult) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *BalanceResult) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *BalanceResult) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(in *jlexer.Lexer, out *BalanceAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "target": - out.Target = string(in.String()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(out *jwriter.Writer, in BalanceAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"target\":" - out.RawString(prefix[1:]) - out.String(string(in.Target)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v BalanceAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v BalanceAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *BalanceAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *BalanceAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(l, v) -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/async.go b/src/__tests__/integration/data/wasm/go/src/common/async.go deleted file mode 100644 index 295228ff..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/async.go +++ /dev/null @@ -1,43 +0,0 @@ -package common - -import ( - "math/rand" - "syscall/js" -) - -func Await(awaitable js.Value) ([]js.Value, []js.Value) { - then := make(chan []js.Value) - defer close(then) - thenFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - then <- args - return nil - }) - defer thenFunc.Release() - - catch := make(chan []js.Value) - defer close(catch) - catchFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - catch <- args - return nil - }) - defer catchFunc.Release() - - awaitable.Call("then", thenFunc).Call("catch", catchFunc) - - select { - case result := <-then: - return result, nil - case err := <-catch: - return nil, err - } -} - -var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -func RandSeq(n int) string { - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] - } - return string(b) -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/block/imports.go b/src/__tests__/integration/data/wasm/go/src/common/imports/block/imports.go deleted file mode 100644 index 401aaf12..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/block/imports.go +++ /dev/null @@ -1,22 +0,0 @@ -package block - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func IndepHash() string { - return importBlock().Call("indep_hash").String() -} - -func Height() int { - return importBlock().Call("height").Int() -} - -func Timestamp() int { - return importBlock().Call("timestamp").Int() -} - -func importBlock() js.Value { - return imports.RedStone().Get("Block") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/console/imports.go b/src/__tests__/integration/data/wasm/go/src/common/imports/console/imports.go deleted file mode 100644 index a6bf7e49..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/console/imports.go +++ /dev/null @@ -1,14 +0,0 @@ -package console - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func Log(args ...interface{}) { - importConsole().Call("log", args[0], args[1:]) -} - -func importConsole() js.Value { - return imports.RedStone().Get("console") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/contract/imports.go b/src/__tests__/integration/data/wasm/go/src/common/imports/contract/imports.go deleted file mode 100644 index 6510a55c..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/contract/imports.go +++ /dev/null @@ -1,18 +0,0 @@ -package contract - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func Id() string { - return importContract().Call("id").String() -} - -func Owner() string { - return importContract().Call("owner").String() -} - -func importContract() js.Value { - return imports.RedStone().Get("Contract") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/global.go b/src/__tests__/integration/data/wasm/go/src/common/imports/global.go deleted file mode 100644 index 085baed7..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/global.go +++ /dev/null @@ -1,14 +0,0 @@ -package imports - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common" - "syscall/js" -) - -func RedStone() js.Value { - return js.Global(). - Get("redstone"). - Get("go"). - Get(common.GetWasmInstance().ModuleId). - Get("imports") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/smartweave/imports.go b/src/__tests__/integration/data/wasm/go/src/common/imports/smartweave/imports.go deleted file mode 100644 index 431be094..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/smartweave/imports.go +++ /dev/null @@ -1,18 +0,0 @@ -package smartweave - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func ReadContractState(contractTxId string) js.Value { - promise := importSmartWeave().Call("readContractState", contractTxId).JSValue() - result, _ := common.Await(promise) - - return result[0] -} - -func importSmartWeave() js.Value { - return imports.RedStone().Get("SmartWeave") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/transaction/imports.go b/src/__tests__/integration/data/wasm/go/src/common/imports/transaction/imports.go deleted file mode 100644 index 88ecf7b6..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/transaction/imports.go +++ /dev/null @@ -1,22 +0,0 @@ -package transaction - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports" - "syscall/js" -) - -func Id() string { - return importTransaction().Call("id").String() -} - -func Owner() string { - return importTransaction().Call("owner").String() -} - -func Target() string { - return importTransaction().Call("target").String() -} - -func importTransaction() js.Value { - return imports.RedStone().Get("Transaction") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/imports/wasm_module/imports.go b/src/__tests__/integration/data/wasm/go/src/common/imports/wasm_module/imports.go deleted file mode 100644 index 4c768794..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/imports/wasm_module/imports.go +++ /dev/null @@ -1,13 +0,0 @@ -package wasm_module - -import ( - "syscall/js" -) - -func RegisterWasmModule(wasmModuleId string) { - importModule().Call("registerWasmModule", wasmModuleId) -} - -func importModule() js.Value { - return js.Global().Get("redstone").Get("go").Get("WasmModule") -} diff --git a/src/__tests__/integration/data/wasm/go/src/common/wasm.go b/src/__tests__/integration/data/wasm/go/src/common/wasm.go deleted file mode 100644 index 50003512..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common/wasm.go +++ /dev/null @@ -1,134 +0,0 @@ -package common - -import ( - "encoding/json" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/wasm_module" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common_types" - "math/rand" - "syscall/js" - "time" -) - -type WasmInstance struct { - ModuleId string -} - -var singleton *WasmInstance - -func GetWasmInstance() *WasmInstance { - // it is not thread safe, but wasm is single-threaded - // alternatively could use sync.Once - but it would increase the binary size. - if singleton == nil { - singleton = &WasmInstance{} - } - return singleton -} - -func Run(contract common_types.SwContract) { - // generating random module id and registering it on host - // a workaround for potential wasm modules collision - rand.Seed(time.Now().UnixNano()) - moduleId := RandSeq(20) - - js.Global().Set(moduleId, make(map[string]interface{})) - wasmModule := js.Global().Get(moduleId) - // the Go way of defining WASM exports... - // standard "exports" from the wasm module do not work here... - // that's kinda ugly TBH - wasmModule.Set("handle", handle(contract)) - wasmModule.Set("initState", initState(contract)) - wasmModule.Set("currentState", currentState(contract)) - wasmModule.Set("lang", lang()) - wasmModule.Set("version", version()) - - GetWasmInstance().ModuleId = moduleId - wasm_module.RegisterWasmModule(moduleId) - - // Prevent the function from returning, which is required in a wasm module - // i.e. "Error: Go program has already exited" is thrown otherwise on host - <-make(chan bool) -} - -func handle(contract common_types.SwContract) js.Func { - // note: each 'exported' function has to be wrapped into - // js.FuncOf(func(this js.Value, args []js.Value) interface{} - // - that's kinda ugly too... - return js.FuncOf(func(this js.Value, handleArgs []js.Value) interface{} { - - // exception handling - promisifiedHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - resolve := args[0] - reject := args[1] - - go func() { - actionJson := handleArgs[0].String() - var action common_types.Action - err := action.UnmarshalJSON([]byte(actionJson)) - if err != nil { - doReject(err, reject) - } - - _, err = json.Marshal(action) - if err != nil { - doReject(err, reject) - } - - state, result, err := contract.Handle(action, []byte(actionJson)) - - if err != nil { - // err should be an instance of `error`, eg `errors.New("some error")` - doReject(err, reject) - } else { - if state != nil { - contract.UpdateState(state) - } - resultMarshalled, _ := json.Marshal(result) - resolve.Invoke(string(resultMarshalled)) - } - }() - - return nil - }) - - promiseConstructor := js.Global().Get("Promise") - return promiseConstructor.New(promisifiedHandler) - }) -} - -func doReject(err error, reject js.Value) { - errorConstructor := js.Global().Get("Error") - errorObject := errorConstructor.New(err.Error()) - reject.Invoke(errorObject) -} - -func currentState(contract common_types.SwContract) interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - data, _ := json.Marshal(contract.CurrentState()) - return string(data) - }) -} - -func initState(contract common_types.SwContract) interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - contract.InitState(args[0].String()) - return nil - }) -} - -func version() interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - return 1 - }) -} - -// Lang workaround for now to simplify type reading without as/loader or wasm-bindgen -// 1 = assemblyscript -// 2 = rust -// 3 = go -// 4 = swift -// 5 = c -func lang() interface{} { - return js.FuncOf(func(this js.Value, args []js.Value) interface{} { - return 3 - }) -} diff --git a/src/__tests__/integration/data/wasm/go/src/common_types/types.go b/src/__tests__/integration/data/wasm/go/src/common_types/types.go deleted file mode 100644 index a329bace..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common_types/types.go +++ /dev/null @@ -1,20 +0,0 @@ -package common_types - -type Action struct { - Function string `json:"function"` -} - -type ActionResult = interface{} - -// SwContract We need to use "any" (interface{}) type here for the state - as this is -// a common interface for all contracts implemented in Go WASM. -// Version with generics is available on branch ppe/go-generics (but to use it real life -// we need to wait for the official release of Go 1.18 and tinygo compiler with generics -// support added - https://github.com/tinygo-org/tinygo/issues/2158) -//easyjson:skip -type SwContract interface { - Handle(action Action, actionBytes []byte) (interface{}, ActionResult, error) - InitState(stateJson string) - UpdateState(newState interface{}) - CurrentState() interface{} -} diff --git a/src/__tests__/integration/data/wasm/go/src/common_types/types_easyjson.go b/src/__tests__/integration/data/wasm/go/src/common_types/types_easyjson.go deleted file mode 100644 index de04b869..00000000 --- a/src/__tests__/integration/data/wasm/go/src/common_types/types_easyjson.go +++ /dev/null @@ -1,85 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package common_types - -import ( - json "encoding/json" - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(in *jlexer.Lexer, out *Action) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(out *jwriter.Writer, in Action) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"function\":" - out.RawString(prefix[1:]) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v Action) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v Action) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *Action) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Action) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoCommonTypes(l, v) -} diff --git a/src/__tests__/integration/data/wasm/go/src/impl/actions.go b/src/__tests__/integration/data/wasm/go/src/impl/actions.go deleted file mode 100644 index b0c3a879..00000000 --- a/src/__tests__/integration/data/wasm/go/src/impl/actions.go +++ /dev/null @@ -1,75 +0,0 @@ -package impl - -import ( - "errors" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/smartweave" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/transaction" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/types" -) - -func Transfer(state types.PstState, action types.TransferAction) (*types.PstState, error) { - if action.Qty == 0 { - return nil, errors.New("[CE:ITQ] invalid transfer qty") - } - - caller := transaction.Owner() - - if callerBalance, ok := state.Balances[caller]; ok { - if callerBalance < action.Qty { - return nil, errors.New("[CE:CBNE] caller balance not enough: " + string(state.Balances[caller])) - } - - callerBalance -= action.Qty - state.Balances[caller] = callerBalance - - if targetBalance, ok := state.Balances[action.Target]; ok { - targetBalance += action.Qty - state.Balances[action.Target] = targetBalance - } else { - state.Balances[action.Target] = action.Qty - } - - } else { - return nil, errors.New("[CE:CNF] caller not found: " + caller) - } - - return &state, nil -} - -func Balance(state types.PstState, action types.BalanceAction) (*types.BalanceResult, error) { - if targetBalance, ok := state.Balances[action.Target]; ok { - return &types.BalanceResult{ - Balance: targetBalance, - }, nil - } else { - return nil, errors.New("[CE:TNF] target not found: " + action.Target) - } -} - -func ForeignCall(state types.PstState, action types.ForeignCallAction) (*types.PstState, error) { - if action.ContractTxId == "bad_contract" { - return nil, errors.New("[CE:WFC] Wrong foreign contract") - } - - result := smartweave.ReadContractState(action.ContractTxId) - if result.Get("ticker").String() == "FOREIGN_PST" { - for key, _ := range state.Balances { - state.Balances[key] += 1000 - } - } - - return &state, nil -} - -func Evolve(state types.PstState, action types.EvolveAction) (*types.PstState, error) { - if !state.CanEvolve { - return nil, errors.New("[CE:ENA] Evolve not allowed") - } - if state.Owner != transaction.Owner() { - return nil, errors.New("[CE:OOE] Only owner can evolve") - } - - state.Evolve = action.Value - - return &state, nil -} \ No newline at end of file diff --git a/src/__tests__/integration/data/wasm/go/src/impl/pst-contract.go b/src/__tests__/integration/data/wasm/go/src/impl/pst-contract.go deleted file mode 100644 index 7da21a52..00000000 --- a/src/__tests__/integration/data/wasm/go/src/impl/pst-contract.go +++ /dev/null @@ -1,99 +0,0 @@ -package impl - -import ( - "errors" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/block" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common/imports/console" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common_types" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/types" -) - -type PstContract struct { - state types.PstState -} - -// Handle the function that contract developers actually need to implement -func (c *PstContract) Handle(action common_types.Action, actionBytes []byte) (interface{}, common_types.ActionResult, error) { - fn := action.Function - console.Log("Calling", fn) - - console.Log("Block height", block.Height()) - console.Log("Block indep_hash", block.IndepHash()) - console.Log("Block timestamp", block.Timestamp()) - - clonedState := c.CloneState().(types.PstState) - - switch fn { - case "transfer": - // not sure how to "automatically" handle casting to concrete action impl in Go. - // https://eagain.net/articles/go-json-kind/ - // https://eagain.net/articles/go-dynamic-json/ - var transfer types.TransferAction - err := transfer.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - state, err := Transfer(clonedState, transfer) - return state, nil, err - case "evolve": - var evolve types.EvolveAction - err := evolve.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - state, err := Evolve(clonedState, evolve) - return state, nil, err - case "balance": - var balance types.BalanceAction - err := balance.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - result, err := Balance(clonedState, balance) - return nil, result, err - case "foreignCall": - var foreignCall types.ForeignCallAction - err := foreignCall.UnmarshalJSON(actionBytes) - if err != nil { - return nil, nil, err - } - state, err := ForeignCall(clonedState, foreignCall) - return state, nil, err - default: - return nil, nil, errors.New("[RE:WTF] unknown function: " + fn) - } -} - -func (c *PstContract) InitState(stateJson string) { - var state types.PstState - err := state.UnmarshalJSON([]byte(stateJson)) - if err != nil { - return // TODO: throw in a similar way as in handle - } - c.UpdateState(&state) -} - -func (c *PstContract) UpdateState(newState interface{}) { - // note: we're first type asserting here to the pointer to types.PstState - // - and the retrieving value from the pointer - c.state = *(newState.(*types.PstState)) -} - -func (c *PstContract) CurrentState() interface{} { - return c.state -} - -// CloneState TODO: discuss whether it is necessary -// it allows to make the given action transactional, but -// at the cost of performance -func (c *PstContract) CloneState() interface{} { - json, _ := c.state.MarshalJSON() - state := types.PstState{} - err := state.UnmarshalJSON(json) - if err != nil { - // TODO: return error - return types.PstState{} - } - - return state -} diff --git a/src/__tests__/integration/data/wasm/go/src/main.go b/src/__tests__/integration/data/wasm/go/src/main.go deleted file mode 100644 index f2f6ed79..00000000 --- a/src/__tests__/integration/data/wasm/go/src/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common" - "github.com/redstone-finance/redstone-contracts-wasm/go/src/impl" -) - -// contract - implementation of the SwContract interface -var contract = impl.PstContract{} - -// handles all the WASM-JS related trickery... -func main() { - common.Run(&contract) -} diff --git a/src/__tests__/integration/data/wasm/go/src/types/types.go b/src/__tests__/integration/data/wasm/go/src/types/types.go deleted file mode 100644 index b43c81b8..00000000 --- a/src/__tests__/integration/data/wasm/go/src/types/types.go +++ /dev/null @@ -1,39 +0,0 @@ -package types - -import ( - "github.com/redstone-finance/redstone-contracts-wasm/go/src/common_types" -) - -type PstState struct { - Ticker string `json:"ticker"` - Name string `json:"name"` - Owner string `json:"owner"` - Evolve string `json:"evolve"` - CanEvolve bool `json:"canEvolve"` - Balances map[string]uint64 `json:"balances"` -} - -type TransferAction struct { - common_types.Action - Target string `json:"target"` - Qty uint64 `json:"qty"` -} - -type EvolveAction struct { - common_types.Action - Value string `json:"value"` -} - -type BalanceAction struct { - common_types.Action - Target string `json:"target"` -} - -type ForeignCallAction struct { - common_types.Action - ContractTxId string `json:"contractTxId"` -} - -type BalanceResult struct { - Balance uint64 `json:"balance"` -} diff --git a/src/__tests__/integration/data/wasm/go/src/types/types_easyjson.go b/src/__tests__/integration/data/wasm/go/src/types/types_easyjson.go deleted file mode 100644 index f6462484..00000000 --- a/src/__tests__/integration/data/wasm/go/src/types/types_easyjson.go +++ /dev/null @@ -1,515 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package types - -import ( - json "encoding/json" - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(in *jlexer.Lexer, out *TransferAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "target": - out.Target = string(in.String()) - case "qty": - out.Qty = uint64(in.Uint64()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(out *jwriter.Writer, in TransferAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"target\":" - out.RawString(prefix[1:]) - out.String(string(in.Target)) - } - { - const prefix string = ",\"qty\":" - out.RawString(prefix) - out.Uint64(uint64(in.Qty)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v TransferAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v TransferAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *TransferAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *TransferAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(in *jlexer.Lexer, out *PstState) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "ticker": - out.Ticker = string(in.String()) - case "name": - out.Name = string(in.String()) - case "owner": - out.Owner = string(in.String()) - case "evolve": - out.Evolve = string(in.String()) - case "canEvolve": - out.CanEvolve = bool(in.Bool()) - case "balances": - if in.IsNull() { - in.Skip() - } else { - in.Delim('{') - out.Balances = make(map[string]uint64) - for !in.IsDelim('}') { - key := string(in.String()) - in.WantColon() - var v1 uint64 - v1 = uint64(in.Uint64()) - (out.Balances)[key] = v1 - in.WantComma() - } - in.Delim('}') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(out *jwriter.Writer, in PstState) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"ticker\":" - out.RawString(prefix[1:]) - out.String(string(in.Ticker)) - } - { - const prefix string = ",\"name\":" - out.RawString(prefix) - out.String(string(in.Name)) - } - { - const prefix string = ",\"owner\":" - out.RawString(prefix) - out.String(string(in.Owner)) - } - { - const prefix string = ",\"evolve\":" - out.RawString(prefix) - out.String(string(in.Evolve)) - } - { - const prefix string = ",\"canEvolve\":" - out.RawString(prefix) - out.Bool(bool(in.CanEvolve)) - } - { - const prefix string = ",\"balances\":" - out.RawString(prefix) - if in.Balances == nil && (out.Flags&jwriter.NilMapAsEmpty) == 0 { - out.RawString(`null`) - } else { - out.RawByte('{') - v2First := true - for v2Name, v2Value := range in.Balances { - if v2First { - v2First = false - } else { - out.RawByte(',') - } - out.String(string(v2Name)) - out.RawByte(':') - out.Uint64(uint64(v2Value)) - } - out.RawByte('}') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v PstState) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v PstState) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *PstState) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *PstState) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes1(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(in *jlexer.Lexer, out *ForeignCallAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "contractTxId": - out.ContractTxId = string(in.String()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(out *jwriter.Writer, in ForeignCallAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"contractTxId\":" - out.RawString(prefix[1:]) - out.String(string(in.ContractTxId)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v ForeignCallAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v ForeignCallAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *ForeignCallAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *ForeignCallAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes2(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(in *jlexer.Lexer, out *EvolveAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "value": - out.Value = string(in.String()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(out *jwriter.Writer, in EvolveAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"value\":" - out.RawString(prefix[1:]) - out.String(string(in.Value)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v EvolveAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v EvolveAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *EvolveAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *EvolveAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes3(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(in *jlexer.Lexer, out *BalanceResult) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "balance": - out.Balance = uint64(in.Uint64()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(out *jwriter.Writer, in BalanceResult) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"balance\":" - out.RawString(prefix[1:]) - out.Uint64(uint64(in.Balance)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v BalanceResult) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v BalanceResult) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *BalanceResult) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *BalanceResult) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes4(l, v) -} -func easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(in *jlexer.Lexer, out *BalanceAction) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "target": - out.Target = string(in.String()) - case "function": - out.Function = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(out *jwriter.Writer, in BalanceAction) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"target\":" - out.RawString(prefix[1:]) - out.String(string(in.Target)) - } - { - const prefix string = ",\"function\":" - out.RawString(prefix) - out.String(string(in.Function)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v BalanceAction) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v BalanceAction) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *BalanceAction) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *BalanceAction) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComRedstoneFinanceRedstoneContractsWasmGoSrcTypes5(l, v) -} diff --git a/src/__tests__/integration/wasm/as-deploy-write-read.test.ts b/src/__tests__/integration/wasm/as-deploy-write-read.test.ts deleted file mode 100644 index f1bef7bd..00000000 --- a/src/__tests__/integration/wasm/as-deploy-write-read.test.ts +++ /dev/null @@ -1,184 +0,0 @@ -import fs from 'fs'; - -import ArLocal from 'arlocal'; -import Arweave from 'arweave'; -import { JWKInterface } from 'arweave/node/lib/wallet'; -import path from 'path'; -import { mineBlock } from '../_helpers'; -import { Contract } from '../../../contract/Contract'; -import { SmartWeaveTags } from '../../../core/SmartWeaveTags'; -import { Warp } from '../../../core/Warp'; -import { WarpFactory } from '../../../core/WarpFactory'; -import { LoggerFactory } from '../../../logging/LoggerFactory'; -import { TagsParser } from '../../../core/modules/impl/TagsParser'; - -interface ExampleContractState { - counter: number; - firstName: string; - lastName: string; -} - -describe('Testing the Warp client for AssemblyScript WASM contract', () => { - let contractSrc: Buffer; - let initialState: string; - let contractTxId: string; - - let wallet: JWKInterface; - - let arweave: Arweave; - let arlocal: ArLocal; - let warp: Warp; - let contract: Contract; - let tagsParser: TagsParser; - - beforeAll(async () => { - // note: each tests suit (i.e. file with tests that Jest is running concurrently - // with another files has to have ArLocal set to a different port!) - arlocal = new ArLocal(1300, false); - await arlocal.start(); - - LoggerFactory.INST.logLevel('error'); - tagsParser = new TagsParser(); - - warp = WarpFactory.forLocal(1300); - ({ arweave } = warp); - - ({ jwk: wallet } = await warp.generateWallet()); - contractSrc = fs.readFileSync(path.join(__dirname, '../data/wasm/as/assemblyscript-counter.wasm')); - initialState = fs.readFileSync(path.join(__dirname, '../data/wasm/counter-init-state.json'), 'utf8'); - - // deploying contract using the new SDK. - ({ contractTxId } = await warp.createContract.deploy({ - wallet, - initState: initialState, - src: contractSrc, - wasmSrcCodeDir: path.join(__dirname, '../data/wasm/as/assembly') - })); - - contract = warp.contract(contractTxId).setEvaluationOptions({ - gasLimit: 1000000000, - mineArLocalBlocks: false - }); - contract.connect(wallet); - - await mineBlock(warp); - }, 50000); - - afterAll(async () => { - await arlocal.stop(); - }); - - it('should properly deploy contract', async () => { - const contractTx = await arweave.transactions.get(contractTxId); - - expect(contractTx).not.toBeNull(); - - const contractSrcTx = await arweave.transactions.get( - tagsParser.getTag(contractTx, SmartWeaveTags.CONTRACT_SRC_TX_ID) - ); - expect(tagsParser.getTag(contractSrcTx, SmartWeaveTags.CONTENT_TYPE)).toEqual('application/wasm'); - expect(tagsParser.getTag(contractSrcTx, SmartWeaveTags.WASM_LANG)).toEqual('assemblyscript'); - }); - - it('should properly read initial state', async () => { - const contractState = (await contract.readState()).cachedValue.state; - expect(contractState.counter).toEqual(0); - expect(contractState.firstName).toEqual('first_ppe'); - expect(contractState.lastName).toEqual('last_ppe'); - }); - - it('should properly register interactions', async () => { - for (let i = 0; i < 100; i++) { - await contract.writeInteraction({ function: 'increment' }); - } - }, 10000); - - it('should properly read state after adding interactions', async () => { - await mineBlock(warp); - - expect((await contract.readState()).cachedValue.state.counter).toEqual(100); - }); - - it('should properly view contract state', async () => { - const interactionResult = await contract.viewState({ function: 'fullName' }); - - expect(interactionResult.result.fullName).toEqual('first_ppe last_ppe'); - }); - - it('should measure gas during dryWrite', async () => { - const result = await contract.dryWrite({ - function: 'increment' - }); - - expect(result.gasUsed).toBeGreaterThanOrEqual(12200000); - expect(result.gasUsed).toBeLessThanOrEqual(20316175); - }); - - it('should return stable gas results', async () => { - const results = []; - - for (let i = 0; i < 10; i++) { - results.push( - await contract.dryWrite({ - function: 'increment' - }) - ); - } - - results.forEach((result) => { - expect(result.gasUsed).toBeGreaterThanOrEqual(12200000); - expect(result.gasUsed).toBeLessThanOrEqual(20316175); - }); - }); - - it('should return exception for inf. loop function for dry run', async () => { - const result = await contract.dryWrite({ - function: 'infLoop' - }); - - expect(result.type).toEqual('exception'); - expect(result.errorMessage.startsWith('[RE:OOG')).toBeTruthy(); - }); - - /*it('should skip interaction during contract state read if gas limit exceeded', async () => { - const txId = await contract.writeInteraction({ function: 'infLoop' }); - await mineBlock(warp); - - const result = await contract.readState(); - - expect(result.validity[txId]).toBeFalsy(); - - const callStack = contract.getCallStack(); - callStack.getInteraction(txId); - - expect(callStack.getInteraction(txId)).toEqual({}); - });*/ - - it("should properly evolve contract's source code", async () => { - expect((await contract.readState()).cachedValue.state.counter).toEqual(100); - - const newContractSrc = fs.readFileSync(path.join(__dirname, '../data/wasm/as/assemblyscript-counter-evolve.wasm')); - - const srcTx = await warp.createSourceTx( - { - src: newContractSrc, - wasmSrcCodeDir: path.join(__dirname, '../data/wasm/as/assembly-evolve') - }, - wallet - ); - const newSrcTxId = await warp.saveSourceTx(srcTx); - - await mineBlock(warp); - - await contract.evolve(newSrcTxId); - await mineBlock(warp); - - await contract.writeInteraction({ - function: 'increment' - }); - await mineBlock(warp); - - // note: evolve should increment by 2 instead of 1 - expect((await contract.readState()).cachedValue.state.counter).toEqual(102); - }); -}); diff --git a/src/__tests__/integration/wasm/go-deploy-write-read.test.ts b/src/__tests__/integration/wasm/go-deploy-write-read.test.ts deleted file mode 100644 index deed2bc4..00000000 --- a/src/__tests__/integration/wasm/go-deploy-write-read.test.ts +++ /dev/null @@ -1,252 +0,0 @@ -import fs from 'fs'; - -import ArLocal from 'arlocal'; -import Arweave from 'arweave'; -import { JWKInterface } from 'arweave/node/lib/wallet'; -import path from 'path'; -import { mineBlock } from '../_helpers'; -import { PstState, PstContract } from '../../../contract/PstContract'; -import { SmartWeaveTags } from '../../../core/SmartWeaveTags'; -import { Warp } from '../../../core/Warp'; -import { WarpFactory } from '../../../core/WarpFactory'; -import { LoggerFactory } from '../../../logging/LoggerFactory'; -import { TagsParser } from '../../../core/modules/impl/TagsParser'; - -describe('Testing the Go WASM Profit Sharing Token', () => { - let wallet: JWKInterface; - let walletAddress: string; - - let initialState: PstState; - - let arweave: Arweave; - let arlocal: ArLocal; - let warp: Warp; - let pst: PstContract; - let tagsParser: TagsParser; - - let contractTxId: string; - - let properForeignContractTxId: string; - let wrongForeignContractTxId: string; - - beforeAll(async () => { - // note: each tests suit (i.e. file with tests that Jest is running concurrently - // with another files has to have ArLocal set to a different port!) - arlocal = new ArLocal(1150, false); - await arlocal.start(); - - LoggerFactory.INST.logLevel('error'); - tagsParser = new TagsParser(); - - warp = WarpFactory.forLocal(1150); - ({ arweave } = warp); - - ({ jwk: wallet } = await warp.generateWallet()); - walletAddress = await arweave.wallets.jwkToAddress(wallet); - - const contractSrc = fs.readFileSync(path.join(__dirname, '../data/wasm/go/go-pst.wasm')); - const stateFromFile: PstState = JSON.parse(fs.readFileSync(path.join(__dirname, '../data/token-pst.json'), 'utf8')); - - initialState = { - ...stateFromFile, - ...{ - owner: walletAddress, - balances: { - ...stateFromFile.balances, - [walletAddress]: 555669 - } - } - }; - - // deploying contract using the new SDK. - ({ contractTxId } = await warp.createContract.deploy({ - wallet, - initState: JSON.stringify(initialState), - src: contractSrc, - wasmSrcCodeDir: path.join(__dirname, '../data/wasm/go/src') - })); - - ({ contractTxId: properForeignContractTxId } = await warp.createContract.deploy({ - wallet, - initState: JSON.stringify({ - ...initialState, - ...{ - ticker: 'FOREIGN_PST', - name: 'foreign contract' - } - }), - src: contractSrc, - wasmSrcCodeDir: path.join(__dirname, '../data/wasm/go/src') - })); - - ({ contractTxId: wrongForeignContractTxId } = await warp.createContract.deploy({ - wallet, - initState: JSON.stringify({ - ...initialState, - ...{ - ticker: 'FOREIGN_PST_2', - name: 'foreign contract 2' - } - }), - src: contractSrc, - wasmSrcCodeDir: path.join(__dirname, '../data/wasm/go/src') - })); - - // connecting to the PST contract - pst = warp.pst(contractTxId); - - // connecting wallet to the PST contract - pst.connect(wallet); - - await mineBlock(warp); - }, 50000); - - afterAll(async () => { - await arlocal.stop(); - }); - - it('should properly deploy contract', async () => { - const contractTx = await arweave.transactions.get(contractTxId); - - expect(contractTx).not.toBeNull(); - - const contractSrcTx = await arweave.transactions.get( - tagsParser.getTag(contractTx, SmartWeaveTags.CONTRACT_SRC_TX_ID) - ); - expect(tagsParser.getTag(contractSrcTx, SmartWeaveTags.CONTENT_TYPE)).toEqual('application/wasm'); - expect(tagsParser.getTag(contractSrcTx, SmartWeaveTags.WASM_LANG)).toEqual('go'); - }); - - it('should read pst state and balance data', async () => { - expect(await pst.currentState()).toEqual(initialState); - - expect((await pst.currentBalance('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M')).balance).toEqual(10000000); - expect((await pst.currentBalance('33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA')).balance).toEqual(23111222); - expect((await pst.currentBalance(walletAddress)).balance).toEqual(555669); - }); - - it('should properly transfer tokens', async () => { - await pst.transfer({ - target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M', - qty: 555 - }); - - await mineBlock(warp); - - expect((await pst.currentState()).balances[walletAddress]).toEqual(555669 - 555); - expect((await pst.currentState()).balances['uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M']).toEqual(10000000 + 555); - }); - - it('should properly view contract state', async () => { - const result = (await pst.currentBalance('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M')).balance; - expect(result).toEqual(10000000 + 555); - }); - - // note: the dummy logic on the test contract should add 1000 tokens - // to each address, if the foreign contract state 'ticker' field = 'FOREIGN_PST' - it('should properly read foreign contract state', async () => { - await pst.writeInteraction({ - function: 'foreignCall', - contractTxId: wrongForeignContractTxId - }); - await mineBlock(warp); - expect((await pst.currentState()).balances[walletAddress]).toEqual(555669 - 555); - expect((await pst.currentState()).balances['uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M']).toEqual(10000000 + 555); - - await pst.writeInteraction({ - function: 'foreignCall', - contractTxId: properForeignContractTxId - }); - await mineBlock(warp); - expect((await pst.currentState()).balances[walletAddress]).toEqual(555669 - 555 + 1000); - expect((await pst.currentState()).balances['uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M']).toEqual( - 10000000 + 555 + 1000 - ); - }); - - xit('should return stable gas results', async () => { - const results = []; - - for (let i = 0; i < 10; i++) { - const result = await pst.dryWrite({ - function: 'transfer', - target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M', - qty: 555 - }); - results.push(result); - } - - results.forEach((result) => { - expect(result.gasUsed).toEqual(81158922); - }); - }, 10000); - - it('should properly handle runtime errors', async () => { - const result = await pst.dryWrite({ - target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M', - qty: 555 - }); - - expect(result.type).toEqual('exception'); - expect(result.errorMessage).toEqual('[RE:WTF] unknown function: '); - }); - - it("should properly evolve contract's source code", async () => { - const result = (await pst.currentBalance('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M')).balance; - expect(result).toEqual(10000000 + 1000 + 555); - - const newContractSrc = fs.readFileSync(path.join(__dirname, '../data/wasm/go/go-pst-evolve.wasm')); - - const srcTx = await warp.createSourceTx( - { - src: newContractSrc, - wasmSrcCodeDir: path.join(__dirname, '../data/wasm/go/src-evolve') - }, - wallet - ); - const newSrcTxId = await warp.saveSourceTx(srcTx); - - await mineBlock(warp); - - await pst.evolve(newSrcTxId); - await mineBlock(warp); - - // note: evolve should add to the transfer additional 200 - await pst.transfer({ - target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M', - qty: 555 - }); - - await mineBlock(warp); - - expect((await pst.currentState()).balances['uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M']).toEqual( - 10000000 + 555 + 1000 + 555 + 200 - ); - }); - - it('should properly handle contract errors', async () => { - const result = await pst.dryWrite({ - function: 'transfer', - target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M', - qty: 0 - }); - - expect(result.type).toEqual('error'); - expect(result.errorMessage).toEqual('[CE:ITQ] invalid transfer qty'); - }); - - it('should honor gas limits', async () => { - pst.setEvaluationOptions({ - gasLimit: 9000000 - }); - - const result = await pst.dryWrite({ - function: 'transfer', - target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M', - qty: 555 - }); - - expect(result.type).toEqual('exception'); - expect(result.errorMessage.startsWith('[RE:OOG] Out of gas!')).toBeTruthy(); - }); -}); diff --git a/src/contract/deploy/impl/SourceImpl.ts b/src/contract/deploy/impl/SourceImpl.ts index 2626b2cb..2a6e6b83 100644 --- a/src/contract/deploy/impl/SourceImpl.ts +++ b/src/contract/deploy/impl/SourceImpl.ts @@ -1,18 +1,17 @@ /* eslint-disable */ import metering from 'warp-wasm-metering'; -import { Go } from '../../../core/modules/impl/wasm/go-wasm-imports'; -import fs, { PathOrFileDescriptor } from 'fs'; -import { matchMutClosureDtor } from '../../../core/modules/impl/wasm/wasm-bindgen-tools'; -import { ArWallet, ContractType } from '../CreateContract'; -import { SmartWeaveTags } from '../../../core/SmartWeaveTags'; -import { LoggerFactory } from '../../../logging/LoggerFactory'; -import { Source } from '../Source'; -import { Buffer } from 'warp-isomorphic'; -import { Warp } from '../../../core/Warp'; -import { Signature, CustomSignature } from '../../../contract/Signature'; -import { WARP_GW_URL } from '../../../core/WarpFactory'; -import { TagsParser } from '../../../core/modules/impl/TagsParser'; -import { Transaction } from '../../../utils/types/arweave-types'; +import fs, {PathOrFileDescriptor} from 'fs'; +import {matchMutClosureDtor} from '../../../core/modules/impl/wasm/wasm-bindgen-tools'; +import {ArWallet, ContractType} from '../CreateContract'; +import {SmartWeaveTags} from '../../../core/SmartWeaveTags'; +import {LoggerFactory} from '../../../logging/LoggerFactory'; +import {Source} from '../Source'; +import {Buffer} from 'warp-isomorphic'; +import {Warp} from '../../../core/Warp'; +import {CustomSignature, Signature} from '../../../contract/Signature'; +import {WARP_GW_URL} from '../../../core/WarpFactory'; +import {TagsParser} from '../../../core/modules/impl/TagsParser'; +import {Transaction} from '../../../utils/types/arweave-types'; const wasmTypeMapping: Map = new Map([ [1, 'assemblyscript'], @@ -32,12 +31,13 @@ export class SourceImpl implements Source { private readonly logger = LoggerFactory.INST.create('Source'); private signature: Signature; - constructor(private readonly warp: Warp) {} + constructor(private readonly warp: Warp) { + } async createSourceTx(sourceData: SourceData, wallet: ArWallet | CustomSignature): Promise { this.logger.debug('Creating new contract source'); - const { src, wasmSrcCodeDir, wasmGlueCode } = sourceData; + const {src, wasmSrcCodeDir, wasmGlueCode} = sourceData; this.signature = new Signature(this.warp, wallet); const signer = this.signature.signer; @@ -60,30 +60,25 @@ export class SourceImpl implements Source { const moduleImports = WebAssembly.Module.imports(wasmModule); let lang: number; - if (this.isGoModule(moduleImports)) { - const go = new Go(null); - const module = new WebAssembly.Instance(wasmModule, go.importObject); - // DO NOT await here! - go.run(module); - lang = go.exports.lang(); - wasmVersion = go.exports.version(); - } else { - // @ts-ignore - const module: WebAssembly.Instance = await WebAssembly.instantiate(src, dummyImports(moduleImports)); - // @ts-ignore - if (!module.instance.exports.lang) { - throw new Error(`No info about source type in wasm binary. Did you forget to export "lang" function?`); - } - // @ts-ignore - lang = module.instance.exports.lang(); - // @ts-ignore - wasmVersion = module.instance.exports.version(); - if (!wasmTypeMapping.has(lang)) { - throw new Error(`Unknown wasm source type ${lang}`); - } + + // @ts-ignore + const module: WebAssembly.Instance = await WebAssembly.instantiate(src, dummyImports(moduleImports)); + // @ts-ignore + if (!module.instance.exports.lang) { + throw new Error(`No info about source type in wasm binary. Did you forget to export "lang" function?`); + } + // @ts-ignore + lang = module.instance.exports.lang(); + // @ts-ignore + wasmVersion = module.instance.exports.version(); + if (!wasmTypeMapping.has(lang)) { + throw new Error(`Unknown wasm source type ${lang}`); } wasmLang = wasmTypeMapping.get(lang); + if (wasmLang != 'rust') { + throw new Error('Support for for Go and AssemblyScript contract has been dropped. See https://github.com/warp-contracts/warp/issues/348'); + } if (wasmSrcCodeDir == null) { throw new Error('No path to original wasm contract source code'); } @@ -91,20 +86,18 @@ export class SourceImpl implements Source { const zippedSourceCode = await this.zipContents(wasmSrcCodeDir); data.push(zippedSourceCode); - if (wasmLang == 'rust') { - if (!wasmGlueCode) { - throw new Error('No path to generated wasm-bindgen js code'); - } - const wasmBindgenSrc = fs.readFileSync(wasmGlueCode, 'utf-8'); - const dtor = matchMutClosureDtor(wasmBindgenSrc); - metadata['dtor'] = parseInt(dtor); - data.push(Buffer.from(wasmBindgenSrc)); + if (!wasmGlueCode) { + throw new Error('No path to generated wasm-bindgen js code'); } + const wasmBindgenSrc = fs.readFileSync(wasmGlueCode, 'utf-8'); + const dtor = matchMutClosureDtor(wasmBindgenSrc); + metadata['dtor'] = parseInt(dtor); + data.push(Buffer.from(wasmBindgenSrc)); } const allData = contractType == 'wasm' ? this.joinBuffers(data) : src; - srcTx = await this.warp.arweave.createTransaction({ data: allData }); + srcTx = await this.warp.arweave.createTransaction({data: allData}); srcTx.addTag(SmartWeaveTags.APP_NAME, 'SmartWeaveContractSource'); // TODO: version should be taken from the current package.json version. @@ -167,12 +160,6 @@ export class SourceImpl implements Source { } } - private isGoModule(moduleImports: WebAssembly.ModuleImportDescriptor[]) { - return moduleImports.some((moduleImport) => { - return moduleImport.module == 'env' && moduleImport.name.startsWith('syscall/js'); - }); - } - private joinBuffers(buffers: Buffer[]): Buffer { const length = buffers.length; const result = []; @@ -194,7 +181,7 @@ export class SourceImpl implements Source { incrementAmount: 1000 * 1024 // grow by 1000 kilobytes each time buffer overflows. }); const archive = archiver('zip', { - zlib: { level: 9 } // Sets the compression level. + zlib: {level: 9} // Sets the compression level. }); archive.on('error', function (err: any) { throw err; @@ -210,7 +197,7 @@ export class SourceImpl implements Source { private async postSource(srcTx: Transaction = null): Promise { const response = await fetch(`${WARP_GW_URL}/gateway/sources/deploy`, { method: 'POST', - body: JSON.stringify({ srcTx }), + body: JSON.stringify({srcTx}), headers: { 'Accept-Encoding': 'gzip, deflate, br', 'Content-Type': 'application/json', @@ -235,7 +222,8 @@ function dummyImports(moduleImports: WebAssembly.ModuleImportDescriptor[]) { if (!Object.prototype.hasOwnProperty.call(imports, moduleImport.module)) { imports[moduleImport.module] = {}; } - imports[moduleImport.module][moduleImport.name] = function () {}; + imports[moduleImport.module][moduleImport.name] = function () { + }; }); return imports; diff --git a/src/core/modules/impl/HandlerExecutorFactory.ts b/src/core/modules/impl/HandlerExecutorFactory.ts index 119538db..a6cccdaf 100644 --- a/src/core/modules/impl/HandlerExecutorFactory.ts +++ b/src/core/modules/impl/HandlerExecutorFactory.ts @@ -1,8 +1,5 @@ import Arweave from 'arweave'; -import loader from '@assemblyscript/loader'; -import { asWasmImports } from './wasm/as-wasm-imports'; import { rustWasmImports } from './wasm/rust-wasm-imports'; -import { Go } from './wasm/go-wasm-imports'; import * as vm2 from 'vm2'; import { WarpCache } from '../../../cache/WarpCache'; import { ContractDefinition } from '../../../core/ContractDefinition'; @@ -82,16 +79,6 @@ export class HandlerExecutorFactory implements ExecutorFactory extends AbstractContractHandler { constructor( diff --git a/src/core/modules/impl/handler/WasmHandlerApi.ts b/src/core/modules/impl/handler/WasmHandlerApi.ts index 13940ca2..632f3ec9 100644 --- a/src/core/modules/impl/handler/WasmHandlerApi.ts +++ b/src/core/modules/impl/handler/WasmHandlerApi.ts @@ -3,7 +3,6 @@ import { ContractDefinition } from '../../../../core/ContractDefinition'; import { ExecutionContext } from '../../../../core/ExecutionContext'; import { EvalStateResult } from '../../../../core/modules/StateEvaluator'; import { SmartWeaveGlobal } from '../../../../legacy/smartweave-global'; -import stringify from 'safe-stable-stringify'; import { InteractionData, InteractionResult } from '../HandlerExecutorFactory'; import { AbstractContractHandler } from './AbstractContractHandler'; @@ -80,19 +79,10 @@ export class WasmHandlerApi extends AbstractContractHandler { initState(state: State): void { switch (this.contractDefinition.srcWasmLang) { - case 'assemblyscript': { - const statePtr = this.wasmExports.__newString(stringify(state)); - this.wasmExports.initState(statePtr); - break; - } case 'rust': { this.wasmExports.initState(state); break; } - case 'go': { - this.wasmExports.initState(stringify(state)); - break; - } default: { throw new Error(`Support for ${this.contractDefinition.srcWasmLang} not implemented yet.`); } @@ -101,13 +91,6 @@ export class WasmHandlerApi extends AbstractContractHandler { private async doHandle(action: any): Promise { switch (this.contractDefinition.srcWasmLang) { - case 'assemblyscript': { - const actionPtr = this.wasmExports.__newString(stringify(action.input)); - const resultPtr = this.wasmExports.handle(actionPtr); - const result = this.wasmExports.__getString(resultPtr); - - return JSON.parse(result); - } case 'rust': { let handleResult = await this.wasmExports.handle(action.input); if (!handleResult) { @@ -136,10 +119,6 @@ export class WasmHandlerApi extends AbstractContractHandler { } } } - case 'go': { - const result = await this.wasmExports.handle(stringify(action.input)); - return JSON.parse(result); - } default: { throw new Error(`Support for ${this.contractDefinition.srcWasmLang} not implemented yet.`); } @@ -148,17 +127,9 @@ export class WasmHandlerApi extends AbstractContractHandler { private doGetCurrentState(): State { switch (this.contractDefinition.srcWasmLang) { - case 'assemblyscript': { - const currentStatePtr = this.wasmExports.currentState(); - return JSON.parse(this.wasmExports.__getString(currentStatePtr)); - } case 'rust': { return this.wasmExports.currentState(); } - case 'go': { - const result = this.wasmExports.currentState(); - return JSON.parse(result); - } default: { throw new Error(`Support for ${this.contractDefinition.srcWasmLang} not implemented yet.`); } diff --git a/src/core/modules/impl/wasm/as-wasm-imports.ts b/src/core/modules/impl/wasm/as-wasm-imports.ts deleted file mode 100644 index 625a1cd4..00000000 --- a/src/core/modules/impl/wasm/as-wasm-imports.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { SmartWeaveGlobal } from '../../../../legacy/smartweave-global'; -import { LoggerFactory } from '../../../../logging/LoggerFactory'; - -export const asWasmImports = (swGlobal: SmartWeaveGlobal, wasmInstance: any): any => { - const wasmLogger = LoggerFactory.INST.create('WASM:AS'); - - return { - metering: { - usegas: swGlobal.useGas - }, - console: { - 'console.log': function (msgPtr) { - wasmLogger.debug(`${swGlobal.contract.id}: ${wasmInstance.exports.__getString(msgPtr)}`); - }, - 'console.logO': function (msgPtr, objPtr) { - wasmLogger.debug( - `${swGlobal.contract.id}: ${wasmInstance.exports.__getString(msgPtr)}`, - JSON.parse(wasmInstance.exports.__getString(objPtr)) - ); - } - }, - block: { - 'Block.height': function () { - return swGlobal.block.height; - }, - 'Block.indep_hash': function () { - return wasmInstance.exports.__newString(swGlobal.block.indep_hash); - }, - 'Block.timestamp': function () { - return swGlobal.block.timestamp; - } - }, - transaction: { - 'Transaction.id': function () { - return wasmInstance.exports.__newString(swGlobal.transaction.id); - }, - 'Transaction.owner': function () { - return wasmInstance.exports.__newString(swGlobal.transaction.owner); - }, - 'Transaction.target': function () { - return wasmInstance.exports.__newString(swGlobal.transaction.target); - } - }, - contract: { - 'Contract.id': function () { - return wasmInstance.exports.__newString(swGlobal.contract.id); - }, - 'Contract.owner': function () { - return wasmInstance.exports.__newString(swGlobal.contract.owner); - } - }, - api: { - _readContractState: (fnIndex, contractTxIdPtr) => { - const contractTxId = wasmInstance.exports.__getString(contractTxIdPtr); - const callbackFn = getFn(fnIndex); - console.log('Simulating read state of', contractTxId); - return setTimeout(() => { - console.log('calling callback'); - callbackFn( - wasmInstance.exports.__newString( - JSON.stringify({ - contractTxId - }) - ) - ); - }, 1000); - }, - clearTimeout - }, - env: { - abort(messagePtr, fileNamePtr, line, column) { - const message = wasmInstance.exports.__getString(messagePtr); - wasmLogger.error('--------------------- Error message from AssemblyScript ----------------------\n'); - wasmLogger.error(' ' + message); - wasmLogger.error(' In file "' + wasmInstance.exports.__getString(fileNamePtr) + '"'); - wasmLogger.error(` on line ${line}, column ${column}.`); - wasmLogger.error('------------------------------------------------------------------------------\n'); - - throw new Error(message); - } - } - }; - - function getFn(idx) { - return wasmInstance.exports.table.get(idx); - } -}; diff --git a/src/core/modules/impl/wasm/go-wasm-imports.ts b/src/core/modules/impl/wasm/go-wasm-imports.ts deleted file mode 100644 index d0a1050f..00000000 --- a/src/core/modules/impl/wasm/go-wasm-imports.ts +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// This file has been modified for use by the TinyGo compiler. - -import { SmartWeaveGlobal } from '../../../../legacy/smartweave-global'; -import { LoggerFactory } from '../../../../logging/LoggerFactory'; - -// note: this file has been further modified to be used -// with Warp SDK. -/* tslint:disable */ -/* eslint-disable */ -/* YOLO */ - -const encoder = new TextEncoder(); -const decoder = new TextDecoder('utf-8'); -let logLine = []; - -let globalJsModule; - -// crying while committing... -(function (global) { - globalJsModule = global; - globalJsModule.redstone = { - go: {} - }; -}).call( - this, - typeof global !== 'undefined' - ? global - : typeof self !== 'undefined' - ? self - : typeof window !== 'undefined' - ? window - : {} -); - -export class Go { - private _callbackTimeouts: Map; - private _nextCallbackTimeoutID: number; - private _inst: any; - private _values: any; - private _ids: any; - private _idPool: any; - private _goRefCounts: any; - importObject: any; - private exited: boolean; - private _resolveCallbackPromise: () => void; - private _pendingEvent: any; - private _id: string; - public exports: any; - - constructor(swGlobal: SmartWeaveGlobal) { - this._callbackTimeouts = new Map(); - this._nextCallbackTimeoutID = 1; - - const wasmLogger = LoggerFactory.INST.create('WASM:Go'); - - let go = this; - // it is safe to redeclare this for each new module in the global scope - // - this function is called only during module initialization. - globalJsModule.redstone.go = { - WasmModule: { - registerWasmModule: function (moduleId) { - go._id = moduleId; - go.exports = globalJsModule[moduleId]; - delete globalJsModule[moduleId]; - - globalJsModule.redstone.go[moduleId] = {}; - globalJsModule.redstone.go[moduleId].imports = { - console: { - log: function (...args) { - wasmLogger.debug(args[0], ...args.slice(1)); - } - }, - Transaction: { - id: function () { - return swGlobal.transaction.id; - }, - owner: function () { - return swGlobal.transaction.owner; - }, - target: function () { - return swGlobal.transaction.target; - } - }, - Block: { - indep_hash: function () { - return swGlobal.block.indep_hash; - }, - height: function () { - return swGlobal.block.height; - }, - timestamp: function () { - return swGlobal.block.timestamp; - } - }, - Contract: { - id: function () { - return swGlobal.contract.id; - }, - owner: function () { - return swGlobal.contract.owner; - } - }, - SmartWeave: { - readContractState: async function (contractTxId) { - return await swGlobal.contracts.readContractState(contractTxId); - } - } - }; - } - } - }; - - const mem = () => { - // The buffer may change when requesting more memory. - return new DataView(this._inst.exports.memory.buffer); - }; - - const setInt64 = (addr, v) => { - mem().setUint32(addr + 0, v, true); - mem().setUint32(addr + 4, Math.floor(v / 4294967296), true); - }; - - const getInt64 = (addr) => { - const low = mem().getUint32(addr + 0, true); - const high = mem().getInt32(addr + 4, true); - return low + high * 4294967296; - }; - - const loadValue = (addr) => { - const f = mem().getFloat64(addr, true); - if (f === 0) { - return undefined; - } - if (!isNaN(f)) { - return f; - } - - const id = mem().getUint32(addr, true); - return this._values[id]; - }; - - const storeValue = (addr, v) => { - const nanHead = 0x7ff80000; - - if (typeof v === 'number') { - if (isNaN(v)) { - mem().setUint32(addr + 4, nanHead, true); - mem().setUint32(addr, 0, true); - return; - } - if (v === 0) { - mem().setUint32(addr + 4, nanHead, true); - mem().setUint32(addr, 1, true); - return; - } - mem().setFloat64(addr, v, true); - return; - } - - switch (v) { - case undefined: - mem().setFloat64(addr, 0, true); - return; - case null: - mem().setUint32(addr + 4, nanHead, true); - mem().setUint32(addr, 2, true); - return; - case true: - mem().setUint32(addr + 4, nanHead, true); - mem().setUint32(addr, 3, true); - return; - case false: - mem().setUint32(addr + 4, nanHead, true); - mem().setUint32(addr, 4, true); - return; - } - - let id = this._ids.get(v); - if (id === undefined) { - id = this._idPool.pop(); - if (id === undefined) { - id = this._values.length; - } - this._values[id] = v; - this._goRefCounts[id] = 0; - this._ids.set(v, id); - } - this._goRefCounts[id]++; - let typeFlag = 1; - switch (typeof v) { - case 'string': - typeFlag = 2; - break; - case 'symbol': - typeFlag = 3; - break; - case 'function': - typeFlag = 4; - break; - } - mem().setUint32(addr + 4, nanHead | typeFlag, true); - mem().setUint32(addr, id, true); - }; - - const loadSlice = (array, len, cap = null) => { - return new Uint8Array(this._inst.exports.memory.buffer, array, len); - }; - - const loadSliceOfValues = (array, len, cap) => { - const a = new Array(len); - for (let i = 0; i < len; i++) { - a[i] = loadValue(array + i * 8); - } - return a; - }; - - const loadString = (ptr, len) => { - return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len)); - }; - - const timeOrigin = Date.now() - performance.now(); - this.importObject = { - wasi_snapshot_preview1: { - // https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write - fd_write: function (fd, iovs_ptr, iovs_len, nwritten_ptr) { - let nwritten = 0; - if (fd == 1) { - for (let iovs_i = 0; iovs_i < iovs_len; iovs_i++) { - let iov_ptr = iovs_ptr + iovs_i * 8; // assuming wasm32 - let ptr = mem().getUint32(iov_ptr + 0, true); - let len = mem().getUint32(iov_ptr + 4, true); - nwritten += len; - for (let i = 0; i < len; i++) { - let c = mem().getUint8(ptr + i); - if (c == 13) { - // CR - // ignore - } else if (c == 10) { - // LF - // write line - let line = decoder.decode(new Uint8Array(logLine)); - logLine = []; - console.log(line); - } else { - logLine.push(c); - } - } - } - } else { - console.error('invalid file descriptor:', fd); - } - mem().setUint32(nwritten_ptr, nwritten, true); - return 0; - }, - fd_close: () => 0, // dummy - fd_fdstat_get: () => 0, // dummy - fd_seek: () => 0, // dummy - proc_exit: (code) => { - // @ts-ignore - if (global.process) { - // Node.js - process.exit(code); - } else { - // Can't exit in a browser. - throw 'trying to exit with code ' + code; - } - }, - random_get: (bufPtr, bufLen) => { - crypto.getRandomValues(loadSlice(bufPtr, bufLen, null)); - return 0; - } - }, - env: { - // func ticks() float64 - 'runtime.ticks': () => { - return timeOrigin + performance.now(); - }, - - // func sleepTicks(timeout float64) - 'runtime.sleepTicks': (timeout) => { - // Do not sleep, only reactivate scheduler after the given timeout. - setTimeout(this._inst.exports.go_scheduler, timeout); - }, - - // func finalizeRef(v ref) - // https://github.com/tinygo-org/tinygo/issues/1140#issuecomment-718145455 - 'syscall/js.finalizeRef': (v_addr) => { - // Note: TinyGo does not support finalizers so this is only called - // for one specific case, by js.go:jsString. - const id = mem().getUint32(v_addr, true); - this._goRefCounts[id]--; - if (this._goRefCounts[id] === 0) { - const v = this._values[id]; - this._values[id] = null; - this._ids.delete(v); - this._idPool.push(id); - } - }, - - // func stringVal(value string) ref - 'syscall/js.stringVal': (ret_ptr, value_ptr, value_len) => { - const s = loadString(value_ptr, value_len); - storeValue(ret_ptr, s); - }, - - // func valueGet(v ref, p string) ref - 'syscall/js.valueGet': (retval, v_addr, p_ptr, p_len) => { - let prop = loadString(p_ptr, p_len); - let value = loadValue(v_addr); - let result = Reflect.get(value, prop); - storeValue(retval, result); - }, - - // func valueSet(v ref, p string, x ref) - 'syscall/js.valueSet': (v_addr, p_ptr, p_len, x_addr) => { - const v = loadValue(v_addr); - const p = loadString(p_ptr, p_len); - const x = loadValue(x_addr); - Reflect.set(v, p, x); - }, - - // func valueDelete(v ref, p string) - 'syscall/js.valueDelete': (v_addr, p_ptr, p_len) => { - const v = loadValue(v_addr); - const p = loadString(p_ptr, p_len); - Reflect.deleteProperty(v, p); - }, - - // func valueIndex(v ref, i int) ref - 'syscall/js.valueIndex': (ret_addr, v_addr, i) => { - storeValue(ret_addr, Reflect.get(loadValue(v_addr), i)); - }, - - // valueSetIndex(v ref, i int, x ref) - 'syscall/js.valueSetIndex': (v_addr, i, x_addr) => { - Reflect.set(loadValue(v_addr), i, loadValue(x_addr)); - }, - - // func valueCall(v ref, m string, args []ref) (ref, bool) - 'syscall/js.valueCall': (ret_addr, v_addr, m_ptr, m_len, args_ptr, args_len, args_cap) => { - const v = loadValue(v_addr); - const name = loadString(m_ptr, m_len); - const args = loadSliceOfValues(args_ptr, args_len, args_cap); - try { - const m = Reflect.get(v, name); - storeValue(ret_addr, Reflect.apply(m, v, args)); - mem().setUint8(ret_addr + 8, 1); - } catch (err) { - storeValue(ret_addr, err); - mem().setUint8(ret_addr + 8, 0); - } - }, - - // func valueInvoke(v ref, args []ref) (ref, bool) - 'syscall/js.valueInvoke': (ret_addr, v_addr, args_ptr, args_len, args_cap) => { - try { - const v = loadValue(v_addr); - const args = loadSliceOfValues(args_ptr, args_len, args_cap); - storeValue(ret_addr, Reflect.apply(v, undefined, args)); - mem().setUint8(ret_addr + 8, 1); - } catch (err) { - storeValue(ret_addr, err); - mem().setUint8(ret_addr + 8, 0); - } - }, - - // func valueNew(v ref, args []ref) (ref, bool) - 'syscall/js.valueNew': (ret_addr, v_addr, args_ptr, args_len, args_cap) => { - const v = loadValue(v_addr); - const args = loadSliceOfValues(args_ptr, args_len, args_cap); - try { - storeValue(ret_addr, Reflect.construct(v, args)); - mem().setUint8(ret_addr + 8, 1); - } catch (err) { - storeValue(ret_addr, err); - mem().setUint8(ret_addr + 8, 0); - } - }, - - // func valueLength(v ref) int - 'syscall/js.valueLength': (v_addr) => { - return loadValue(v_addr).length; - }, - - // valuePrepareString(v ref) (ref, int) - 'syscall/js.valuePrepareString': (ret_addr, v_addr) => { - const s = String(loadValue(v_addr)); - const str = encoder.encode(s); - storeValue(ret_addr, str); - setInt64(ret_addr + 8, str.length); - }, - - // valueLoadString(v ref, b []byte) - 'syscall/js.valueLoadString': (v_addr, slice_ptr, slice_len, slice_cap) => { - const str = loadValue(v_addr); - loadSlice(slice_ptr, slice_len, slice_cap).set(str); - }, - - // func valueInstanceOf(v ref, t ref) bool - 'syscall/js.valueInstanceOf': (v_addr, t_addr) => { - return loadValue(v_addr) instanceof loadValue(t_addr); - }, - - // func copyBytesToGo(dst []byte, src ref) (int, bool) - 'syscall/js.copyBytesToGo': (ret_addr, dest_addr, dest_len, dest_cap, source_addr) => { - let num_bytes_copied_addr = ret_addr; - let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable - - const dst = loadSlice(dest_addr, dest_len); - const src = loadValue(source_addr); - if (!(src instanceof Uint8Array)) { - mem().setUint8(returned_status_addr, 0); // Return "not ok" status - return; - } - const toCopy = src.subarray(0, dst.length); - dst.set(toCopy); - setInt64(num_bytes_copied_addr, toCopy.length); - mem().setUint8(returned_status_addr, 1); // Return "ok" status - }, - - // copyBytesToJS(dst ref, src []byte) (int, bool) - // Originally copied from upstream Go project, then modified: - // https://github.com/golang/go/blob/3f995c3f3b43033013013e6c7ccc93a9b1411ca9/misc/wasm/wasm_exec.js#L404-L416 - 'syscall/js.copyBytesToJS': (ret_addr, dest_addr, source_addr, source_len, source_cap) => { - let num_bytes_copied_addr = ret_addr; - let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable - - const dst = loadValue(dest_addr); - const src = loadSlice(source_addr, source_len); - if (!(dst instanceof Uint8Array)) { - mem().setUint8(returned_status_addr, 0); // Return "not ok" status - return; - } - const toCopy = src.subarray(0, dst.length); - dst.set(toCopy); - setInt64(num_bytes_copied_addr, toCopy.length); - mem().setUint8(returned_status_addr, 1); // Return "ok" status - } - } - }; - } - - async run(instance) { - this._inst = instance; - this._values = [ - // JS values that Go currently has references to, indexed by reference id - NaN, - 0, - null, - true, - false, - global, - this - ]; - this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id - this._ids = new Map(); // mapping from JS values to reference ids - this._idPool = []; // unused ids that have been garbage collected - this.exited = false; // whether the Go program has exited - - const mem = new DataView(this._inst.exports.memory.buffer); - - while (true) { - const callbackPromise = new Promise((resolve) => { - this._resolveCallbackPromise = () => { - if (this.exited) { - throw new Error('bad callback: Go program has already exited'); - } - setTimeout(resolve, 0); // make sure it is asynchronous - }; - }); - this._inst.exports._start(); - if (this.exited) { - break; - } - await callbackPromise; - } - } - - _resume() { - if (this.exited) { - throw new Error('Go program has already exited'); - } - this._inst.exports.resume(); - if (this.exited) { - this._resolveExitPromise(); - } - } - - _makeFuncWrapper(id) { - const go = this; - return function () { - const event = { id: id, this: this, args: arguments }; - go._pendingEvent = event; - go._resume(); - // @ts-ignore - return event.result; - }; - } - - private _resolveExitPromise() {} -} diff --git a/src/utils/types/arweave-types.ts b/src/utils/types/arweave-types.ts index 805f2ca8..9855644d 100644 --- a/src/utils/types/arweave-types.ts +++ b/src/utils/types/arweave-types.ts @@ -164,7 +164,7 @@ export class Transaction extends BaseObject implements TransactionInterface { } public async prepareChunks(data: Uint8Array) { - throw new Error('Should not be called, use arweave-js version'); + throw new Error('Should not be called, use arweave-js version.'); } // Returns a chunk in a format suitable for posting to /chunk. @@ -186,7 +186,7 @@ export class Transaction extends BaseObject implements TransactionInterface { } public async getSignatureData(): Promise { - throw new Error('Should not be called, use arweave-js'); + throw new Error('Should not be called, use arweave-js version.'); } }