feat: rust wasm contracts (WIP)

This commit is contained in:
ppedziwiatr
2022-02-25 11:23:27 +01:00
committed by Piotr Pędziwiatr
parent 9245f58c5b
commit 09398452f8
16 changed files with 1087 additions and 73 deletions

View File

@@ -0,0 +1,9 @@
{
"ticker": "EXAMPLE_PST_TOKEN",
"name": "token name",
"owner": "uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M",
"balances": {
"uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M": 10000000,
"33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA": 23111222
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -5,7 +5,7 @@ import Arweave from 'arweave';
import { JWKInterface } from 'arweave/node/lib/wallet';
import { Contract, getTag, LoggerFactory, SmartWeave, SmartWeaveNodeFactory, SmartWeaveTags } from '@smartweave';
import path from 'path';
import { addFunds, mineBlock } from './_helpers';
import { addFunds, mineBlock } from '../_helpers';
interface ExampleContractState {
counter: number;
@@ -13,7 +13,7 @@ interface ExampleContractState {
lastName: string;
}
describe('Testing the SmartWeave client for WASM contract', () => {
describe('Testing the SmartWeave client for AssemblyScript WASM contract', () => {
let contractSrc: Buffer;
let initialState: string;
let contractTxId: string;
@@ -44,8 +44,8 @@ describe('Testing the SmartWeave client for WASM contract', () => {
wallet = await arweave.wallets.generate();
await addFunds(arweave, wallet);
contractSrc = fs.readFileSync(path.join(__dirname, 'data/wasm/counter.wasm'));
initialState = fs.readFileSync(path.join(__dirname, 'data/wasm/counter-init-state.json'), 'utf8');
contractSrc = fs.readFileSync(path.join(__dirname, '../data/wasm/assemblyscript-counter.wasm'));
initialState = fs.readFileSync(path.join(__dirname, '../data/wasm/counter-init-state.json'), 'utf8');
// deploying contract using the new SDK.
contractTxId = await smartweave.createContract.deploy({
@@ -69,6 +69,8 @@ describe('Testing the SmartWeave client for WASM contract', () => {
it('should properly deploy contract', async () => {
const contractTx = await arweave.transactions.get(contractTxId);
console.log(contractTx.id);
expect(contractTx).not.toBeNull();
expect(getTag(contractTx, SmartWeaveTags.CONTRACT_TYPE)).toEqual('wasm');
expect(getTag(contractTx, SmartWeaveTags.WASM_LANG)).toEqual('assemblyscript');
@@ -89,7 +91,7 @@ describe('Testing the SmartWeave client for WASM contract', () => {
for (let i = 0; i < 100; i++) {
await contract.writeInteraction({ function: 'increment' });
}
});
}, 10000);
it('should properly read state after adding interactions', async () => {
await mineBlock(arweave);

View File

@@ -0,0 +1,127 @@
import fs from 'fs';
import ArLocal from 'arlocal';
import Arweave from 'arweave';
import {JWKInterface} from 'arweave/node/lib/wallet';
import {
getTag,
InteractionResult,
LoggerFactory,
PstContract,
PstState,
SmartWeave,
SmartWeaveNodeFactory, SmartWeaveTags
} from '@smartweave';
import path from 'path';
import {addFunds, mineBlock} from "../_helpers";
describe('Testing the Rust WASM Profit Sharing Token', () => {
let contractSrc: string;
let wallet: JWKInterface;
let walletAddress: string;
let initialState: PstState;
let arweave: Arweave;
let arlocal: ArLocal;
let smartweave: SmartWeave;
let pst: PstContract;
let contractTxId: 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(1301, false);
await arlocal.start();
arweave = Arweave.init({
host: 'localhost',
port: 1301,
protocol: 'http'
});
LoggerFactory.INST.logLevel('error');
smartweave = SmartWeaveNodeFactory.memCached(arweave);
wallet = await arweave.wallets.generate();
await addFunds(arweave, wallet);
walletAddress = await arweave.wallets.jwkToAddress(wallet);
const contractSrc = fs.readFileSync(path.join(__dirname, '../data/wasm/smartweave_contract_bg.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 smartweave.createContract.deploy({
wallet,
initState: JSON.stringify(initialState),
src: contractSrc
});
// connecting to the PST contract
pst = smartweave.pst(contractTxId);
// connecting wallet to the PST contract
pst.connect(wallet);
await mineBlock(arweave);
});
afterAll(async () => {
await arlocal.stop();
});
it('should properly deploy contract', async () => {
const contractTx = await arweave.transactions.get(contractTxId);
console.log(contractTx.id);
expect(contractTx).not.toBeNull();
expect(getTag(contractTx, SmartWeaveTags.CONTRACT_TYPE)).toEqual('wasm');
expect(getTag(contractTx, SmartWeaveTags.WASM_LANG)).toEqual('rust');
const contractSrcTx = await arweave.transactions.get(getTag(contractTx, SmartWeaveTags.CONTRACT_SRC_TX_ID));
expect(getTag(contractSrcTx, SmartWeaveTags.CONTENT_TYPE)).toEqual('application/wasm');
expect(getTag(contractSrcTx, SmartWeaveTags.WASM_LANG)).toEqual('rust');
});
it('should read pst state and balance data', async () => {
expect(await pst.currentState()).toEqual(initialState);
expect((await pst.currentBalance('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M'))).toEqual(10000000);
expect((await pst.currentBalance('33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA'))).toEqual(23111222);
expect((await pst.currentBalance(walletAddress))).toEqual(555669);
});
it('should properly transfer tokens', async () => {
await pst.transfer({
target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M',
qty: 555
});
await mineBlock(arweave);
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');
expect(result).toEqual(10000000 + 555);
});
});

View File

@@ -67,7 +67,7 @@ describe.each(chunked)('v1 compare.suite %#', (contracts: string[]) => {
);
});
describe.each(chunkedGw)('gateways compare.suite %#', (contracts: string[]) => {
fdescribe.each(chunkedGw)('gateways compare.suite %#', (contracts: string[]) => {
// note: concurrent doesn't seem to be working here, duh...
// will probably need to manually split all the test cases to separate test files
it.concurrent.each(contracts)(

View File

@@ -101,6 +101,7 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
const baseState =
cachedState == null ? executionContext.contractDefinition.initState : cachedState.cachedValue.state;
const baseValidity = cachedState == null ? {} : cachedState.cachedValue.validity;
// eval state for the missing transactions - starting from latest value from cache.

View File

@@ -1,8 +1,9 @@
/* eslint-disable */
import { ContractData, ContractType, CreateContract, FromSrcTxContractData, SmartWeaveTags } from '@smartweave/core';
import {ContractData, ContractType, CreateContract, FromSrcTxContractData, SmartWeaveTags} from '@smartweave/core';
import Arweave from 'arweave';
import { LoggerFactory } from '@smartweave/logging';
import { imports } from './wasmImports';
import {LoggerFactory} from '@smartweave/logging';
import {asWasmImports} from './wasm/as-wasm-imports';
import {rustWasmImports} from "./wasm/rust-wasm-imports";
const wasmTypeMapping: Map<number, string> = new Map([
[1, 'assemblyscript'],
@@ -22,9 +23,9 @@ export class DefaultCreateContract implements CreateContract {
async deploy(contractData: ContractData): Promise<string> {
this.logger.debug('Creating new contract');
const { wallet, src, initState, tags, transfer } = contractData;
const {wallet, src, initState, tags, transfer} = contractData;
const srcTx = await this.arweave.createTransaction({ data: src }, wallet);
const srcTx = await this.arweave.createTransaction({data: src}, wallet);
const contractType: ContractType = src instanceof Buffer ? 'wasm' : 'js';
@@ -42,7 +43,7 @@ export class DefaultCreateContract implements CreateContract {
const module = await WebAssembly.instantiate(src, dummyImports());
// @ts-ignore
if (!module.instance.exports.type) {
throw new Error(`No info about source type in wasm binary. Did you forget to export global "type" value?`);
throw new Error(`No info about source type in wasm binary. Did you forget to export "type" function?`);
}
// @ts-ignore
const type = module.instance.exports.type();
@@ -78,9 +79,9 @@ export class DefaultCreateContract implements CreateContract {
async deployFromSourceTx(contractData: FromSrcTxContractData): Promise<string> {
this.logger.debug('Creating new contract from src tx');
const { wallet, srcTxId, initState, tags, transfer } = contractData;
const {wallet, srcTxId, initState, tags, transfer} = contractData;
let contractTX = await this.arweave.createTransaction({ data: initState }, wallet);
let contractTX = await this.arweave.createTransaction({data: initState}, wallet);
if (+transfer?.winstonQty > 0 && transfer.target.length) {
this.logger.debug('Creating additional transaction with AR transfer', transfer);
@@ -121,10 +122,17 @@ export class DefaultCreateContract implements CreateContract {
}
function dummyImports() {
return imports(
{
useGas: function () {}
} as any,
null
);
const dummySwGlobal = {
useGas: function () {
}
} as any;
const dummyModuleInstance = {
exports: {}
}
return {
...rustWasmImports(dummySwGlobal, dummyModuleInstance).imports,
...asWasmImports(dummySwGlobal, dummyModuleInstance)
}
}

View File

@@ -35,7 +35,8 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
protected constructor(
protected readonly arweave: Arweave,
private readonly executionContextModifiers: ExecutionContextModifier[] = []
) {}
) {
}
async eval<State>(
executionContext: ExecutionContext<State, HandlerApi<State>>,
@@ -56,8 +57,8 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
currentTx: CurrentTx[]
): Promise<EvalStateResult<State>> {
const stateEvaluationBenchmark = Benchmark.measure();
const { ignoreExceptions, stackTrace, internalWrites } = executionContext.evaluationOptions;
const { contract, contractDefinition, sortedInteractions } = executionContext;
const {ignoreExceptions, stackTrace, internalWrites} = executionContext.evaluationOptions;
const {contract, contractDefinition, sortedInteractions} = executionContext;
let currentState = baseState.state;
const validity = baseState.validity;
@@ -72,6 +73,8 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
let lastConfirmedTxState: { tx: GQLNodeInterface; state: EvalStateResult<State> } = null;
const missingInteractionsLength = missingInteractions.length;
executionContext.handler.initState(currentState);
for (let i = 0; i < missingInteractionsLength; i++) {
const missingInteraction = missingInteractions[i];
const singleInteractionBenchmark = Benchmark.measure();
@@ -94,7 +97,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
const interactionCall: InteractionCall = contract
.getCallStack()
.addInteractionData({ interaction: null, interactionTx, currentTx });
.addInteractionData({interaction: null, interactionTx, currentTx});
// creating a Contract instance for the "writing" contract
const writingContract = executionContext.smartweave.contract(
@@ -155,7 +158,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
gasUsed: 0 // TODO...
});
this.logger.debug('New state after internal write', { contractTxId: contractDefinition.txId, newState });
this.logger.debug('New state after internal write', {contractTxId: contractDefinition.txId, newState});
} else {
// "direct" interaction with this contract - "standard" processing
const inputTag = this.tagsParser.getInputTag(missingInteraction, executionContext.contractDefinition.txId);
@@ -224,7 +227,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
// I'm really NOT a fan of this "modify" feature, but I don't have idea how to better
// implement the "evolve" feature
for (const { modify } of this.executionContextModifiers) {
for (const {modify} of this.executionContextModifiers) {
executionContext = await modify<State>(currentState, executionContext);
}
}

View File

@@ -11,9 +11,10 @@ import {
} from '@smartweave';
import { ContractHandlerApi } from './ContractHandlerApi';
import loader from '@assemblyscript/loader';
import { imports } from './wasmImports';
import { WasmContractHandlerApi } from './WasmContractHandlerApi';
import metering from 'redstone-wasm-metering';
import { asWasmImports } from './wasm/as-wasm-imports';
import { rustWasmImports } from './wasm/rust-wasm-imports';
/**
* A factory that produces handlers that are compatible with the "current" style of
@@ -30,29 +31,56 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
owner: contractDefinition.owner
});
if (contractDefinition.contractType == 'js') {
if (contractDefinition.contractType == 'wasm') {
this.logger.info('Creating handler for wasm contract', contractDefinition.txId);
const meteredWasmBinary = metering.meterWASM(contractDefinition.srcBinary, {
meterType: 'i32'
});
let wasmInstance;
let jsExports = null;
switch (contractDefinition.srcWasmLang) {
case 'assemblyscript': {
const wasmInstanceExports = {
exports: null
};
wasmInstance = loader.instantiateSync(meteredWasmBinary, asWasmImports(swGlobal, wasmInstanceExports));
// note: well, exports are required by some imports
// - e.g. those that use wasmModule.exports.__newString underneath (like Block.indep_hash)
wasmInstanceExports.exports = wasmInstance.exports;
break;
}
case 'rust': {
const wasmInstanceExports = {
exports: null
};
const wasmModule = new WebAssembly.Module(meteredWasmBinary);
const { imports, exports } = rustWasmImports(swGlobal, wasmInstanceExports);
jsExports = exports;
this.logger.debug('Imports', imports);
wasmInstance = new WebAssembly.Instance(wasmModule, imports);
wasmInstanceExports.exports = wasmInstance.exports;
break;
}
default: {
throw new Error(`Support for ${contractDefinition.srcWasmLang} not implemented yet.`);
}
}
return new WasmContractHandlerApi(swGlobal, contractDefinition, jsExports || wasmInstance.exports);
} else {
this.logger.info('Creating handler for js contract', contractDefinition.txId);
const normalizedSource = normalizeContractSource(contractDefinition.src);
const contractFunction = new Function(normalizedSource);
return new ContractHandlerApi(swGlobal, contractFunction, contractDefinition);
} else {
this.logger.info('Creating handler for wasm contract', contractDefinition.txId);
const wasmModuleData = {
exports: null
};
const meteredWasmBinary = metering.meterWASM(contractDefinition.srcBinary, {
meterType: 'i32'
});
const wasmModule = loader.instantiateSync(meteredWasmBinary, imports(swGlobal, wasmModuleData));
wasmModuleData.exports = wasmModule.exports;
return new WasmContractHandlerApi(swGlobal, contractDefinition, wasmModule.exports);
}
}
}

View File

@@ -24,11 +24,6 @@ export class WasmContractHandlerApi<State> implements HandlerApi<State> {
this.contractLogger = LoggerFactory.INST.create(swGlobal.contract.id);
}
initState(state: State): void {
const statePtr = this.wasmExports.__newString(stringify(state));
this.wasmExports.initState(statePtr);
}
async handle<Input, Result>(
executionContext: ExecutionContext<State>,
currentResult: EvalStateResult<State>,
@@ -43,7 +38,7 @@ export class WasmContractHandlerApi<State> implements HandlerApi<State> {
this.swGlobal.gasLimit = executionContext.evaluationOptions.gasLimit;
this.swGlobal.gasUsed = 0;
const handlerResult = this.doHandle(interaction);
const handlerResult = await this.doHandle(interaction);
return {
type: 'ok',
@@ -83,17 +78,70 @@ export class WasmContractHandlerApi<State> implements HandlerApi<State> {
}
}
private doHandle(action: any): any {
this.logger.debug('Action', action.input);
const actionPtr = this.wasmExports.__newString(stringify(action.input));
const resultPtr = this.wasmExports.handle(actionPtr);
const result = this.wasmExports.__getString(resultPtr);
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.logger.debug('Before init state', this.wasmExports);
this.wasmExports.initState(state);
this.logger.debug('After init state');
break;
}
default: {
throw new Error(`Support for ${this.contractDefinition.srcWasmLang} not implemented yet.`);
}
}
}
return JSON.parse(result);
private async doHandle(action: any): Promise<any> {
switch (this.contractDefinition.srcWasmLang) {
case "assemblyscript": {
this.logger.debug('Action', action.input);
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": {
this.logger.debug("exports", this.wasmExports);
let handleResult = await this.wasmExports.handle(action.input);
this.logger.debug("handleResult", handleResult);
if (!handleResult) {
return;
}
this.logger.debug("handleResult.ok", handleResult.Ok);
if (Object.prototype.hasOwnProperty.call(handleResult, 'Ok')) {
return handleResult.Ok;
} else {
throw new Error(handleResult.Err)
}
}
default: {
throw new Error(`Support for ${this.contractDefinition.srcWasmLang} not implemented yet.`);
}
}
}
private doGetCurrentState(): State {
const currentStatePtr = this.wasmExports.currentState();
return JSON.parse(this.wasmExports.__getString(currentStatePtr));
switch (this.contractDefinition.srcWasmLang) {
case "assemblyscript": {
const currentStatePtr = this.wasmExports.currentState();
return JSON.parse(this.wasmExports.__getString(currentStatePtr));
}
case "rust": {
return this.wasmExports.currentState();
}
default: {
throw new Error(`Support for ${this.contractDefinition.srcWasmLang} not implemented yet.`);
}
}
}
}

View File

@@ -1,6 +1,6 @@
import { LoggerFactory, SmartWeaveGlobal } from '@smartweave';
export const imports = (swGlobal: SmartWeaveGlobal, wasmModule: any): any => {
export const asWasmImports = (swGlobal: SmartWeaveGlobal, wasmInstance: any): any => {
const wasmLogger = LoggerFactory.INST.create('WASM');
return {
@@ -9,12 +9,12 @@ export const imports = (swGlobal: SmartWeaveGlobal, wasmModule: any): any => {
},
console: {
'console.log': function (msgPtr) {
wasmLogger.debug(`${swGlobal.contract.id}: ${wasmModule.exports.__getString(msgPtr)}`);
wasmLogger.debug(`${swGlobal.contract.id}: ${wasmInstance.exports.__getString(msgPtr)}`);
},
'console.logO': function (msgPtr, objPtr) {
wasmLogger.debug(
`${swGlobal.contract.id}: ${wasmModule.exports.__getString(msgPtr)}`,
JSON.parse(wasmModule.exports.__getString(objPtr))
`${swGlobal.contract.id}: ${wasmInstance.exports.__getString(msgPtr)}`,
JSON.parse(wasmInstance.exports.__getString(objPtr))
);
}
},
@@ -23,7 +23,7 @@ export const imports = (swGlobal: SmartWeaveGlobal, wasmModule: any): any => {
return swGlobal.block.height;
},
'Block.indep_hash': function () {
return wasmModule.exports.__newString(swGlobal.block.indep_hash);
return wasmInstance.exports.__newString(swGlobal.block.indep_hash);
},
'Block.timestamp': function () {
return swGlobal.block.timestamp;
@@ -31,32 +31,32 @@ export const imports = (swGlobal: SmartWeaveGlobal, wasmModule: any): any => {
},
transaction: {
'Transaction.id': function () {
return wasmModule.exports.__newString(swGlobal.transaction.id);
return wasmInstance.exports.__newString(swGlobal.transaction.id);
},
'Transaction.owner': function () {
return wasmModule.exports.__newString(swGlobal.transaction.owner);
return wasmInstance.exports.__newString(swGlobal.transaction.owner);
},
'Transaction.target': function () {
return wasmModule.exports.__newString(swGlobal.transaction.target);
return wasmInstance.exports.__newString(swGlobal.transaction.target);
}
},
contract: {
'Contract.id': function () {
return wasmModule.exports.__newString(swGlobal.contract.id);
return wasmInstance.exports.__newString(swGlobal.contract.id);
},
'Contract.owner': function () {
return wasmModule.exports.__newString(swGlobal.contract.owner);
return wasmInstance.exports.__newString(swGlobal.contract.owner);
}
},
api: {
_readContractState: (fnIndex, contractTxIdPtr) => {
const contractTxId = wasmModule.exports.__getString(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(
wasmModule.exports.__newString(
wasmInstance.exports.__newString(
JSON.stringify({
contractTxId
})
@@ -69,8 +69,8 @@ export const imports = (swGlobal: SmartWeaveGlobal, wasmModule: any): any => {
env: {
abort(messagePtr, fileNamePtr, line, column) {
console.error('--------------------- Error message from AssemblyScript ----------------------');
console.error(' ' + wasmModule.exports.__getString(messagePtr));
console.error(' In file "' + wasmModule.exports.__getString(fileNamePtr) + '"');
console.error(' ' + wasmInstance.exports.__getString(messagePtr));
console.error(' In file "' + wasmInstance.exports.__getString(fileNamePtr) + '"');
console.error(` on line ${line}, column ${column}.`);
console.error('------------------------------------------------------------------------------\n');
}
@@ -78,6 +78,6 @@ export const imports = (swGlobal: SmartWeaveGlobal, wasmModule: any): any => {
};
function getFn(idx) {
return wasmModule.exports.table.get(idx);
return wasmInstance.exports.table.get(idx);
}
};

View File

@@ -0,0 +1,523 @@
/* tslint:disable */
/* eslint-disable */
/* a kind of magic */
import {LoggerFactory, timeout} from "@smartweave";
export const rustWasmImports = (swGlobal, wasmInstance: any): any => {
const wasmLogger = LoggerFactory.INST.create('WASM');
//const wasm = wasmInstance.exports;
const rawImports = {
metering: {
usegas: swGlobal.useGas
},
"console": {
log: function (value) {
wasmLogger.debug(`${swGlobal.contract.id}: ${value}`);
}
},
"Block": {
height: function () {
return swGlobal.block.height;
},
indep_hash: function () {
return swGlobal.block.indep_hash;
},
timestamp: function () {
return swGlobal.block.timestamp;
}
},
"Transaction": {
id: function () {
return swGlobal.transaction.id;
},
owner: function () {
return swGlobal.transaction.owner;
},
target: function () {
return swGlobal.transaction.target;
},
},
"Contract": {
id: function () {
return swGlobal.contract.id;
},
owner: function () {
return swGlobal.contract.owner;
}
},
"SmartWeave": {
readContractState: async function (contractTxId) {
console.log('js: readContractState before timeout');
await timeout(1000);
console.log('js: readContractState after timeout');
return {
value: contractTxId
}
}
}
}
let exports: any = {};
let imports: any = {};
imports['__wbindgen_placeholder__'] = exports;
const {TextDecoder, TextEncoder} = require(`util`);
let cachedTextDecoder = new TextDecoder('utf-8', {ignoreBOM: true, fatal: true});
cachedTextDecoder.decode();
let cachegetUint8Memory0 = null;
function getUint8Memory0() {
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasmInstance.exports.memory.buffer) {
cachegetUint8Memory0 = new Uint8Array(wasmInstance.exports.memory.buffer);
}
return cachegetUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
const heap = new Array(32).fill(undefined);
heap.push(undefined, null, true, false);
let heap_next = heap.length;
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
function getObject(idx) {
return heap[idx];
}
let WASM_VECTOR_LEN = 0;
let cachedTextEncoder = new TextEncoder('utf-8');
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length);
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len);
const mem = getUint8Memory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3);
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
offset += ret.written;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
let cachegetInt32Memory0 = null;
function getInt32Memory0() {
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasmInstance.exports.memory.buffer) {
cachegetInt32Memory0 = new Int32Array(wasmInstance.exports.memory.buffer);
}
return cachegetInt32Memory0;
}
function dropObject(idx) {
if (idx < 36) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
function debugString(val) {
// primitive types
const type = typeof val;
if (type == 'number' || type == 'boolean' || val == null) {
return `${val}`;
}
if (type == 'string') {
return `"${val}"`;
}
if (type == 'symbol') {
const description = val.description;
if (description == null) {
return 'Symbol';
} else {
return `Symbol(${description})`;
}
}
if (type == 'function') {
const name = val.name;
if (typeof name == 'string' && name.length > 0) {
return `Function(${name})`;
} else {
return 'Function';
}
}
// objects
if (Array.isArray(val)) {
const length = val.length;
let debug = '[';
if (length > 0) {
debug += debugString(val[0]);
}
for (let i = 1; i < length; i++) {
debug += ', ' + debugString(val[i]);
}
debug += ']';
return debug;
}
// Test for built-in
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
let className;
if (builtInMatches.length > 1) {
className = builtInMatches[1];
} else {
// Failed to match the standard '[object ClassName]'
return toString.call(val);
}
if (className == 'Object') {
// we're a user defined class or Object
// JSON.stringify avoids problems with cycles, and is generally much
// easier than looping through ownProperties of `val`.
try {
return 'Object(' + JSON.stringify(val) + ')';
} catch (_) {
return 'Object';
}
}
// errors
if (val instanceof Error) {
return `${val.name}: ${val.message}\n${val.stack}`;
}
// TODO we could test for more things here, like `Set`s and `Map`s.
return className;
}
function makeMutClosure(arg0, arg1, dtor, f) {
const state = {a: arg0, b: arg1, cnt: 1, dtor};
const real = (...args) => {
// First up with a closure we increment the internal reference
// count. This ensures that the Rust closure environment won't
// be deallocated while we're invoking it.
state.cnt++;
const a = state.a;
state.a = 0;
try {
return f(a, state.b, ...args);
} finally {
if (--state.cnt === 0) {
wasmInstance.exports.__wbindgen_export_2.get(state.dtor)(a, state.b);
} else {
state.a = a;
}
}
};
real.original = state;
return real;
}
function __wbg_adapter_14(arg0, arg1, arg2) {
wasmInstance.exports._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h0af8cf16c8647f23(arg0, arg1, addHeapObject(arg2));
}
/**
* @param {any} interaction
* @returns {Promise<any>}
*/
exports.handle = function (interaction) {
console.log("handleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", interaction);
console.log("handleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", wasmInstance.exports.handle);
var ret = wasmInstance.exports.handle(addHeapObject(interaction));
return takeObject(ret);
};
let stack_pointer = 32;
function addBorrowedObject(obj) {
if (stack_pointer == 1) throw new Error('out of js stack');
heap[--stack_pointer] = obj;
return stack_pointer;
}
/**
* @param {any} state
*/
exports.initState = function (state) {
console.log("INIT STATE11111111");
try {
console.log(state);
wasmInstance.exports.initState(addBorrowedObject(state));
} finally {
heap[stack_pointer++] = undefined;
}
};
/**
* @returns {any}
*/
exports.currentState = function () {
var ret = wasmInstance.exports.currentState();
return takeObject(ret);
};
/**
* @returns {string}
*/
exports.lang = function () {
try {
const retptr = wasmInstance.exports.__wbindgen_add_to_stack_pointer(-16);
wasmInstance.exports.lang(retptr);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasmInstance.exports.__wbindgen_add_to_stack_pointer(16);
wasmInstance.exports.__wbindgen_free(r0, r1);
}
};
/**
* @returns {number}
*/
exports.type = function () {
var ret = wasmInstance.exports.type();
return ret;
};
function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
wasmInstance.exports.__wbindgen_exn_store(addHeapObject(e));
}
}
function __wbg_adapter_42(arg0, arg1, arg2, arg3) {
wasmInstance.exports.wasm_bindgen__convert__closures__invoke2_mut__h1aa5ebac0642c58b(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
}
/**
*/
class StateWrapper {
__destroy_into_raw() {
// @ts-ignore
const ptr = this.ptr;
// @ts-ignore
this.ptr = 0;
return ptr;
}
free() {
const ptr = this.__destroy_into_raw();
wasmInstance.exports.__wbg_statewrapper_free(ptr);
}
}
exports.StateWrapper = StateWrapper;
exports.__wbg_indephash_5169b74d7073ec06 = function (arg0) {
console.log("block indep hash");
var ret = rawImports.Block.indep_hash();
var ptr0 = passStringToWasm0(ret, wasmInstance.exports.__wbindgen_malloc, wasmInstance.exports.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};
exports.__wbg_height_7e2d5ab154a32c53 = function () {
var ret = rawImports.Block.height();
return ret;
};
exports.__wbg_timestamp_b2ae03e8830bf361 = function () {
var ret = rawImports.Block.timestamp();
return ret;
};
exports.__wbg_id_96159534c1352b1f = function () {
var ret = rawImports.Contract.id();
return ret;
};
exports.__wbg_owner_584edbeb2fc79632 = function (arg0) {
var ret = rawImports.Contract.owner();
var ptr0 = passStringToWasm0(ret, wasmInstance.exports.__wbindgen_malloc, wasmInstance.exports.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};
exports.__wbg_id_004f7156a1dccfe0 = function () {
var ret = rawImports.Transaction.id();
return ret;
};
exports.__wbg_owner_3b98731ef4bca542 = function (arg0) {
var ret = rawImports.Transaction.owner();
var ptr0 = passStringToWasm0(ret, wasmInstance.exports.__wbindgen_malloc, wasmInstance.exports.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};
exports.__wbg_target_900d26a5419b4869 = function (arg0) {
var ret = rawImports.Transaction.target();
var ptr0 = passStringToWasm0(ret, wasmInstance.exports.__wbindgen_malloc, wasmInstance.exports.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};
exports.__wbg_log_5f1f23db3aa2a6c6 = function (arg0, arg1) {
rawImports.console.log(getStringFromWasm0(arg0, arg1));
};
exports.__wbindgen_json_parse = function (arg0, arg1) {
var ret = JSON.parse(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
exports.__wbindgen_json_serialize = function (arg0, arg1) {
const obj = getObject(arg1);
var ret = JSON.stringify(obj === undefined ? null : obj);
var ptr0 = passStringToWasm0(ret, wasmInstance.exports.__wbindgen_malloc, wasmInstance.exports.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};
exports.__wbindgen_object_drop_ref = function (arg0) {
takeObject(arg0);
};
exports.__wbindgen_cb_drop = function (arg0) {
const obj = takeObject(arg0).original;
if (obj.cnt-- == 1) {
obj.a = 0;
return true;
}
var ret = false;
return ret;
};
exports.__wbg_readContractState_251600c2ccc5a557 = function (arg0, arg1) {
var ret = rawImports.SmartWeave.readContractState(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
exports.__wbg_call_94697a95cb7e239c = function () {
return handleError(function (arg0, arg1, arg2) {
var ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments)
};
exports.__wbg_new_4beacc9c71572250 = function (arg0, arg1) {
try {
var state0 = {a: arg0, b: arg1};
var cb0 = (arg0, arg1) => {
const a = state0.a;
state0.a = 0;
try {
return __wbg_adapter_42(a, state0.b, arg0, arg1);
} finally {
state0.a = a;
}
};
var ret = new Promise(cb0);
return addHeapObject(ret);
} finally {
state0.a = state0.b = 0;
}
};
exports.__wbg_resolve_4f8f547f26b30b27 = function (arg0) {
var ret = Promise.resolve(getObject(arg0));
return addHeapObject(ret);
};
exports.__wbg_then_a6860c82b90816ca = function (arg0, arg1) {
var ret = getObject(arg0).then(getObject(arg1));
return addHeapObject(ret);
};
exports.__wbg_then_58a04e42527f52c6 = function (arg0, arg1, arg2) {
var ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
};
exports.__wbindgen_debug_string = function (arg0, arg1) {
var ret = debugString(getObject(arg1));
var ptr0 = passStringToWasm0(ret, wasmInstance.exports.__wbindgen_malloc, wasmInstance.exports.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};
exports.__wbindgen_throw = function (arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
exports.__wbindgen_closure_wrapper218 = function (arg0, arg1, arg2) {
var ret = makeMutClosure(arg0, arg1, 75, __wbg_adapter_14);
return addHeapObject(ret);
};
imports.metering = rawImports.metering;
return {imports, exports};
}

265
tools/report.json Normal file
View File

@@ -0,0 +1,265 @@
{
"contractTxId": "sR3FG6Wvvq0uYeILMCkK-tG7i2N0fxIB2LpgqgS__TI",
"depth": 0,
"label": "",
"interactions": {
"dataType": "Map",
"value": [
[
"W1COLMVJN2nr1G-Qe03lozP6fOKFotXxyxRR5FSU6pc",
{
"interactionInput": {
"txId": "W1COLMVJN2nr1G-Qe03lozP6fOKFotXxyxRR5FSU6pc",
"blockHeight": 879965,
"blockTimestamp": 1645687971,
"caller": "LOLS0MQ6sKprHDYVgwfYaMm0ypRmVU0T6oYQxrx3Bks",
"functionArguments": [
{
"function": "transfer",
"qty": "1000000000000000",
"target": "kyGgyXpsHGX8wT9Oe4rsIGNb7ilybknVvSjcrLKVt1Y"
},
{
"function": "transfer",
"qty": "1000000000000000",
"target": "SFvtYkST38oYwQGG1NuVeA7EMaM2QLhzBXGwDXe1fjg"
},
{
"function": "transfer",
"qty": "1000000000000000",
"target": "FDtVABwHgn1VL4bgLwkiP-UbWtvSBZ-XZ9TLuQDN1fQ"
},
{
"function": "transfer",
"qty": "1000000000000000",
"target": "iqqGjbgTJIrXVo71pySg2uiwhqEb-QShNGj-APcxhoQ"
}
],
"foreignContractCalls": {
"dataType": "Map",
"value": []
}
},
"interactionOutput": {
"cacheHit": false,
"intermediaryCacheHit": false,
"executionTime": 6,
"errorMessage": "No function supplied or function not recognised: \\"
undefined
\
\
""
}
}
],
[
"p5tPewKCHD8P6w4p-Jtn0UIV0CwaZCSUZt6PV9vezRg",
{
"interactionInput": {
"txId": "p5tPewKCHD8P6w4p-Jtn0UIV0CwaZCSUZt6PV9vezRg",
"blockHeight": 879975,
"blockTimestamp": 1645688473,
"caller": "LOLS0MQ6sKprHDYVgwfYaMm0ypRmVU0T6oYQxrx3Bks",
"functionArguments": [
{
"function": "transfer",
"qty": 1000000000000000,
"target": "kyGgyXpsHGX8wT9Oe4rsIGNb7ilybknVvSjcrLKVt1Y"
},
{
"function": "transfer",
"qty": 1000000000000000,
"target": "SFvtYkST38oYwQGG1NuVeA7EMaM2QLhzBXGwDXe1fjg"
},
{
"function": "transfer",
"qty": 1000000000000000,
"target": "FDtVABwHgn1VL4bgLwkiP-UbWtvSBZ-XZ9TLuQDN1fQ"
},
{
"function": "transfer",
"qty": 1000000000000000,
"target": "iqqGjbgTJIrXVo71pySg2uiwhqEb-QShNGj-APcxhoQ"
}
],
"foreignContractCalls": {
"dataType": "Map",
"value": []
}
},
"interactionOutput": {
"cacheHit": false,
"intermediaryCacheHit": false,
"executionTime": 2,
"errorMessage": "No function supplied or function not recognised: \\"
undefined
\
\
""
}
}
],
[
"iJoZwH9dwHPWS8l0z4j6JRNOET_mXjHdi10eVOnGnhA",
{
"interactionInput": {
"txId": "iJoZwH9dwHPWS8l0z4j6JRNOET_mXjHdi10eVOnGnhA",
"blockHeight": 879981,
"blockTimestamp": 1645689677,
"caller": "LOLS0MQ6sKprHDYVgwfYaMm0ypRmVU0T6oYQxrx3Bks",
"functionArguments": [
{
"function": "transfer",
"qty": 1000000000000000,
"target": "DEgJqP8Zd4RBld0JCuc2U-UKtUJyNtLcW6jt4k6L1pQ"
}
],
"foreignContractCalls": {
"dataType": "Map",
"value": []
}
},
"interactionOutput": {
"cacheHit": false,
"intermediaryCacheHit": false,
"executionTime": 2,
"errorMessage": "No function supplied or function not recognised: \\"
undefined
\
\
""
}
}
],
[
"WHiXm0P6BTne5_VxNk76U4H6Zl3D_SoQ8-KRaAMlgNM",
{
"interactionInput": {
"txId": "WHiXm0P6BTne5_VxNk76U4H6Zl3D_SoQ8-KRaAMlgNM",
"blockHeight": 879985,
"blockTimestamp": 1645690362,
"caller": "LOLS0MQ6sKprHDYVgwfYaMm0ypRmVU0T6oYQxrx3Bks",
"functionName": "transfer",
"functionArguments": {
"function": "transfer",
"qty": 1000000000000000,
"target": "DEgJqP8Zd4RBld0JCuc2U-UKtUJyNtLcW6jt4k6L1pQ"
},
"foreignContractCalls": {
"dataType": "Map",
"value": []
}
},
"interactionOutput": {
"cacheHit": false,
"intermediaryCacheHit": false,
"executionTime": 1
}
}
],
[
"6IOtBWPh-9loPiJ8V2zIo1NzGtYNn4kA_Xdt9P1IIFg",
{
"interactionInput": {
"txId": "6IOtBWPh-9loPiJ8V2zIo1NzGtYNn4kA_Xdt9P1IIFg",
"blockHeight": 880001,
"blockTimestamp": 1645692336,
"caller": "LOLS0MQ6sKprHDYVgwfYaMm0ypRmVU0T6oYQxrx3Bks",
"functionArguments": [
{
"function": "transfer",
"qty": 1000000000000000,
"target": "kyGgyXpsHGX8wT9Oe4rsIGNb7ilybknVvSjcrLKVt1Y"
},
{
"function": "transfer",
"qty": 1000000000000000,
"target": "SFvtYkST38oYwQGG1NuVeA7EMaM2QLhzBXGwDXe1fjg"
}
],
"foreignContractCalls": {
"dataType": "Map",
"value": []
}
},
"interactionOutput": {
"cacheHit": false,
"intermediaryCacheHit": false,
"executionTime": 2,
"errorMessage": "No function supplied or function not recognised: \\"
undefined
\
\
""
}
}
],
[
"ipmwMylSfoiXUPqm8e5_oLvzWAoel98jRt00ewJa7hk",
{
"interactionInput": {
"txId": "ipmwMylSfoiXUPqm8e5_oLvzWAoel98jRt00ewJa7hk",
"blockHeight": 880051,
"blockTimestamp": 1645698048,
"caller": "LOLS0MQ6sKprHDYVgwfYaMm0ypRmVU0T6oYQxrx3Bks",
"functionArguments": "[{\\"
function
\
\
":\\"
transfer
\
\
",\\"
qty
\
\
":1000000000000000,\\"
target
\
\
":\\"
kyGgyXpsHGX8wT9Oe4rsIGNb7ilybknVvSjcrLKVt1Y
\
\
"},{\\"
function
\
\
":\\"
transfer
\
\
",\\"
qty
\
\
":1000000000000000,\\"
target
\
\
":\\"
SFvtYkST38oYwQGG1NuVeA7EMaM2QLhzBXGwDXe1fjg
\
\
"}]",
"foreignContractCalls": {
"dataType": "Map",
"value": []
}
},
"interactionOutput": {
"cacheHit": false,
"intermediaryCacheHit": false,
"executionTime": 1,
"errorMessage": "No function supplied or function not recognised: \\"
undefined
\
\
""
}
}
]
]
}
}