Kaynağa Gözat

book: add event graph doc and spec

Dastan-glitch 2 yıl önce
ebeveyn
işleme
b059c31865

+ 57 - 44
doc/src/misc/event_graph/event_graph.md

@@ -1,69 +1,82 @@
 # Event Graph
 # Event Graph
 
 
-The event graph represents sequential events in an asynchronous environment.
+Event graph is a syncing mechanism between nodes working asynchronously.
 
 
 ![](event_graph.png)
 ![](event_graph.png)
+ 
+The graph here is a DAG (Directed Acyclic Graph) in which the nodes 
+(vertices) are user created and pushed events and the edges are the 
+parent-child relation between the two endpoints.
 
 
-Events can form small forks which should be quickly reconciled as new nodes are
-added to the structure and pull them in.
+The main purpose of the graph is synchronization. This allows nodes in 
+the network maintain a fully synced store of objects. How those objects 
+are interpreted is up to the application.
 
 
-Ties are broken using the timestamps inside the events.
+Each node is read-only and this is an append-only data structure. 
+However the application may wish to prune old data from the store to 
+conserve memory.
 
 
-The main purpose of the graph is *synchronization*. This allows nodes in the network
-maintain a fully synced store of objects. How those objects are interpreted is up
-to the application.
+## Synchronization
 
 
-We add a little more information about the objects which is that they are events
-with a timestamp, which allows our algorithm to be more intelligent.
+When a new node joins the network it starts with a genesis event, and 
+will:
+1. ask for all connected peers for their unreferenced events (tips).
+2. Compare received tips with local ones, identify which we are missing.
+3. Request missing tips from peers.
+4. Recursively request events backwards.
 
 
-Each node is read-only and this is an append-only data structure. However the
-application may wish to prune old data from the store to conserve memory.
+We always save the tree database so once we restart before next 
+rotation we reload the tree and continue from where we left off 
+(previous steps 1 through 4).
 
 
-## Synchronization
+We stay in sync while connected by properly handling a new recieved 
+event, we insert it into our dag and mark it as seen, this new event 
+will be a new unreferenced event to be referenced by a newer event
+if we for some reason didn't receive the event, we will be requesting 
+it when reciveing newer events as we don't accept events unless we have 
+their parents existing in our dag.
 
 
-Nodes in the event graph are active, whereas nodes not yet in the graph are orphans.
+Synchronization task should start as soon as we connect to the p2p network.
 
 
-When node A receives an event from node B, it will check whether all parents are in the
-active pool. If there are missing parents then:
+## Sorting events
 
 
-1. Check whether the missing parents exist in the orphans pool.
-    1. If they have missing parents (they should), then request their missing parent events
-       from node B.
-2. If the missing parents are not in the orphans pool:
-    1. Add this event to the orphans pool.
-    2. Request the missing parent events from node B.
+We perform a topological order of the dag, where we convert the dag 
+into a sequence starting from the erlier event (genesis) to the later.
 
 
-Once a node is successfully added to the active pool, and linked in the event graph, then
-we call `reorganize()`. This function loops through all the orphans, and tries to relink
-them with the active pool. If there are any missing parents, then they are added back to
-the orphan pool.
+Since events could have multiple parents, there is no uniqe ordering of 
+this dag, meaning events in the same layer could switch places in the 
+resulted sequence, to overcome this we introduce timestamps as metadata 
+of the events, we do `Depth First Search` (DFS) of the graph for every 
+unreferenced tip to ensure visiting every event and sort them based on 
+thier timestamp.
+
+In case of a tie in timestamps we use event id to break the tie.
 
 
 ## Creating an Event
 ## Creating an Event
 
 
 ![](p2p-network.png)
 ![](p2p-network.png)
 
 
-In this example A creates a new event. Since the event is new, it is impossible for
-any nodes in the network to possess it, so A does not need to send an `inv`.
+Typically events are propagated through the network by rebroadcasting 
+the received event to other connected peers.
 
 
-1. A creates a new event.
-2. A sends `event` to $B_1, \dots, B_n$
+In this example A creates a new event and boradcast it to its connected 
+peers (B nodes), and those in turn rebroadcast it to their connected 
+peers (C nodes), and so on, until every single node has received the 
+event.
+1. `Node A` creates a new event.
+2. `Node A` sends `event` to $B_1, \dots, B_n$
 3. For each $B_i$ in $\{B_1, \dots, B_n\}$:
 3. For each $B_i$ in $\{B_1, \dots, B_n\}$:
-    1. Create an `inv` representing the event.
-    2. Broadcast to all connected nodes `p2p.broadcast(inv)`.
-
-
-Upon receiving an `inv`:
-
-1. Check if we already have the event. If not then reply back with `getevent`.
-2. The node receives `getevent`, and sends `event` back.
-
-So in this diagram, A will send `event` to $B_1, \dots, B_6$. Each $B_i$ will respond
-back to A with `inv`. Each one of $C_1, \dots, C_3$ also receive `inv`, 
-and since they don't have the event, they will send back to $B_3$,
-a `getevent` message. $B_3$ will send them the `event`.
+    1. validate the event (is it older than genesis, time drifted, malicous or 
+    not, etc..).
+    2. Check if we already have the event. also check if we have all of 
+    its parents.
+    3. request missing parents if any and add them to the DAG.
+    4. if all the checks pass we add the actual recieved event to the DAG.
+    5. Relay the event to other peers.
 
 
 ## Genesis Event
 ## Genesis Event
 
 
-All nodes start with a single hardcoded genesis event in their graph. The application
-layer should ignore this event. This serves as the origin event for synchronization.
+All nodes start with a single hardcoded genesis event in their graph. 
+The application layer should ignore this event. This serves as the 
+origin event for synchronization.
 
 

+ 41 - 25
doc/src/misc/event_graph/network_protocol.md

@@ -2,48 +2,64 @@
 
 
 ## Common Structures
 ## Common Structures
 
 
-### EventId
+### Event
 
 
-```rust
-type EventId = [u8; 32];
-```
+Representation of an event in the Event Graph.
+This is either sent when a new event is created, or in response to `EventReq`.
 
 
-## inv
+| Description   | Data Type      	   | Comments           		    |
+|-------------- | -------------------- | ------------------------------ |
+| timestamp	  	| `u64`                | Timestamp of the event    	    |
+| content	  	| `Vec<u8>`            | Content of the event    	    |
+| parents	  	| `u64`                | Parent nodes in the event DAG  |
 
 
-Inventory vectors are used for notifying other nodes about objects they have or data which is being requested.
+Receiving an event with missing parents, the node will issue `EventReq`
+requesting the missing parent from a peer.
 
 
-| Description   | Data Type      	   | Comments           		|
-|-------------- | -------------------- | -------------------------- |
-| invs	  	  	| `Vec<EventId>`       | Inventory items    		|
+### Event ID
+
+Is [blake3::Hash](https://docs.rs/blake3/latest/blake3/struct.Hash.html) 
+of the event, we use those IDs to request and reply 
+events and tips (tips being childless events in the graph).
 
 
-Upon receiving an unknown inventory object, a node will issue `getevent`.
 
 
-## getevent
+## P2P Messages
 
 
-Requests event data from a node.
+### EventPut
+
+This message serves as a container of the event being published on 
+the network.
 
 
 | Description   | Data Type      	   | Comments           		|
 | Description   | Data Type      	   | Comments           		|
 |-------------- | -------------------- | -------------------------- |
 |-------------- | -------------------- | -------------------------- |
-| invs	  	  	| `Vec<EventId>`       | Inventory items    		|
+| EventPut	  	| `Event`              | Event data.         		|
+
+### EventReq
 
 
-## event
+Requests event data from a peer.
 
 
-Event object data. This is either sent when a new event is created, or in response to `getevent`.
+| Description   | Data Type      	   | Comments           		   |
+|-------------- | -------------------- | ----------------------------- |
+| EventReq	  	| `EventId`            | Request event using its ID.   |
+
+### EventRep
+
+Replys back the requested event's data.
 
 
 | Description   | Data Type      	   | Comments           		|
 | Description   | Data Type      	   | Comments           		|
 |-------------- | -------------------- | -------------------------- |
 |-------------- | -------------------- | -------------------------- |
-| parents	  	| `Vec<EventId>`       | Parent events      		|
-| timestamp 	| `u64`                | Event timestamp    		|
-| action    	| `T`                  | Event specific data      	|
+| EventRep	  	| `Event`              | Reply event data.     		|
 
 
-## syncevent
+### TipReq
 
 
-This message is sent at fixed intervals when connecting to the network.
-It uses this message to synchronize with the current network state.
+Requests tips from connected peers.
+We use this message as first step into syncing asking connected peers 
+for their DAG's tips.
 
 
-Once updated, a node uses the messages above to stay synchronized.
+### TipRep
 
 
-| Description   | Data Type      	   | Comments           		|
-|-------------- | -------------------- | -------------------------- |
-| invs	  	  	| `Vec<EventId>`       | Inventory items    		|
+Replys back our DAG tips' IDs.
 
 
+| Description   | Data Type      	   | Comments      |
+|-------------- | -------------------- | ------------- |
+| TipRep	  	| `Vec<EventId>`       | Event IDs.    |