-
Notifications
You must be signed in to change notification settings - Fork 3
host calls wip #455
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
host calls wip #455
Conversation
tomusdrw
commented
Nov 29, 2025
- Handle host calls.
- Initial version of host calls handling.
✅ Deploy Preview for pvm-debugger ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 📝 WalkthroughWalkthroughThis pull request introduces a comprehensive host call debugging system to the PVM debugger. It adds a HostCallDialog component with specialized handlers for different host call types (Gas, Fetch, Info, Log, Provide, Read, Transfer, Write, Yield), supporting utilities for memory simulation and state management, and new web worker command handlers. The Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/ProgramLoader/examplePrograms.ts (2)
54-54: Inconsistent gas value: Use DEFAULT_GAS or document the reason.The
gameOfLifeprogram uses a hardcoded gas value of10_000_000n, while other programs (fibonacci, add, storeU16, empty) now useDEFAULT_GAS. This inconsistency undermines the centralization effort. If this program requires more gas, consider documenting why with a comment.Apply this diff to use the default:
- gas: 10_000_000n, + gas: DEFAULT_GAS,Or document the special requirement:
- gas: 10_000_000n, + // Game of Life requires more gas due to complex simulation + gas: 10_000_000n,
63-63: Inconsistent gas value: Use DEFAULT_GAS or document the reason.The
branchprogram uses a hardcoded gas value of10n, while other programs now useDEFAULT_GAS. This inconsistency undermines the centralization effort. If this minimal gas is intentional for testing purposes, consider documenting it.Apply this diff to use the default:
- gas: 10n, + gas: DEFAULT_GAS,Or document the special requirement:
- gas: 10n, + // Minimal gas for testing branch behavior + gas: 10n,
🧹 Nitpick comments (32)
src/components/Registers/index.tsx (1)
14-14: Host status formatter: enum key casing and multi‑worker exitArg handlingThe new
formatterlogic looks good for enriching the status label, but there are two potential pitfalls worth checking:
Enum key casing:
statusValue === Status.HOSTassumes aHOSTmember. If yourStatustype/enum uses names likeHost(as suggested by the workerStatusmapping), this will either not compile or always be false, anddisplayText/extra classes will never be applied for host status. Please confirm the actualStatusdefinition and align the member name accordingly.Using only
workers[0]?.exitArg: You’re always readingexitArgfrom the first worker, both for the main cell and the per‑worker tooltip rows (sinceformattercloses overworkersandformatValueToDisplayapplies it to each worker’s value). If multiple workers can have differentexitArgvalues, this will misrepresent them in the tooltip and in the summary. Consider derivingexitArgfrom the worker whose value you’re formatting (or from a selected/active worker in state) instead of hard‑coding index0.Also applies to: 175-193
src/packages/web-worker/command-handlers/set-memory.ts (1)
1-35: SetMemory handler shape looks good; consider awaitingsetMemoryThe handler’s null-check and structured
CommandStatusresponses look consistent with other worker commands. GivenrunSetMemoryisasync, it would be safer to await the PVM call so any async failures are caught by thistry/catch:- try { - // Use the PVM's setMemory API to write data - pvm.setMemory(address, data); + try { + // Use the PVM's setMemory API to write data + await pvm.setMemory(address, data);This is a no-op if
setMemoryis currently synchronous but future‑proofs the handler if the API becomes async. As per coding guidelines, this keeps the worker RPC behavior predictable for WASM-facing consumers.src/components/ProgramLoader/Examples.tsx (1)
9-9: SPI args integration into Doom/GoL example loads looks correctReading
spiArgsfromstate.debugger.spiArgsand threading it intoloadFileFromUint8Arrayfor the Doom and GoL examples brings these flows in line with the rest of the SPI-loading pipeline, and should work well with thespiArgsAsByteshandling inside the loader.As a minor hardening step, you might eventually want to pass a well-typed
initialStateobject instead of{}in these two calls so that, if the detection logic ever falls back to the generic PVM path, it doesn’t rely on an empty object.Also applies to: 14-14, 59-60, 79-80
src/components/Instructions/BasicBlocks/CollapsibleInstructionsTable.tsx (1)
23-23: Defensive ArgsDecoder initialization avoids crashes in widestItemValueWrapping
decodeAndGetArgsDecoder(program)in atry/catchhere and falling back to""if decoding fails is a sensible way to prevent broken/partial programs from crashing the instructions table while computing column widths. If you find it useful during debugging, you could also log the decode failure once inside thecatch, but the current behavior is acceptable and keeps the UI resilient.Also applies to: 169-174
src/components/HostCallDialog/handlers/storageManager.ts (2)
26-38: Write method behavior is clear but consider edge cases.The
write()method's delete-on-null behavior is well-documented. However, consider:
- The return value (previous length) might be unexpected for callers expecting a boolean or void
- No validation that
valueis a valid Uint8Array when non-nullConsider adding a validation check:
write(key: BytesBlob, value: Uint8Array | null): number | null { const keyHex = key.toString(); const previousValue = this.storage.get(keyHex); const previousLength = previousValue ? previousValue.length : null; if (value === null) { this.storage.delete(keyHex); } else { + if (!(value instanceof Uint8Array)) { + throw new TypeError('Value must be a Uint8Array'); + } this.storage.set(keyHex, new Uint8Array(value)); } return previousLength; }
9-61: Consider adding a method to get storage size.For debugging and monitoring purposes, consider adding a method to get the current storage size (number of entries or total bytes).
/** * Get the number of entries in storage. */ getSize(): number { return this.storage.size; } /** * Get the total number of bytes stored. */ getTotalBytes(): number { let total = 0; for (const value of this.storage.values()) { total += value.length; } return total; }src/packages/web-worker/command-handlers/set-state.ts (1)
17-67: Consider using DEFAULT_REGS for initialization.The PR introduces
DEFAULT_REGSconstant insrc/types/pvm.ts. Consider whether this handler should support resetting to default values whenregsis not provided or is empty.Example enhancement:
import { DEFAULT_REGS } from "@/types/pvm"; export type SetStateParams = { pvm: PvmApiInterface | null; regs?: bigint[]; // Make optional gas: bigint; }; // Inside runSetState: const regsToSet = regs && regs.length === 13 ? regs : DEFAULT_REGS;src/components/HostCallDialog/handlers/ProvideHostCall.tsx (2)
44-66: Consider extracting common partialState stubs to reduce duplication.The
partialStateobject is duplicated in both the mount effect andhandleResume. The stub methods (transfer,checkPreimageStatus, etc.) are identical. Consider extracting a factory function or base object:+// At module level or inside component +const createBasePartialState = (resolvedServiceId: ReturnType<typeof block.tryAsServiceId>): Omit<PartialState, 'providePreimage'> => ({ + transfer: () => Result.ok(OK), + checkPreimageStatus: () => null, + requestPreimage: () => Result.ok(OK), + forgetPreimage: () => Result.ok(OK), + eject: () => Result.ok(OK), + newService: () => Result.ok(resolvedServiceId), + upgradeService: () => {}, + updateValidatorsData: () => Result.ok(OK), + checkpoint: () => {}, + updateAuthorizationQueue: () => Result.ok(OK), + updatePrivilegedServices: () => Result.ok(OK), + yield: () => {}, +}); // Then use: const partialState: PartialState = { + ...createBasePartialState(resolvedServiceId), providePreimage: (service, preimage) => { /* capture logic */ }, - transfer: () => Result.ok(OK), - // ... rest of stubs };Also applies to: 99-113
94-135: Consider extracting memory preloading logic.The memory preloading pattern (lines 117-122) duplicates lines 72-77. This could be extracted to a helper function for maintainability.
Additionally, the async
handleResumesetsisExecutingto true but doesn't have cleanup if the component unmounts during execution. This is a minor concern sinceonResumelikely navigates away.+const preloadPreimageMemory = async ( + ctx: HostCallContext, + regs: bigint[], + readMemory: (addr: number, len: number) => Promise<Uint8Array> +) => { + const preimagePointer = Number(regs[8] ?? 0n); + const preimageLength = Number(regs[9] ?? 0n); + if (preimagePointer > 0 && preimageLength > 0) { + const preimageData = await readMemory(preimagePointer, preimageLength); + ctx.preloadMemory(preimagePointer, preimageData); + } +};src/components/HostCallDialog/MemoryEditor.tsx (3)
51-77:onMemoryChangein dependency array may cause spurious reloads.The
onMemoryChangecallback is included in the dependency array but isn't used inside the effect. If the parent doesn't memoize this callback, the effect will re-run on every parent render, triggering unnecessary memory fetches.useEffect(() => { const loadMemory = async () => { // ...loading logic }; loadMemory(); - }, [address, length, readMemory, onMemoryChange]); + }, [address, length, readMemory]);
115-129: Single-byte edit sends entire buffer; address is view start, not edited byte.When editing one byte,
onMemoryChangereceives the view's start address and the entire buffer. If consumers expect per-byte edits (asMemoryEditsuggests), this could cause issues or inefficiencies. Consider sending only the edited byte's address and value.const handleByteBlur = useCallback(() => { if (editingByte === null || !data || address === null) { setEditingByte(null); return; } const byteValue = parseInt(editValue || "0", 16); if (!isNaN(byteValue) && byteValue >= 0 && byteValue <= 255) { const newData = new Uint8Array(data); newData[editingByte] = byteValue; setData(newData); - onMemoryChange?.(address, newData); + // Send only the edited byte's address and value + onMemoryChange?.(address + editingByte, new Uint8Array([byteValue])); } setEditingByte(null); }, [editingByte, editValue, data, address, onMemoryChange]);
158-176: Labels not associated with inputs viahtmlFor/id.The
<label>elements are not programmatically linked to their corresponding inputs, which reduces accessibility for screen readers.<div className="flex-1"> - <label className="text-sm font-medium">Start Address</label> + <label htmlFor="memory-start-address" className="text-sm font-medium">Start Address</label> <Input + id="memory-start-address" className="font-mono" placeholder="0x1000" value={addressInput} onChange={(e) => updateAddress(e.target.value)} disabled={disabled} /> </div> <div className="flex-1"> - <label className="text-sm font-medium">Length (max {MAX_LENGTH})</label> + <label htmlFor="memory-length" className="text-sm font-medium">Length (max {MAX_LENGTH})</label> <Input + id="memory-length" className="font-mono" placeholder="256" value={lengthInput} onChange={(e) => updateLength(e.target.value)} disabled={disabled} /> </div>src/components/HostCallDialog/handlers/FetchHostCall.tsx (1)
91-95: Effect resets input to same constant on everyfetchKindchange.The effect resets
hexInputtoDEFAULT_CONSTANTSwheneverfetchKindchanges. SinceDEFAULT_CONSTANTSis a constants-specific value, this may not be appropriate for other fetch kinds (Entropy, WorkPackage, etc.). Consider using kind-specific defaults or preserving user input.src/components/HostCallDialog/handlers/InfoHostCall.tsx (3)
48-52: Effect with empty dependency array doesn't reset on dialog reopen.The effect runs only once on mount. If the component isn't unmounted between dialog opens (e.g., kept in DOM but hidden), the form won't reset. Consider adding
hasHostCallOpenor similar dependency, or resetting in a parent-controlled manner.
58-76: No input validation beforeBigInt/Numberparsing.
BigInt(balance)and similar calls will throwSyntaxErrorif the string is empty or invalid (e.g., "abc"). While the outer try-catch handles this, the error message will be cryptic. Consider validating inputs before parsing or providing field-specific error feedback.try { // Parse form values const codeHashBytes = bytes.BytesBlob.parseBlob(codeHash).raw; if (codeHashBytes.length !== 32) { throw new Error("Code hash must be exactly 32 bytes"); } + // Validate numeric inputs + const numericFields = { balance, accumulateMinGas, onTransferMinGas, storageBytes, gratisStorage }; + for (const [name, value] of Object.entries(numericFields)) { + if (!/^\d+$/.test(value.trim())) { + throw new Error(`${name} must be a valid non-negative integer`); + } + } + const serviceInfo = ServiceAccountInfo.create({
90-95:isExecutingnot reset on success path.When
onResumesucceeds,isExecutingremainstrue. If the dialog doesn't unmount (e.g., due to an error in the resume flow after this component's try block), the buttons stay disabled permanently.const { modifiedRegs, finalGas, memoryEdits } = ctx.getResult(); onResume(mode, modifiedRegs, finalGas, memoryEdits); + setIsExecuting(false); } catch (e) { console.error(e); setError(e instanceof Error ? e.message : "Failed to execute info"); setIsExecuting(false); }src/components/HostCallDialog/index.tsx (1)
112-125: Memory edit merge by address may cause data loss with overlapping ranges.The merge logic replaces edits at the same start address. If one edit writes bytes at address 0x1000 (length 256) and another at 0x1000 (length 1), the first is replaced entirely. Consider merging by range overlap or using a more sophisticated merge strategy.
src/components/HostCallDialog/handlers/ReadHostCall.tsx (2)
38-92: Potential stale closure risk withonResumein effect dependencies.The
onResumecallback is included in the dependency array but the effect is guarded byhasExecuted.current, meaning subsequent identity changes won't trigger re-execution. IfonResumechanges after the initial execution but before auto-resume completes, the stale callback could be invoked at line 79.Consider extracting
onResumefrom the dependency array and using a ref to hold the latest callback, or ensure the parent component memoizesonResumewithuseCallback.
62-69: Consider extracting memory preloading into a helper.The key memory preloading logic (lines 62-69) is duplicated in
handleResume(lines 121-127). For maintainability, consider extracting this into a small helper function within the component.+ const preloadKeyMemory = useCallback(async (ctx: HostCallContext) => { + const keyPointer = Number(regs[8] ?? 0n); + const keyLength = Number(regs[9] ?? 0n); + if (keyLength > 0) { + const keyData = await readMemory(keyPointer, keyLength); + ctx.preloadMemory(keyPointer, keyData); + } + }, [regs, readMemory]);Also applies to: 121-127
src/components/HostCallDialog/DefaultHostCallContent.tsx (2)
54-56: Consider extracting the gas adjustment constant.The magic number
10nfor gas adjustment should be a named constant to improve readability and maintainability.+const HOST_CALL_GAS_COST = 10n; + // Set gas to current gas - 10 (as per requirement) const currentGas = currentState.gas ?? DEFAULT_GAS; -const newGas = currentGas > 10n ? currentGas - 10n : 0n; +const newGas = currentGas > HOST_CALL_GAS_COST ? currentGas - HOST_CALL_GAS_COST : 0n;
62-70: Avoid calling callbacks inside setState updater functions.Invoking
onRegsChangeinside thesetRegsupdater is a side effect within React's state update, which is unconventional and may cause issues with React's batching or concurrent features.const handleRegisterChange = (index: number, value: string) => { const newValue = stringToNumber(value, BigInt); - setRegs((prev) => { - const newRegs = [...prev]; - newRegs[index] = newValue; - onRegsChange(newRegs); - return newRegs; - }); + const newRegs = [...regs]; + newRegs[index] = newValue; + setRegs(newRegs); + onRegsChange(newRegs); };src/components/HostCallDialog/handlers/YieldHostCall.tsx (2)
43-62: Extract duplicatepartialStatestub into a factory or constant.The
partialStateobject is defined twice with nearly identical stub implementations. Consider extracting a factory function to reduce duplication and ensure consistency.+const createPartialStateStub = ( + resolvedServiceId: ReturnType<typeof block.tryAsServiceId>, + onYield?: (hash: OpaqueHash) => void +): PartialState => ({ + yield: onYield ?? (() => {}), + transfer: () => Result.ok(OK), + checkPreimageStatus: () => null, + requestPreimage: () => Result.ok(OK), + forgetPreimage: () => Result.ok(OK), + eject: () => Result.ok(OK), + newService: () => Result.ok(resolvedServiceId), + upgradeService: () => {}, + updateValidatorsData: () => Result.ok(OK), + checkpoint: () => {}, + updateAuthorizationQueue: () => Result.ok(OK), + updatePrivilegedServices: () => Result.ok(OK), + providePreimage: () => Result.ok(OK), +});Also applies to: 95-109
44-47: Consider using a shared utility for bytes-to-hex conversion.The manual hex conversion could be extracted to a utility function in
hostCallUtils.tsfor consistency with other conversions likehexToAscii.src/components/HostCallDialog/handlers/TransferHostCall.tsx (2)
45-68: Extract duplicatepartialStatestub to reduce code duplication.Similar to other handlers, the
partialStateobject is duplicated between the initial execution andhandleResume. This pattern repeats across multiple host call handlers (YieldHostCall, TransferHostCall, etc.) and could benefit from a shared factory function.Also applies to: 101-115
74-79: ExtractMEMO_SIZEas a module-level constant.The constant is defined inline and duplicated. Moving it to module scope improves clarity.
+const MEMO_SIZE = 128; // TRANSFER_MEMO_BYTES + // Inside execute function: -const MEMO_SIZE = 128; // TRANSFER_MEMO_BYTES if (memoPointer > 0) {src/components/HostCallDialog/handlers/WriteHostCall.tsx (3)
83-148: Consider extracting duplicate memory preloading logic.The memory preloading logic for key and value (lines 102-123) is duplicated in
handleResume(lines 172-188). Consider extracting this into a shared helper function to reduce code duplication and maintenance burden.+const preloadKeyValueMemory = async ( + ctx: HostCallContext, + regs: bigint[], + readMemory: (address: number, length: number) => Promise<Uint8Array> +) => { + const keyPointer = Number(regs[7] ?? 0n); + const keyLength = Number(regs[8] ?? 0n); + let keyHex = ""; + if (keyLength > 0) { + const keyData = await readMemory(keyPointer, keyLength); + ctx.preloadMemory(keyPointer, keyData); + keyHex = bytesToHex(keyData); + } + + const valuePointer = regs[9] ?? 0n; + const valueLength = Number(regs[10] ?? 0n); + const MAX_U64 = 0xffffffffffffffffn; + const isDelete = valuePointer >= MAX_U64; + let valueHex: string | null = null; + if (!isDelete && valueLength > 0) { + const valueData = await readMemory(Number(valuePointer), valueLength); + ctx.preloadMemory(Number(valuePointer), valueData); + valueHex = bytesToHex(valueData); + } + + return { keyHex, keyLength, valueHex, valueLength, isDelete }; +};
196-200: Inconsistent error message handling between initial execution and resume.The initial execution (line 142) extracts the message from the error object, but
handleResume(line 198) uses a generic fallback. Consider applying the same detailed error extraction pattern for consistency.} catch (e) { console.error(e); - setError(e instanceof Error ? e.message : "Failed to execute write"); + const msg = e !== null && typeof e === "object" && "message" in e ? (e as { message: string }).message : ""; + setError(e instanceof Error ? e.message : `Failed to execute write: ${msg}`); setIsExecuting(false); }
116-117: ExtractMAX_U64as a module-level constant.
MAX_U64is defined identically on lines 116 and 183. Move it to the top of the file with the other constants to avoid duplication.const { Write, HostCallResult } = jam_host_calls.general; const { Result } = utils; type AccountsWrite = jam_host_calls.general.AccountsWrite; + +// Maximum u64 value - indicates deletion when used as value pointer +const MAX_U64 = 0xffffffffffffffffn;Then remove the local declarations on lines 116 and 183.
src/components/HostCallDialog/handlers/hostCallUtils.ts (2)
113-123: Consider validating hex characters inhexToBytes.The function validates string length but
parseIntwith radix 16 will returnNaNfor invalid hex characters, which becomes0when used as a byte. Consider adding validation for invalid characters.export function hexToBytes(hex: string): Uint8Array { const clean = hex.replace(/^0x/i, "").replace(/\s/g, ""); if (clean.length % 2 !== 0) { throw new Error("Invalid hex string length"); } + if (!/^[0-9a-fA-F]*$/.test(clean)) { + throw new Error("Invalid hex characters"); + } const bytes = new Uint8Array(clean.length / 2); for (let i = 0; i < clean.length; i += 2) { bytes[i / 2] = parseInt(clean.slice(i, i + 2), 16); } return bytes; }
37-56: Line 17 comment is misleading about supporting "proper partial reads"The
MockMemoryclass stores regions but only returns data if a read is fully contained within a single region. Reads spanning multiple preloaded regions silently return zeros. However, current host call handlers preload only the exact contiguous regions they need and don't perform spanning reads, so this isn't a practical issue. Consider clarifying the comment on line 17 to accurately describe the actual behavior and limitations.src/store/workers/workersSlice.ts (1)
687-700: Consider error handling if resume execution fails.After closing the dialog (lines 684-685), if
runAllWorkers,stepAllWorkers, or refresh operations fail, the user loses the ability to retry from the dialog. Consider keeping the dialog open until execution succeeds, or providing a way to recover.One approach is to wrap the resume logic in a try-catch and re-open the dialog on failure:
+ try { // Resume execution based on mode if (mode === "run") { dispatch(setIsRunMode(true)); await dispatch(runAllWorkers()).unwrap(); } else if (mode === "block") { const stepsToPerform = calculateStepsToExitBlockForAllWorkers(getState() as RootState); await dispatch(stepAllWorkers({ stepsToPerform })).unwrap(); } else { // step await dispatch(stepAllWorkers({ stepsToPerform: 1 })).unwrap(); } await dispatch(refreshPageAllWorkers()); await dispatch(refreshMemoryRangeAllWorkers()).unwrap(); + } catch (error) { + // Re-open dialog on failure so user can retry + dispatch(setHasHostCallOpen(true)); + throw error; + }src/store/debugger/debuggerSlice.ts (1)
86-93: Verify the hardcoded spiArgs default value.The default
spiArgsis set tonew Uint8Array([0x18, 0x00, 0x00]). Consider adding a comment explaining what this value represents, or extracting it as a named constant insrc/types/pvm.tsalongsideDEFAULT_REGSandDEFAULT_GAS.+// Default SPI arguments: 0x180000 (format TBD) +export const DEFAULT_SPI_ARGS = new Uint8Array([0x18, 0x00, 0x00]);Then import and use
DEFAULT_SPI_ARGSin the initial state.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (37)
package.json(1 hunks)src/App.tsx(2 hunks)src/components/DebuggerSettings/Content.tsx(1 hunks)src/components/HostCallDialog/DefaultHostCallContent.tsx(1 hunks)src/components/HostCallDialog/MemoryEditor.tsx(1 hunks)src/components/HostCallDialog/handlers/FetchHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/GasHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/HostCallActionButtons.tsx(1 hunks)src/components/HostCallDialog/handlers/InfoHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/LogHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/ProvideHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/ReadHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/TransferHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/WriteHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/YieldHostCall.tsx(1 hunks)src/components/HostCallDialog/handlers/hostCallUtils.ts(1 hunks)src/components/HostCallDialog/handlers/index.ts(1 hunks)src/components/HostCallDialog/handlers/storageManager.ts(1 hunks)src/components/HostCallDialog/handlers/types.ts(1 hunks)src/components/HostCallDialog/index.tsx(1 hunks)src/components/Instructions/BasicBlocks/CollapsibleInstructionsTable.tsx(2 hunks)src/components/ProgramLoader/Examples.tsx(3 hunks)src/components/ProgramLoader/Loader.tsx(1 hunks)src/components/ProgramLoader/examplePrograms.ts(5 hunks)src/components/ProgramLoader/loadingUtils.ts(3 hunks)src/components/Registers/index.tsx(2 hunks)src/hooks/useDebuggerActions.ts(3 hunks)src/packages/web-worker/command-handlers/index.ts(1 hunks)src/packages/web-worker/command-handlers/memory.ts(1 hunks)src/packages/web-worker/command-handlers/set-memory.ts(1 hunks)src/packages/web-worker/command-handlers/set-state.ts(1 hunks)src/packages/web-worker/types.ts(3 hunks)src/packages/web-worker/worker.ts(1 hunks)src/pages/ProgramLoader.tsx(2 hunks)src/store/debugger/debuggerSlice.ts(6 hunks)src/store/workers/workersSlice.ts(3 hunks)src/types/pvm.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
src/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/components/**/*.{ts,tsx}: Keep reusable UI components insrc/components/
Write TypeScript-first functional components
Files:
src/components/Instructions/BasicBlocks/CollapsibleInstructionsTable.tsxsrc/components/ProgramLoader/Examples.tsxsrc/components/HostCallDialog/index.tsxsrc/components/DebuggerSettings/Content.tsxsrc/components/HostCallDialog/handlers/storageManager.tssrc/components/HostCallDialog/handlers/types.tssrc/components/HostCallDialog/handlers/ProvideHostCall.tsxsrc/components/HostCallDialog/handlers/HostCallActionButtons.tsxsrc/components/HostCallDialog/handlers/ReadHostCall.tsxsrc/components/HostCallDialog/handlers/index.tssrc/components/HostCallDialog/handlers/TransferHostCall.tsxsrc/components/HostCallDialog/handlers/LogHostCall.tsxsrc/components/HostCallDialog/handlers/WriteHostCall.tsxsrc/components/HostCallDialog/handlers/InfoHostCall.tsxsrc/components/HostCallDialog/DefaultHostCallContent.tsxsrc/components/Registers/index.tsxsrc/components/HostCallDialog/handlers/GasHostCall.tsxsrc/components/HostCallDialog/handlers/FetchHostCall.tsxsrc/components/HostCallDialog/handlers/hostCallUtils.tssrc/components/HostCallDialog/MemoryEditor.tsxsrc/components/HostCallDialog/handlers/YieldHostCall.tsxsrc/components/ProgramLoader/Loader.tsxsrc/components/ProgramLoader/examplePrograms.tssrc/components/ProgramLoader/loadingUtils.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use two-space indentation in TypeScript files
Use descriptive filenames in kebab-case (e.g.,memory-range-panel.tsx)
Validate external inputs with Zod when parsing user data
Files:
src/components/Instructions/BasicBlocks/CollapsibleInstructionsTable.tsxsrc/packages/web-worker/command-handlers/memory.tssrc/components/ProgramLoader/Examples.tsxsrc/components/HostCallDialog/index.tsxsrc/packages/web-worker/command-handlers/set-state.tssrc/components/DebuggerSettings/Content.tsxsrc/components/HostCallDialog/handlers/storageManager.tssrc/components/HostCallDialog/handlers/types.tssrc/packages/web-worker/types.tssrc/components/HostCallDialog/handlers/ProvideHostCall.tsxsrc/pages/ProgramLoader.tsxsrc/components/HostCallDialog/handlers/HostCallActionButtons.tsxsrc/components/HostCallDialog/handlers/ReadHostCall.tsxsrc/packages/web-worker/command-handlers/index.tssrc/components/HostCallDialog/handlers/index.tssrc/packages/web-worker/worker.tssrc/components/HostCallDialog/handlers/TransferHostCall.tsxsrc/packages/web-worker/command-handlers/set-memory.tssrc/components/HostCallDialog/handlers/LogHostCall.tsxsrc/components/HostCallDialog/handlers/WriteHostCall.tsxsrc/components/HostCallDialog/handlers/InfoHostCall.tsxsrc/components/HostCallDialog/DefaultHostCallContent.tsxsrc/components/Registers/index.tsxsrc/components/HostCallDialog/handlers/GasHostCall.tsxsrc/store/workers/workersSlice.tssrc/components/HostCallDialog/handlers/FetchHostCall.tsxsrc/types/pvm.tssrc/components/HostCallDialog/handlers/hostCallUtils.tssrc/components/HostCallDialog/MemoryEditor.tsxsrc/components/HostCallDialog/handlers/YieldHostCall.tsxsrc/App.tsxsrc/components/ProgramLoader/Loader.tsxsrc/components/ProgramLoader/examplePrograms.tssrc/hooks/useDebuggerActions.tssrc/components/ProgramLoader/loadingUtils.tssrc/store/debugger/debuggerSlice.ts
src/**/*.{css,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Favor Tailwind utilities from
globals.cssbefore adding new CSS files
Files:
src/components/Instructions/BasicBlocks/CollapsibleInstructionsTable.tsxsrc/components/ProgramLoader/Examples.tsxsrc/components/HostCallDialog/index.tsxsrc/components/DebuggerSettings/Content.tsxsrc/components/HostCallDialog/handlers/ProvideHostCall.tsxsrc/pages/ProgramLoader.tsxsrc/components/HostCallDialog/handlers/HostCallActionButtons.tsxsrc/components/HostCallDialog/handlers/ReadHostCall.tsxsrc/components/HostCallDialog/handlers/TransferHostCall.tsxsrc/components/HostCallDialog/handlers/LogHostCall.tsxsrc/components/HostCallDialog/handlers/WriteHostCall.tsxsrc/components/HostCallDialog/handlers/InfoHostCall.tsxsrc/components/HostCallDialog/DefaultHostCallContent.tsxsrc/components/Registers/index.tsxsrc/components/HostCallDialog/handlers/GasHostCall.tsxsrc/components/HostCallDialog/handlers/FetchHostCall.tsxsrc/components/HostCallDialog/MemoryEditor.tsxsrc/components/HostCallDialog/handlers/YieldHostCall.tsxsrc/App.tsxsrc/components/ProgramLoader/Loader.tsx
src/packages/web-worker/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Keep WASM-facing workers in
src/packages/web-workerwith RPC shapes aligned with integrations listed inREADME.md
Files:
src/packages/web-worker/command-handlers/memory.tssrc/packages/web-worker/command-handlers/set-state.tssrc/packages/web-worker/types.tssrc/packages/web-worker/command-handlers/index.tssrc/packages/web-worker/worker.tssrc/packages/web-worker/command-handlers/set-memory.ts
src/pages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Keep feature views in
src/pages/
Files:
src/pages/ProgramLoader.tsx
src/store/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Keep Redux logic in
src/store/
Files:
src/store/workers/workersSlice.tssrc/store/debugger/debuggerSlice.ts
src/{hooks,store}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Keep stateful flows in hooks or Redux slices
Files:
src/store/workers/workersSlice.tssrc/hooks/useDebuggerActions.tssrc/store/debugger/debuggerSlice.ts
src/{hooks,lib}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Keep shared helpers in
src/hooks/andsrc/lib/
Files:
src/hooks/useDebuggerActions.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Pull requests should summarize intent, list verification steps or commands, and mention any PVM compatibility or worker contract changes
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to src/packages/web-worker/**/*.{ts,tsx} : Keep WASM-facing workers in `src/packages/web-worker` with RPC shapes aligned with integrations listed in `README.md`
Applied to files:
src/packages/web-worker/command-handlers/memory.tssrc/packages/web-worker/command-handlers/set-state.tssrc/packages/web-worker/types.tssrc/packages/web-worker/command-handlers/index.tssrc/packages/web-worker/worker.tssrc/packages/web-worker/command-handlers/set-memory.tssrc/store/workers/workersSlice.ts
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to src/**/*.spec.{ts,tsx} : Cover success and failure paths for reducers, hooks, and components that manage debugger state
Applied to files:
src/components/ProgramLoader/Examples.tsxsrc/components/DebuggerSettings/Content.tsxsrc/packages/web-worker/command-handlers/index.tssrc/hooks/useDebuggerActions.tssrc/store/debugger/debuggerSlice.ts
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to tests/**/*.spec.ts : Playwright specs in `tests/` should script critical journeys such as uploading WASM or stepping instructions
Applied to files:
src/packages/web-worker/command-handlers/index.ts
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to src/components/**/*.{ts,tsx} : Write TypeScript-first functional components
Applied to files:
src/components/HostCallDialog/handlers/WriteHostCall.tsx
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to src/**/*.{ts,tsx} : Validate external inputs with Zod when parsing user data
Applied to files:
src/components/ProgramLoader/loadingUtils.ts
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to src/{hooks,store}/**/*.{ts,tsx} : Keep stateful flows in hooks or Redux slices
Applied to files:
src/store/debugger/debuggerSlice.ts
📚 Learning: 2025-11-24T22:06:57.521Z
Learnt from: CR
Repo: FluffyLabs/pvm-debugger PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:06:57.521Z
Learning: Applies to src/store/**/*.{ts,tsx} : Keep Redux logic in `src/store/`
Applied to files:
src/store/debugger/debuggerSlice.ts
🧬 Code graph analysis (26)
src/components/Instructions/BasicBlocks/CollapsibleInstructionsTable.tsx (2)
src/packages/pvm/pvm/args-decoder.ts (1)
ArgsDecoder(22-203)src/components/Instructions/utils.tsx (1)
decodeAndGetArgsDecoder(39-49)
src/components/ProgramLoader/Examples.tsx (3)
src/components/ProgramLoader/types.ts (1)
ProgramUploadFileOutput(3-10)src/store/hooks.ts (1)
useAppSelector(5-5)src/components/ProgramLoader/loadingUtils.ts (1)
loadFileFromUint8Array(42-141)
src/components/HostCallDialog/index.tsx (5)
src/context/NumeralSystemContext.tsx (1)
NumeralSystemContext(4-8)src/components/HostCallDialog/DefaultHostCallContent.tsx (2)
MemoryEdit(10-10)DefaultHostCallContent(32-135)src/store/workers/workersSlice.ts (3)
MemoryEdit(629-632)HostCallResumeMode(603-603)resumeAfterHostCall(634-702)src/types/pvm.ts (2)
DEFAULT_REGS(14-14)DEFAULT_GAS(17-17)src/components/HostCallDialog/handlers/index.ts (1)
getHostCallHandler(31-33)
src/packages/web-worker/command-handlers/set-state.ts (3)
src/packages/web-worker/types.ts (1)
PvmApiInterface(102-102)src/types/pvm.ts (1)
ExpectedState(47-49)src/packages/web-worker/utils.ts (2)
regsAsUint8(22-37)getState(11-20)
src/components/DebuggerSettings/Content.tsx (3)
src/context/NumeralSystemContext.tsx (1)
NumeralSystemContext(4-8)src/utils/loggerService.tsx (1)
error(39-45)src/store/debugger/debuggerSlice.ts (1)
setSpiArgs(199-201)
src/components/HostCallDialog/handlers/types.ts (2)
src/types/pvm.ts (1)
ExpectedState(47-49)src/store/workers/workersSlice.ts (2)
HostCallResumeMode(603-603)MemoryEdit(629-632)
src/packages/web-worker/types.ts (1)
src/types/pvm.ts (1)
ExpectedState(47-49)
src/components/HostCallDialog/handlers/ProvideHostCall.tsx (5)
src/components/HostCallDialog/handlers/types.ts (2)
HostCallHandlerProps(4-15)HostCallHandler(17-26)src/types/pvm.ts (1)
DEFAULT_REGS(14-14)src/utils/loggerService.tsx (1)
error(39-45)src/components/HostCallDialog/handlers/hostCallUtils.ts (3)
OK(13-13)HostCallContext(155-190)hexToAscii(131-140)src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (1)
HostCallActionButtons(10-27)
src/pages/ProgramLoader.tsx (1)
src/types/pvm.ts (1)
DEFAULT_GAS(17-17)
src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (2)
src/store/workers/workersSlice.ts (1)
HostCallResumeMode(603-603)src/components/ui/button.tsx (1)
Button(14-19)
src/components/HostCallDialog/handlers/ReadHostCall.tsx (6)
src/components/HostCallDialog/handlers/types.ts (2)
HostCallHandlerProps(4-15)HostCallHandler(17-26)src/components/HostCallDialog/handlers/index.ts (2)
HostCallHandlerProps(43-43)HostCallHandler(43-43)src/types/pvm.ts (1)
DEFAULT_REGS(14-14)src/components/HostCallDialog/handlers/storageManager.ts (2)
storageManager(64-64)read(16-19)src/components/HostCallDialog/handlers/hostCallUtils.ts (3)
HostCallContext(155-190)read(37-56)hexToAscii(131-140)src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (1)
HostCallActionButtons(10-27)
src/components/HostCallDialog/handlers/index.ts (9)
src/components/HostCallDialog/handlers/types.ts (1)
HostCallHandler(17-26)src/components/HostCallDialog/handlers/GasHostCall.tsx (1)
GasHostCall(99-104)src/components/HostCallDialog/handlers/FetchHostCall.tsx (1)
FetchHostCall(210-215)src/components/HostCallDialog/handlers/ReadHostCall.tsx (1)
ReadHostCall(218-223)src/components/HostCallDialog/handlers/WriteHostCall.tsx (1)
WriteHostCall(294-299)src/components/HostCallDialog/handlers/InfoHostCall.tsx (1)
InfoHostCall(242-247)src/components/HostCallDialog/handlers/TransferHostCall.tsx (1)
TransferHostCall(182-187)src/components/HostCallDialog/handlers/YieldHostCall.tsx (1)
YieldHostCall(158-163)src/components/HostCallDialog/handlers/ProvideHostCall.tsx (1)
ProvideHostCall(176-181)
src/components/HostCallDialog/handlers/TransferHostCall.tsx (3)
src/components/HostCallDialog/handlers/types.ts (2)
HostCallHandlerProps(4-15)HostCallHandler(17-26)src/types/pvm.ts (1)
DEFAULT_REGS(14-14)src/components/HostCallDialog/handlers/hostCallUtils.ts (3)
OK(13-13)HostCallContext(155-190)hexToAscii(131-140)
src/packages/web-worker/command-handlers/set-memory.ts (1)
src/packages/web-worker/types.ts (1)
PvmApiInterface(102-102)
src/components/HostCallDialog/handlers/LogHostCall.tsx (4)
src/packages/web-worker/goWasmExec.js (1)
decoder(194-194)src/components/HostCallDialog/handlers/types.ts (2)
HostCallHandlerProps(4-15)HostCallHandler(17-26)src/utils/loggerService.tsx (1)
error(39-45)src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (1)
HostCallActionButtons(10-27)
src/components/HostCallDialog/handlers/InfoHostCall.tsx (6)
src/components/HostCallDialog/handlers/index.ts (2)
HostCallHandlerProps(43-43)HostCallHandler(43-43)src/types/pvm.ts (1)
DEFAULT_REGS(14-14)src/utils/loggerService.tsx (1)
error(39-45)src/components/HostCallDialog/handlers/hostCallUtils.ts (1)
HostCallContext(155-190)src/components/ui/input.tsx (1)
Input(13-13)src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (1)
HostCallActionButtons(10-27)
src/components/Registers/index.tsx (3)
src/packages/web-worker/wasmBindgenInit.ts (1)
Status(218-231)src/lib/utils.ts (1)
cn(6-8)src/packages/ui-kit/DarkMode/utils.ts (1)
isDarkMode(5-7)
src/components/HostCallDialog/handlers/GasHostCall.tsx (4)
src/components/HostCallDialog/handlers/index.ts (2)
HostCallHandlerProps(43-43)HostCallHandler(43-43)src/types/pvm.ts (1)
DEFAULT_REGS(14-14)src/components/HostCallDialog/handlers/hostCallUtils.ts (1)
HostCallContext(155-190)src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (1)
HostCallActionButtons(10-27)
src/store/workers/workersSlice.ts (4)
src/store/debugger/debuggerSlice.ts (2)
setPendingHostCallIndex(190-192)setHasHostCallOpen(187-189)src/packages/web-worker/utils.ts (1)
getState(11-20)src/store/index.ts (1)
RootState(29-29)src/store/utils.ts (2)
asyncWorkerPostMessage(14-38)hasCommandStatusError(40-42)
src/components/HostCallDialog/handlers/hostCallUtils.ts (1)
src/types/pvm.ts (2)
DEFAULT_REGS(14-14)DEFAULT_GAS(17-17)
src/App.tsx (1)
src/components/HostCallDialog/index.tsx (1)
HostCallDialog(46-198)
src/components/ProgramLoader/Loader.tsx (1)
src/store/debugger/debuggerSlice.ts (1)
setSpiArgs(199-201)
src/components/ProgramLoader/examplePrograms.ts (1)
src/types/pvm.ts (1)
DEFAULT_GAS(17-17)
src/hooks/useDebuggerActions.ts (1)
src/components/HostCallDialog/handlers/storageManager.ts (1)
storageManager(64-64)
src/components/ProgramLoader/loadingUtils.ts (1)
src/types/pvm.ts (1)
DEFAULT_GAS(17-17)
src/store/debugger/debuggerSlice.ts (2)
src/types/pvm.ts (3)
DEFAULT_REGS(14-14)DEFAULT_GAS(17-17)SpiProgram(6-9)src/packages/web-worker/wasmBindgenInit.ts (1)
Status(218-231)
🔇 Additional comments (42)
src/packages/web-worker/command-handlers/memory.ts (1)
75-96: LGTM! Enhanced error messages improve debuggability.The
dumpParamshelper and updated error messages provide valuable context when memory operations fail. The implementation is clean, consistent across all error branches, and will make troubleshooting invalid memory addresses, out-of-bounds ranges, and invalid ranges much easier.package.json (1)
34-34: Update to @typeberry/lib looks fine; please confirm compatibilityBumping
@typeberry/libto^0.4.1-3923458is reasonable, but since core PVM decoding and host-call behavior depend on it, please confirm the existing test suite (especially program loading and host-call flows) still passes and that no RPC/ABI shapes changed unexpectedly.src/components/HostCallDialog/handlers/HostCallActionButtons.tsx (1)
1-27: HostCallActionButtons mapping and API look solidThe component cleanly maps the three buttons to
"run" | "step" | "block"and centralizes the disabled state, which should make host-call handlers easy to wire. No changes requested.src/App.tsx (1)
13-13: Root-level HostCallDialog integration is appropriateMounting
HostCallDialogalongsideToastContainergives a global, layout-independent host-call UI while actual visibility remains controlled by store state (hasHostCallOpen). This is a good place for the dialog; no changes needed.Also applies to: 49-49
src/pages/ProgramLoader.tsx (1)
4-4: Use of DEFAULT_GAS for JAM SPI URL loads improves consistency (confirm intended value)Switching the JAM SPI URL loader to use
DEFAULT_GASinstead of a hardcoded10000nkeeps gas initialization aligned with the shared constant fromtypes/pvm. Please just confirm thatDEFAULT_GAS(currently1_000_000n) is the desired starting gas for JAM SPI programs loaded via URL, since this increases the initial budget compared to the previous value.Also applies to: 77-91
src/types/pvm.ts (1)
13-17: LGTM! Centralized defaults improve consistency.The introduction of
DEFAULT_REGSandDEFAULT_GASconstants is a good practice that standardizes VM initialization across the codebase.src/packages/web-worker/worker.ts (1)
130-156: LGTM! New command handlers follow established patterns.The
SET_STATEandSET_MEMORYcommand handlers are implemented consistently with existing command handlers, maintaining the established error handling and response structure.src/hooks/useDebuggerActions.ts (2)
44-44: LGTM! Storage cleanup on restart is appropriate.Clearing storage at the start of
restartProgramensures a clean state for host-call interactions.
68-68: LGTM! Storage cleanup on start is appropriate.Clearing storage at the start of
startProgramensures a clean state for host-call interactions.src/components/ProgramLoader/Loader.tsx (1)
27-39: The code correctly usesparsed.raw.The property is consistently used throughout the codebase when accessing the Uint8Array from
BytesBlob.parseBlob()results. This pattern is identical inDebuggerSettings/Content.tsxand verified across all usages in the repository.src/components/DebuggerSettings/Content.tsx (1)
29-42: The code is correct. Throughout the codebase,bytes.BytesBlob.parseBlob()consistently returns an object with a.rawproperty containing the Uint8Array. This pattern is used identically in multiple files (ProgramLoader.tsx, FetchHostCall.tsx, ProgramTextLoader/index.tsx, loadingUtils.ts, Loader.tsx, and InfoHostCall.tsx), confirming thatparsed.rawis the correct property to dispatch.Likely an incorrect or invalid review comment.
src/components/HostCallDialog/handlers/types.ts (1)
1-26: Well-structured type definitions for host call handlers.The interfaces are cleanly defined with proper JSDoc documentation and correct type references. The
HostCallHandlerPropsprovides a clear contract for handler components, andHostCallHandlerestablishes a consistent registry pattern.src/components/HostCallDialog/handlers/index.ts (2)
43-43: Type re-exports look good.Proper barrel export pattern for centralizing type access through the handlers module.
12-26: Clean handler registry implementation with efficient O(1) lookup.The pattern of using an array for ordered registration and a Map for O(1) lookup is appropriate. The Map is constructed once at module load time. Verification confirms all nine handlers have unique indices (0, 1, 3, 4, 5, 20, 25, 26, 100) with no duplicates.
src/components/HostCallDialog/handlers/LogHostCall.tsx (3)
5-35: Log level utilities are well-implemented.The enum, styles mapping, and helper functions provide clear type-safe handling of log levels with appropriate fallback for unknown values.
53-81: Memory loading effect is well-structured.The async loading pattern with proper loading/error state management and cleanup is good. The dependency array correctly includes all values used in the effect.
137-142: Verify the host call index 100 for the log handler.Other handlers use indices in the 0-26 range, but LogHostCall uses index 100. Please verify this matches the actual PVM host call specification for logging.
src/packages/web-worker/command-handlers/index.ts (1)
6-7: Clean integration of new command handlers.The new
runSetStateandrunSetMemoryhandlers follow the established pattern and are properly wired into the export. This aligns with the web-worker RPC conventions. As per learnings, this maintains consistency with the WASM-facing worker architecture.Also applies to: 15-16
src/components/HostCallDialog/handlers/ProvideHostCall.tsx (3)
1-10: Imports and setup look appropriate.The component properly imports from
@typeberry/libfor the Provide host call implementation and related utilities.
35-92: Mount execution with StrictMode guard is correctly implemented.The
hasExecutedref pattern properly prevents double execution in React StrictMode. The capture mechanism for preimage data through theprovidePreimagecallback is clever.
141-173: UI implementation is clean and well-organized.The component properly handles loading, error, and data display states. The ASCII preview for smaller preimages (≤256 bytes) is a nice touch for debugging. The action buttons are correctly disabled during loading/execution.
src/components/HostCallDialog/handlers/FetchHostCall.tsx (1)
210-215: LGTM!The handler structure correctly implements the
HostCallHandlerinterface with appropriate index, name, and component reference.src/components/HostCallDialog/handlers/InfoHostCall.tsx (1)
242-247: LGTM!The handler structure correctly implements the
HostCallHandlerinterface with index 5 matching the "info" host call.src/packages/web-worker/types.ts (1)
43-44: LGTM!The new
SET_STATEandSET_MEMORYcommands follow the existing pattern for request/response types. The payload structures are appropriate for their purposes:SET_STATEupdates registers and gas, whileSET_MEMORYwrites data at a specific address.Also applies to: 69-70, 84-85
src/components/HostCallDialog/index.tsx (3)
82-84: Hardcoded gas deduction of 10 may not match actual host call gas costs.The fallback gas calculation subtracts 10 unconditionally. Different host calls may have different gas costs. This could lead to incorrect gas tracking.
Is the 10-unit gas deduction intentional as a default/placeholder? If host calls have variable costs, consider making this configurable or documenting the assumption.
140-148: LGTM on modal behavior.Preventing escape, outside clicks, and hiding the close button is appropriate here since the user must handle the host call to continue PVM execution. The dialog correctly forces interaction.
175-182: Verify thatreadMemoryis passed correctly to custom handler.Custom handlers receive
readMemorybut some handlers (likeFetchHostCall,InfoHostCall) don't appear to use it in their current implementations. Ensure this prop is intentionally part of the interface for future use or consider making it optional inHostCallHandlerProps.src/components/HostCallDialog/handlers/ReadHostCall.tsx (1)
218-223: LGTM!The handler export correctly registers index 3 for the "read" host call with custom UI enabled.
src/components/HostCallDialog/DefaultHostCallContent.tsx (1)
85-134: LGTM!The two-column layout with gas/registers on the left and memory editor on the right is well-structured and responsive.
src/components/HostCallDialog/handlers/YieldHostCall.tsx (1)
158-163: LGTM!The handler export correctly registers index 25 for the "yield" host call.
src/components/HostCallDialog/handlers/TransferHostCall.tsx (1)
143-179: LGTM!The UI clearly displays all transfer data fields (destination, amount, gas, memo) with both hex and ASCII representations for the memo.
src/components/HostCallDialog/handlers/GasHostCall.tsx (2)
26-56: LGTM!The gas host call implementation is clean and straightforward. The execute-on-mount pattern with
hasExecutedref correctly prevents duplicate execution.
99-104: LGTM!The handler export correctly registers index 0 for the "gas" host call with custom UI.
src/components/HostCallDialog/handlers/WriteHostCall.tsx (1)
215-291: LGTM!The render logic is well-structured with clear conditional rendering for different states (loading, error, display). The UI properly handles the delete operation case and provides good user feedback with ASCII previews for smaller values.
src/components/HostCallDialog/handlers/hostCallUtils.ts (2)
77-85: LGTM!The
submethod correctly handles gas underflow by setting gas to 0 and returningtrueto indicate exhaustion. This aligns with typical PVM gas semantics.
155-189: LGTM!The
HostCallContextclass provides a clean abstraction for setting up host call execution environments. It properly initializes mock memory, gas counter, and registers, and thegetResult()method provides a unified way to extract the execution outcome.src/store/workers/workersSlice.ts (3)
266-272: LGTM!Good fallback behavior when
hostCallsTraceis null. Opening the dialog allows users to manually configure the host call response, which is essential for interactive debugging without pre-recorded traces.
605-627: LGTM!The
readMemoryRangethunk correctly reads memory from the first worker and propagates errors appropriately. Using the first worker is consistent with the host call dialog's single-context approach.
664-681: Consider clarifying memory edit semantics across workers before optimizing.If memory edits can affect shared state visible to other workers or if deterministic replay is required across the system, sequential processing of all workers may be necessary. However, if edits are worker-isolated or order-independent, the current parallel approach is appropriate. Verify whether your use case requires global memory edit ordering.
src/store/debugger/debuggerSlice.ts (3)
110-115: LargeinstructionCountdefault may affect UI responsiveness.The
instructionCounthas been increased from 1 to 10,000. While this improves execution speed for long programs, it may cause noticeable UI freezes during run mode. Ensure this value is appropriate for the expected use cases.
190-192: LGTM!The
setPendingHostCallIndexreducer is correctly typed withnumber | nullpayload, matching the state definition on line 33.
199-201: LGTM!Good improvement to explicitly type the
setSpiArgspayload asUint8Array, providing better type safety.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>