Here’s the sync/serve protocols under the assumption that we want all honest nodes to have all the syntactically-valid ballots (except when there’s a malfeasance proof that entails discarding of dishonest ballots) and all the unified content blocks (UCBs).
Note that sync’ing should be different in case we decide to invalidate this assumption (in favor of aggressive pruning), but that might be significantly less conservative.
Serve protocol:
- Purpose: newcomer node fetching all the data of layers that she never reached yet.
- The newcomer node requests “serve(start_layer=x, end_layer=y)” from her neighbor(s), and the honest neighbor sends all the syntactically-valid ballots and contextually-valid UCBs of layers x…y as data stream.
- Note that the honest neighbor will have rules regarding how to throttle these “serve” requests, specifically:
** not allowing more than N serve requests simultaneously
** not allowing repeated serve requests from the same neighbor (determined according to the neighbor’s IP address)
** using less bandwidth and lower priority for “serve” requests, relative to other communication. - The default honest newcomer may request multiple neighbors to serve her the data concurrently, for example serve(start=1, end=1000) request sent to neighbor Alice and serve(start=1001, end=2000) request sent to neighbor Bob and serve(start=2001, end=3000) request sent to neighbor Carol, etc.
Sync reconciliation protocol for the contextually-valid mesh:
- Note: The UCB of layer J has the list of rewarded ballots (i.e., the ballots of layer J that voted on layer J-1 and the earlier layers) with multiplicities.
** For example the list can be “Alice:2, Bob:1, Carol:4” meaning that Alice had 2 rewarded ballots, Bob had 1 rewarded ballot, and Carol had 4 rewarded ballots.
** The honest smesher needs to verify that she indeed has all of these rewarded ballots (in the above example the ballot of multiplicity=2 of Alice and the ballot of multiplicity=1 of Bob and the ballot of multiplicity=4 of Carol), otherwise she requests from neighbors (or else via gossip) the missing rewarded ballots, and as long as these rewarded ballots are unavailable she considers the UCB to be invalid and votes against it (voting still in favor is a less conservative approach). - We have at most one contextually valid UCB per layer.
- Every honest node maintains the cumulative hash-chain of the contextually valid UCBs.
- The two neighbors perform binary search to find the first layer J that they disagree on.
** When the disagreed-upon layer is discovered, the neighbor Alice send her UCB to neighbor Bob, then Bob computes the symmetric difference (according to his own layer) and sends back to Alice his UCB along with the rewarded ballots that Alice is missing, and then Alice sends him the rewarded ballots that he’s missing (according to the listed rewards in his UCB).
** The neighbors Alice and Bob continue consecutively with layer J+1, then layer J+2, then layer J+3, and so on, performing the same symmetric difference protocol. If the symmetric differences starting from layer J are large (in other words, the intersection is almost empty) then both of them switch to “serve” mode.
Sync reconciliation protocol for the contextually-invalid mesh:
- For non-rewarded ballots, each honest node sorts them according to local timestamps (so the ballot that was received most recently will be the last in the sorting, even if it’s a ballot of an old layer), but also maintains their hash-chain according to lexicographical ordering.
- In the first sync round the neighbor Alice will send to the neighbor Bob her latest batch (according to ber local timestamp ordering) of non-rewarded blocks (the default batch size is a protocol parameter, it can be e.g. 100). Then Bob computes the symmetric difference (with his own latest batch) and sends the result back to Alice.
- If Alice and Bob still don’t agree on the lexicographical hash-chain value (in particular if the entire batch was already known to the other neighbor) then Alice will send her previous batch, and so on (for example, the last batch contains non-rewarded ballots 1 to 100 that were receiving during the first three months after genesis, the one-before-last batch contains non-rewarded ballots 101 to 200 were received during the next two months after that, etc.)
- If after several rounds (i.e., batches) Bob never sent any non-rewarded ballots that Alice didn’t already have, then Alice will switch to “serve” mode, and in the end ask Bob to send the ballots that she is missing (the same is also true vice versa, i.e., Bob will switch to serve mode if Alice didn’t send ballots that he didn’t already have).
Sync’ing of contextually-invalid UCBs:
- The default behavior of the honest node is not to sync her contextually-invalid UCBs at all, but also not to prune each contextually-invalid UCB for as long as she has honest ballots that voted for it (if all the ballots that voted for the UCB were discarded and replaced with malfeasance proofs, then the contextually invalid UCB should be discard too).
- Note that the honest node Alice may store ballots that vote for a hash of UCB for which Alice doesn’t have the preimage.