|
| 1 | + |
| 2 | +This document describes what bookmarks are, and how they are used in client-server protocol. |
| 3 | + |
| 4 | +A stream is a sequence of entries, where these entries belong to some specific operation, and are identified by an entry number. |
| 5 | + |
| 6 | +In the generic sense, an entry can be any piece of data relevant to an application's context. They can be either events or bookmarks. |
| 7 | + |
| 8 | +Events are defined by the application. Stream clients provide relevant information about an event that must be streamed. |
| 9 | + |
| 10 | +In the case of the Polygon zkEVM, entries are actually L2 blocks, while operations are thought of as batches. |
| 11 | + |
| 12 | +So then, when the stream source triggers the $\texttt{StartAtomicOp()}$ function and the corresponding message is sent to the stream server, that message in the Polygon zkEVM context, amounts to an instruction to "begin a batch, and prepare to receive its related entries (i.e., blocks) that are about to follow." |
| 13 | + |
| 14 | +Again, in the Polygon zkEVM context, the message sent when the $\texttt{CommitAtomicOp()}$ function is called, is tantamout to saying: "close the batch with the last entry received." |
| 15 | + |
| 16 | +Note that without these two messages, the stream server has no means of knowing where a batch starts and ends. |
| 17 | + |
| 18 | +Similarly, in the client-server protocol, there is a need for a stream client to indicate to the stream server what entry the streaming should begin with. |
| 19 | + |
| 20 | +A **bookmark** is used for this purpose by the stream client. |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +### What is a bookmark? |
| 25 | + |
| 26 | +A bookmark is an entry in a stream, and therefore has an entry number, denoted by $\texttt{entryNumber}$. |
| 27 | + |
| 28 | +A bookmark is essentially a string of bytes. It links an $\texttt{entryNumber}$ to a string of bytes in a way that is meaningful to an application. |
| 29 | + |
| 30 | +Stream clients can request stream servers to start the stream from a particular bookmark using the $\texttt{StartBookmark()}$ method. |
| 31 | + |
| 32 | +A bookmark is a type of a stream entry, used as an identifier. It points to a specific position in the stream from which the stream server must begin the streaming. |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +### StartBookmark command |
| 38 | + |
| 39 | +In addition to the $\texttt{start()}$ and $\texttt{stop()}$ commands of the client-server protocol, a command called $\texttt{StartBookmark()}$ is added. |
| 40 | + |
| 41 | +In the similar way the $\texttt{start()}$ and $\texttt{stop()}$ commands are identified by $\texttt{1}$ and $\texttt{2}$, respectively, the $\texttt{StartBookmark()}$ command is identified with the number $4$. |
| 42 | + |
| 43 | +The $\texttt{StartBookmark()}$command is as follows: |
| 44 | + |
| 45 | +$$ |
| 46 | +\begin{aligned} |
| 47 | +1.\qquad &\mathtt{u64\ command\ =\ 4} \\ |
| 48 | +2.\qquad &\mathtt{u64\ streamType} \qquad //\ \texttt{e.g. 1:}\ \mathtt{zkEVM\ Sequencer} \\ |
| 49 | +3.\qquad &\mathtt{u32\ bookmarkLength} \qquad //\ \texttt{Length of fromBookmark}\\ |
| 50 | +4.\qquad &\mathtt{u8[\ ]\ fromBookmark} |
| 51 | +\end{aligned} |
| 52 | +$$ |
| 53 | + |
| 54 | +As previously seen with other commands, $\texttt{streamType}$ refers to the network associated with the stream source. |
| 55 | + |
| 56 | +When calling the $\texttt{StartBookmark()}$ function, and the corresponding message is sent to the stream server, the stream client must provide a bookmark. That is, a string of bytes together with the length of the string, denoted by $\texttt{bookmarkLength}$. |
| 57 | + |
| 58 | +**Example**: |
| 59 | + |
| 60 | +Consider the Polygon zkEVM case, where entries are L2 blocks. As seen in the above diagram, a bookmark precedes events. |
| 61 | + |
| 62 | +In this context, the data of each block is preceded by a bookmark entry, and this bookmark entry contains among other things the block number. |
| 63 | + |
| 64 | +It is more meaningful to use the $\texttt{blockNumber}$ in the Polygon zkEVM context. |
| 65 | + |
| 66 | +That is, the $\texttt{blockNumber}$ of the block with which the streaming must begin as requested by the stream client. |
| 67 | + |
| 68 | +### Bookmarks DB |
| 69 | + |
| 70 | +Although stream entries are recorded in the **stream file**, there's a database called **Bookmarks DB**, which is specifically for storing all bookmarks. |
| 71 | + |
| 72 | +The Bookmarks DB is a key-value database that maps a bookmark (used as a key) with its entry number (used as the value). The technology behind Bookmarks DB is [LevelDB](https://github.com/google/leveldb?tab=readme-ov-file), which is an open-source, fast key-value storage library written by Google's developers. |
| 73 | + |
| 74 | +So, when a stream client requests the stream server to start streaming from a specific bookmark, it provides the bookmark as a string of bytes. |
| 75 | + |
| 76 | +The stream server performs a binary search in order to locate the bookmark in the Bookmarks DB, and fetches the corresponding $\texttt{entryNumber}$ from the Bookmarks DB. It then begins to stream entries, starting from the $\texttt{entryNumber}$ onwards. |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | +All commands made by stream clients return a response, called a $\texttt{Result}$ entry. The format of such a $\texttt{Result}$ entry is as follows: |
| 82 | + |
| 83 | +$$ |
| 84 | +\begin{aligned} |
| 85 | +1.\qquad &\texttt{u8 packetType // 0xff:Result} \\ |
| 86 | +2.\qquad &\texttt{u32 length // Total length of the entry} \\ |
| 87 | +3.\qquad &\texttt{u32 errorNum // Error code (e.g. 0:OK)} \\ |
| 88 | +4.\qquad &\texttt{u8[] errorStr} |
| 89 | +\end{aligned} |
| 90 | +$$ |
| 91 | + |
| 92 | +Whenever a stream client calls the $\texttt{start()}$ function, the stream server responds with the $\texttt{Result}$ entry first, followed by all the entries. |
| 93 | + |
| 94 | +In the client-server protocol, each message from the stream server has its identifier or packetType. |
| 95 | + |
| 96 | +As seen in the code above, the $\texttt{Result}$ entry has the identifier, $\texttt{0xff}$, at the protocol level. |
| 97 | + |
| 98 | +The $\texttt{Result}$ identifier is followed by the total length of the entry. |
| 99 | + |
| 100 | +Next is a code of an error message, $\texttt{errorStr}$. If everything goes well then a $\texttt{0}$ is sent, meaning $\texttt{OK}$. |
| 101 | + |
| 102 | +A string is also sent, which is in a more human readable text. |
| 103 | + |
| 104 | +An error is sent in the form of a code and a string, where the string is just an array of bytes, and each byte is an ASCII character. |
0 commit comments