Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First host calls handled - read, write #253

Merged
merged 41 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
cb28660
refactor steps state
krystian50 Dec 7, 2024
ddac3fb
Add host call example
krystian50 Dec 8, 2024
7ac4bc6
Add host calls component
krystian50 Dec 9, 2024
3678135
Add write host-call
krystian50 Dec 9, 2024
479e4fc
Add host calls to pvm
krystian50 Dec 9, 2024
7539acb
Add host calls to pvm
krystian50 Dec 9, 2024
08653b0
change service id
krystian50 Dec 9, 2024
2bb3ebd
Do not stop debugger on host call
wkwiatek Dec 9, 2024
26b2511
Show host call popup when status is HOST; move logic to separated wor…
wkwiatek Dec 9, 2024
9154aac
Ensure run is working properly
wkwiatek Dec 9, 2024
0f322b4
Fix linter
krystian50 Dec 11, 2024
8b61941
Merge branch 'main' into host-calls-cleanup
krystian50 Dec 14, 2024
98fdbe2
refactor
krystian50 Dec 14, 2024
78fde84
Host calls cleanup (#251)
krystian50 Dec 15, 2024
ff25f70
Revert "Host calls cleanup (#251)" (#252)
krystian50 Dec 15, 2024
04f35b0
Merge branch 'host-calls-read' into host-calls-cleanup
krystian50 Dec 15, 2024
1f15888
Merge branch 'main' into host-calls-cleanup
krystian50 Dec 16, 2024
d9526a1
Add trie inputs
krystian50 Dec 19, 2024
cf73e78
Merge branch 'main' into host-calls-cleanup
krystian50 Dec 19, 2024
0050441
Add trie input
krystian50 Dec 20, 2024
2064dea
fix hex val and empty key
krystian50 Dec 21, 2024
09fdbe5
Store write host call data
krystian50 Dec 22, 2024
dcd2b33
format valueblob
krystian50 Dec 22, 2024
b709d48
fix write host call
krystian50 Dec 24, 2024
418cd36
Change layout
krystian50 Dec 29, 2024
653195b
workarounds for other pvms
krystian50 Dec 30, 2024
3f82b60
Fix object freeze issue
krystian50 Dec 30, 2024
4939210
fix error handling
krystian50 Dec 31, 2024
aba3036
remove unused files
krystian50 Dec 31, 2024
46b1717
remove comments
krystian50 Dec 31, 2024
ee022b1
remove comments
krystian50 Dec 31, 2024
83c653b
Add service id
krystian50 Jan 1, 2025
c55fa5b
no error fo empty storage record
krystian50 Jan 1, 2025
4aaab9c
change pvm generated hash
krystian50 Jan 1, 2025
cba4673
Merge branch 'main' into host-calls-cleanup
krystian50 Jan 4, 2025
20dd983
fix lint
krystian50 Jan 4, 2025
0831568
fix batched steps
krystian50 Jan 4, 2025
0cccda8
fix continue after host call
krystian50 Jan 4, 2025
ec5e36d
fix type error
krystian50 Jan 8, 2025
cfdd918
Move setting service id
krystian50 Jan 8, 2025
738d5d0
Change set service id
krystian50 Jan 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
"@reduxjs/toolkit": "^2.2.8",
"@tanstack/react-virtual": "^3.10.9",
"@typeberry/block": "^0.0.1-1a02906",
"@typeberry/jam-host-calls": "0.0.1-f33d167",
"@typeberry/pvm-debugger-adapter": "0.1.0-dc28f3f",
"@typeberry/spectool-wasm": "0.18.0",
"@uiw/react-codemirror": "^4.23.6",
"blake2b": "^2.1.4",
"class-variance-authority": "^0.7.0",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
Expand All @@ -54,6 +56,7 @@
},
"devDependencies": {
"@playwright/test": "^1.47.2",
"@types/blake2b": "^2.1.3",
"@types/lodash": "^4.17.7",
"@types/node": "^20.14.11",
"@types/react": "^18.3.3",
Expand Down
5 changes: 3 additions & 2 deletions src/components/DebuggerControlls/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ export const DebuggerControlls = () => {
await dispatch(setAllWorkersCurrentState(initialState));
}

await dispatch(stepAllWorkers()).unwrap();

// NOTE [ToDr] Despite settings "batched steps", when
// the user clicks "Step" we want just single step to happen.
await dispatch(stepAllWorkers({ stepsToPerform: 1 })).unwrap();
dispatch(setIsProgramEditMode(false));
} catch (error) {
if (error instanceof Error || isSerializedError(error)) {
Expand Down
110 changes: 87 additions & 23 deletions src/components/DebuggerSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,44 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Settings } from "lucide-react";
import { CheckCircle, Settings } from "lucide-react";
import { Input } from "@/components/ui/input";
import { useAppSelector } from "@/store/hooks";
import { useDispatch } from "react-redux";
import { setStepsToPerform } from "@/store/debugger/debuggerSlice";
import { useAppDispatch, useAppSelector } from "@/store/hooks";
import { setHasHostCallOpen, setServiceId, setStepsToPerform } from "@/store/debugger/debuggerSlice";
import { Button } from "../ui/button";
import { NumeralSystemContext } from "@/context/NumeralSystemContext";
import { valueToNumeralSystem } from "../Instructions/utils";
import { useContext, useState } from "react";
import { setAllWorkersServiceId } from "@/store/workers/workersSlice";
import { isSerializedError } from "@/store/utils";
import { logger } from "@/utils/loggerService";

function stringToNumber<T>(value: string, cb: (x: string) => T): T {
try {
return cb(value);
} catch (_e) {
return cb("0");
}
}

export const DebuggerSettings = () => {
const debuggerState = useAppSelector((state) => state.debugger);
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const { numeralSystem } = useContext(NumeralSystemContext);
const [error, setError] = useState<string>();

const onServiceIdChange = async (newServiceId: number) => {
setError("");
try {
dispatch(setServiceId(newServiceId));
await dispatch(setAllWorkersServiceId()).unwrap();
} catch (e) {
if (e instanceof Error || isSerializedError(e)) {
setError(e.message);
logger.error(e.toString(), { error: e, hideToast: true });
}
}
};

return (
<Dialog>
Expand All @@ -29,24 +58,59 @@ export const DebuggerSettings = () => {
<span className="text-xl">Debugger Settings</span>
</DialogTitle>
<DialogDescription asChild>
<p className="py-4 ">
<span className="block text-lg text-black font-bold mb-2">Number of batched steps</span>
<span className="mb-3 block">
To speed up execution PVMs can run multiple steps internally after clicking "Run". This may lead to
inaccurate stops in case the execution diverges between them.
</span>
<Input
type="number"
step={1}
min={1}
max={1000}
placeholder="Batched steps"
onChange={(ev) => {
dispatch(setStepsToPerform(parseInt(ev.target.value)));
}}
value={debuggerState.stepsToPerform}
/>
</p>
<div>
<div className="mt-3">
<span className="block text-lg text-black font-bold mb-2">Service id</span>
<span className="mb-3 block">Provide storage service id</span>
<Input
onChange={(e) => {
const value = e.target?.value;
const parsedValue = stringToNumber(value, Number);
onServiceIdChange(parsedValue);
}}
value={valueToNumeralSystem(debuggerState.serviceId ?? 0, numeralSystem)}
/>
</div>

<div className="py-4">
<span className="block text-lg text-black font-bold mb-2">Number of batched steps</span>
<span className="mb-3 block">
To speed up execution PVMs can run multiple steps internally after clicking "Run". This may lead to
inaccurate stops in case the execution diverges between them.
</span>
<Input
type="number"
step={1}
min={1}
max={1000}
placeholder="Batched steps"
onChange={(ev) => {
dispatch(setStepsToPerform(parseInt(ev.target.value)));
}}
value={debuggerState.stepsToPerform}
/>
<div className="py-4">
<span className="block text-lg text-black font-bold mb-2">Storage Value</span>

<span className="mb-3 block">
Set storage for read & write host calls. Confirm empty, if you want to process. Storage can be
modified by running program.
</span>

<div className="flex">
<Button onClick={() => dispatch(setHasHostCallOpen(true))}>Set storage</Button>

{debuggerState.storage !== null && (
<span className="flex items-center ml-3">
<CheckCircle color="green" className="mr-2" /> Storage provided
</span>
)}
</div>
</div>
</div>

{error && <p className="text-red-500 text-sm mt-2">{error}</p>}
</div>
</DialogDescription>
</DialogHeader>
</DialogContent>
Expand Down
98 changes: 98 additions & 0 deletions src/components/HostCalls/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { useAppDispatch, useAppSelector } from "@/store/hooks.ts";
import { handleHostCall, setAllWorkersStorage } from "@/store/workers/workersSlice";
import { TrieInput } from "./trie-input";
import { Button } from "../ui/button";
import { setHasHostCallOpen, setStorage } from "@/store/debugger/debuggerSlice";
import { useEffect, useState } from "react";
import { CurrentInstruction, DebuggerEcalliStorage } from "@/types/pvm";
import { ArgumentType } from "@typeberry/pvm-debugger-adapter";
import { isSerializedError } from "@/store/utils";

const isEcalliWriteOrRead = (currentInstruction: CurrentInstruction) => {
return (
currentInstruction &&
"args" in currentInstruction &&
currentInstruction.args.type === ArgumentType.ONE_IMMEDIATE &&
(currentInstruction.args.immediateDecoder.getSigned() === 2 ||
currentInstruction.args.immediateDecoder.getSigned() === 3)
);
};
export const HostCalls = () => {
const dispatch = useAppDispatch();
const { storage, hasHostCallOpen, programPreviewResult } = useAppSelector((state) => state.debugger);
const firstWorker = useAppSelector((state) => state.workers?.[0]);
const currentInstruction = firstWorker?.currentInstruction;

const [newStorage, setNewStorage] = useState<DebuggerEcalliStorage | null>();
const [error, setError] = useState<string>();
const previousInstruction =
programPreviewResult[
programPreviewResult.findIndex(
(instruction) => instruction.instructionCode === currentInstruction?.instructionCode,
) - 1
];

const isOnEcalli = previousInstruction && isEcalliWriteOrRead(previousInstruction);

useEffect(() => {
setNewStorage(storage);
}, [storage]);

const onSubmit = async () => {
setError("");

try {
dispatch(setStorage(newStorage || []));
await dispatch(setAllWorkersStorage()).unwrap();
try {
if (isOnEcalli) {
await dispatch(handleHostCall()).unwrap();
}

dispatch(setHasHostCallOpen(false));
} catch (e) {
if (e instanceof Error || isSerializedError(e)) {
setError(e.message);
}
}
} catch (e) {
if (e instanceof Error || isSerializedError(e)) {
setError(e.message);
}
}
};

return (
<Dialog
open={hasHostCallOpen}
onOpenChange={(val) => {
if (!val) {
dispatch(setHasHostCallOpen(false));
}
}}
>
<DialogContent className="min-w-[80vw] min-h-[70vh] max-h-[70vh]" hideClose={isOnEcalli}>
<div className="flex flex-col">
<DialogHeader>
<DialogTitle className="mb-4">Define ecalli data</DialogTitle>
</DialogHeader>

<div className="mt-6">
<span className="block text-md text-black font-bold mb-2">Storage value</span>
<span>Please provide JSON storage or confirm empty</span>
<div className="border-gray-100 border-2 rounded-lg pt-1 mt-2 h-[45vh] overflow-y-auto">
<TrieInput onChange={(v) => setNewStorage(v)} initialRows={storage} />
</div>
</div>
{error && <p className="text-red-500 text-sm mt-2">{error}</p>}
</div>
<div className="flex mt-2 ml-auto">
<Button type="submit" onClick={onSubmit}>
Confirm
</Button>
</div>
</DialogContent>
</Dialog>
);
};
Loading
Loading