Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions docs/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@

| Module | Role |
|---|---|
| [`server.py`](server.md) — `StellarRpcServer` | Long-running HTTP/JSON-RPC server wrapping the one-shot K interpreter; `handle_rpc` dispatch; owns the io-dir files. Holds no ledger or receipt state. |
| [`transaction.py`](transaction.md) — `TransactionEncoder` | XDR → request envelope + (for wasm uploads) kasmer steps; address/contract-id helpers. |
| [`server.py`](server.md) — `StellarRpcServer` | Long-running HTTP/JSON-RPC server wrapping the one-shot K interpreter; `handle_rpc` → `_dispatch` routing (bad params raise `RpcError`). Holds no ledger or receipt state; delegates the io-dir to `ChainStore`. |
| `store.py` — `ChainStore` | Owns the io-dir layout: the sole reader/writer of `state.kore`, `metadata.json`, and the `receipts/` `ledgers/` `events/` `requests/` `wasms/` files. |
| [`transaction.py`](transaction.md) — `TransactionEncoder` | XDR → request envelope (`TxRequest`/`SimulateRequest`) + (for wasm uploads) kasmer steps; address/contract-id helpers. |
| [`interpreter.py`](interpreter.md) — `NodeInterpreter` | Runs request envelopes through `llvm_interpret`; persists `state.kore`. No `kast`↔`kore` whole-config conversions. |
| `scval.py` | XDR `SCVal` ↔ request/response JSON (`scval_to_json`, `scval_from_json`). |
| `ledger_entries.py` | `getLedgerEntries` XDR translation: base64 `LedgerKey` → key descriptors for the semantics, intermediate entries → base64 `LedgerEntryData`. |
| `errors.py` | The internal exceptions: `NodeInterpreterError`, `TransactionEncodingError`, and `RpcError` (a JSON-RPC error with its spec code). |
| [`kdist/node.md`](node-semantics.md) | The K RPC layer: reads `request.json`, dispatches, updates `metadata.json` and the per-transaction `receipts/` files, writes `response.json`. |

State lives in the io dir as `state.kore` (KORE world state) and `metadata.json` (ledger counter), with per-transaction receipts and traces under `receipts/` and `traces/`. See [architecture.md](architecture.md).
Expand Down
63 changes: 63 additions & 0 deletions src/komet_node/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""The exceptions komet-node raises internally.

Collected in one module so no layer has to reach into another purely for an error type
(the encoder, for instance, must not depend on the interpreter just to signal a bad input).

- :class:`NodeInterpreterError` — the K interpreter subprocess failed.
- :class:`TransactionEncodingError` — a Stellar transaction could not be encoded.
- :class:`RpcError` — a JSON-RPC error to hand back to the client.
"""

from __future__ import annotations


class NodeError(RuntimeError):
"""Base class for komet-node's own errors."""


class NodeInterpreterError(NodeError):
"""The K interpreter subprocess failed or produced no usable output."""


class TransactionEncodingError(NodeError):
"""A Stellar transaction could not be encoded into a node request envelope.

Raised by :class:`~komet_node.transaction.TransactionEncoder` for inputs it cannot
translate (sub-stroop XLM amounts, malformed strkey addresses). On the admission path
the server catches it and turns it into a ``txMALFORMED`` status response.
"""


class RpcError(Exception):
"""A JSON-RPC error to return to the client, carrying its spec code and message.

Raised by request validation and dispatch in the server so the envelope builders can
return a single value type instead of threading a pre-formatted error string back
through their return type. :meth:`~komet_node.server.StellarRpcServer.handle_rpc`
catches it and formats the error envelope. The classmethods name the JSON-RPC 2.0
error codes; ``invalid_params`` prepends the conventional ``Invalid params:`` prefix.
"""

code: int
message: str

def __init__(self, code: int, message: str) -> None:
super().__init__(code, message)
self.code = code
self.message = message

@classmethod
def invalid_request(cls, message: str) -> RpcError:
return cls(-32600, message)

@classmethod
def invalid_params(cls, detail: str) -> RpcError:
return cls(-32602, f'Invalid params: {detail}')

@classmethod
def method_not_found(cls, message: str = 'Method not found') -> RpcError:
return cls(-32601, message)

@classmethod
def internal(cls, message: str = 'Internal error') -> RpcError:
return cls(-32603, message)
8 changes: 3 additions & 5 deletions src/komet_node/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
from pyk.kore.syntax import App, SortApp
from pyk.utils import check_file_path, run_process_2

from .errors import NodeInterpreterError
from .utils import simbolik_definition

if TYPE_CHECKING:
from collections.abc import Mapping
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -122,7 +124,7 @@ def run(
self,
state_file: Path,
io_dir: Path,
request: dict[str, Any],
request: Mapping[str, Any],
program_steps: list[KInner] | None = None,
*,
commit: bool = True,
Expand Down Expand Up @@ -180,7 +182,3 @@ def _inject_program(self, pattern: Pattern, steps: list[KInner]) -> Pattern:
"""
steps_kore = kast_to_kore(self.definition.kdefinition, steps_of(steps), KSort('Steps'))
return _set_cell(pattern, _PROGRAM_CELL, steps_kore)


class NodeInterpreterError(RuntimeError):
pass
Loading
Loading