Skip to content

Regular Event as Custom App Data for CRDT applications#667

Closed
waterblower wants to merge 5 commits intonostr-protocol:masterfrom
waterblower:master
Closed

Regular Event as Custom App Data for CRDT applications#667
waterblower wants to merge 5 commits intonostr-protocol:masterfrom
waterblower:master

Conversation

@waterblower
Copy link

@waterblower waterblower commented Jul 14, 2023

CRDT stands for Conflict-free replicated data type and it's a good way to implement a distributed system for high eventual consistency, high availability and network partition tolerance.

Having custom app data as regular events instead of replaceable events is a critical step towards CRDT over Nostr.

Blowater has been using this approach for months and it proves very reliable and fast.

@staab
Copy link
Member

staab commented Jul 14, 2023

I agree in principle, although I think it's ok for long form posts. See #349 for a similar issue.

@fiatjaf
Copy link
Member

fiatjaf commented Jul 14, 2023

This NIP is useless since it doesn't define any standard that can be followed.

@waterblower
Copy link
Author

@fiatjaf What do you mean by it's useless since it doesn't define any standard that can be followed?

The only difference between this NIP and kind 30078 is that it's not a replaceable event and everything else should stay they same. Public config will be stored in tags and private config should be encrypted in stored in content.

Do you mean that I should write the format down in the NIP?

@waterblower
Copy link
Author

@fiatjaf Just added format description

@waterblower
Copy link
Author

@staab For long posts, we need to distinguish between publishing format and editing format. It's ok to use replaceable events for publishing. But when the author is drafting locally, having regular events to save all draft history is nice.

The history doesn't have to be editing history. It just needs to be historical versions that the author has saved by clicking the save button.

Yes, #349 has the same idea as this NIP.

@nostronaut
Copy link

CRDT stands for Conflict-free replicated data type and it's a good way to implement a distributed system for high eventual consistency, high availability and network partition tolerance.

in a byzantine fault free environment, eventual consistency in a distributed system without shared mutable state comes for free. That is: if we have each user running its own thread, when the distributed threads eventually meet, they are consistent with each other because they did not mutate shared state.

Or: if each and every user has an independent, linear, consistent log of events, the aggregate of all log of events of all users is as well consistent, that is why there is free eventual consistency

byzantine faults can be seen as a user having parallel, inconsistent histories, and that means they were not single threading, they multithreaded creating the byzantine fault

the following comment also summarizes the problem of absence of consensus for contact list management: #349 (comment) pointing out the need of a back link to the previous contact list that needs to be consumed in order to create the new contact list.

in #419 we are proposing an efficient building block for easily and cheaply producing and verifying consistency over entire sequences of events

Having custom app data as regular events instead of replaceable events is a critical step towards CRDT over Nostr.

as quoted above, the current PR proposes excluding replaceable in certain conditions, because they would behave as byzantine faults, or as a fork in the history of events

if replaceable events from a given author follow a provable linear order, eventual consistency will arise. of course many of the replaced events might not be available at all, thus one cannot verify the history of events, and that is the harder problem. in other words: its easy to observe in real time that an operation is valid for a well connected, always online user, but for fully validating the history of an author at a later time will require availability of historical, possibly volatile data

@waterblower
Copy link
Author

waterblower commented Jul 17, 2023

@nostronaut
Yes I agree with all your comments and this NIP is one possible proposal for eventual consistency.

if replaceable events from a given author follow a provable linear order, eventual consistency will arise.

Do you mean that relays should implement this provable linear order? Then this needs to change how current replaceable events are defined or extend the definition of replaceable events.

Using regular events basically means "let the client to figure out the order". For example, in Blowater, I used Lamport Clock and am considering Vector Clock. Each client can choose to implement their orders for more flexibility, especially for features that's not meant to be shared across clients.

@nostronaut
Copy link

Do you mean that relays should implement this provable linear order? Then this needs to change how current replaceable events are defined or extend the definition of replaceable events.

no, we just stated the problem, not the solution

what we are stating:

  • without commiting to the order of events, its hard to achieve consistency in a distributed manner because timestamps must not be trusted
  • and if commiting to the order of events, only online users can see the update process is happening correctly in real time
  • or, the hard case, if commiting to the order of events, for the often offline clients, there is the extra requirement that something/someone needs to serve archival data in order to make proofs of inclusion of those events in the author's history, for clients that missed the events in real time but still want to validate that two messages are in the same chain of messages and one follows the other

given the constraints, you are probably right that a relay (or a client that is always online listening to relays) may be at the right spot for validating in real time the order of events with very low overhead

Using regular events basically means "let the client to figure out the order". For example, in Blowater, I used Lamport Clock and am considering Vector Clock. Each client can choose to implement their orders for more flexibility, especially for features that's not meant to be shared across clients.

oh, nice, so we're on the same page.

merkle mountain range may be the state of art, optimal data structure here, as it commits to the content of all previous events in every new event, it has a sequence number, and permits deleting many events, while still making it possible to cryptographically verify the history of events by traversing an append only tree rather than a linked list. its almost a notary.

we implemented a demo nostr client in rust here using MMR: https://github.com/nostronaut/mmr-nostr/blob/master/src/client.rs where the client validates the append operations, and any dumb relay can be used

if u want to join efforts, we are here

@waterblower waterblower closed this by deleting the head repository Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants