From d023a8f3e94d21466ced497c338c314a43f6c217 Mon Sep 17 00:00:00 2001 From: ppedziwiatr Date: Fri, 29 Mar 2024 11:27:30 +0100 Subject: [PATCH] feat: quickjs plugin --- src/core/WarpPlugin.ts | 3 +- .../modules/impl/HandlerExecutorFactory.ts | 69 ++++++++++++++++++- src/index.ts | 2 + src/utils/types/mutually-exclusive.ts | 2 + 4 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 src/utils/types/mutually-exclusive.ts diff --git a/src/core/WarpPlugin.ts b/src/core/WarpPlugin.ts index 40eead82..3e332b02 100644 --- a/src/core/WarpPlugin.ts +++ b/src/core/WarpPlugin.ts @@ -10,7 +10,8 @@ export const knownWarpPlugins = [ 'deploy', 'contract-blacklist', 'vm2', - 'vrf' + 'vrf', + 'quickjs' ] as const; type WarpPluginPartialType = `smartweave-extension-${string}`; export type WarpKnownPluginType = (typeof knownWarpPlugins)[number]; diff --git a/src/core/modules/impl/HandlerExecutorFactory.ts b/src/core/modules/impl/HandlerExecutorFactory.ts index 1b3904d4..36c00834 100644 --- a/src/core/modules/impl/HandlerExecutorFactory.ts +++ b/src/core/modules/impl/HandlerExecutorFactory.ts @@ -16,6 +16,7 @@ import { isBrowser } from '../../../utils/utils'; import { Buffer } from 'warp-isomorphic'; import { InteractionState } from '../../../contract/states/InteractionState'; import { WarpLogger } from '../../../logging/WarpLogger'; +import { XOR } from 'utils/types/mutually-exclusive'; // 'require' to fix esbuild adding same lib in both cjs and esm format // https://github.com/evanw/esbuild/issues/1950 @@ -208,6 +209,15 @@ export class HandlerExecutorFactory implements ExecutorFactory>('quickjs'); + return quickJsPlugin.process({ + contractSource: contractDefinition.src, + evaluationOptions, + swGlobal: swGlobal, + contractDefinition, + binaryType: 'release_sync' + }); } else { const contractFunction = new Function(normalizedSource); const handler = isBrowser() @@ -286,11 +296,11 @@ export interface HandlerApi { export type HandlerResult = { result: Result; state: State; - event: InteractionCompleteEvent; + event?: InteractionCompleteEvent; gasUsed?: number; }; -export type InteractionResult = HandlerResult & { +type WarpInteractionResult = HandlerResult & { type: InteractionResultType; errorMessage?: string; error?: unknown; @@ -298,6 +308,25 @@ export type InteractionResult = HandlerResult & { originalErrorMessages?: Record; }; +export type AoInteractionResult = { + Memory: string; + Error: string; + Messages: { + target: string; + data: string; + anchor: string; + tags: { name: string; value: string }[]; + }[]; + Spawns: { + data: string; + anchor: string; + tags: { name: string; value: string }[]; + }[]; + Output: Result; +}; + +export type InteractionResult = XOR, AoInteractionResult>; + export type InteractionType = 'view' | 'write'; export type ContractInteraction = { @@ -330,3 +359,39 @@ export interface VM2PluginInput { logger: WarpLogger; contractDefinition: ContractDefinition; } + +export type QuickJsBinaryType = 'release_sync' | 'release_async' | 'debug_sync' | 'debug_async'; + +export interface QuickJsPluginInput { + contractSource: string; + evaluationOptions: EvaluationOptions; + swGlobal: SmartWeaveGlobal; + contractDefinition: ContractDefinition; + binaryType: QuickJsBinaryType; +} + +export interface QuickJsOptions { + memoryLimit?: number; + maxStackSize?: number; + interruptCycles?: number; + timeout?: number; +} + +export interface QuickJsPluginMessage { + Cron: boolean; + Data: string | Buffer; + Epoch: number; + From: string; + Id: string | undefined; + Nonce: number; + Owner: string; + Signature: string | undefined; + Tags: { + [key: string]: string | undefined; + }; + Target: string; + Timestamp: string; + ['Block-Height']: string; + ['Forwarded-By']: string; + ['Hash-Chain']: string; +} diff --git a/src/index.ts b/src/index.ts index 522a81cd..fff92734 100644 --- a/src/index.ts +++ b/src/index.ts @@ -53,6 +53,8 @@ export * from './contract/Signature'; export * from './contract/EvaluationOptionsEvaluator'; export * from './contract/deploy/Source'; export * from './contract/deploy/CreateContract'; +export * from './contract/states/ContractInteractionState'; +export * from './contract/states/InteractionState'; export * from './legacy/gqlResult'; export * from './legacy/smartweave-global'; diff --git a/src/utils/types/mutually-exclusive.ts b/src/utils/types/mutually-exclusive.ts new file mode 100644 index 00000000..a314dbdc --- /dev/null +++ b/src/utils/types/mutually-exclusive.ts @@ -0,0 +1,2 @@ +type Without = { [P in Exclude]?: never }; +export type XOR = T | U extends object ? (Without & U) | (Without & T) : T | U;