2024-12-24 13:58:02 -06:00
|
|
|
# Concepts
|
|
|
|
|
2024-12-24 14:02:21 -06:00
|
|
|
| | Implemented | Notes |
|
|
|
|
| ------------- | ----------- | ------------------------------------------------------------------------ |
|
|
|
|
| Peering | Yes | Currently using `RHIZOME_SEED_PEERS`, no gossip / discovery |
|
|
|
|
| Schemas | Not really | Currently very thin layer allowing TypedCollections |
|
|
|
|
| Relationships | No | Supporting relational algebra among domain entities |
|
2024-12-25 00:42:16 -06:00
|
|
|
| Views | Yes | Lossless: Map the `targetContext`s as properties of domain entities. |
|
|
|
|
| | | Lossy: Use a delta filter and a resolver function to produce a view. |
|
|
|
|
| | | Currently using functions rather than JSON-Logic expressions. |
|
2024-12-24 14:02:21 -06:00
|
|
|
| Functions | No | Arbitrary subscribers to delta stream (that can also emit deltas?) |
|
|
|
|
| Tests | Minimal | So far we have a few `ts-jest` tests. Need a plan for multi-node tests. |
|
|
|
|
| Identity | No | Probably a public key / private key system |
|
|
|
|
| Contexts | No | Each context may involve different lossy functions and delta filters |
|
|
|
|
| HTTP API | Yes | Basic peering info and entity CRUD |
|
2024-12-24 13:58:02 -06:00
|
|
|
|
2024-12-25 00:42:16 -06:00
|
|
|
If we express views and filter rules as JSON-Logic, we can easily include them in records.
|
|
|
|
|
|
|
|
## Clocks?
|
|
|
|
|
|
|
|
Do we want to involve a time synchronization protocol? e.g. ntpd
|
|
|
|
|
|
|
|
If not, what's the best we could do?
|
|
|
|
|
|
|
|
Maybe just expect nodes to record relative times, and
|
|
|
|
patch together a sequence based on the relative times.
|
|
|
|
This adds complexity and still has limited precision.
|
|
|
|
|
|
|
|
We could just let the clocks drift and so on, and make inferences at
|
|
|
|
query resolution time.
|
|
|
|
|
|
|
|
We could do some extra work and keep track of what time our peers think it is.
|
|
|
|
Then if their clocks drift relative to ours, we can seek consensus among a broader range of peers.
|
|
|
|
|
|
|
|
But at that point just run ntpd. Can still do consensus to verify
|
|
|
|
but probably no need to implement custom time synchronization protocol.
|
|
|
|
|
|
|
|
Wait NTP is centralized isn't it, not peer to peer...
|
|
|
|
|
|
|
|
## Peering
|
|
|
|
|
|
|
|
### ZeroMQ
|
|
|
|
Currently we're handling networking with ZeroMQ pub/sub over TCP transport.
|
|
|
|
|
|
|
|
* ZeroMQ supports encryption, with public/private key pairs.
|
|
|
|
* A subscriber needs to know the public key of the publisher in order to connect.
|
|
|
|
* We're aiming for symmetry, so we'll need a strategy to establish these reciprocal relationships.
|
|
|
|
|
|
|
|
### GossipSub
|
|
|
|
One option is to replace ZeroMQ with GossipSub,
|
|
|
|
which may function better in an open network envoronment.
|
|
|
|
|
|
|
|
Considerations with GossipSub may include
|
|
|
|
* topics -- namespacing
|
|
|
|
* peer discovery
|
|
|
|
|
|
|
|
### TincVPN
|
|
|
|
Another layer which is available would be [Tinc VPN](https://tinc-vpn.org).
|
|
|
|
|
|
|
|
Tinc...
|
|
|
|
* is a daemon
|
|
|
|
* creates a mesh VPN
|
|
|
|
* uses tap/tun network devices
|
|
|
|
* network can run in router, switch, or hub mode
|
|
|
|
* performs UDP hole punching
|
|
|
|
* forwards packets among peers
|
|
|
|
* performs spanning tree routing
|
|
|
|
* participants only see messages if they've added the sender's public key to their configuration
|
|
|
|
|
|
|
|
Ideally at least one node in a given network
|
|
|
|
needs to listen on a public interface address.
|
|
|
|
|
|
|
|
[Tinc configuration docs](https://tinc-vpn.org/documentation/Main-configuration-variables.html)
|
|
|
|
provide some insight into its functioning.
|
|
|
|
|
|
|
|
Considerations imposed by Tinc would include
|
|
|
|
* IP addressing
|
|
|
|
* public key management
|
|
|
|
|
2024-12-24 13:58:02 -06:00
|
|
|
# Development / Demo
|
|
|
|
|
2024-12-22 17:30:41 -06:00
|
|
|
## Setup
|
2024-12-19 23:16:45 -06:00
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
Install [`nvm`](https://nvm.sh)
|
2024-12-22 17:30:41 -06:00
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
Clone repo
|
|
|
|
```bash
|
|
|
|
git clone https://gitea.dgov.io/ladd/rhizome
|
|
|
|
```
|
2024-12-22 17:30:41 -06:00
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
Use `nvm` to install and activate the target nodejs version
|
2024-12-22 17:30:41 -06:00
|
|
|
```bash
|
|
|
|
nvm install
|
2024-12-24 13:41:31 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
Install nodejs packages
|
|
|
|
```bash
|
2024-12-22 17:30:41 -06:00
|
|
|
npm install
|
|
|
|
```
|
|
|
|
|
|
|
|
## Build
|
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
Compile Typescript
|
2024-12-22 17:30:41 -06:00
|
|
|
```bash
|
2024-12-24 13:41:31 -06:00
|
|
|
npm run build
|
|
|
|
```
|
2024-12-22 17:30:41 -06:00
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
During development, it's useful to run the compiler in watch mode:
|
|
|
|
```bash
|
|
|
|
npm run build:watch
|
2024-12-22 17:30:41 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
## Run
|
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
To demonstrate the example application, you can open multiple terminals, and in each terminal execute something like the following:
|
2024-12-22 17:30:41 -06:00
|
|
|
|
2024-12-22 17:33:22 -06:00
|
|
|
```bash
|
2024-12-24 13:41:31 -06:00
|
|
|
export DEBUG="*,-express"
|
2024-12-22 17:33:22 -06:00
|
|
|
export RHIZOME_REQUEST_BIND_PORT=4000
|
|
|
|
export RHIZOME_PUBLISH_BIND_PORT=4001
|
|
|
|
export RHIZOME_SEED_PEERS='127.0.0.1:4002, 127.0.0.1:4004'
|
|
|
|
export RHIZOME_HTTP_API_PORT=3000
|
|
|
|
export RHIZOME_PEER_ID=peer1
|
2024-12-24 13:41:31 -06:00
|
|
|
npm run example-app
|
2024-12-22 17:33:22 -06:00
|
|
|
```
|
2024-12-22 17:32:00 -06:00
|
|
|
|
2024-12-22 17:33:22 -06:00
|
|
|
```bash
|
2024-12-24 13:41:31 -06:00
|
|
|
export DEBUG="*,-express"
|
2024-12-22 17:33:22 -06:00
|
|
|
export RHIZOME_REQUEST_BIND_PORT=4002
|
|
|
|
export RHIZOME_PUBLISH_BIND_PORT=4003
|
|
|
|
export RHIZOME_SEED_PEERS='127.0.0.1:4000, 127.0.0.1:4004'
|
2024-12-24 13:41:31 -06:00
|
|
|
export RHIZOME_HTTP_API_PORT=3001
|
2024-12-22 17:33:22 -06:00
|
|
|
export RHIZOME_PEER_ID=peer2
|
2024-12-24 13:41:31 -06:00
|
|
|
npm run example-app
|
2024-12-22 17:33:22 -06:00
|
|
|
```
|
2024-12-22 17:32:19 -06:00
|
|
|
|
2024-12-22 17:33:22 -06:00
|
|
|
```bash
|
2024-12-24 13:41:31 -06:00
|
|
|
export DEBUG="*,-express"
|
2024-12-22 17:33:22 -06:00
|
|
|
export RHIZOME_REQUEST_BIND_PORT=4004
|
|
|
|
export RHIZOME_PUBLISH_BIND_PORT=4005
|
|
|
|
export RHIZOME_SEED_PEERS='127.0.0.1:4000, 127.0.0.1:4002'
|
2024-12-24 13:41:31 -06:00
|
|
|
export RHIZOME_HTTP_API_PORT=3002
|
2024-12-22 17:33:22 -06:00
|
|
|
export RHIZOME_PEER_ID=peer3
|
2024-12-24 13:41:31 -06:00
|
|
|
npm run example-app
|
2024-12-22 17:33:22 -06:00
|
|
|
```
|
2024-12-22 17:30:41 -06:00
|
|
|
|
|
|
|
In a separate terminal, you can use `curl` to interact with an instance.
|
|
|
|
|
|
|
|
`jq` is helpful for formatting the json responses.
|
|
|
|
|
2024-12-24 13:41:31 -06:00
|
|
|
Query the number of peers seen by a given node (including itself)
|
2024-12-22 17:33:22 -06:00
|
|
|
```bash
|
|
|
|
curl -s http://localhost:3000/peers/count | jq
|
2024-12-24 13:41:31 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
Query the list of peers seen by a given node (including itself)
|
|
|
|
```bash
|
2024-12-22 17:33:22 -06:00
|
|
|
curl -s http://localhost:3000/peers | jq
|
2024-12-24 13:41:31 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
Query the number of deltas ingested by this node
|
|
|
|
```bash
|
2024-12-22 17:33:22 -06:00
|
|
|
curl -s http://localhost:3000/deltas/count | jq
|
2024-12-24 13:41:31 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
Query the list of deltas ingested by this node
|
|
|
|
```bash
|
2024-12-22 17:33:22 -06:00
|
|
|
curl -s http://localhost:3000/deltas | jq
|
|
|
|
```
|
2024-12-23 17:29:38 -06:00
|
|
|
|