komet-node is a local Stellar testnet backed by the K semantics of Soroban. The compiled semantics are a one-shot interpreter (one process per request, no networking, no state between runs), so Python wraps them into a long-running server: it holds the HTTP socket, keeps state on disk between runs, and decodes Stellar XDR, which K cannot. The RPC layer itself — method dispatch, receipt bookkeeping, ledger accounting, status, and response formatting — runs inside the K semantics (node.md).
| Module | Role |
|---|---|
server.py — 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 — TransactionEncoder |
XDR → request envelope (TxRequest/SimulateRequest) + (for wasm uploads) kasmer steps; address/contract-id helpers. |
interpreter.py — 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 |
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.
test_server.pydrives the running HTTP server end-to-end. It exercises the read-only methods,sendTransaction+getTransaction, the history methods (getTransactions/getLedgersresponse shapes, pagination, and parameter validation against the official spec and the Go protocol structs), ledger increments, the full lifecycle (create → upload wasm → deploy → invoke), thetraceTransactionflows, andgetLedgerEntries(account, contract code, contract instance, and persistent storage entries viastorage.wat, plus its parameter validation).test_call_tx_with_argsdeploysargs.watand calls functions withbool,u32,i32,u64,i64,u128,i128, andsymbolarguments, exercising thescval_to_json/#decodeArgpipeline.test_get_events.pycoversgetEvents: request validation, the empty-window shape, the full shape of an event emitted viacontract_event(data/wasm/events.wat), filtering, and pagination.test_integration.pyandtest_unit.pyhold small sanity checks.
Run with make test (requires make kdist-build first).
The tests do not yet cover bytes / address SCVal arguments or SCVec / SCMap (and scval_to_json does not yet encode the latter).
resultXdr/resultMetaXdrare synthesised:feeChargedis 0, ledger-entry change sets are empty, and the InvokeHostFunction success hash covers only the return value (komet-node does not track fees, entry changes, or events).sendTransaction'serrorResultXdris always a generictxMALFORMEDresult (no per-cause codes such astxBAD_SEQ— sequence numbers, fees, and signatures are not modelled), anddiagnosticEventsXdris never populated (both fields are optional in the spec).TRY_AGAIN_LATERis never returned by design: it signals mempool backpressure, which cannot arise in a synchronous node without a mempool.SCVec/SCMapcontract arguments are not yet encoded.- The
xdrFormatparameter is accepted ongetTransaction,sendTransaction,getTransactions,getLedgers,getLedgerEntries, andgetEvents, but only the default'base64'is supported;'json'is rejected with-32602. simulateTransactiononly simulates invoke-contract host functions (not uploads/deploys);authis always empty,minResourceFee/transactionDataare synthetic constants, andevents/restorePreamble/stateChangesand theresourceConfig/authMode/xdrFormatparameters are not supported.getEventsserves contract events only:systemevents are never emitted (the semantics have no source of them), and events whose topics/data have no staging representation (maps, errors, 256-bit ints) are dropped with a warning.- TTL/footprint operations are not implemented.
getFeeStatsreports constant distributions (there is no fee market); only itslatestLedgeris live.getTransactions/getLedgersserve only ledgers with an index file underledgers/; io-dirs created before the ledger index existed resume fine, but their earlier ledgers do not appear in the history.getLedgerEntriescovers the entry types the K state tracks (ACCOUNT,CONTRACT_DATA,CONTRACT_CODE); other key types are reported as not found.lastModifiedLedgerSeqis approximated by the current ledger (per-entry modification ledgers are not tracked), and only the balance is real inACCOUNTentries (sequence number, thresholds, etc. are synthesised constants).- Receipts are not a stable format: older io-dirs store
ledger/createdAtwith pre-spec types and lackapplicationOrder/feeBump. Resume only io-dirs written by the same version, or start fresh.