Implement typeConversion APIs bytesToHex, bigIntToString and stringToH160 (#19)

* Implement host api typeConversion.bytesToHex

* Complete host api bigIntToString.

* Create TypeId for assemblyscript loader.

* Implement host apis bigInt fromString, plus and minus
This commit is contained in:
2021-12-28 16:08:04 +05:30
committed by nabarun
parent d247815ce2
commit e10f61ba61
6 changed files with 425 additions and 42 deletions
+143 -6
View File
@@ -4,6 +4,11 @@
import fs from 'fs/promises';
import loader from '@assemblyscript/loader';
import { utils, BigNumber } from 'ethers';
import { TypeId } from './types';
type idOfType = (TypeId: number) => number
export const instantiate = async (filePath: string): Promise<loader.ResultObject & { exports: any }> => {
const buffer = await fs.readFile(filePath);
@@ -18,16 +23,16 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
},
'typeConversion.stringToH160': () => {
console.log('typeConversion.stringToH160');
console.log('index typeConversion.stringToH160');
},
'typeConversion.bytesToHex': () => {
console.log('typeConversion.bytesToHex');
console.log('index typeConversion.bytesToHex');
},
// 'typeConversion.bytesToString': () => {
// console.log('typeConversion.bytesToString');
// },
'typeConversion.bigIntToString': () => {
console.log('typeConversion.bigIntToString');
console.log('index typeConversion.bigIntToString');
},
// 'bigDecimal.fromString': () => {
@@ -83,8 +88,136 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
}
},
conversion: {
'typeConversion.stringToH160': () => {
console.log('typeConversion.stringToH160');
'typeConversion.stringToH160': (s: number) => {
const string = __getString(s);
const address = utils.getAddress(string);
const byteArray = utils.arrayify(address);
const uint8ArrayId = getIdOfType(TypeId.Uint8Array);
const ptr = __newArray(uint8ArrayId, byteArray);
return ptr;
},
'typeConversion.bigIntToString': (bigInt: number) => {
const bigIntByteArray = __getArray(bigInt);
const bigNumber = BigNumber.from(bigIntByteArray);
const ptr = __newString(bigNumber.toString());
return ptr;
},
'typeConversion.bigIntToHex': () => {
console.log('index typeConversion.bigIntToHex');
},
'typeConversion.bytesToHex': (bytes: number) => {
const byteArray = __getArray(bytes);
const hexString = utils.hexlify(byteArray);
const ptr = __newString(hexString);
return ptr;
},
'typeConversion.bytesToString': () => {
console.log('index typeConversion.bytesToString');
},
'typeConversion.bytesToBase58': () => {
console.log('index typeConversion.bytesToBase58');
}
},
numbers: {
'bigDecimal.dividedBy': (x: number, y: number) => {
console.log('numbers bigDecimal.dividedBy');
const bigDecimaly = BigDecimal.wrap(y);
const yDigitsBigIntArray = __getArray(bigDecimaly.digits);
const yDigits = BigNumber.from(yDigitsBigIntArray);
const yExpBigIntArray = __getArray(bigDecimaly.exp);
const yExp = BigNumber.from(yExpBigIntArray);
console.log('y digits and exp', yDigits, yExp);
},
'bigDecimal.toString': () => {
console.log('numbers bigDecimal.toString');
},
'bigDecimal.fromString': () => {
console.log('numbers bigDecimal.toString');
},
'bigDecimal.plus': () => {
console.log('bigDecimal.plus');
},
'bigDecimal.minus': () => {
console.log('bigDecimal.minus');
},
'bigDecimal.times': () => {
console.log('bigDecimal.times');
},
'bigInt.fromString': (s: number) => {
const string = __getString(s);
const bigNumber = BigNumber.from(string);
const hex = bigNumber.toHexString();
const bytes = utils.arrayify(hex);
const uint8ArrayId = getIdOfType(TypeId.Uint8Array);
const ptr = __newArray(uint8ArrayId, bytes);
const bigInt = BigInt.fromSignedBytes(ptr);
return bigInt;
},
'bigInt.plus': (x: number, y: number) => {
const xBigIntArray = __getArray(x);
const xBigNumber = BigNumber.from(xBigIntArray);
const yBigIntArray = __getArray(y);
const yBigNumber = BigNumber.from(yBigIntArray);
const sum = xBigNumber.add(yBigNumber);
const ptr = __newString(sum.toString());
const sumBigInt = BigInt.fromString(ptr);
return sumBigInt;
},
'bigInt.minus': (x: number, y: number) => {
const xBigIntArray = __getArray(x);
const xBigNumber = BigNumber.from(xBigIntArray);
const yBigIntArray = __getArray(y);
const yBigNumber = BigNumber.from(yBigIntArray);
const diff = xBigNumber.sub(yBigNumber);
const ptr = __newString(diff.toString());
const sumBigInt = BigInt.fromString(ptr);
return sumBigInt;
},
'bigInt.dividedBy': () => {
console.log('bigInt.dividedBy');
},
'bigInt.times': () => {
console.log('bigInt.times');
},
'bigInt.dividedByDecimal': () => {
console.log('bigInt.dividedByDecimal');
},
'bigInt.mod': () => {
console.log('bigInt.mod');
},
'bigInt.bitOr': () => {
console.log('bigInt.bitOr');
},
'bigInt.bitAnd': () => {
console.log('bigInt.bitAnd');
},
'bigInt.leftShift': () => {
console.log('bigInt.leftShift');
},
'bigInt.rightShift': () => {
console.log('bigInt.rightShift');
},
'bigInt.pow': () => {
console.log('bigInt.pow');
}
}
};
@@ -92,7 +225,11 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
const instance = await loader.instantiate(buffer, imports);
const exports = instance.exports;
const { __getString } = exports;
const { __getString, __newString, __getArray, __newArray } = exports;
const getIdOfType: idOfType = exports.id_of_type as idOfType;
const BigDecimal: any = exports.BigDecimal as any;
const BigInt: any = exports.BigInt as any;
return instance;
};
+54
View File
@@ -0,0 +1,54 @@
//
// Copyright 2021 Vulcanize, Inc.
//
import path from 'path';
import { expect } from 'chai';
import { instantiate } from './index';
const EXAMPLE_WASM_FILE_PATH = '../test/subgraph/example1/build/Example1/Example1.wasm';
describe('typeConversion wasm tests', () => {
let exports: any;
before(async () => {
const filePath = path.resolve(__dirname, EXAMPLE_WASM_FILE_PATH);
const instance = await instantiate(filePath);
exports = instance.exports;
const { _start } = exports;
// Important to call _start for built subgraphs on instantiation!
// TODO: Check api version https://github.com/graphprotocol/graph-node/blob/6098daa8955bdfac597cec87080af5449807e874/runtime/wasm/src/module/mod.rs#L533
_start();
});
it('should execute bigInt fromString API', () => {
const { testBigIntFromString, __getString } = exports;
const ptr = testBigIntFromString();
expect(__getString(ptr)).to.equal('123');
});
it('should execute bigInt plus API', () => {
const { testBigIntPlus, __getString } = exports;
const ptr = testBigIntPlus();
expect(__getString(ptr)).to.equal('200');
});
it('should execute bigInt minus API', () => {
const { testBigIntMinus, __getString } = exports;
const ptr = testBigIntMinus();
expect(__getString(ptr)).to.equal('100');
});
it('should execute bigDecimal dividedBy API', () => {
const { testBigDecimalDividedBy, __getString } = exports;
const ptr = testBigDecimalDividedBy();
expect(__getString(ptr)).to.equal('10000000000000000');
console.log(__getString(ptr));
});
});
@@ -0,0 +1,46 @@
//
// Copyright 2021 Vulcanize, Inc.
//
import path from 'path';
import { expect } from 'chai';
import { instantiate } from './index';
const EXAMPLE_WASM_FILE_PATH = '../test/subgraph/example1/build/Example1/Example1.wasm';
describe('typeConversion wasm tests', () => {
let exports: any;
before(async () => {
const filePath = path.resolve(__dirname, EXAMPLE_WASM_FILE_PATH);
const instance = await instantiate(filePath);
exports = instance.exports;
const { _start } = exports;
// Important to call _start for built subgraphs on instantiation!
// TODO: Check api version https://github.com/graphprotocol/graph-node/blob/6098daa8955bdfac597cec87080af5449807e874/runtime/wasm/src/module/mod.rs#L533
_start();
});
it('should execute typeConversion bytesToHex API', () => {
const { testBytesToHex, __getString } = exports;
const ptr = testBytesToHex();
expect(__getString(ptr)).to.equal('0x231a');
});
it('should execute typeConversion bigIntToString API', () => {
const { testBigIntToString, __getString } = exports;
const ptr = testBigIntToString();
expect(__getString(ptr)).to.equal('1000000000000000000');
});
it('should execute typeConversion stringToH160 API', () => {
const { testStringToH160, __getString } = exports;
const ptr = testStringToH160();
expect(__getString(ptr)).to.equal('0xafad925b5eae1e370196cba39893e858ff7257d5');
});
});
+59
View File
@@ -0,0 +1,59 @@
//
// Copyright 2021 Vulcanize, Inc.
//
// TypeId from https://github.com/graphprotocol/graph-ts/blob/master/global/global.ts
export enum TypeId {
String = 0,
ArrayBuffer = 1,
Int8Array = 2,
Int16Array = 3,
Int32Array = 4,
Int64Array = 5,
Uint8Array = 6,
Uint16Array = 7,
Uint32Array = 8,
Uint64Array = 9,
Float32Array = 10,
Float64Array = 11,
BigDecimal = 12,
ArrayBool = 13,
ArrayUint8Array = 14,
ArrayEthereumValue = 15,
ArrayStoreValue = 16,
ArrayJsonValue = 17,
ArrayString = 18,
ArrayEventParam = 19,
ArrayTypedMapEntryStringJsonValue = 20,
ArrayTypedMapEntryStringStoreValue = 21,
SmartContractCall = 22,
EventParam = 23,
EthereumTransaction = 24,
EthereumBlock = 25,
EthereumCall = 26,
WrappedTypedMapStringJsonValue = 27,
WrappedBool = 28,
WrappedJsonValue = 29,
EthereumValue = 30,
StoreValue = 31,
JsonValue = 32,
EthereumEvent = 33,
TypedMapEntryStringStoreValue = 34,
TypedMapEntryStringJsonValue = 35,
TypedMapStringStoreValue = 36,
TypedMapStringJsonValue = 37,
TypedMapStringTypedMapStringJsonValue = 38,
ResultTypedMapStringJsonValueBool = 39,
ResultJsonValueBool = 40,
ArrayU8 = 41,
ArrayU16 = 42,
ArrayU32 = 43,
ArrayU64 = 44,
ArrayI8 = 45,
ArrayI16 = 46,
ArrayI32 = 47,
ArrayI64 = 48,
ArrayF32 = 49,
ArrayF64 = 50,
ArrayBigDecimal = 51,
}