Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ Clients send the following commands:
| `PublishNote` | Send a few bytes to another client addressed by topic (good for key exchange) |
| `FetchNote` | Request a note addressed by topic |
| `SendData` | Store/forward bytes to other clients, addressed by relay-authenticated public keys |
| `StoreChunk` | Store bytes for other clients to fetch addressed by key and public key. |
| `GetChunk` | Request stored chunk |
| `ChunksPresent` | Ask which chunks exist |


### Server Events

Expand All @@ -75,8 +71,6 @@ The relay server sends the following events:
| `Who` | Challenge for authenticating a client's public/private keys and spam mitigation |
| `Note` | Data payload of a note requested by `FetchNote` |
| `Data` | Data payload from another client, addressed by relay-authenticated public key |
| `Chunk` | Data payload response to `GetChunk` request |
| `ChunkStatus` | Response to `ChunksPresent` indicating which chunks exist/don't |

### Authentication

Expand All @@ -102,13 +96,12 @@ Client Relay

### Data

There are 3 ways clients can exchange data:
There are 2 ways clients can exchange data:

1. Notes - public notes that are accessed by knowing the note *topic*. Notes are a good way to do key exchange. Notes expire after a short time.
2. Messages - ordered, stored-and-forwarded messages sent from one client to another client. These are automatically sent to a client upon connection, and deleted when sent. Messages expire after a while.
3. Chunks - clients store chunks with a string *key* and choose which clients (by their public key) are allowed to fetch uploaded chunks. Chunks may be overwritten. Chunks expire a while after their last update.
2. Messages - ordered, stored-and-forwarded messages sent from one client to another client. These are automatically sent to a client upon connection, and deleted when sent. Messages expire after a while. Messages with a non-blank key will overwrite undelivered messages with the same key.

All forms of exchanging data are unreliable. Build with that in mind.
Build relay clients with the understanding that all forms of exchanging data through this relay are unreliable.

#### Notes

Expand Down Expand Up @@ -146,6 +139,33 @@ Alice Relay Bob
│ │ │
```

#### Messages with keys

1. Alice sends `SendData(dst=BOBPK, key=apple, data=core)`
2. Alice sends `SendData(dst=BOBPK, key=banana, data=boat)`
3. Alice sends `SendData(dst=BOBPK, key=apple, data=pie)` (replacing prior `key=apple` message)
4. Bob connects
5. Server sends to Bob `Data(src=ALICEPK, key=banana, data=boat)`
6. Server sends to Bob `Data(src=ALICEPK, key=apple, data=pie)`

```
Alice Relay Bob
│ │ │
├───Authenticated─┤ │
│ │ │
│ SendData(Bob,1) │ │
├────────────────►│ │
│ SendData(Bob,2) │ │
├────────────────►│ │
│ SendData(Bob,1) │ │
├────────────────►│ │
│ │ Data(Alice, 2) │
│ ├────────────────►│
│ │ Data(Alice, 1) │
│ ├────────────────►│
│ │ │
```

#### Chunks

1. Alice sends `StoreChunk(dst=[BOBPK], key=apple, val=seed)`
Expand Down
1 change: 1 addition & 0 deletions changes/new-Chunks-are-gone-20251210-102219.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Chunks are gone in favor of overwriteable Data messages
40 changes: 7 additions & 33 deletions src/bucketsrelay/v2/cli.nim
Original file line number Diff line number Diff line change
Expand Up @@ -115,48 +115,22 @@ proc doCommand(client: NetstringClient, full: seq[string], ctx: var CmdContext)
if dst.string == "":
dst = SignPublicKey.deserialize(i.use(args))
let val = i.use(args)
waitFor client.sendData(dst, val)
let key = if i < args.len:
i.use(args)
else:
""
waitFor client.sendData(@[dst], val, key)
of "recv":
let data = waitFor client.getData()
echo data
of "store":
var dst = ctx.dst
if dst.string == "" or args.len >= 3:
dst = SignPublicKey.deserialize(i.use(args))
echo "Using key=" & dst.nice
let key = i.use(args)
let val = i.use(args)
waitFor client.storeChunk(@[dst], key, val)
of "get":
var src = ctx.dst
if src.string == "" or args.len >= 2:
src = SignPublicKey.deserialize(i.use(args))
echo "Using key=" & src.serialize
let key = i.use(args)
let odata = waitFor client.getChunk(src, key)
if odata.isSome:
echo odata.get()
else:
echo "(none)"
of "has":
var src = ctx.dst
if src.string == "" or args.len >= 2:
src = SignPublicKey.deserialize(i.use(args))
echo "Using key=" & src.serialize
let key = i.use(args)
let res = waitFor client.hasChunk(src, key)
echo $res
of "help":
echo """
post TOPIC DATA
fetch TOPIC
dst PUBKEY
Set the destination PUBKEY for future commands
send [PUBKEY] DATA
Set the destination PUBKEY for future sends
send [PUBKEY] DATA [KEY]
recv
store [PUBKEY] KEY VAL
get [PUBKEY] KEY
has [PUBKEY] KEY
help
"""
else:
Expand Down
Loading