aboutsummaryrefslogtreecommitdiffstats
path: root/src/transport/wire.rs
Commit message (Collapse)AuthorAgeFilesLines
* sync: a delta's signatures as a blob of their owntv30 hours1-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | A sync message larger than the threshold for its peer (16 chunks, lower on a slow link or after a message to it failed whole) goes as a delta: the peer fetches its changes in chunks, from any node holding them. Its signatures, each writer's latest with changes in it, went in the envelope offering it: up to 65536 of them, 6 MiB, in one message, the size the delta exists to avoid. Nor did an Automerge message count its signatures (one per writer in a whole document pulled) towards the threshold. A delta's signatures are now a blob of their own: the offerer packs and keeps them (Blobs::keep, the latest 64), and the spec names them by BLAKE3 hash and size (DeltaSpec::signatures, None where no signature vouches for its changes). They are served as content (BlobId::Content), so their hash checks them. The receiver fetches them from the offerer alone, as another node holding the changes holds signatures of its own, before the changes, and offers them under the write lock just before judging the changes, so they wait for them as before. The envelope of a delta carries none. An Automerge message's signatures count towards its size: past the threshold, it goes as a delta. Wire version 49.
* signatures: a transfer carries one signature per writer in ittv4 days1-1/+1
| | | | | | | | | | | | | | | | | | | | | | Under a policy requiring signatures, a node takes a change only once a signature vouches for it: one of the change itself, or of a later change of the same writer. A writer is a node's run, each start, rejoin or drop making a fresh actor, so an epoch gathers writers for as long as it lasts, and a transfer of its whole history (a joiner pulling the document, a delta) must carry a signature for each of them, or the joiner waits for the rest for good. A message's signatures are now chosen by what it carries: * changes, up to 256 signed among them: each one's signature; * more (a whole document pulled): each writer's latest signed change among them, found by the document's change metadata (`Signatures::for_changes`), vouching for the rest; * a delta: each writer with changes in it (`get_changes_meta(from)`), its latest verified signature (`for_delta`). A message carries up to 65536 (6 MiB), and as many wait at the receiver for their changes (a delta's come after it). So a transfer leaves writers unvouched only in an epoch with more than 65536 runs writing since it began; a remake starts the count again. Wire version 48.
* signatures: up to 4096 in a message, each actor's latest past themtv4 days1-1/+1
| | | | | | | | | | | | | | | | Review 4, F5: a delta, and a message whose changes held more than 256 signatures (a whole document pulled, of any real history), carried each actor's latest signature, the 256 that became latest last. An actor is a node's run, so past 256 runs writing in an epoch, some actors' changes arrived unvouched at the puller under a policy requiring signatures, waited, and every resend carried the same 256: a joiner never finished. A message now carries up to 4096 signatures (`MAX_PER_MESSAGE`, as many as wait for their changes, `MAX_PENDING`: 384 KiB at most), all of its changes' up to there, each actor's latest past it and for a delta, and a receiver takes as many (wire version 47). An epoch with more than 4096 runs writing would still leave some unvouched in such a transfer, which the constant says; sending each actor of the transfer its own latest would need the actors of a delta's changes, which only rebuilding their metadata gives.
* swarm: no SIGNATUREStv4 days1-11/+2
| | | | | | | | | | | | | | Signatures sent on their own (SIGNATURES, every second, to each peer not sent them yet) flooded every link: a signature made after its change left, or one that came with changes, went to every neighbour, whether or not it got the change along with its signature elsewhere. With every change of a node signed as it leaves (1217) and signatures going where their changes go (1218), none is left for them to carry: the message, its task and its traffic counter go (wire version 46). Signatures waiting for their changes are offered as before when sync messages bring them, and the changes waiting for signatures judged again with the next batch.
* roots: an epoch's root pinned, and named in every handshaketv4 days1-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Review 2, N7, the care it raised: a joining node's empty document took as the first epoch's root whatever dependency-less change came first, from whichever peer it joined through; the first epoch's ID is all zeros, so nothing pinned it. A remake's epoch has its ID, the snapshot change's hash, which the rules hold its root to. * Every node names its epoch's root in HELLO and HELLO_REPLY (the epoch's ID for a remake's, its genesis change for the first; wire version 45). A node whose document starts from another root of the same epoch refuses the handshake, logging it: another history under the swarm's ID, a forged root or a genesis started again. * A joining node with an empty document takes as its root only the one it was given (--genesis-root, new), else the one its peers name, and none while they name different ones (access::screen::RootPin, kept in Screening across documents): one peer hands it another root only if it is all the joiner hears, or never, with --genesis-root. A root refused is listed with the refused, what builds on it with it. * The genesis node logs the root (`The swarm's root`); GET /admin/epochs shows it (`root`). A genesis started again under a remembered swarm ID used to merge with the nodes of it still running; they now refuse it (another root), and the docs say to join them with seeds instead. The epoch's identity stays as it is (generation 0 all zeros): records and epoch metadata name it so, and every comparison of epochs with them.
* envelope: a signed value names its swarmtv5 days1-1/+1
| | | | | | | | | | | | Review 3.1, part of finding 12: a signed value's payload bound path, user, time and prev, but not the swarm. A user with the same name and key in two swarms could have an envelope replayed from one into the other, wherever the path holds no envelope yet (prev ""). The payload now names the swarm (`swarm`), and a node takes an envelope only for its own. /auth/whoami says the swarm, and continuum-signed and the example in api.md sign it. Wire version 44: nodes before this refuse such envelopes, and those after refuse the old ones.
* rules: a carried remake record taken from the coordinator its snapshot namestv5 days1-1/+1
| | | | | | | | | | | | | | | | | Review finding 7, second part: a record carried into a new epoch whole (proposal and decision in one change) was taken from any member, for any remake ID. A member could write a forged record, decision included, for a fresh ID in a single change. The snapshot's epoch metadata now names the remake's coordinator, as the quorum built it. The carried-record exception holds only in a later epoch, only for the remake that made it, and only from the coordinator its snapshot names, where there is no record yet. Wire version 43: the snapshot, and so the epoch ID, changes. The review suggested carrying the record inside the snapshot instead. The snapshot can't hold the decision, which names the snapshot's own hash. So the snapshot vouches for who may carry the record instead.
* swarm: changes taken unjudged, dropped (REFUSALS)tv5 days1-2/+11
| | | | | | | | | A node refusing changes a peer brought tells it which broke a rule; the peer judges them itself, and if its rules refuse them too, drops them with all built on them (its document forked without them, a fresh actor), quarantining its own writes among them. Wire version 42. Auth plan M6 (rejoin on taint).
* signatures: on their own (SIGNATURES)tv5 days1-2/+11
| | | | | | | Signatures no sync message took go on their own within a second, to each peer not sent them yet (wire version bumped). Auth plan M5.
* signatures: with sync messagestv5 days1-1/+2
| | | | | | | Sync messages carry, for each actor's writes, the latest signature the sender checked; the receiver checks it once it holds the change. Auth plan M5.
* dashboard: without LINKS; LINKS removedtv5 days1-47/+2
| | | | | | | | | The dashboard reads every member's links from the members themselves; LINKS and LINKS_REPLY, swarm::links and their wire tags go (wire version bumped). Nodes the browser can't reach are drawn from what the reachable ones measure. Auth plan M3.
* HyParView (slim)tv7 days1-2/+30
|
* plumtreetv7 days1-2/+21
|
* indirect probestv7 days1-2/+23
|
* other wire versions warnedtv7 days1-0/+46
|
* round trips in treestv8 days1-2/+6
|
* pushed heads as tipstv8 days1-1/+1
|
* push changes experimenttv8 days1-1/+1
|
* deflate blob chunkstv8 days1-1/+1
|
* deflate blob chunkstv8 days1-1/+1
|
* epoch tag in synctv8 days1-2/+15
|
* no swarm ID in synctv8 days1-2/+1
|
* dashboard: swarm-wide epoch shinetv8 days1-1/+2
|
* time blob messagestv8 days1-1/+3
|
* hop delaystv8 days1-1/+2
|
* any message taken as deliveredtv8 days1-1/+2
|
* tree messages need no answertv9 days1-1/+1
|
* replace eager links by treestv10 days1-8/+2
|
* add writer treestv10 days1-1/+2
|
* measure 2-hop neighbourhoodtv10 days1-2/+6
|
* dashboard: show eager links on the maptv10 days1-1/+3
|
* introduce eager linkstv10 days1-2/+6
|
* announcements answered only if heads differtv10 days1-2/+6
|
* swarm: relay links messagestv10 days1-1/+9
|
* fixup: golden byte follows wire versiontv12 days1-6/+17
|
* links report downtv12 days1-1/+2
|
* rename AutoMerge to Documenttv13 days1-5/+5
|
* links replies carry clock offsetstv13 days1-7/+11
|
* pong carries timetv13 days1-17/+22
|
* unify hex builderstv13 days1-1/+1
|
* unify wire encodertv13 days1-1/+16
|
* allow links subscriptionstv13 days1-7/+8
|
* farewell means dormanttv13 days1-7/+11
|
* links answers connection typetv14 days1-7/+8
|
* dashboard: show all links between peerstv14 days1-7/+11
|
* add links messagestv14 days1-8/+33
| | | | | | | | | Introduce two new wire messages, LINKS and LINKS_REPLY (swarm::links). A member answers with its links: for each peer, the transport, whether it’s relayed, the RTT, and whether it’s dormant. It answers members only, at most every 5 s. This bumps wire::VERSION to 7. Every build answers, with or without the feature, so every node needs this patch before the map shows anything beyond its own node.
* decouple simulation test from myceliumtv14 days1-0/+87
|
* measure pathstv2026-10-281-5/+24
|
* rename PING/PONG to STATUS/STATUS_REPLYtv2026-10-281-18/+19
|
* add identity layertv2026-10-271-6/+48
|