-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Waku Sync 2.0
Waku Sync 1.0 wraps the Negentropy (RBSR based) protocol. I believe that designing a new RBSR protocol specifically for Waku would increase it's usefulness and efficiency.
I will describe version 2.0 below. Keep in mind that I will not explain range based set reconciliation in this post.
Why range based set reconciliation?
The flexibility of RBSR in terms of storage technology, stateless syncing sessions and overall simplicity makes RBSR a good fit for Waku. The ability to generate membership proofs could also be added as a separate system if needed.
Prolly trees have the capability of membership proofs (they are merkle trees after all) but would require the implementation of a garbage collector and the tree state cannot be changed while a sync is ongoing. The rigid structure that give Prolly trees their usefulness is also a detriment. Physical storage cannot be adapted to data structure but the opposite is true.
Overview
The ultimate goal is that syncing pair of nodes have the same set of messages. To achieve this we will use 2 protocols concurrently. One of those protocols will be used to transfer messages the other to inform the first as to which messages to transfer.
Reconciliation
This protocol is responsible for set reconciliation and is inspired by Negentropy but with modification because knowing the nature of the data stored (Waku messages) allow us to make informed decisions about fingerprinting function to use, attack vectors and storage data structure. We will also use specific sync ranges to optimize for Waku use cases (light push, filter, relay).
Transfer
This is the simplest of the 2 systems, it's main purpose is to send messages to the other node in the sync pair. It's only input will be message hashes and will rely on storage for message retrieval. To lower latency, no buffer or batching will be done so that messages are integrated into the set of the recipient node as fast as possible. This way if the recipient node is also syncing with other nodes at the same time this new message may also be synced and transferred.
Reconciliation Protocol
Operates on sets of elements that can be totally ordered. In our case timestamp and hash is used as the total order.
Range Choice
Ranges can be chosen based on the specific use case to reduce the number of round-trips in best case scenario. For example, if the context of the sync require fast propagation (Relay), smaller ranges in recent history would be best (RLN epoch). Inversely, for syncing archives choosing large ranges in the oldest part of the set would be preferable.
Various nodes can use any strategy the protocol stays the same.
Fingerprinting Function
The fingerprinting of a range would be the XOR operation applied to every hash in that range. Waku messages are hashed and then RLN verified when received. Reusing this hash and the timestamp included makes the most sense.
Attack Vectors
The sync process can be perturbed by carefully crafting Waku messages that combined with others would lead to range fingerprints identical to another so as to prevent syncing of that range by other nodes. While in theory possible it would be impractical. The first problem is that messages are encrypted, it is not possible to associate users to messages. Second, the very specific case where the sync process skips a range due to an attack has low impact. When syncing at a later moment, ranges would differs and the targeted message would still be synced. Sending messages also has a cost via RLN which act as a deterrent. Finally if an attacker has control of enough nodes they could use far more effective attacks than temporarily disturbing the sync process.
Bidirectionality
Negentropy assumes a client-server model, we don't, only the client know all the differences in their case. We want both nodes to know the differences for each ranges. When receiving a item set we will answer with our own item set and indicate that the sync for that range is done.
Storage
The goal of any storage implementation is to make the range fingerprinting as efficient as possible for that specific use case.
Queues
Light clients should sync very small range as to keep computation and state stored reasonably low. In-memory queues should be enough to hold the state and fingerprints can be computed by simple iteration.
Trees
Tree structures will be needed when linearly iterating to compute fingerprints becomes too inefficient. Instead of O(n) complexity they can compute fingerprints in O(log n) of the data set size. For queries that include content topics K-D trees could also be used. The problem is that inserting and removing elements of the tree also has a cost. We know that insertion will be frequent and deletions can also be in cases where the whole set is not keep but only the latest subset. Balancing these properties present an interesting engineering challenge.
Transfer Protocol
Messages will be sent on a best effort basis without retry, responses or error handling. The assumption is that any message that fail to reach it's destination will be synchronized and sent later. On the receiving end, every messages will be hashed and RLN proofs verified then added to the local storage. Nodes will only accept incoming connections from nodes they are synchronizing with.
Waku message proto buffers will be reused as wire-format.
Connection & Scoring
Who to sync with may not be part of the protocol but is an important detail nonetheless. In theory, choosing random peers may be best but in practice we may want to keep track of latency, online status and amount of messages synced so that the local node can curate a high quality list of peers. Another strategy we could implement is optimistic tit-for-tats (a la BitTorrent), since we can easily count how many missed messages we sent and received and from whom.