# gizfs:node

A storage node: one process owns one locked durable range. Connection tasks authenticate and enqueue; only the volume actor changes Raft or filesystem/object metadata. fs/server.giz runs one node from its command line; `embedded` runs one inside another process. Automatic scrub preserves policy coverage; no auto-GC.

```gizlang
import * as Node from "gizfs:node";
```

## Types

### `Restore`

```gizlang
type Restore = { bundle: bytes; sourceKey: bytes; }
```

A signed backup bundle (`Client.backup`) and the master key of its source store.

- `bundle`: `bytes`
- `sourceKey`: `bytes`

## Functions

### `serve`

```gizlang
function serve(sys: System, path: string, id: i64, listener: Listener, tenant: string, endpoints: Vec<Protocol.Endpoint>, copies: i64, domains: i64, master: bytes, history: string, restore: Option<Restore>, route: Option<Task.Channel<Protocol.LocalRoute>>, initial: Vec<i64>, disks: Vec<string>): Result<i64, string>
```

VOTERS: the voters of the range when this node starts with a new directory (a node that joins a running range gives
its current voters, and is a learner until `topology` makes it a voter); none: every node of ENDPOINTS.

Effects: fail, read, write, console, io.

### `formats`

```gizlang
function formats(): Vec<Codec.Format>
```

The on-disk formats of this module. A test opens a committed store sample of every version.

Effects: fail.

### `embeddedEnvironment`

```gizlang
function embeddedEnvironment(sys: System, path: string, tenant: string): Result<Vec<string>, string>
```

The environment of a client of the embedded store in `path`: `GIZ_STORAGE_NODES` and
`GIZ_STORAGE_CREDENTIAL` of the tenant's root principal.

Effects: fail, io.

### `embedded`

```gizlang
function embedded(sys: System, path: string, tenant: string): Result<Volume.Client, string>
```

A single-node store inside this process, in the folder `path` (made when it is missing). The first use
writes `path/EMBEDDED` (mode 0600): the tenant, a port on 127.0.0.1, the history
and a random master key. A later use reads it and listens on the same port,
because the endpoint is part of the durable topology. A malformed file, another
tenant or a taken port is an error, never a new store: a new master would orphan
the data. The node serves in a task until the process ends. Gives a client of the
tenant's root principal once the node leads.

Effects: fail, read, write, console, io.

### `restoreEmbedded`

```gizlang
function restoreEmbedded(sys: System, path: string, tenant: string, bundle: bytes, sourceKey: bytes): Result<Volume.Client, string>
```

A new embedded store in `path` from a backup of another one. Before the call, copy
`bundle` from `Client.backup` of the source, then the files `blob-1-*` of the source's
`bytes/` into `path/bytes/` (after the backup returns: the backup pins them). `path`
must hold no other store file. The new store has a new master key and history, so
`sourceKey` (the source's master key) cannot write it. Gives a client once every
restored chunk is verified; until then the store refuses reads and writes. `EMBEDDED`
appears only then. A failed restore leaves a folder that no call opens: remove it and copy again.

Effects: fail, read, write, console, io.

### `routedClient`

```gizlang
function routedClient(sys: System, endpoints: Vec<Protocol.Endpoint>, master: bytes, tenant: string, routes: Task.Channel<Protocol.LocalRoute>, failed: Task.Cell<string>, rounds: i64, ready: (client: Volume.Client) => bool): Result<Volume.Client, string>
```

The client of the root principal of TENANT for the node in this process that sends its route on ROUTES (serve, which
closes ROUTES when it stops, and FAILED says why). It reaches the node with no socket (Protocol.LocalRoute); others
use the node's port. It is given once the node leads with its log applied and READY holds, within ROUNDS of 25 ms.

Effects: fail, read, write, console, io.

