feat: extensions for SmartWeave global

This commit is contained in:
ppe
2022-11-13 17:42:05 +01:00
committed by just_ppe
parent f901cb51f0
commit 587fec8e60
8 changed files with 868 additions and 119 deletions

View File

@@ -92,11 +92,11 @@
"eslint-plugin-prettier": "^3.4.1", "eslint-plugin-prettier": "^3.4.1",
"gen-esm-wrapper": "^1.1.3", "gen-esm-wrapper": "^1.1.3",
"jest": "^28.1.3", "jest": "^28.1.3",
"node-nlp": "^4.24.0",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"simple-statistics": "^7.7.0", "simple-statistics": "^7.7.0",
"smartweave": "0.4.48", "smartweave": "0.4.48",
"sqlite3": "^5.0.2",
"ts-jest": "^28.0.7", "ts-jest": "^28.0.7",
"ts-node": "^10.2.1", "ts-node": "^10.2.1",
"typescript": "^4.7.4", "typescript": "^4.7.4",
@@ -110,7 +110,6 @@
"archiver": false, "archiver": false,
"stream-buffers": false, "stream-buffers": false,
"constants": false, "constants": false,
"knex": false,
"os": false, "os": false,
"process": false "process": false
} }

View File

@@ -1,4 +1,4 @@
export const knownWarpPlugins = ['evm-signature-verification'] as const; export const knownWarpPlugins = ['evm-signature-verification', 'smartweave-extension'] as const;
export type WarpPluginType = typeof knownWarpPlugins[number]; export type WarpPluginType = typeof knownWarpPlugins[number];
export interface WarpPlugin<T, R> { export interface WarpPlugin<T, R> {

View File

@@ -36,6 +36,12 @@ export class JsHandlerApi<State> extends AbstractContractHandler<State> {
this.assignWrite(executionContext, currentTx); this.assignWrite(executionContext, currentTx);
this.assignRefreshState(executionContext); this.assignRefreshState(executionContext);
const { warp } = executionContext;
if (warp.hasPlugin('smartweave-extension')) {
const extension = warp.loadPlugin<any, void>('smartweave-extension');
extension.process(this.swGlobal.extensions);
}
const handlerResult = await Promise.race([timeoutPromise, this.contractFunction(stateCopy, interaction)]); const handlerResult = await Promise.race([timeoutPromise, this.contractFunction(stateCopy, interaction)]);
if (handlerResult && (handlerResult.state !== undefined || handlerResult.result !== undefined)) { if (handlerResult && (handlerResult.state !== undefined || handlerResult.result !== undefined)) {

View File

@@ -50,6 +50,8 @@ export class SmartWeaveGlobal {
refreshState: () => Promise<any>; refreshState: () => Promise<any>;
}; };
extensions: any;
_activeTx?: GQLNodeInterface; _activeTx?: GQLNodeInterface;
caller?: string; caller?: string;
@@ -91,6 +93,8 @@ export class SmartWeaveGlobal {
this.useGas = this.useGas.bind(this); this.useGas = this.useGas.bind(this);
this.getBalance = this.getBalance.bind(this); this.getBalance = this.getBalance.bind(this);
this.extensions = {};
} }
useGas(gas: number) { useGas(gas: number) {

View File

@@ -4,6 +4,36 @@ export async function handle(state, action) {
const input = action.input; const input = action.input;
const caller = action.caller; const caller = action.caller;
if (input.function === 'train') {
const manager = new SmartWeave.extensions.NlpManager({languages: ['en'], forceNER: true});
manager.addDocument('en', 'goodbye for now', 'greetings.bye');
manager.addDocument('en', 'bye bye take care', 'greetings.bye');
manager.addDocument('en', 'okay see you later', 'greetings.bye');
manager.addDocument('en', 'bye for now', 'greetings.bye');
manager.addDocument('en', 'i must go', 'greetings.bye');
manager.addDocument('en', 'hello', 'greetings.hello');
manager.addDocument('en', 'hi', 'greetings.hello');
manager.addDocument('en', 'howdy', 'greetings.hello');
manager.addAnswer('en', 'greetings.bye', 'Till next time');
manager.addAnswer('en', 'greetings.bye', 'see you soon!');
manager.addAnswer('en', 'greetings.hello', 'Hey there!');
manager.addAnswer('en', 'greetings.hello', 'Greetings!');
await manager.train();
manager.save();
const response = await manager.process('en', 'I should go now');
state.nlp = response;
return {
state
};
}
if (input.function === 'require') {
const fs = require('fs');
console.log(fs);
}
if (input.function === 'storeBalance') { if (input.function === 'storeBalance') {
const target = input.target; const target = input.target;
const height = SmartWeave.block.height; const height = SmartWeave.block.height;
@@ -12,7 +42,7 @@ export async function handle(state, action) {
} }
state.wallets[height][target] = await SmartWeave.arweave.wallets.getBalance(target); state.wallets[height][target] = await SmartWeave.arweave.wallets.getBalance(target);
return { state }; return {state};
} }
if (input.function === 'vrf') { if (input.function === 'vrf') {

View File

@@ -4,7 +4,9 @@ import {defaultCacheOptions, defaultWarpGwOptions, LoggerFactory, WarpFactory} f
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import {JWKInterface} from 'arweave/node/lib/wallet'; import {JWKInterface} from 'arweave/node/lib/wallet';
import {LmdbCache} from "warp-contracts-lmdb"; import {WarpPlugin, WarpPluginType} from "../src/core/WarpPlugin";
const { NlpManager } = require('node-nlp');
async function main() { async function main() {
let wallet: JWKInterface = readJSON('./.secrets/33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA.json');; let wallet: JWKInterface = readJSON('./.secrets/33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA.json');;
@@ -17,18 +19,21 @@ async function main() {
protocol: 'https' protocol: 'https'
}); });
class NlpExtension implements WarpPlugin<any, void> {
process(input: any): void {
input.NlpManager = NlpManager;
}
type(): WarpPluginType {
return 'smartweave-extension';
}
}
try { try {
const warp = WarpFactory const warp = WarpFactory
.forMainnet({...defaultCacheOptions, inMemory: false}) .forMainnet({...defaultCacheOptions, inMemory: true})
.useStateCache(new LmdbCache({ .use(new NlpExtension());
...defaultCacheOptions,
dbLocation: `./cache/warp/state`
}
))
.useContractCache(new LmdbCache({
...defaultCacheOptions,
dbLocation: `./cache/warp/contracts`
}));
/*const warp = WarpFactory /*const warp = WarpFactory
.custom(arweave, { .custom(arweave, {
...defaultCacheOptions, ...defaultCacheOptions,
@@ -47,11 +52,12 @@ async function main() {
const initialState = fs.readFileSync(path.join(__dirname, 'data/js/token-pst.json'), 'utf8'); const initialState = fs.readFileSync(path.join(__dirname, 'data/js/token-pst.json'), 'utf8');
// case 1 - full deploy, js contract // case 1 - full deploy, js contract
const {contractTxId} = await warp.createContract.deploy({ /*const {contractTxId} = await warp.createContract.deploy({
wallet, wallet,
initState: initialState, initState: initialState,
src: jsContractSrc, src: jsContractSrc,
}); });*/
// case 2 - deploy from source, js contract // case 2 - deploy from source, js contract
/*const {contractTxId} = await warp.createContract.deployFromSourceTx({ /*const {contractTxId} = await warp.createContract.deployFromSourceTx({
wallet, wallet,
@@ -75,34 +81,31 @@ async function main() {
srcTxId: "5wXT-A0iugP9pWEyw-iTbB0plZ_AbmvlNKyBfGS3AUY", srcTxId: "5wXT-A0iugP9pWEyw-iTbB0plZ_AbmvlNKyBfGS3AUY",
});*/ });*/
const contract = warp.contract('hYZBzN5FsC7P90cmfNZ0eokOUyiIvPve6JUd-9EdPAQ') const contract = warp.contract<any>('QZfrcazIy1xhWhdztArMDSivrM23B0F4tAEFf6XJzt4')
.setEvaluationOptions({
})
.connect(wallet); .connect(wallet);
/*await contract.writeInteraction({ await contract.writeInteraction<any>({
function: 'transfer', function: "train",
target: 'fffAfVHv6-qJmB9EISNLno6Tqcjp2-MS3R-m7d3hpOc',
qty: 55555
}); });
await contract.writeInteraction({
function: 'transfer', /*await contract.writeInteraction<any>({
target: 'fffAfVHv6-qJmB9EISNLno6Tqcjp2-MS3R-m7d3hpOc', function: "storeBalance",
qty: 55555 target: "M-mpNeJbg9h7mZ-uHaNsa5jwFFRAq0PsTkNWXJ-ojwI",
}); });
await contract.writeInteraction({
function: 'transfer', await contract.writeInteraction<any>({
target: 'fffAfVHv6-qJmB9EISNLno6Tqcjp2-MS3R-m7d3hpOc', function: "storeBalance",
qty: 55555 target: "M-mpNeJbg9h7mZ-uHaNsa5jwFFRAq0PsTkNWXJ-ojwI",
});
await contract.writeInteraction({
function: 'transfer',
target: 'fffAfVHv6-qJmB9EISNLno6Tqcjp2-MS3R-m7d3hpOc',
qty: 55555
});*/ });*/
const {cachedValue} = await contract.readState(); const {cachedValue} = await contract.readState();
logger.info("Result", cachedValue.state); logger.info("Result");
logger.info("errors", cachedValue.errorMessages); console.dir(cachedValue.state);
} catch (e) { } catch (e) {
logger.error(e) logger.error(e)

View File

@@ -1,31 +0,0 @@
/* eslint-disable */
import Arweave from 'arweave';
import {defaultCacheOptions, defaultWarpGwOptions, LoggerFactory, WarpFactory} from '../src';
LoggerFactory.INST.logLevel('debug');
async function main() {
const arweave = Arweave.init({
host: 'arweave.net', // Hostname or IP address for a Arweave host
port: 443, // Port
protocol: 'https', // Network protocol http or https
timeout: 60000, // Network request timeouts in milliseconds
logging: false // Enable network request logging
});
const warp = WarpFactory.forMainnet({
...defaultCacheOptions,
dbLocation: './tools/.leveldb'
});
const result = await warp.migrationTool.migrateSqlite("./tools/sqlite/contracts-3008.sqlite");
console.log(result);
const dump = await warp.stateEvaluator.dumpCache();
console.log(dump);
}
main().catch((e) => console.error(e));

840
yarn.lock

File diff suppressed because it is too large Load Diff