From c2d055bd2dea721bf545e601e64413229e98e410 Mon Sep 17 00:00:00 2001 From: Bob Webb Date: Sun, 19 Jan 2025 15:21:55 +0100 Subject: [PATCH 1/5] WIP: branches doc --- packages/core/branches.md | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 packages/core/branches.md diff --git a/packages/core/branches.md b/packages/core/branches.md new file mode 100644 index 000000000..cc907adbc --- /dev/null +++ b/packages/core/branches.md @@ -0,0 +1,54 @@ +# Branches + +In Canvas, the message log is an acyclic directed graph. Messages can have multiple "parents". This results in messages being partially ordered, i.e. some messages are children/ancestors of each other and some occur concurrently. Inside our implementation of Runtime and GossipLog we keep track of the "branch number" of each message and effect. Note that unlike the clock number, the branch number is local to each peer. The same message (i.e. same contents, same transitive set of parents) may have a different branch number on different peers. + +This document will explain how branch numbers are determined and then explain how they are used within Canvas. Attention will be given to the data model and algorithms used. + +## Relevant tables: + +- `$messages` - this table stores the id, signature, message contents (the `message` column), hash, branch and clock information about each message that the peer sees. +- `$effects` - in the case where a message is an action, it may make changes to the data in ModelDB. We call these changes "effects". This table stores the key (which consists of the model name and the key to be updated) and value that were set, as well as the branch number and clock of the message that produced the effect. +- `$branch_merges` - this table stores the points where branches split off from and/or join each other. TODO: we aren't actually using this - delete? + +## How branch numbers are calculated + +When Canvas receives a new message (either by syncing with another peer or generating a message locally, e.g. when the user performs an action or creates a session), it is assigned a "branch number". These are positive integers, starting at zero. + +The algorithm is as follows: + +1. If the message has no parents, then allocate a new branch number and return it. +2. Out of the parent messages, select parent with the lowest clock value. Call this the "first parent" (TODO: it might be useful to agree on a terminology for this). +3. If the "first parent" is the latest message on its branch (i.e. the peer has not seen any of its "children" yet), then return this parent's branch number. +4. Otherwise, allocate a new branch number. + +To allocate a new branch number, choose the current maximum branch number across all messages and add `1`. + +### Example + + From cd19922659d9b538e5a5b973fdd5c1b494f6d66c Mon Sep 17 00:00:00 2001 From: Bob Webb Date: Mon, 20 Jan 2025 01:40:22 +0100 Subject: [PATCH 2/5] amend algorithm --- packages/core/branches.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/branches.md b/packages/core/branches.md index cc907adbc..84518ce57 100644 --- a/packages/core/branches.md +++ b/packages/core/branches.md @@ -17,9 +17,8 @@ When Canvas receives a new message (either by syncing with another peer or gener The algorithm is as follows: 1. If the message has no parents, then allocate a new branch number and return it. -2. Out of the parent messages, select parent with the lowest clock value. Call this the "first parent" (TODO: it might be useful to agree on a terminology for this). -3. If the "first parent" is the latest message on its branch (i.e. the peer has not seen any of its "children" yet), then return this parent's branch number. -4. Otherwise, allocate a new branch number. +2. If the parent with the highest branch value is the latest message on its branch (i.e. the peer has not seen any of its "children" yet), then return this parent's branch number. +3. Otherwise, allocate a new branch number. To allocate a new branch number, choose the current maximum branch number across all messages and add `1`. From b17197a4e38853ac3aff4991ca41a2cf07df0582 Mon Sep 17 00:00:00 2001 From: Bob Webb Date: Mon, 20 Jan 2025 15:29:03 +0100 Subject: [PATCH 3/5] move branches.md, add svg files --- packages/core/{ => internal_docs}/branches.md | 41 ++++++++++++++----- packages/core/internal_docs/images/step_1.svg | 1 + packages/core/internal_docs/images/step_2.svg | 1 + packages/core/internal_docs/images/step_3.svg | 1 + packages/core/internal_docs/images/step_4.svg | 1 + packages/core/internal_docs/images/step_5.svg | 1 + packages/core/internal_docs/images/step_6.svg | 1 + packages/core/internal_docs/images/step_7.svg | 1 + 8 files changed, 38 insertions(+), 10 deletions(-) rename packages/core/{ => internal_docs}/branches.md (66%) create mode 100644 packages/core/internal_docs/images/step_1.svg create mode 100644 packages/core/internal_docs/images/step_2.svg create mode 100644 packages/core/internal_docs/images/step_3.svg create mode 100644 packages/core/internal_docs/images/step_4.svg create mode 100644 packages/core/internal_docs/images/step_5.svg create mode 100644 packages/core/internal_docs/images/step_6.svg create mode 100644 packages/core/internal_docs/images/step_7.svg diff --git a/packages/core/branches.md b/packages/core/internal_docs/branches.md similarity index 66% rename from packages/core/branches.md rename to packages/core/internal_docs/branches.md index 84518ce57..573760c51 100644 --- a/packages/core/branches.md +++ b/packages/core/internal_docs/branches.md @@ -24,19 +24,40 @@ To allocate a new branch number, choose the current maximum branch number across ### Example - +Branch numbers can be used to help generate graph layouts for displaying Canvas message logs. On a given peer, each pair of `(clock, branch)` has at most one message associated with it.