March Docs

NodeRpc

NodeRpc: the receive-side RPC dispatcher + caller-side reply logic (P1 L4).

The pure orchestration that sits between the net-kernel transport and a node's enrolled targets. The responder decodes nothing here (it works on an already- decoded CallRequest): it looks the target up by identity, runs the CAS admission check (RemoteCall.verify), invokes the local marshalling stub, and builds the CallReply to frame back. The caller side interprets a reply and makes the failure-isolation decisions (deadline expiry, peer-down).

The target table is injected here. In the full system the compiler-emitted enroll/stub mechanism (a function-by-identity registry + marshalling stubs) populates it; modelling it as an injected Targets keeps this layer pure and unit-testable and pins down exactly what that mechanism must provide: per target, its (sig_hash, impl_hash) and an invoke : args-bytes -> result-bytes stub (Err models a crash/exit inside the target body).

Types

typeTargetTarget = {#
typeTargetsTargets = Targets(Map(String, Target))#

Functions

fnemptyempty() : Targets do Targets(Map.empty()) end#
fnenrollenroll(t : Targets, module_name : String, fn_name : String, target : Target) : Targets#
fnhandle_framehandle_frame(t : Targets, bytes : List(Int)) : Option(CallReply)#
fnhandle_requesthandle_request(t : Targets, req : CallRequest) : CallReply#
fninterpretinterpret(reply : CallReply) : Result(List(Int), CallError)#
fnmatchesmatches(req : CallRequest, reply : CallReply) : Bool#
fnpeer_down_errorpeer_down_error() : CallError do NoConnection end#
fntimed_outtimed_out(now : Int, deadline : Int) : Bool do now >= deadline end#