Skip to content

Commit 87fb082

Browse files
committed
Performance, background rendering, stack labels
1 parent e93ee0e commit 87fb082

File tree

14 files changed

+567
-117
lines changed

14 files changed

+567
-117
lines changed

libauth

Submodule libauth updated 208 files

src/editor/Editor.tsx

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ import {
66
CurrentScripts,
77
EvaluationViewerSettings,
88
IDESupportedProgramState,
9+
IDESupportedVM,
910
} from '../state/types';
1011
import { unknownValue } from '../utils';
1112

1213
import { getCurrentScripts, getUsedIds } from './common';
14+
import { DebugWorkerResult } from './debug-worker';
15+
// eslint-disable-next-line import/no-unresolved
16+
import DebugWorker from './debug-worker.ts?worker';
1317
import { ImportExportDialog } from './dialogs/import-export-dialog/ImportExportDialog';
1418
import { ImportScriptDialog } from './dialogs/import-script-dialog/ImportScriptDialog';
1519
import { NewEntityDialog } from './dialogs/new-entity-dialog/NewEntityDialog';
@@ -33,7 +37,8 @@ import { WalletEditor } from './wallet/wallet-editor/WalletEditor';
3337
import { WalletHistoryExplorer } from './wallet/wallet-history-explorer/WalletHistoryExplorer';
3438
import { WelcomePane } from './welcome-pane/WelcomePane';
3539

36-
import { useCallback, useEffect, useState } from 'react';
40+
import { stringify } from '@bitauth/libauth';
41+
import { useCallback, useEffect, useRef, useState } from 'react';
3742
import { Mosaic } from 'react-mosaic-component';
3843
import { connect } from 'react-redux';
3944

@@ -60,13 +65,17 @@ type EditorDispatch = {
6065
changeEvaluationViewerSettings: typeof ActionCreators.changeEvaluationViewerSettings;
6166
importExport: typeof ActionCreators.importExport;
6267
switchScenario: typeof ActionCreators.switchScenario;
68+
startDebugging: typeof ActionCreators.startDebugging;
69+
finishDebugging: typeof ActionCreators.finishDebugging;
6370
};
6471

6572
type EditorProps<ProgramState extends IDESupportedProgramState> = {
6673
computed: ComputedEditorState<ProgramState>;
6774
currentlyEditingInternalId: string | undefined;
6875
currentScripts: CurrentScripts;
6976
activeDialog: ActiveDialog;
77+
currentVmId: IDESupportedVM;
78+
debug: AppState['debug'];
7079
evaluationViewerSettings: EvaluationViewerSettings;
7180
usedIds: string[];
7281
} & EditorDispatch;
@@ -78,6 +87,8 @@ export const Editor = connect(
7887
currentScripts: getCurrentScripts(state),
7988
activeDialog: state.activeDialog,
8089
evaluationViewerSettings: state.evaluationViewerSettings,
90+
currentVmId: state.currentVmId,
91+
debug: state.debug,
8192
usedIds: getUsedIds(state),
8293
}),
8394
{
@@ -92,6 +103,8 @@ export const Editor = connect(
92103
ActionCreators.changeEvaluationViewerSettings,
93104
importExport: ActionCreators.importExport,
94105
switchScenario: ActionCreators.switchScenario,
106+
startDebugging: ActionCreators.startDebugging,
107+
finishDebugging: ActionCreators.finishDebugging,
95108
},
96109
)((props: EditorProps<IDESupportedProgramState>) => {
97110
const [projectExplorerWidth, setProjectExplorerWidth] = useState(21);
@@ -151,6 +164,53 @@ export const Editor = connect(
151164
viewerRefCallbackFrame2,
152165
viewerRefCallbackFrame3,
153166
];
167+
const workerRef = useRef<Worker>();
168+
const lastKey = useRef<string>();
169+
170+
const { finishDebugging } = props;
171+
useEffect(() => {
172+
workerRef.current = new DebugWorker();
173+
workerRef.current.onmessage = (e: MessageEvent<DebugWorkerResult>) => {
174+
finishDebugging(e.data);
175+
};
176+
return () => {
177+
workerRef.current?.terminate();
178+
};
179+
}, [finishDebugging]);
180+
181+
const { computed, currentVmId, startDebugging, debug: debugState } = props;
182+
useEffect(() => {
183+
if (
184+
computed.editorMode === ProjectEditorMode.isolatedScriptEditor ||
185+
computed.editorMode === ProjectEditorMode.scriptPairEditor ||
186+
computed.editorMode === ProjectEditorMode.testedScriptEditor
187+
) {
188+
const scriptMode = computed;
189+
const key = stringify(
190+
{
191+
vmId: currentVmId,
192+
config: scriptMode.workerDetails.compilerConfiguration,
193+
lockingScriptId: scriptMode.workerDetails.lockingScriptId,
194+
unlockingScriptId: scriptMode.workerDetails.unlockingScriptId,
195+
scenarioId: scriptMode.workerDetails.scenarioId,
196+
},
197+
0,
198+
);
199+
if (key !== lastKey.current) {
200+
lastKey.current = key;
201+
const compilationId = debugState.compilationId + 1;
202+
startDebugging();
203+
workerRef.current?.postMessage({
204+
compilerConfiguration: scriptMode.workerDetails.compilerConfiguration,
205+
lockingScriptId: scriptMode.workerDetails.lockingScriptId,
206+
unlockingScriptId: scriptMode.workerDetails.unlockingScriptId,
207+
scenarioId: scriptMode.workerDetails.scenarioId,
208+
vmId: currentVmId,
209+
compilationId,
210+
});
211+
}
212+
}
213+
}, [computed, currentVmId, startDebugging, debugState.compilationId]);
154214

155215
useEffect(() => {
156216
const setKey = (value: unknown) => {
@@ -217,6 +277,7 @@ export const Editor = connect(
217277
debugTrace={computed.debugTrace}
218278
evaluationViewerSettings={props.evaluationViewerSettings}
219279
importExport={props.importExport}
280+
isProcessing={computed.isProcessing}
220281
scenarioDetails={computed.scenarioDetails}
221282
showControls={indexFromTop === 0}
222283
switchScenario={props.switchScenario}

src/editor/debug-worker.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/// <reference lib="webworker" />
2+
import {
3+
DebugDetails,
4+
IDESupportedProgramState,
5+
IDESupportedVM,
6+
} from '../state/types';
7+
8+
import { IDESupportedAuthenticationProgram } from './editor-types';
9+
10+
import {
11+
createCompiler,
12+
createVirtualMachineBch2023,
13+
createVirtualMachineBch2025,
14+
createVirtualMachineBch2026,
15+
createVirtualMachineBchSpec,
16+
ScenarioGenerationDebuggingResult,
17+
stringify,
18+
} from '@bitauth/libauth';
19+
20+
export type DebugWorkerJob = {
21+
compilerConfiguration: unknown;
22+
lockingScriptId?: string;
23+
unlockingScriptId?: string;
24+
scenarioId?: string;
25+
vmId: IDESupportedVM;
26+
compilationId: number;
27+
};
28+
29+
export type DebugWorkerResult = {
30+
compilationId: number;
31+
result: DebugDetails['result'];
32+
};
33+
34+
const debugCache = new Map<
35+
string,
36+
{ debugTrace: IDESupportedProgramState[]; verifyResult: string | true }
37+
>();
38+
const scenarioCache = new Map<
39+
string,
40+
string | ScenarioGenerationDebuggingResult<IDESupportedProgramState>
41+
>();
42+
const debugKey = (
43+
vmId: IDESupportedVM,
44+
program: IDESupportedAuthenticationProgram,
45+
) => `${vmId}:${stringify(program, 0)}`;
46+
const scenarioKey = (
47+
configuration: unknown,
48+
lockingScriptId: string | undefined,
49+
unlockingScriptId: string | undefined,
50+
scenarioId: string | undefined,
51+
) =>
52+
`${lockingScriptId ?? ''}:${unlockingScriptId ?? ''}:${scenarioId ?? ''}:${stringify(configuration, 0)}`;
53+
54+
self.onmessage = (event: MessageEvent<DebugWorkerJob>) => {
55+
const {
56+
compilerConfiguration,
57+
lockingScriptId,
58+
unlockingScriptId,
59+
scenarioId,
60+
vmId,
61+
compilationId,
62+
} = event.data;
63+
64+
const sKey = scenarioKey(
65+
compilerConfiguration,
66+
lockingScriptId,
67+
unlockingScriptId,
68+
scenarioId,
69+
);
70+
let scenarioGeneration = scenarioCache.get(sKey);
71+
if (scenarioGeneration === undefined) {
72+
const compiler = createCompiler(
73+
compilerConfiguration as ReturnType<
74+
typeof createCompiler
75+
>['configuration'],
76+
);
77+
scenarioGeneration = compiler.generateScenario({
78+
debug: true,
79+
lockingScriptId,
80+
unlockingScriptId,
81+
scenarioId,
82+
}) as string | ScenarioGenerationDebuggingResult<IDESupportedProgramState>;
83+
scenarioCache.set(sKey, scenarioGeneration);
84+
if (scenarioCache.size > 20) {
85+
const first = scenarioCache.keys().next().value as string;
86+
scenarioCache.delete(first);
87+
}
88+
}
89+
90+
const program =
91+
typeof scenarioGeneration !== 'string' &&
92+
typeof scenarioGeneration.scenario !== 'string'
93+
? scenarioGeneration.scenario.program
94+
: undefined;
95+
96+
let debugTrace: IDESupportedProgramState[] | undefined;
97+
let verifyResult: string | true | undefined;
98+
if (program !== undefined) {
99+
const dKey = debugKey(vmId, program);
100+
const cached = debugCache.get(dKey);
101+
if (cached !== undefined) {
102+
({ debugTrace, verifyResult } = cached);
103+
} else {
104+
const vm =
105+
vmId === 'BCH_2023_05'
106+
? createVirtualMachineBch2023()
107+
: vmId === 'BCH_2025_05'
108+
? createVirtualMachineBch2025()
109+
: vmId === 'BCH_2026_05'
110+
? createVirtualMachineBch2026()
111+
: createVirtualMachineBchSpec();
112+
debugTrace = vm.debug(program) as IDESupportedProgramState[];
113+
verifyResult = vm.verify(program);
114+
debugCache.set(dKey, { debugTrace, verifyResult });
115+
if (debugCache.size > 20) {
116+
const first = debugCache.keys().next().value as string;
117+
debugCache.delete(first);
118+
}
119+
}
120+
}
121+
const workResult: DebugWorkerResult = {
122+
compilationId,
123+
result: {
124+
debugTrace: debugTrace!,
125+
scenarioGeneration,
126+
verifyResult: verifyResult!,
127+
},
128+
};
129+
self.postMessage(workResult);
130+
};

src/editor/dialogs/import-export-dialog/ImportExportDialog.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ export const ImportExportDialog = connect(
250250
return;
251251
}
252252
const checkMarkers = () => {
253-
const markers = monaco.editor.getModelMarkers({});
253+
const markers = monaco.editor.getModelMarkers({
254+
resource: model.uri,
255+
});
254256
setErrorCount(markers.length);
255257
};
256258
/**
@@ -305,7 +307,7 @@ export const ImportExportDialog = connect(
305307
)}
306308
</div>
307309
<Button
308-
disabled={template === props.WalletTemplate}
310+
// disabled={template === props.WalletTemplate}
309311
className={
310312
errorCount !== 0 ||
311313
errorMessage !== '' ||
@@ -314,6 +316,10 @@ export const ImportExportDialog = connect(
314316
: ''
315317
}
316318
onClick={() => {
319+
if (template === props.WalletTemplate) {
320+
setErrorMessage(`The template hasn't been modified.`);
321+
return;
322+
}
317323
let parsed: unknown;
318324
try {
319325
parsed = JSON.parse(template);

0 commit comments

Comments
 (0)