Refresh README and config example
Document the event-sourced store, gossip replication, push-on-commit, compaction and the TLS peer link; drop the stale persistence status.
This commit is contained in:
parent
0af7f10c3d
commit
d30f5c05a6
2 changed files with 64 additions and 10 deletions
60
README.md
60
README.md
|
|
@ -2,18 +2,56 @@
|
||||||
|
|
||||||
A federated IRC services daemon in Rust. Protocol-agnostic core, InspIRCd link first.
|
A federated IRC services daemon in Rust. Protocol-agnostic core, InspIRCd link first.
|
||||||
|
|
||||||
Clean-room — inspired by the ideas behind modern event-log/gossip services, not
|
Clean-room, inspired by the ideas behind modern event-log/gossip services, not
|
||||||
derived from any project's source.
|
derived from any project's source.
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
- **`proto/`** — the ircd link layer. A `Protocol` trait maps raw server-to-server
|
- **`proto/`** the ircd link layer. A `Protocol` trait maps raw server-to-server
|
||||||
lines to/from a normalized `NetEvent`/`NetAction` model. The engine never touches
|
lines to and from a normalized `NetEvent`/`NetAction` model, so the engine never
|
||||||
a raw line, so a new ircd = one new module. InspIRCd is the first.
|
touches a raw line and a new ircd is one new module. InspIRCd is the first.
|
||||||
- **`engine/`** — the services engine: live network `state`, an `EventLog` (every
|
- **`engine/`** the services engine: live network `state`, the account store, and
|
||||||
persistent change is an `Event`; state is a fold over the log — this is what makes
|
the `Service` trait. The store is event-sourced: every change is an `Event`
|
||||||
replicating across nodes a later addition, not a rewrite), and the `Service` trait.
|
appended to a per-node log, and state is a fold over that log.
|
||||||
- **`services/`** — the pseudo-clients: NickServ first, then ChanServ / OperServ / …
|
- **`gossip/`** node-to-node replication over the logs.
|
||||||
|
- **`services/`** the pseudo-clients: NickServ first, then ChanServ / OperServ.
|
||||||
|
|
||||||
|
## Replication
|
||||||
|
|
||||||
|
Each log entry carries an `origin`, a per-origin `seq`, and a Lamport clock. Peers
|
||||||
|
connect, exchange version vectors, and send each other the entries the other
|
||||||
|
lacks; a freshly committed entry is also pushed immediately, so a registration
|
||||||
|
propagates in milliseconds. Ingest is idempotent, so re-delivery and reconnect
|
||||||
|
after a split both converge. The log is compacted to one entry per account as it
|
||||||
|
grows. An account registered on any node works on all of them.
|
||||||
|
|
||||||
|
## Config
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[uplink]
|
||||||
|
host = "127.0.0.1"
|
||||||
|
port = 7000
|
||||||
|
password = "linkpw"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
name = "services.example"
|
||||||
|
sid = "42S"
|
||||||
|
|
||||||
|
[gossip] # omit to run a single, non-replicating node
|
||||||
|
bind = "0.0.0.0:16700"
|
||||||
|
secret = "shared-secret"
|
||||||
|
|
||||||
|
[gossip.tls] # omit for a plaintext link
|
||||||
|
cert = "certs/nodeA.crt"
|
||||||
|
key = "certs/nodeA.key"
|
||||||
|
ca = "certs/ca.crt" # a peer must present a certificate signed by this CA
|
||||||
|
|
||||||
|
[[peer]]
|
||||||
|
addr = "nodeB.example:16700"
|
||||||
|
name = "nodeB" # TLS name to expect; must match the peer certificate
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate certificates with `scripts/gen-certs.sh`.
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
|
|
@ -24,5 +62,7 @@ cargo run -- config.toml
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Early scaffold: links to an InspIRCd uplink and introduces NickServ. Burst/mode
|
Links to an InspIRCd uplink and runs NickServ (REGISTER, IDENTIFY, LOGOUT, CERT,
|
||||||
handling and account persistence are next.
|
and SASL PLAIN / SCRAM-SHA-256/512 / EXTERNAL) over an event-sourced account store
|
||||||
|
replicated between nodes by gossip, with an optional mutually authenticated TLS
|
||||||
|
peer link. Next: ChanServ.
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,17 @@ name = "services.example.net"
|
||||||
sid = "42S" # 3 chars, unique on the network
|
sid = "42S" # 3 chars, unique on the network
|
||||||
description = "Federated Services"
|
description = "Federated Services"
|
||||||
protocol = 1206 # InspIRCd link protocol version (1206 = insp4, 1205 = insp3)
|
protocol = 1206 # InspIRCd link protocol version (1206 = insp4, 1205 = insp3)
|
||||||
|
|
||||||
|
# Node-to-node replication. Omit this section (and [[peer]]) to run a single node.
|
||||||
|
# [gossip]
|
||||||
|
# bind = "0.0.0.0:16700" # where peers reach us; omit for a dial-only node
|
||||||
|
# secret = "shared-secret" # both nodes must present the same secret
|
||||||
|
#
|
||||||
|
# [gossip.tls] # omit for a plaintext link; see scripts/gen-certs.sh
|
||||||
|
# cert = "certs/node.crt"
|
||||||
|
# key = "certs/node.key"
|
||||||
|
# ca = "certs/ca.crt" # a peer must present a certificate signed by this CA
|
||||||
|
#
|
||||||
|
# [[peer]] # one block per other node
|
||||||
|
# addr = "other-node:16700"
|
||||||
|
# name = "other-node" # TLS name to expect; must match the peer certificate
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue