Conclusions
Use content-based ids.
Yet node may equivocate. Equivocations are not detectable, as no virtual chain is proposed to have.
Further, how to limit harm of equivocations was not mentioned.
Conclusions
Use content-based ids.
Yet node may equivocate. Equivocations are not detectable, as no virtual chain is proposed to have.
Further, how to limit harm of equivocations was not mentioned.
For example, in WOOT [ 33]and YATA [ 32 ], an insertion operation must referencethe IDs of the predecessor and successor elements, andthe algorithms depend on the predecessor appearingbefore the successor in the sequence. The order ofthese elements is not apparent from the IDs alone, sothe algorithm must inspect the CRDT state to checkthat the predecessor and successor references are valid
Yeah, again, have causality in DAG. Or better, don't use this kind of causality. Referring to heads and having op like "insert at position X" will be enough to restore the context - what's befere, what's after.
but Byzantine nodes maynot set this metadata correctly
Strange. If we do have causality as refering to "heads" by content-address - that's not a problem. Won't happen.
I.e., have causality at the DAG level, not in payloads.
The 3f + 1 assumption meansthese protocols cannot be deployed in open peer-to-peersystems, since they would be vulnerable to Sybil attacks [ 15].
I.e., 3f+1 is not suitable for open peer-to-peer systems.
blockchains [ 5 ]
refs to Hashgraph
If authentication of updates is desired, i.e. if it is importantto know which node generated which update, then updatescan additionally be cryptographically signed. However, thisis not necessary for achieving Strong Eventual Consistency
When updates are generatedconcurrently and then merged, the next update containsmultiple predecessors
Given many updates are merged at the same time pointers are = many. But given we merge right away having learned an update - we always merge two updates - hence two pointers.
Consequently, if updateu2 depends on update u1, it could happen that somenodes deliver u1 before u2 and hence process bothupdates correctly, but other nodes may try to deliveru2 and fail because they have not yet delivered u1. Thissituation also leads to divergence.
I.e., linking by non-content-based id is not BFT.
Say a Byzantine node generates twodifferent updates u1 and u2 that create two differentitems with the same ID. If a node has already deliveredu1 and then subsequently delivers u2, the update u2will be rejected, but a node that has not previously de-livered u1 may accept u2. Since one node accepted u2and the other rejected it, those nodes fail to converge,even if we have eventual delivery
I.e., giving nodes IDs that are not content-based is not BFT strategy.
Unfortunately, version vectors are not safe in the presenceof Byzantine nodes, as shown in Figure 1. This is because aByzantine node may generate several distinct updates withthe same sequence number, and send them to different nodes(this failure mode is known as equivocation). Subsequently,when correct nodes p and q exchange version vectors, theymay believe that they have delivered the same set of updatesbecause their version vectors are identical, even though theyhave in fact delivered different updates.
Version vectors are not BFT
This algorithm has the downside thatmany updates may be sent to nodes that have already re-ceived them from another node, wasting network bandwidth
I.e., relying on stale knowledge of what others know in order to sync them may result in many "knew that already" cases.
In some cases, a causal de-livery algorithm additionally ensures that when one updatehas a dependency on an earlier update, the earlier update isdelivered before the later update on all replicas
The network is not necessarily com-plete, i.e. it is not required for every node to be able to com-municate with every other node
they must either exer-cise centralised control over which nodes are allowed to jointhe network
Not necessarily. PoS can be used to invite, sharing with invited member the invitee's stake. Thus it does not affect consensus.
As stake determines weight on consensus.
And as stake may determine how often peers choose to sync to that node. Thus limiting harm done on the communication level by low-stake Sybils.
Virtual chain axiom
This, in turn, requires either having knowledge of thecurrent replica-set or using an external source of truth (i.e. ablockchain), a system constraint that we did not have before
Snapshot requires knowledge that everybody knows the snapshotted stuff.
Given we have derived total order, we can snapshot and garbage collect ops that been received and seen by all.
Given members are managed as ops - we know who members are at the point of total ordering.
Operations are easy to define, asthey just need to be commutative, so that the resulting state willbe the same in every replica regardless of the order in whichthey have received the operations
And non-commutative ops can be supported by adding derived total order.
wecan sign the broadcast messages, thus leaving signatures outof the Merkle-DAG
We lose trust in messages. They don't prove authenticity. So peers talk "off the record". And we can't trust anything said.
Comparing version vectors betweenpayloads is an inclusion check without the need to perform aDAG-walking
Version Vectors does not represent equivocations / forks.
E.g., it conveys "Alice's 3rd" (is X remotely). Where Alice could have created equivocation, and locally Alice's 3rd event is Y.
It is clear thatthis approach will bring some benefits
Namely, less metadata.
Perhaps it could be mitigated via metadata compaction on sync and snapshots to garbage-collect history.
Smart Merge is built on a customized adaptation of Myer's diff algorithm and Google's diff-match-patch
The Git's way. Snapshots as the source of truth, derive deltas to merge.
Please note that it is impossible to revoke a device
initial
bottom
¬∃b′ ∈ blocklace : (b′ ̸ = b ∧ b′.creator = b.creator ∧ observes(b′, b))
b
is a tip
received_orders
Begs for gossip-about-gossip.
Once a recipient has received one copy of a message, they MUST ignore subsequent copies that arrive, such that resends are idempotent
Strange. I'd thought that hash-based equility check would be enough to give idempotence on receival. "I've seen it already, noop".
When Alice and Bob are both bidding in an auction protocol, each of them marks their first bid with sender_order: 1, their second bid with sender_order: 2, and so forth.
If we were to use causal broadcast / Cordial Dissemination - they would not arrive out-of-order.
Cordial Dissemination would require gossip-about-gossip though.
sender_order
A way to construct self-parent chain in thread's context.
We suggest that the messaging standards all erred by treating public-key encryption and digital signatures as if they were fully independent operations
I'd expect that
When B receives A's signed & encrypted message, B can't know how many hands it has passed through, even if B trusts A to be careful.
Craft a new pub key and disclose it only to Alice?
But in reality, when Charlie gets Alice's message via Bob, Charlie very likely will assume that Alice sent it to him directly
Sign&Encrypt is not meant to be user-facing.
Devs should take care of not having ambiguity of the recipient if it's needed.
In this case, Alice will be blamed conclusively for Bob's exposure of their company's secrets.
Again a wrong assumption. Alice signed the "sales plan". Yet we know nothing of whether she sent it to anybody, thus she can't be blamed for it popping somewhere.
Here, Bob has misled Charlie to believe that ``Alice loves Charlie.''
Charlie here takes on wrong assumption that "I love you" is meant for him. Whereas what Alice expressed with her message is ambiguous, a simple attestation that she loves something.
forces the sender to talk “on the record”
Signature is "on the record".
centralized servers and certificate authorities perpetuate a power and UX imbalance between servers and clients that doesn’t fit with peer-oriented DIDComm Messaging
web security is provided at the transport level (TLS); it is not an independent attribute of the messages themselves
I.e., in web, parties that reside on the ends of an encrypted channel authorize each other. Whereas data that's passed between them does not have this authorization built in.
Taking a reverse approach, akin to having locks on data and not a channel, we can have authorization on data and not the channel.
The Broadcast Channel API allows basic communication between browsing contexts (that is, windows, tabs, frames, or iframes) and workers on the same origin.
Broacdast Channel API works on the same origin.
withtokens provided by their IdP.
The new device needs to receive the secret s withoutleaking it to any third party
Finally, EL PASSO supports multi-device scenarios. It en-ables users to easily register new devices (e.g., laptop, phone,tablet) and supports easy identity recovery in case of the theftof one device. It natively supports 2FA: An RP may requestand assess that users connect from two different devices inorder to sign on their services (multi-device support).
intra-RP linkability
Perhaps user's ID for that RP can be a hash of userID + RPID.
Commonly, this is accomplished through a pub-licly available list of credential statuses (either listing the revokedor valid credentials).
Claims about one's identity (authorized devices), could be maintained by the quorum of these devices. Or by a quorum of one's devices and his friends.
Trust anchors affirm the provenance of identitiesand public attributes (DIDDocs)
DID is an id + a way to resolve associated to ID info (DIDDoc). Seems strange to couple the two. I'd like to have one ID and plenty of methods to resolve info behind it. A kind of MultiDID.
Alternatively, a simple public key canserve as an identifier, eliminating the DID/DIDDoc abstraction2
This would require having private key portable. Which is not secure.
according to my entire history
Adding time todigital social contracts is an anticipated future extension
If one user marks a word as bold and another user marks the same word as non-bold, thereis no final state that preserves both users’ intentions and also ensures convergence
Having "bold" mean some semantics, e.g., important.
Then they merge. Alice does not consider it important, Bob does -> render both. E.g., Bob's "importance" expressed as bold, Alices "not important" as grayed text.
If the context has changed
E.g.,
"Ny is a great city."
Alice removes "great".
Bob wonts to replace it with "gorgeous", by removing "reat" and adding "orgeous".
Having merged:
"Ny is a orgeous city."
Begs for semantic intent preservation, such as "reword great to gorgeous".
Rather than seeing document history as a linear sequence of versions,we could see it as a multitude of projected views on top of a database of granular changes
That would be nice.
As well as preserving where ops come from.
Screams to have gossip-about-gossip. I'm surprised people do not discover it.
Another approach is to maintain all operations for a particular document version in anordered log, and to append new operations at the end when they are generated. To mergetwo document versions with logs 𝐿1 and 𝐿2 respectively, we scan over the operations in𝐿1, ignoring any operations that already exist in 𝐿2; any operations that do not exist in 𝐿2are applied to the 𝐿1 document and appended to 𝐿1 in the order they appear in 𝐿2.
This much like Chronofold's subjective logs.
Do the docs need to be shared in full? The only thing we need is delta ops.
Peritext works bycapturing a document’s edit history as a log of operations
How that works is not mentioned.
I guess ops are collected into logs, per member, based on their IDs.
A step short from having gossip-about-gossip.
but since a given client never uses the same counter value twice, the combination ofcounter and nodeId is globally unique
What stops him?
Another area for future exploration is moving and duplicating text within a document. If twopeople concurrently cut-paste the same text to different places in a document, and then furthermodify the pasted text, what is the most sensible outcome?
span can be deleted once causalstability [2] has ensured that there will be no more concurrent insertions into that span
Fig. 4
Uhh, I'd imagine "remove" would refer to "bold" annotation.
Otherwise, there can be another "bold" with t < 20, that would be accidentally removed.
Syntactic intent is not preserved.
For example, a developer mightdecide that colored text marks should be allowed to overlap, with the overlap region rendering ablend of the colors
That would be better for user to decide.
I think a good default is to express semantics explicitly.
I.e., for Bob to not automatically state his utterance as important just because it's atop of Alice's, that she considers important.
If Bob tries to reword - ok. If Bob want to add - no.
No
Given Bold, Italic, Colored are syntactic representation of semantics that we do capture - they can overlap.
Moreover, in Bob's user-defined mapping from semantics to syntax, Bob's "important" can be bold, while Alice's "important" can be italic.
Conflicts occur not only with colors; even simple bold formatting operations canproduce conflicts
Again, let them capture semantics.
Say, "Alice considers "The fox jumped"" as important. Alice changes mind, only "The" is important. Bob considers "jumped" as important.
Result: Alice considers "The" important. Bob considers "jumped" important.
Consider assigning colored highlighting to some text
Color is meant to convey some semantics. Like "accent", or "important". These semantics can coexist, just like italic and bold.
So a solution may be to: 1. Let users express semantics of their annotations 2. Give user-customizable defaults of how they are to be rendered.
Ensuring, that semantics's render is composable. I.e., it conveys originally asigned semantics.
Furthermore, as with plain text CRDTs, this model only preserves low-level syntactic intent,and manual intervention will often be necessary to preserve semantic intent based on a humanunderstanding of the text
Good remark of syntactic vs semantic intent preservation.
Semantics are in the head of a person, that conveys them as syntactic ops. I.e., semantics get specified down to ops.
Merging syntactically may not always preserve semantics. I.e., one wants to "make defs easier to read by converting them to CamelCase", another wants the same but via snake-case. Having merged them syntactically, we get Camel-Snake-Case-Hybrid, which does not preserve any semantic intent. The semantics intent here are not conflict-free in the first case, though.
Make defs readable
| |
as CamelCase as Snake Case
| |
modify to CC modify to SC
They diverged at this point, even before getting to syntactic changes.
The best solution would be to solve original problem in a different way - let defs be user-specific. But that's blue sky thinking. Although done in Unison, we do have syntactic systems around.
So staying in a syntactic land, the best we could do is to capture the original intent: "Make defs readable".
Then we need a smart agent, human or an AI, specify it further.
With this strategy, the rendered result is
The key idea is to store formatting spans alongside the plaintext character sequence,linked to a stable identifier for the first and last character of each span, and then to derive the final formattedtext from these spans in a deterministic way that ensures concurrent operations commute
I.e., let's capture user's intent as ops, not their result.
Privacy is realized by the group founder creating a specialkeypair for the group and secretly sharing the private group key with every new group member.When a member is removed from a group or leaves it, the founder has to renew the group’s keypair
Have locks on data is a nice idea.
But given we have dissemination/disclosure among friends only, do we need to encrypt the blocks? Given communication channels are encrypted.
However, by doing so the sender mayreveal additional information through the block’s hash pointers, e.g. the identities of other groupmembers
Well, when sharing such a block off-group, you may skip transmitting its deps. In Social Networking that may be alright. And when off-group agent gets accepted to group, he's able to get the stuff below.
However, that does complicate piggybacking, as it'll be seen that the previously off-group agent has some block (but actually he doesn't have its deps).
reserved words
Perhaps a sort of protobuf is better.
A group creator can invite other agents to become members and remove members atwill.
Goes against democratic principles.
A democratic way will be to raise a BAN poll.
Thegrassroots WhatsApp-like protocol WL employs a hypergraph (a graph in which an edge mayconnect any number of vertices). A hyperedge connecting agents 𝑃 ⊂ Π means that the agents in 𝑃are members in a group represented by the hyperedge
I.e., an edge of a hypergraph is a set of vertices.
This is akin to a pub/sub topic.
SMS
has an IPaddress
Multiaddr could be used instead, to aid connectivity
Inpractice, an agent is an app running on a smartphone
Agent = process
Federated systems aimto distribute control, but federated servers are still controlled autocratically
Note that Grassroots Social Networking requires dissemination, and Grassroots Cryptocurrenciesrequire also equivocation exclusion, but neither require consensus. Consensus is needed only byhigher-level applications that employ “on-chain” governance such as grassroots social contracts [7 ],the grassroots counterpart of miner-operated smart contracts, and grassroots representative assem-blies (in preparation).
Consensus is required for smartcontracts and governance.
Payments and social networking require weaker equivocation-exclusion.
and if located behind a firewall that preventssmartphones from communicating directly,
Huh, such firewalls exist? I thought they can be hole-punched.
In particular, adeep-fake payload that is not attributed to its source can be promptly filtered as spam
^
However, sinceevery block in GSN is signed, when one breaches privacy within the protocol the breach carriestheir signature so the culprit can be identified.
What stops a culprit to send off-group a message that is not his own? We can only achieve the "culprit detection" by addressing and signing every message we send to A. This is a lot of re-signing. And we won't have a convergent DAG.
A rather elaborate set of protocols and infrastructure (named STUN, TURN, TURNS, ICE)is needed to overcome these Internet limitations.
And that is not enough if one's (or is it both?) behind a symmetric NAT.
Furthermore, each block sent includes the most recent IP address of the sender,allowing agents to keep track of their friend’s changing IP addresses.
Perhaps better to attach a new IP address to a message once it does change. What's the point in telling over-and-over the same IP?
Every so often, an agent 𝑝sends to every friend 𝑞 every block 𝑝 knows and believes that 𝑞 needs, based on the last blockreceived from 𝑞.
^
Agents communicate only with their friends
More like an edge gives a communication path.
A->B (A follows B) - B can talk to A.
A<->B - B can talk to A, A can talk to B.
However, their exclusion is not required in social networking, and hence social networking protocolscan be simpler than payment systems protocols
I.e., Equivocation exclusion is not required for social networking.
Grassroots Social Networking safety implies that each member can be held accountable to theirown utterances, as well as to utterances that they forward. As Grassroots Social Networking hasno controlling entity that can be held accountable in case members of the social network breakthe law, accountability and law enforcement in Grassroots Social Networking are more similarto real life then to the social networks we are familiar with.
I.e., protocol creators are not responsible for how it's used.
In WhatsApp, members of a group must trust the serviceto correctly identify the member who authored an utterance, and utterances forwarded from onegroup to another have no credible attribution or context
^
In existing social networks, utterances by members do not carry intrinsic attribution orprovenance. Hence, Twitter members must trust the social network operator to correctly identifythe authorship of a tweet
^
As a screenshot with a tweet could easily be a fake, an author of a tweetcan later repudiate it simply by deleting it, and no proof that the tweet ever existed can be provided,except perhaps by the operator itself.
^
Naturally, an actual Grassroots Social Networking application may integratethe two protocols to provide both public feeds and private groups
Perhaps better to have a permissions mechanism that is generic to express both cases, and more, so folks can manage it flexibly as they need.
The WhatsApp-like network has private groups, members of each group being both the authors andfollowers of its feed
This couples two things: read permissions, write permissions.
Having them defined separately and explicitly, group's empowered with flexible controls.
E.g., as in OrbitDB's policies.
The Twitter-like network has public feeds
So this is a kin to pub/sub, with single authorized publisher.
friendsneed
"want" rather?
"need" would be for refs of a message you don't have. But then such a message could have been required to come with deps.
, free of third-party control
E.g., Airbnb that may refuse access to service because you're from country X, despite that host is willing to accept you.
The consensus is reached in the same way as fortransactions i.e. using hasgraph consensus algorithm. The onlydifference is, that the concerning events in the hashgraph nowcontain other type of data instead of transactions
Not necessarily, how to store received event
s is an implementation detail. One could dump them in an array on a side. Can be as efficient as array of pointers to events. Where idx of this array is event's position in total order.
DL
Composing Implementations
Any correct
implementation
can be composed with any other (compatible) correct
implementation
, and it is guaranteed to be correct
.
This implies that any correct run of the imple-mentation that stutters indefinitely has infinitely many opportunities to activatethe specification. Under the standard assumption that an opportunity that ispresented infinitely often is eventually seized, a live implementation does notdeadlock as it eventually activates the specification.
Live
I.e., there is a possible further computation from y
to y'
, as well as from sigma(y)
to sigma(y')
.
I.e., from any TS' computable mapped state y
there is a computable mapped state y'
.
Complete
Any compute in a TS can be performed in an implementing TS TS'.
I.e., any compute in TS maps to compute in TS'.
I.e., any TS compute is translatable to TS'
Safe
I.e., any compute in an implementing TS TS' can be performed in TS.
I.e., any compute in TS' maps to compute in TS.
I.e., any TS' compute is translatable to TS.
implementedtransition system (henceforth – specification),
specification
is an implementation of a TS by a TS'.
An implementation is correct if it is safe, complete and live.
Given two transition systems T S = (S, s0, T ) and T S′ = (S′, s′0, T ′) an im-plementation of T S by T S′ is a function σ : S′ → S where σ(s′0) = s0.
empty if s = s′
empty
meaning, noop
\ self
?
I guess any s
has such empty
transition for it.
Also note that T and T f are not necessarydisjoint, for the same reason that even a broken clock shows the correct houronce in a while
Huuh?
We denote by s ∗−→ s′ ∈ T the existence of a correctcomputation (empty if s = s′) from s to s′
A transition in T f \ T is faulty, and a computation is faulty if it
A transition s → s′ ∈ T is correct, and a computation of correct transitionsis correct.
a run of T S is a computation that starts froms0.
A computation of T S is a sequenceof transitions s −→ s′ −→ · · · ,
Atransition system T S = (S, s0, T, T f ) consists of a set of states S, an initialstate s0 ∈ S, a set of (correct) transitions T ⊆ S2 and a set of faulty transitionsT f ⊆ S2. If T f = ∅ then it may be omitted
the transitions over S are all pairs (s, s′) ∈ S2, also written s → s′.
Given a set S, referred to asstates,
◦
?
and σ32 :S3 → S3
S3 -> S2 ?
→
What does * mean?
TL;DR: Decoupling data dissemination from metadata ordering is the key mechanism to allow scalable and high throughput consensus systems. Moreover, using an efficient implementation of a DAG to abstract the network communication layer from the (zero communication overhead) consensus logic allows for embarrassingly simple and efficient implementations (e.g., more than one order of magnitude throughput improvement compared to Hotstuff).
I.e., collecting data of how processes talk is cheap and preserves what happens on the network. Consensus can be made locally based on that info. Damm simple, data FTW.
Every p-block with a payment in r-coins by a correct trader p ̸ = ris eventually approved or disapproved by an r-block [provided p and r are friends or have acommon friend in SG(B)]a.
Strange that you need to have a friend-path in order to use r
's coins. I'd expect r
to accept&approve a message from me, given I hold his coin (which he can see from my message).
An r-block b that repays a redemption claim with comment (redeem, P ), P =[p1, p2, . . . , pk], k ≥ 1, has a payment in pi-coins, i ∈ [k], provided the balance of r does notinclude any pj -coins for any 1 ≤ j < i at the time of creating b, and has a payment in r-coins,r /∈ P , provided the balance of r does not include any P -coins at the time of creating b
Why have signed coins?
Makes it possible to track which coins been equivocated.
But what's the use for it?
What's the difference between "you can't use these specific coins as they were equivocatedly used already" and "you can't use these opaque coins, as they are in equivocation"?
Later, at least, may succed given equivocation issuer have enough balance for both. Although then there's no point in creating equivocation in the first place. So nevermind, won't happen, except by silly equivocators.
An r-block b with an empty payment and comment (disapprove, h′) pointsto an r-coin payment block b′, where h′ points to the reason for disapproval: To b′, if it isunbalanced, or to a block b′′ equivocating with b′
Again, this can be derived out of DAG. Seems redundant.
It would somewhat spare computation, as one can check equivocation by following a pointer, but then he would need to ensure that both equivocated blocks are observed by a self-parent chain of the "DISAPPROVE" issuer.
An r-block b with an empty payment and comment approve points to balancedr-coin payments block b′, where b does not observe a block equivocating with b′
What's the point of explicit approvals if it can be derived out of DAG?
It won't spare computation, as one would still need to go through DAG and ensure payment's balanced and equivocation-free. Can't trust the issuer of "APPROVE".
Given a blocklace B and two agents p, r ∈ Π, the r-coins balance of p in B isthe sum of r-coins payments accepted by p in B minus the sum of r-coins payments issued by p in B.
Great, so r-balance of p
is derived by the history of ops regarding r
. So no need for p
to calculate it and add to every op, would be redundant. Not sure the derivation is the proposed protocol though.
Finality: A p-block consumes a non-p-block b′ with a payment to p only if r approves b′.
Would be nice to have finality optional. As to not incur round-trip to a possibly offline r
. Double-spends will be detected and punished. Given the value of double-spend spend is less than a cost - no incentive to do so.
and only if r does not have enough p1 coins then r pays any remainder inp2 coins, and only if r does not have enough p2 coins then r pays to p any remainder in r-coins
This behavior needs to be specified more strictly.
I'd assume r
would be in charge to explicitly describe how he wants redemption to happen.
not letting
More like "not being able", as it's not up to him, he can't reject redemption.
consisting of r-coins, which can be thought of as IOUs issued and signed by r
Why do coins need to be signed?
The black agent mints a black coin, increasing its balance from 3 to 4 coins
Why to capture 4
? Ops like burn(10)
, mint(1)
do the same, yet being more semantic, as they convey what happens, rather than the result.
E.g., when green has 3 green_coins, and we see send(1, green_coin, (to) black), send(3, green_coins, (to) green)
did green just miscalculated his balance (should be 2), or did he sent and minted one at the same time?
C
That looks messy, accidentally so, it seems.
Green agent only needs to REDEEM(green_coin) op to convey what he wants.
Self-payments are redundant.
Links other than self-parent and other-parent(s) are redundant. You can derive anybody's balance out of their self-parent chain.
3.1 Other-parent_s_ make the order of received messages ambiguous.
REPAY
is redundant. When REDEEM
is received, and given one can indeed redeem (recepient has his coin at the moment of receival) - the REDEEM should be automatic. I.e., plainly observing that REDEEM
been accepted by recepient is enough to derive out of it one of 1) it's a suffessfull redeem 2) it's a failed redeem.and the red agent acceptsthe payment, increasing its balance to 6 black coins.
Why does he need to explicitly accept? Can't it be done by default? Can he reject?
The black agent approves the payment
Why does he need to approve? It is a mean of equivocation detection. But it requires all coins going through its creator. Incurring latency and possible indefinete out-of-service as creator goes offline.
Why is it not optional? Like we can exchange coins with recepient directly, and he may come to redeem it later, if he wishes, detecting eqiuvocation at that point.
Some services, that offer say a cup of coffee, would be willing to take the risk of loosing $5 of value on to-be-detected equivocations. Since equivocators will be punished severily that does not worth 5$ of value. So they can be rest assured that nobody's gonna do that.
Now this example holds if coffee provider prices in currency other than its own, say bank's.
And banks are generally online. But still. Why force it? Let them do a round-trip to currency owner at their choice, a tradeoff that's up to them.
decreasing its balance to 2 black coins
Why does red agent need to issue pay
to itself?
What red agents holds after he transferred 1 black coin can be derived from history his ops.
We can't trust what he issues, he may issue to self 1000 black coins. So we'd need to go check history whether he computed it right.
But then again, if we need to do that, why issue an explicit payment to self?
Agree to redeem any domestic coin issued in return for any foreign coin held. Forexample, Alice must agree to a request by Bob to redeem an Alice-coin Bob holds against any coin heldby Alice.
The device of Alice may be offline, e.g., smartphone discharged. We can't assume constant connectivity.
eachpricing their goods and services in terms of their own personal coins. Next, assume that every two villagersexchange 100 personal coins with each other
Pricing in your own coins means personal coins may not match in value behind them. One may offer a cup of coffee for 1 coin, another for 5. Simply exchanging 100 coins with each other would mean one'll get 1/5 of value from this exchange. So 1:5 exchange would be needed. But how to know that in advance?
If all agents must obtain and maintain a complete copy of the entire data structure in order to operate it shouldbe called replicated ; it should be called distributed if different agents access, maintain and store different parts ofthe data structure. Similarly for distributed ledgers vs. replicated ledgers, with blockchains falling under the secondcategory. Note that sharded blockchains are replicated, as an agent must obtain all shards in order to operate onthe blockchain
distributed ledger vs replicated ledger
lest any tem-porary decline in personal productivity would result in theperson going broke
Couldn't he spend less? I mean if he doesn't go below his minimal sustainability expenses, he can trade what's left.
Minting: Each agent p mints (i.e. creates initial NFTs with)its own p-coins, as many as it pleases
An agent may create as many agent's coins as he pleases.
Economically, sovereign cryptocurrenciesprovide for grassroots liquidity without external capital or credit,as mutual credit lines can be established via sovereign coinexchange among members of the cryptoeconomy
Sovereign cryptocurrencies allow getting a credit from grassroots. You can convince people that you're a good enterpreneur, they'll exchange their tokens for your yet-to-be-built organization tokens. Possibly exchanging with a discound from your organization, so they can make profit later on, when it's established.
Weshow that the blue leader is ratified by any subsequent cordial leader
The second supermajority is a set of messages that super-ratifies some message. But here we don't make use of super-ratification. Next leader may observe just one message that super-ratifies.
for any p, q ∈ P and anyp-block b ∈ B there is a q-block b′ ∈ B such that b′ ≻ b
Didn't get it. I'd expect that all blocks created by by these guys would refer to their previous blocks. Here the definition seems to say that one guy needs to ref to another's guys blocks, which is not "mutual".
ratified by ablock b if it is ratified by the set of blocks [b
I.e., ratification is a transitive closure.
if [B] includes a supermajority of blocks that approve
I suspect, equivocated blocks are excluded from |B|
.
I.e., do not contribute their ratification to block b
.
For each wave, one of the miners is elected as the leader, and if the first round of thewave has a block produced by the leader, then it is the leader block.
What happens when many users are offline?
(depends how many, if there's not enough to form supermajority - no messages will be created at all)
If there's say 1/3, then I guess it'll be 1/3 of fail-to-select-a-leader attempt.
Also, members could have different stake. Then there may be say 1/5 members that hold supermajority stake, they're online, but the rest 4/5 is not. Then, I guess, there'll be 4/5 failed-to-select-a-leader attempts, on average.
When a waveends, i.e., when the last round of the wave is cordial, the leader block becomes final if it hassufficient blocks that approve it, namely, it is not equivocating and there is a supermajoritywhere each block observes a supermajority that observes the leader block
"supermajority that observes supermajority that observes the leader". How likely that there will be?
Correct minersare cordial in that they wait for round r to attain a supermajority before contributing ablock to round r + 1.
Uff, this gets vague. "Wait" as in "buffer received events"?
But then how do these events get propagated, when everyone's buffering? I thought only events that are accepted into blocklace are propagated.
What stops accepting events right away, and propagating them further? Defining rounds as Hashgraph does. Because this is basically the strive for the same end - a block gets r+1 round when it sees that supermajority sees supermajority.
The thing with this algo is that the communication/dissemination between rounds seems to be hidden / not included in the DAG. What' the point in doing so?
We have less information on our hands of what happened in the system, that may be of value.
Also, by not including communication we miss the oportunity to add more ops when sending stuff to others.
A set of blocks by more than 12 (n + f ) miners is termed asupermajority
When f = 1/3, then supermajority is 2/3.
n = 3 f = 1
(3 + 1) / 2 = 4 / 2 = 2 (out of 3)
The depth of a block in a blocklaceis the length of the maximal path emanating from it
To this end, theblocklace is divided into waves, each consisting of several rounds, the number of which isdifferent for ES and asynchrony (3 and 5 rounds per wave, respectively).
^
In case a wave ends with no finalleader block, unordered blocks will be ordered when some subsequent wave ends with a finalleader block.
A wave may end without leder block elected.
What's the probability of that? Is it included in the reported results?
The protocol might even say that afterAlice syncs to Bob, then Bob will immediately sync back to Alice
This requirement would help to find colluders.
and gossips to him all the events thatshe knows. Bob then creates a new event to record the fact of that gossip
I guess Alice would only need to send Bob events that she knows he does not know.
When Bobgossiped to Alice, he would give her all of the events which he knew and she didnot.
How that's done?
Bob could gossip to Alice all events he knows she knew, based on his hashgraph, but it's not the same as gossiping all events he knows she knows.
Bob may have a stale view of what Alice knows.
The more up-to-date view that Bob can get is when receiving an event from Alice.
Data structures withgraphs of hashes have been used for other purposes, such as in Git where the ver-tices are versions of a file tree, and the edges represent changes
That's not how git works. It does use deltas heavely under the hood, but it's derived out of snapshots, which is the primary data model.
The red eventcan also contain a payload of any transactions that Alice chooses to create at thatmoment, and perhaps a timestamp which is the time and date that Alice claims tohave created it
Payload and timestamps are optional.
Alice then repeats with a differentrandom member.
After sending an event to a random peer, on completion - pick another random one.
Figure 1
^ middle member send his third event to his left and right member. So it's not just "send to one random". How is that specified?
We believe that thelack of a business model that can incentivize ‘genuine’ peer-to-peer applications and the lackof suitable architectural foundations for such applications are the culprit
^
The block content isa pair 퐶 = (푣, 푃) of an arbitrary value 푣 (the block payload)and a set 푃 of the block identities of the predecessors of 푏
Since signature carries ID, referring by hash will not capture ID, wheres referring by ID will. Interesting approach.
the block is valid: valid(푣, ≺푏),using the definition of valid provided by the data type
^ I.e., we need to ensure validity of block's ops. This is a datatype-specific validation.
Contrary to current DAG-like structures that use hashesof content, a blocklace uses signed hashes from which theblock creator can be known. Not only this can aid dissemina-tion, by knowing which node is missing which blocks, butmore importantly, it can be used to detect equivocations andequivocators
Hashgraph gives all of that, as it has signatures. What's new here?
In-deed, the blocklace-based Cordial Dissemination protocol [7,12] employs the fact that a 푝-block 푏 by a correct node 푝 ac-knowledges all the blocks known to 푝 at the time of blockcreation
To be a colluder, 푝 must violate liveness, as it must refuseindefinitely to accept blocks by correct agents that acknowl-edge 푞 as Byzantine.
Perhaps keeping track of to whom events are being sent will allow to collect evidence, that a node violates liveness.
Furthermore, this can be kept local, and only reported when observed that liveness is violated. I.e., "You said that you received my message, but from others said to me later, it wasn't included. I'm reporting you now."
Having collected > 1/3 reports - node can be considered to violate liveness.
In this approach, however, any >1/3 nodes can conspire and exclude any other node they wish, without evidence, "trust us".
Accept the block into the blocklace, resulting in all nodeseventually knowing that 푝 is Byzantine
One pair of equivocated blocks is enough to keep for that purpose. Having learned there are two - subsequent ones can be rejected on receival. Not all nodes will know of equivocator, and will send updates to it. So these updates may not reach the community. But eventually equivocator will be consensually known and excluded.
This is a tradeoff.
Alternative is to stub eqivocated messages, so the correct messages are passed around.
node
Here node
refers to process
/ member
.
Correct nodes create a new block in 퐵 using the identitiesof the set of maximals in 퐵 as predecessors. By definition,all the elements in this set are incomparable, forming anantichain. If that is not the case, the creator is Byzantine
Didn't get it
and eventu-ally excluding any new blocks created by Byzantine agents
Somebody may do some work atop a message that's in fork. What happens to this work if the block gets excluded?
Also "exclude" may mean logical deletion, if we detect nodes that are in fork, we can skip transferring it's ops, instead placing a hash, since these ops won't be used anyways (and can be rather huge, up to a max allowed size), thus preserving causality by having a malicious block around, and saving on metadata by transferring the minimum of information for causality to be preserved. (stubbing content with a hash).
Extant approaches no not attempt to detect equivocations.Messages from Byzantine equivocators that are not rejectedas invalid are simply accepted and treated as if they wereconcurrent operations from different correct nodes.
Not true for Hashgraph. Equivocation there is known as a "fork". Forks are detected and do affect the algorithm of virtual voting (these messages are not "seen", i.e., their ops won't be included). Hashgraph does not propose to reject these messages. I guess this is due to them potentially carrying valid ops from other peers. But overall, nothing stops ignoring Byzantine members or straight out excluding them.
A blocklace 퐵 is then isomorphic to a PO-Log from thepure-op framework, thus is also a pure-op CRDT
Blocklase is a pure-op CRDT.
Causality is baked into each message, but more robustly, not as a version vector, but by hashes. Thus being more suitable for a Byzantine environment.
were max≺ (퐵) is the set of maximal blocks in 퐵 under the≺ relation, i.e., the blocks which are not pointed from anyother block in 퐵
That's interesting. Block may refer to many blocks at once.
Curios whether Hashgraph's consensus can hold with it. It'll give inacurate timestamps. I.e., accuracy of how events been received will suffer. Perhaps we can only receive immediately events that contain ops that requrire a point of order. But overall, receiving and propagating further events right away seems to be a good strategy, since it captures more accurately what happens over-the-network. And it's more constricting, meaning it'll be easier to detect byzantine behaviour. Nodes are required to accept any valid events right away. Given we want to propagate events by gossip fast, we'd need nodes to accept and propagate their newly created event right away.
I.e., the approach of multiple blocks is not gossip-about-gossip.
There's a downside of having to accept right away. That is if we strictly comply to gossip-about-gossip, then event must point to other-parent. But if there's no other-parent, how do we get our local ops packaged and sent?
Perhaps a way is to ease the requirement of other-parent ref, then nodes can add local ops with ref to self-parent alone, and propagate them, will be alright even for a single keystroke op in text editors, although the metadata cost is somewhat high.
Perhaps metadata can be reduced down to signature. So whenever one receives an event with just signature - we know that it's an event with only self-parent ref. A well-known special case.
And when you want to accrete atop other-parent, you include a hash of it.
So the metadata cost is signature and, optionally, 1 hash.
Processing cost of deriving author out of signature, and verification is to be measured.
Note that the virtual chain axiom holds for correct nodessince they create blocks in sequence and include each newblock in their blocklace
Virtual chain is a kind of global chain. Nodes converge into it. There should be a self-parent chain, where forks are detectable and considered byzantine.
But perhaps gossip-about-gossip is even better.
Thus, there are no “dangling pointers” in a blocklace: eachidentity in each set of predecessors of a block in a blocklaceidentifies a block in the blocklace.
Well, ia
is a hash. So it may be missing in B
. Need to ensure that ia
(and all it's transitive deps) are present in B
before accepting it, adding to B
.
E.g., use Reliable Causal Broadcast.
E.g., request missing nodes, holding to a node with dangling pointers before they arrive. Optionally discarding it if deps did not get fetched after a while.
Weassume that the identity (public key) of the node can be ex-tracted from its signature, e.g., using ECDSA.
^
We remark that even if two nodes 푝, 푞 ∈ Π hold identi-cal blocklaces, and each of these nodes creates a new blockwith the same payload and same set of predecessor blocks,and therefore with the same hash, block identities will bedifferent as the hash will be signed by the different privatekeys of 푝 and 푞.
So, nothing stops byzantine members to forge that they received some event from another node.
Can be catered for by wrapping events in a message, containing recepient. This captures more data of what happens on the network. Data FTW.
A block is final when subsequent blocks issuedby a supermajority of the agents approve it. See Figure 1.A
This is interesting. Finality can be derived per event / block.
If the block is urgent then issue an ack block.
Acks as first-class citizens of a DAG
Existing algorithms for payment systems, including the onesin [ 1, 6 , 11], are based on reliable broadcast (RB) [ 2] to disseminateblocks to other agents. RB is an abstraction that prevents Byzantineagents from equivocating, which in the context of a payment systemprevents Byzantine agents from doublespending
Forks may exist in RB. Having learned that every learned of a payment and it had no forks - we can accept. But solely RB seems not enough.
An op-based CRDT is pure if mes-sages contain only the operation (including arguments, if any).
Pure op-based CRDT just propagates ops, causality is preserved by default, guranteed by the messaging API.
The possi-bility of a stable operation obsoleting a new arrival, in its causal future, is notconsidered, but this can easily be changed if some example shows its usefulness
If we have a stable add(v), and we receive add(v,t), the later can be made obsolete.
Here we not only need this to happen but also that no further concur-rent messages may be delivered. Therefore, causal stability is a stronger notion,implying classic message stability
Causal stability - a given message will be in causal past of any yet to receive messages. I.e., there are no messages for any not yet to be learned that do not have a given message in their causal past.
As such, a pure op-basedCRDT implementation is trivial: as when using the standard causal broadcast,the message returned from prepare, containing the operation, will arrive exactlyonce at each replica, it is enough to make effect consist simply in applying thereceived operation to the state, over a standard sequential datatype, i.e., definingfor any datatype operation o:
Prepare phase won't be needed, if we preserve context of the op, e.g., via a hashgraph of ops. So any replica can derive the state an op's been issued on.
Commutative datatypes reflect a principle of permutation equivalence [11]stating that “If all sequential permutations of updates lead to equivalent states,then it should also hold that concurrent executions of the updates lead to equiv-alent states”
This is a stronger requirement than SIM-commutativity.
Ops are guaranteed to commute / result is the same with no regard to order of ops.
Op-based CRDTs can often have a simple and compact state since they can relyon the exactly-once delivery properties of the broadcast service, and thus donot have to explicitly handle non-idempotent operations.
What stops making an op content-addressed, so it's deduplicated on multiple receivals?
I think this would modify your trust model. Say you trusted 10 peers. If one of them was malicious, then you have 1/10 malcious peers and the majority of nodes are good so you could identify the bad node. In the changes you propose, (if I understand correctly), the 1 malicious node, could then send you 100 more malicious nodes. So then you'd be connected to 101/110 malicious peers and the malicious peers would be the majority.
A way to cater for eclipse attack can be to capture node's addresses in a hashgraph of that gossipsub topic. This way, when a new node connects to any of behaving peers, it'll get HG with addresses of others.
That will possute HG with unrelated to domain stuff however.
VectorSync [31] is an enhanced version of ChronoSync[35] which uses version vectors to make synchronisationbetween peers more efficient. Version vectors are more efficientin detection of inconsistencies, than simple message digests, asmentioned earlier. However, similarly to other proposals in thearea, VectorSync needs to realise a ‘leader-based membershipmanagement’ in order to deal with active members that updatethe state of the dataset.
Y.js uses version vectors to sync p2p. Yet it's a brittle approach. No hashgraph integrity.
Moreover, after executing an inverse opera-tion like O2, the document state can no longer be properlyrepresented by the state vector, which is only capable ofrepresenting original normal editing operations
I don't see how Undo would mess up State Vector, being just another op. State Vector bit of that user would increase.
I get a new ClientID for every session, is there a way to make it static for a peer accessing the document?
Would be nice to have truly unique ids. E.g., a public key.
Eats more space, but can be zipped over the wire. Given there are many ops transferred.
Also could be possible to create pubkey -> int mapping per-document, so it's damm more compact. That would require consensus on this map.
Furthermore, due to its design, the garbage collector inYATA may break late join mechanisms. This is becausewhen a user is offline for a period longer than t seconds,it will still hold references to deleted operations, while on-line users who already performed certain removals do not.Therefore, YATA does not support garbage collection for asite while it is offline.
So, whenever there's constantly > 1 users offline on a doc - can't garbage collect / compact.
From our practical experi-ences and the use in production, such a delay is sufficientto ensure that content will be removed safely, without anylosses that may lead to inconsistencies
User may go offline for more than 30 seconds. The approach seems brittle
Conceptually, an insertion marked for deletioncan be garbage collected when all sites received the removeoperation and have in their internal representation the op-eration that is to be garbage collected
.
We denote an insert operation as ok (idk , origink , lef tk ,rightk , isDeletedk , contentk )
That's plenty of metadata.
Why three refs? CT showed that one's enough.
Also strange that deletion mutates an op, rather than being another op. Seems it'll be hard to manage it (undo/redo).
Upon its creation, the operation thus gets as-signed a unique identifier which is composed of the useridand the current operation counter
It's unique as far as user behaves, not creating ops with the same id.
Hash of an op would be a good id. Although it does not come with a counter. So counter, if we need it, is in the op.
The downside ofthis approach is that a state vector must be transmittedwith every operation, where the size of the state vector isproportional to the number of users in a collaborative ses-sion.
.
COT has a simplified design, as only onetransformation function must be defined
.
The ideabehind COT is to save every received operation “as is” in adocument state and preprocess it afterwards given the op-eration context.
.
If you tried to join two lists together, but somebody has added a paragraph between them, your change becomes impossible to execute (you can't join nodes that aren't adjacent), so it is dropped.
Strange. I'd expect user's intent to be preserved.
Instead of a central server calling the shots, you could use a consensus algorithm like Raft to pick an arbiter. (But note that I have not actually tried this.)
That is another step of accidental complexity
Secondly, though most OT systems just represent changes as a series of insertions and deletions, mapping seems to require us to distinguish replacements from the corresponding delete/insert pair. When a replacement happens next to a given position, the position should never move across the replacement, regardless of whether you're mapping forward or backward. In order to be able to support this, CodeMirror's change representation is encoded as a series of replacements. (Insertions become replacements that don't delete anything, and deletions replacements that don't insert anything.)
Flew over my head
This can be derived from a sequence of individual changes, but it seems like it'd be more pleasant if changes were directly kept in that shape.
Chronofold seems to have what's wanted here
When a client receives conflicting remote changes, it first undoes all its local pending changes, applies the remote changes, and then the transformed form of its local changes.
Uhh, strange approach at glance. I'd expect local changes to be preserved and received changes to be transformed and applied atop.
OT algorithms that support decentralized editing rather resemble CRDT algorithms
I don't see it. The OT and CRDT have distinct approaches on how to converge.
OT embraces subjective views, adopting ops of others to it.
CRDT introduces a distributed data model, that every user builds upon.
along with data (often a logical clock) embedded in the IDs
Rather, each object contains ID + clock + author + reference to another object & what not. Hefty on metadata. CRDTs focus on optimizing that. Perhaps another approach is to ditch the distributed model and embrace subjective op logs.
That is where CRDTs come in. They are another approach to convergence that, contrary to operational transformation, does provide a way for us mortals to reason about convergence.
It makes a somewhat easy to grasp distributed model of a doc. Which makes it easy to sync. But building atop it client-side is a pain. It is complex. As Chronofold paper points out. Many projects folded, stating the CRDT model as the source of complexity that's been the cause.
And when you don't have a centralized party to determine the order in which changes get applied, you need, as far as I understand the literature, to keep data beyond the current document (“tombstones” that describe where deletions happened), to guarantee convergence.
Tombstones seem to step away from OT approach.
Where you have a separate from the current-doc representation. A DAG, from what I've seen. E.g., WOOT, CT, other CRDTs.
Periodically try to send those to the server, which will either accept them or, if another client sent a change first, reject them because your changes start in a base document that doesn't match the current central document.
That seems rather harsh on UX. Surely it can be done better.
Here 1. server acts as the source of truth. And 2. clients try to compare-and-swap kind of.
But we don't need 1., clients are the source-of-truth, server is a helper middle man (that should be optional)
And having 2. we would not comply to any of the consistency models of OT - e.g., intents are preserved, happily merging.
Consistency models
^