Skip to content

Commit

Permalink
added wasm test
Browse files Browse the repository at this point in the history
  • Loading branch information
kouraf committed Mar 16, 2022
1 parent 8552997 commit 2a1e992
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 18 deletions.
Binary file added __tests__/integration/data/wasm/go-pst.wasm
Binary file not shown.
205 changes: 205 additions & 0 deletions __tests__/integration/wasm.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import fs from 'fs';

import ArLocal from '../../src/app';
import Arweave from 'arweave';
import { JWKInterface } from 'arweave/node/lib/wallet';
import {
getTag,
LoggerFactory,
PstContract,
PstState,
SmartWeave,
SmartWeaveNodeFactory,
SmartWeaveTags,
} from 'redstone-smartweave';
import path from 'path';

describe('Testing the Go WASM Profit Sharing Token', () => {
let wallet: JWKInterface;
let walletAddress: string;

let initialState: PstState;

let arweave: Arweave;
let arlocal: ArLocal;
let smartweave: SmartWeave;
let pst: PstContract;

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();

arweave = Arweave.init({
host: 'localhost',
port: 1150,
protocol: 'http',
});

LoggerFactory.INST.logLevel('error');

smartweave = SmartWeaveNodeFactory.memCached(arweave);

wallet = await arweave.wallets.generate();

const address = await arweave.wallets.getAddress(wallet);
await arweave.api.get(`/mint/${address}/100000000000000000000`);
walletAddress = await arweave.wallets.jwkToAddress(wallet);

const contractSrc = fs.readFileSync(path.join(__dirname, './data/wasm/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,
},
},
};
properForeignContractTxId = await smartweave.createContract.deploy({
wallet,
initState: JSON.stringify({
...initialState,
...{
ticker: 'FOREIGN_PST',
name: 'foreign contract',
},
}),
src: contractSrc,
});

wrongForeignContractTxId = await smartweave.createContract.deploy({
wallet,
initState: JSON.stringify({
...initialState,
...{
ticker: 'FOREIGN_PST_2',
name: 'foreign contract 2',
},
}),
src: contractSrc,
});

// 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 arweave.api.get('mine');
});

afterAll(async () => {
await arlocal.stop();
});

it('should properly deploy contract', async () => {
const contractTx = await arweave.transactions.get(contractTxId);

expect(contractTx).not.toBeNull();
expect(getTag(contractTx, SmartWeaveTags.CONTRACT_TYPE)).toEqual('wasm');
expect(getTag(contractTx, SmartWeaveTags.WASM_LANG)).toEqual('go');

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('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 arweave.api.get('mine');

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 arweave.api.get('mine');
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 arweave.api.get('mine');
expect((await pst.currentState()).balances[walletAddress]).toEqual(555669 - 555 + 1000);
expect((await pst.currentState()).balances['uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M']).toEqual(
10000000 + 555 + 1000,
);
});

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 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();
});
});
5 changes: 3 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ module.exports = {
},
verbose: true,
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'js'],
transform: {
'node_modules/variables/.+\\.(j|t)sx?$': 'ts-jest',
'^.+\\.(ts|js)$': 'ts-jest',
},
transformIgnorePatterns: ['node_modules/(?!variables/.*)'],
transformIgnorePatterns: ['<rootDir>/node_modules/(?!@assemblyscript/.*)'],
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"tsc-watch": "^4.6.0"
},
"devDependencies": {
"@assemblyscript/loader": "^0.19.23",
"@types/jest": "^27.4.0",
"@types/koa": "^2.13.4",
"@types/koa-bodyparser": "^4.3.5",
Expand All @@ -72,7 +73,8 @@
"copyfiles": "^2.4.1",
"jest": "^27.4.7",
"prettier": "^2.5.1",
"redstone-smartweave": "^0.4.16",
"redstone-smartweave": "^0.4.47",
"redstone-wasm-metering": "^1.0.1",
"rimraf": "^3.0.2",
"supertest": "^6.2.2",
"ts-jest": "^27.1.3",
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"lib": ["es2019", "DOM"]
"lib": ["es2019", "DOM"],
"allowJs": true
},
"include": ["src", "__tests__"],
"exclude": ["node_modules", "**/__tests__/*"]
Expand Down
Loading

0 comments on commit 2a1e992

Please sign in to comment.