diff --git a/package.json b/package.json index a227df88..5d96f0d9 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "stream-buffers": "^3.0.2", "unzipit": "^1.4.0", "warp-arbundles": "^1.0.4", + "warp-contracts": "^1.4.45", "warp-isomorphic": "^1.0.7", "warp-wasm-metering": "1.0.1" }, diff --git a/src/core/modules/StateEvaluator.ts b/src/core/modules/StateEvaluator.ts index f04229ce..603dbe78 100644 --- a/src/core/modules/StateEvaluator.ts +++ b/src/core/modules/StateEvaluator.ts @@ -97,7 +97,8 @@ export class EvalStateResult { constructor( readonly state: State, readonly validity: Record, - readonly errorMessages: Record + readonly errorMessages: Record, + readonly events?: InteractionCompleteEvent[] ) {} } @@ -262,16 +263,6 @@ export interface EvaluationOptions { strictEvolve: boolean; } -// https://github.com/nodejs/node/issues/40678 duh... -export class CustomEvent extends Event { - readonly detail: T; - - constructor(message, data) { - super(message, data); - this.detail = data.detail; - } -} - export class InteractionCompleteEvent { constructor( readonly contractTxId: string, diff --git a/src/core/modules/impl/DefaultStateEvaluator.ts b/src/core/modules/impl/DefaultStateEvaluator.ts index 91f27af3..46904467 100644 --- a/src/core/modules/impl/DefaultStateEvaluator.ts +++ b/src/core/modules/impl/DefaultStateEvaluator.ts @@ -8,7 +8,7 @@ import { GQLNodeInterface, GQLTagInterface } from '../../../legacy/gqlResult'; import { Benchmark } from '../../../logging/Benchmark'; import { LoggerFactory } from '../../../logging/LoggerFactory'; import { indent } from '../../../utils/utils'; -import { EvalStateResult, StateEvaluator, CustomEvent } from '../StateEvaluator'; +import { EvalStateResult, StateEvaluator } from '../StateEvaluator'; import { AbortError, ContractInteraction, HandlerApi, InteractionResult } from './HandlerExecutorFactory'; import { TagsParser } from './TagsParser'; import { VrfPluginFunctions } from '../../WarpPlugin'; @@ -44,7 +44,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { ): Promise>> { return this.doReadState( executionContext.sortedInteractions, - new EvalStateResult(executionContext.contractDefinition.initState, {}, {}), + new EvalStateResult(executionContext.contractDefinition.initState, {}, {}, []), executionContext ); } @@ -61,6 +61,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { let currentSortKey = null; const validity = baseState.validity; const errorMessages = baseState.errorMessages; + const events = []; // TODO: opt - reuse wasm handlers executionContext?.handler.initState(currentState); @@ -97,7 +98,11 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { currentSortKey = missingInteraction.sortKey; contract .interactionState() - .setInitial(contract.txId(), new EvalStateResult(currentState, validity, errorMessages), currentSortKey); + .setInitial( + contract.txId(), + new EvalStateResult(currentState, validity, errorMessages, events), + currentSortKey + ); const singleInteractionBenchmark = Benchmark.measure(); if (missingInteraction.vrf) { @@ -166,7 +171,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { this.logger.warn(`Skipping contract in internal write, reason ${e.subtype || e.name}`); errorMessages[missingInteraction.id] = e; if (canBeCached(missingInteraction)) { - const toCache = new EvalStateResult(currentState, validity, errorMessages); + const toCache = new EvalStateResult(currentState, validity, errorMessages, events); lastConfirmedTxState = { tx: missingInteraction, state: toCache @@ -197,7 +202,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { writingContractState.cachedValue.errorMessages[missingInteraction.id]; } - const toCache = new EvalStateResult(currentState, validity, errorMessages); + const toCache = new EvalStateResult(currentState, validity, errorMessages, events); if (canBeCached(missingInteraction)) { lastConfirmedTxState = { tx: missingInteraction, @@ -244,7 +249,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { const result = await executionContext.handler.handle( executionContext, - new EvalStateResult(currentState, validity, errorMessages), + new EvalStateResult(currentState, validity, errorMessages, events), interactionData ); @@ -274,7 +279,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { currentState = result.state; - const toCache = new EvalStateResult(currentState, validity, errorMessages); + const toCache = new EvalStateResult(currentState, validity, errorMessages, events); if (canBeCached(missingInteraction)) { lastConfirmedTxState = { tx: missingInteraction, @@ -284,9 +289,7 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { const event = result.event; if (event) { - warp.eventTarget.dispatchEvent( - new CustomEvent(isValidInteraction ? 'interactionCompleted' : 'interactionFailed', { detail: event }) - ); + events.push(event); } } @@ -336,11 +339,11 @@ export abstract class DefaultStateEvaluator implements StateEvaluator { } } else { // if that's an inner contract call - only update the state in the uncommitted states - const interactionState = new EvalStateResult(currentState, validity, errorMessages); + const interactionState = new EvalStateResult(currentState, validity, errorMessages, events); contract.interactionState().update(contract.txId(), interactionState, currentSortKey); } } - const evalStateResult = new EvalStateResult(currentState, validity, errorMessages); + const evalStateResult = new EvalStateResult(currentState, validity, errorMessages, events); // state could have been fully retrieved from cache // or there were no interactions below requested sort key