<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Avichal's Substack]]></title><description><![CDATA[Notes on trust and verifiability on the internet, decentralized protocols, open-weight LLMs and local-first software.]]></description><link>https://www.avichalp.me</link><image><url>https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png</url><title>Avichal&apos;s Substack</title><link>https://www.avichalp.me</link></image><generator>Substack</generator><lastBuildDate>Fri, 25 Sep 2026 22:35:26 GMT</lastBuildDate><atom:link href="https://www.avichalp.me/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Avichal]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[avichalp@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[avichalp@substack.com]]></itunes:email><itunes:name><![CDATA[Avichal]]></itunes:name></itunes:owner><itunes:author><![CDATA[Avichal]]></itunes:author><googleplay:owner><![CDATA[avichalp@substack.com]]></googleplay:owner><googleplay:email><![CDATA[avichalp@substack.com]]></googleplay:email><googleplay:author><![CDATA[Avichal]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[On AI Memory]]></title><description><![CDATA[Thoughts on AI assistants with memory]]></description><link>https://www.avichalp.me/p/2025-04-26-on-ai-memory</link><guid isPermaLink="false">https://www.avichalp.me/p/2025-04-26-on-ai-memory</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sat, 26 Apr 2025 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>ChatGPT&#8217;s persistent memory feature feels both exciting and terrifying simultaneously. Its descriptions of me were eerily accurate. I won&#8217;t publicly share much of this information (for example, my salary, how much I have been sleeping lately, my current location, etc.). Yet, without fully realizing the implications, I casually shared it with an AI assistant, unaware it would remember indefinitely.</p><p>Keep the privacy issues aside for this post. If you don&#8217;t think of ChatGPT as a web app with an LLM but as an actual assistant, it makes sense that it would remember all this. A personal assistant who remembers details about your life is way more valuable than an assistant with amnesia.</p><p>Many people think that an AI assistant with a memory will lock you in, like streaming services do by offering a personalized experience. It isn&#8217;t easy to move away from Spotify if you have years of listening history. No other music streaming service could instantly provide you with the same level of music discovery and recommendations. A year ago, I unsubscribed from Spotify, hoping that I could simply use YouTube to listen to music. Every piece of audio content on Spotify must also be on YouTube. The truth is that I still miss Spotify and might resubscribe at some point.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MRz0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MRz0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MRz0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MRz0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MRz0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MRz0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg" width="762" height="275" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:275,&quot;width&quot;:762,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Alok on how defensible is AI memory&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Alok on how defensible is AI memory" title="Alok on how defensible is AI memory" srcset="https://substackcdn.com/image/fetch/$s_!MRz0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MRz0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MRz0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MRz0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ae6d62c-55f3-4ca6-9def-be585c63d47e_762x275.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Alok&#8217;s question on how on defensible is AI memory</em></p><p>However, I don&#8217;t think this is true for AI assistants. The previous generation of machine learning systems were task-specific, such as recommending movies, music, etc. Today&#8217;s transformer based models can learn anything just from a stream of tokens. Imagine exporting your chat history from ChatGPT to Claude. Now Calude will have the same memories. The lock-in effect is not comparable to what we had in the Web2 services.</p><p>It opens up a whole new design space for stateless agents. Imagine an AI assistant that you can spin up on demand, feeding it only the memories you explicitly store and manage yourself. Think of it like entries in a personal journal. Each time you interact, the assistant reads from your journal, provides insights or summaries, and then writes the outcome back into your journal. After your interaction, you shut the assistant down completely. Users can truly own their interactions when AI models can seamlessly import, export, and interpret standardized data formats. This approach lets you retain complete control over your data, prevents you from getting locked into a particular AI assistant provider, and, crucially, it doesn&#8217;t have to compromise the UX.</p><p>Imagine a future with a feed of AI agents, each providing access to specialized tools and the latest AI models. To interact, you&#8217;d simply prepare your prompt, provide your personal memory journal, and enjoy a seamless experience. This portability doesn&#8217;t dilute the AI&#8217;s effectiveness.</p><p>Moreover, specialized, task-focused AI agents could leverage your journal entries for highly contextual interactions. Need a financial planning session? Spin up an agent explicitly trained for the financial domain, temporarily granting it access to relevant sections of your journal. Let the agent update your accounting books. Finished? Shut it down.</p>]]></content:encoded></item><item><title><![CDATA[Journey from Tableland to Recall]]></title><description><![CDATA[Story of pivoting Tableland towards Recall]]></description><link>https://www.avichalp.me/p/2025-04-06-tableland-to-recall</link><guid isPermaLink="false">https://www.avichalp.me/p/2025-04-06-tableland-to-recall</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sun, 06 Apr 2025 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!YKBW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>2022 was a crazy year for crypto. Earlier that year, there was boundless euphoria. People were willing to pay half a million dollars for an ugly picture of a monkey. Towards the end, the euphoria cooled down as the bubble popped. A chain of events that started with the explosion of Terra/Luna and ended with the collapse of FTX.</p><p>2022 was also the year when I took a <a href="https://avichalp.me/posts/2023-02-26-sabbatical-2022/">sabbatical</a>. I was wondering what to work on next. Sometime around June, I got in touch with the Textile team to work on their IPFS tooling as a part-time contractor. Later that year, I decided to join the team full-time to work on <a href="https://tableland.xyz/">Tableland</a>. Before the bubble popped, NFT projects were thriving, and Tableland was starting to get some usage.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FMv3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FMv3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FMv3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FMv3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FMv3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FMv3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg" width="300" height="291" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:291,&quot;width&quot;:300,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;it is fine!&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="it is fine!" title="it is fine!" srcset="https://substackcdn.com/image/fetch/$s_!FMv3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FMv3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FMv3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FMv3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2b9fed-10ec-418d-9dcf-1ef76ea81308_300x291.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>this is fine</em></p><p>Let me briefly describe Tableland at this point. In a nutshell, it is an off-chain database that is driven through onchain events. Every table is represented as an NFT onchain. Any wallet with adequate permissions can write to the table. All tables are public for anyone to read. You could simply spin up a Tableland node, and your database will be synced in a few minutes.</p><p>The Tableland node builds on top of SQLite and listens to EVM events. Every insert or update SQL query is sent to a specific contract. The underlying EVM blockchain determines the order of events. So, there is no need for a consensus protocol at the Tableland layer. The node simply extracts the queries from the event stream and materializes them into its local database.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YKBW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YKBW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 424w, https://substackcdn.com/image/fetch/$s_!YKBW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 848w, https://substackcdn.com/image/fetch/$s_!YKBW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 1272w, https://substackcdn.com/image/fetch/$s_!YKBW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YKBW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png" width="513" height="643" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:643,&quot;width&quot;:513,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;tableland architecture!&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="tableland architecture!" title="tableland architecture!" srcset="https://substackcdn.com/image/fetch/$s_!YKBW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 424w, https://substackcdn.com/image/fetch/$s_!YKBW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 848w, https://substackcdn.com/image/fetch/$s_!YKBW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 1272w, https://substackcdn.com/image/fetch/$s_!YKBW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff819dc26-eb28-41a0-bd4f-d5a3e9dab50e_513x643.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Tableland Architecture</em></p><p>The NFT projects liked Tableland because it enabled them to store and update the NFT metadata in a structured way. Tableland also has sophisticated ACL features. For instance, you could restrict a user to write on a table based on which NFTs they hold or if they are part of a DAO or whatnot. However, no one actually used these features to their full potential.</p><p>After the bubble popped in late 2022, most teams working on such NFT projects vanished and never returned, even after the market conditions improved in late 2023 and early 2024.</p><p>During this time, some DePin projects expressed interest in using Tableland. However, their requirements were different. They wanted an open database with a high write throughput but didn&#8217;t care about table schemas or structured data.</p><p>Tableland&#8217;s write throughput is fundamentally bound by the block time of the underlying blockchain. This inspired us to work on an open object storage system. This time, we built using Tendermint with a bespoke validator set. It is a sidechain that checkpoints to Filecoin. Essentially, you can think of it as Filecoin layer 2.</p><p>We initially called it <a href="https://github.com/textileio/basin">Basin</a> but later renamed it <a href="https://recall.network/">Recall</a>. In the last few months, as we have seen AI agents take off, we are exploring the possibility of using Recall to store agents&#8217; context windows. This would make the context window shareable in a permissionless way, making AI agents composable.</p><p>I will write more about it in the future as the protocol evolves. Meanwhile, you can take a look at the <a href="https://docs.recall.network/">docs</a> and feel free to reach out to me on <a href="https://twitter.com/_avichalp_">X</a> or <a href="https://warpcast.com/avichalp">Farcaster</a>.</p>]]></content:encoded></item><item><title><![CDATA[Tableland Notes - 2023]]></title><description><![CDATA[Notes from working on Tableland for last one year]]></description><link>https://www.avichalp.me/p/2024-02-05-tableland-notes-2023</link><guid isPermaLink="false">https://www.avichalp.me/p/2024-02-05-tableland-notes-2023</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Mon, 05 Feb 2024 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This post contains links to several articles I wrote in 2023 for Tableland <a href="https://tableland.substack.com/">Weeknotes</a>, a weekly newsletter by the Tableland team focusing on the intersection of databases and blockchains. These six articles focus on the replication of Postgres databases, with an emphasis on ensuring that the replicated data is cryptographically verifiable.</p><h3>I</h3><p>The <a href="https://tableland.substack.com/p/weeknotes-september-22-2023#%C2%A7relying-on-the-postgres-streaming-protocol-to-capture-database-changes-and-efficient-data-streams-transfer-with-capn-proto">first</a> post describes how to extract Write Ahead Logs from a Postgres instance, sign them with an Ethereum wallet, and send them to a remote server for replication onto another Postgres instance. The remote server verifies the signature to ensure that the database change is authorized and materializes the WAL message into a row within a table.</p><h3>II</h3><p>The <a href="https://tableland.substack.com/p/weeknotes-october-16-2023#%C2%A7postgres-exports-using-duckdb">second</a> post accomplishes the same goals as the first but uses a different approach. Instead of using Postgres&#8217; logical replication <a href="https://www.postgresql.org/docs/current/protocol-replication.html">protocol</a>, we use DuckDB with the <a href="https://duckdb.org/docs/archive/0.7.1/extensions/postgres.html">postgres_scanner</a> extension. In this approach, we perform a table scan instead of streaming Write Ahead Logs and produce a materialized parquet file as the output. This file is the point-in-time copy of the original database. While DuckDB does all the heavy lifting, this approach has its limits. Scanning the table too often is resource-intensive, especially if the table is large.</p><h3>III</h3><p>In the <a href="https://tableland.substack.com/p/weeknotes-december-4-2023#%C2%A7replicating-postgres-into-duckdb">third</a> post, we modify the approach described in the first. We materialize the WAL locally instead of sending the signed updates to a remote server. We use a DuckDB instance to replicate the source Postgres database locally. At regular intervals, we export the state of the local DuckDB as parquet files, sign it, and send it to the remote storage of persistence.</p><h3>IV</h3><p>The <a href="https://tableland.substack.com/p/weeknotes-october-30-2023#%C2%A7postgres-logical-replication-in-rust">fourth</a> post describes the same thing as the third, but I implemented the prototype in Rust this time. I found that the libraries implementing Postgres&#8217;s replication protocol are less mature than in Go. Rust libraries are more low-level and lack documentation. At the time of the writing, the <code>rust-postgres</code> project has a few open Pull Requests to enable working with logical replication, but these PRs have been open for a long time. However, Materialize&#8217;s <a href="https://github.com/MaterializeInc/rust-postgres">fork</a> is stable and offers these features.</p><h3>V</h3><p>The <a href="https://tableland.substack.com/p/weeknotes-november-13-2023#%C2%A7multiset-hash-in-go-using-ristretto">fifth</a> and sixth posts are about <a href="https://tableland.substack.com/i/137299329/homomorphic-hashing-for-secure-incremental-updates-is-cool-but-not-quite-ready-yet">ECMH</a> and its applications. ECMH stands for Elliptic Curve MultiSet hashes. It is a cryptographic hashing scheme with set semantics. The output of the usual hash function is a digest that looks like a string of random characters. The same applies to ECMH hashes, but they have an additional structure. ECMH hash digests represent a set. You can perform set operations on these, such as inserting or deleting elements. I describe implementing an ECMH-based hashing scheme in Go using the <a href="https://github.com/bwesterb/go-ristretto">go-ristretto</a> library in the last two posts.</p><h3>VI</h3><p>The <a href="https://tableland.substack.com/p/december-18-2023#%C2%A7fingerprinting-database-backups-with-homomorphic-hashes">sixth</a> and the last post describes an application for ECMH. I used set-based hashes to fingerprint a directory in the file system. The fingerprint provides data integrity. By keeping track of the 32-byte fingerprint, we can tell if any of its files are tampered with.</p>]]></content:encoded></item><item><title><![CDATA[Ed25519 Cryptography - Part 1]]></title><description><![CDATA[Elliptic Curve Cryptography with curve 25519]]></description><link>https://www.avichalp.me/p/2023-12-25-ed25519-pt1</link><guid isPermaLink="false">https://www.avichalp.me/p/2023-12-25-ed25519-pt1</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Mon, 25 Dec 2023 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Xf48!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This post is an exercise in digesting <em><a href="https://martin.kleppmann.com/papers/curve25519.pdf">A Tutorial on Elliptic Curve Cryptography</a></em> by <a href="https://martin.kleppmann.com/">Martin Kleppmann</a>.</p><p>In the first part, we will unpack the Finite Field arithmetic. We will implement basic operations such as addition, subtraction, multiplication, and modular inverse. In the next part, we will implement elliptic curve operations for the signature scheme. The original paper used C. I have instead used Rust. However, the following code snippets only use rudimentary language features in order to focus on lower level operations. Needless to say, this code is only for illustration purposes and should not be used in production.</p><p>Before we begin, we should take note of two different data types used here. A Field element is represented as a byte array of 32 bytes in the packed form. In the unpacked form, it will be represented as an array containing 16 elements, each 16-bit wide. The size of a Field element is 256 bits in both representations.</p><p><em>Note: we will use an i64 type for each element in the unpacked array. The remaining bits will be left empty initially. This extra space ensures that we are not risking overflows when performing additions and multiplications</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Xf48!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Xf48!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 424w, https://substackcdn.com/image/fetch/$s_!Xf48!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 848w, https://substackcdn.com/image/fetch/$s_!Xf48!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 1272w, https://substackcdn.com/image/fetch/$s_!Xf48!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Xf48!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png" width="1446" height="488" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:488,&quot;width&quot;:1446,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;field struct&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="field struct" title="field struct" srcset="https://substackcdn.com/image/fetch/$s_!Xf48!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 424w, https://substackcdn.com/image/fetch/$s_!Xf48!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 848w, https://substackcdn.com/image/fetch/$s_!Xf48!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 1272w, https://substackcdn.com/image/fetch/$s_!Xf48!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ba00480-cf02-40dd-b709-8b2ec2e3d4f3_1446x488.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>The field struct</em></p><p>We will perform arithmetic operations such as addition, multiplication, and inverse in the unpacked form and finally output our result in the packed form to save space.</p><p>The most important thing to remember is that any algorithm we implement must be constant time (i.e., O(1)) relative to the input size. Constant time algorithms are more performant and less vulnerable to attacks. If the execution time of cryptographic operations depends on its inputs, then it can be analyzed and reverse-engineered. A cipher system using such algorithms can be broken, leading to dire consequences.<sup>[1]</sup></p><h2>Addition and Subtraction</h2><p>Addition and Subtraction implementations are straightforward. We iterate over our Field array and perform an addition or subtraction operation at every index.</p><p>At this point, we will ignore the possibility of a &#8220;carry&#8221; or a negative result (where the most significant bit is 1). Remember, we are using an <code>i64</code> array to represent one Field element. We can count on the unused bits to handle these scenarios. Later, when we convert the result to the packed format, we will deal with the carry and negative results.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fWZI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fWZI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 424w, https://substackcdn.com/image/fetch/$s_!fWZI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 848w, https://substackcdn.com/image/fetch/$s_!fWZI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 1272w, https://substackcdn.com/image/fetch/$s_!fWZI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fWZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png" width="985" height="565" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:565,&quot;width&quot;:985,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;add and sub&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="add and sub" title="add and sub" srcset="https://substackcdn.com/image/fetch/$s_!fWZI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 424w, https://substackcdn.com/image/fetch/$s_!fWZI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 848w, https://substackcdn.com/image/fetch/$s_!fWZI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 1272w, https://substackcdn.com/image/fetch/$s_!fWZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F014c5d52-82d9-413b-852e-4a237ca573d4_985x565.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>add and sub methods for finite field elements</em></p><h2>Carry</h2><p>Before we get to multiplication, we should consider handling the carry bits. In the unpacked format, each array element is an <code>i64</code> integer. Out of which, we have only used 16 bits.</p><p>Here is how we will handle carryovers. We iterate over the items of the Field element array and divide each integer by <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{16}&quot;,&quot;id&quot;:&quot;p8b6r32z9v&quot;}" data-component-name="InlineLatexToDOM"></span>. There is a carry if the division doesn&#8217;t make all the bits 0. We move the carry over to the subsequent element.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ccj8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ccj8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 424w, https://substackcdn.com/image/fetch/$s_!Ccj8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 848w, https://substackcdn.com/image/fetch/$s_!Ccj8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 1272w, https://substackcdn.com/image/fetch/$s_!Ccj8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ccj8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png" width="1456" height="634" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:634,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;carry&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="carry" title="carry" srcset="https://substackcdn.com/image/fetch/$s_!Ccj8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 424w, https://substackcdn.com/image/fetch/$s_!Ccj8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 848w, https://substackcdn.com/image/fetch/$s_!Ccj8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 1272w, https://substackcdn.com/image/fetch/$s_!Ccj8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa68f8ea3-f6e2-4d37-8b2b-d50f1f74c42d_2254x982.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>carry method used in addition and multiplications</em></p><p>If we find carry bits in the last (15th) element, we add that back to the first element, but only after multiplying the carry by 38. The number 38 seems arbitrary. We must look at the multiplication algorithm to understand its origin. So, stay tuned.</p><p>Calling this function once can cause the element at the first index to exceed <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{16}&quot;,&quot;id&quot;:&quot;n83bxcyvbo&quot;}" data-component-name="InlineLatexToDOM"></span> or even become negative (due to a wrap-around). A second call can fix this. However, if items between the 1st and 15th index are close to <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{16}&quot;,&quot;id&quot;:&quot;m7rqu60shd&quot;}" data-component-name="InlineLatexToDOM"></span>, the carry bits from the 0th index can cause a cascade of carries. It will result in a further carry from the last element to the first, causing it to exceed <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{16}&quot;,&quot;id&quot;:&quot;6k29bbn60g&quot;}" data-component-name="InlineLatexToDOM"></span> again.</p><p>We must call the carry function three times to ensure no carry bits are left in the Field element. Such a carry cascade is no longer possible on a third call since the middle values are now zero.</p><h2>Multiplication</h2><p>Now we are ready to look at multiplication. In the Ed25519 curve, the parameter <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;hbumw3w2f1&quot;}" data-component-name="InlineLatexToDOM"></span> is set to <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{255} - 19&quot;,&quot;id&quot;:&quot;9vjycctzli&quot;}" data-component-name="InlineLatexToDOM"></span>. It is the prime modulo of the Finite Field underlying elliptic curve<sup>[2]</sup>. In practice, all the arithmetic operations on the Field are done modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;i80290t5fv&quot;}" data-component-name="InlineLatexToDOM"></span>.</p><p>Since <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p + 19&quot;,&quot;id&quot;:&quot;knq21wkykc&quot;}" data-component-name="InlineLatexToDOM"></span> is <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{255}&quot;,&quot;id&quot;:&quot;00j96128hv&quot;}" data-component-name="InlineLatexToDOM"></span>, therefore <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2p + 38&quot;,&quot;id&quot;:&quot;tm7un4c39p&quot;}" data-component-name="InlineLatexToDOM"></span> is <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{256}&quot;,&quot;id&quot;:&quot;f7jkhi6p80&quot;}" data-component-name="InlineLatexToDOM"></span>. There are two points to note here.</p><p>First, the size of our data structure is <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{256}&quot;,&quot;id&quot;:&quot;6huga8nn2a&quot;}" data-component-name="InlineLatexToDOM"></span>. It means that reducing any value by modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{256}&quot;,&quot;id&quot;:&quot;cwj0ea9so3&quot;}" data-component-name="InlineLatexToDOM"></span> is easy. Bigger values will automatically overflow.</p><p>Second, in the multiplication function, we can get away by reducing the result by modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2p&quot;,&quot;id&quot;:&quot;hvfdb34ebo&quot;}" data-component-name="InlineLatexToDOM"></span> as long as we later reduce it by <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;4vztghi78p&quot;}" data-component-name="InlineLatexToDOM"></span>. We will do so while packing our result into a byte array before returning the final result.</p><p>We start the multiplication by taking the product of inputs (in the unpacked form) element by element. We store the individual results in the <code>product</code> array so we can add that up to get the final result. This representation is equivalent to a reduction modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{256}&quot;,&quot;id&quot;:&quot;wancmm415e&quot;}" data-component-name="InlineLatexToDOM"></span> or <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2p+38&quot;,&quot;id&quot;:&quot;ft36teeeag&quot;}" data-component-name="InlineLatexToDOM"></span>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!frPR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!frPR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 424w, https://substackcdn.com/image/fetch/$s_!frPR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 848w, https://substackcdn.com/image/fetch/$s_!frPR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 1272w, https://substackcdn.com/image/fetch/$s_!frPR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!frPR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png" width="1054" height="182" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:182,&quot;width&quot;:1054,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;mul algo&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="mul algo" title="mul algo" srcset="https://substackcdn.com/image/fetch/$s_!frPR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 424w, https://substackcdn.com/image/fetch/$s_!frPR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 848w, https://substackcdn.com/image/fetch/$s_!frPR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 1272w, https://substackcdn.com/image/fetch/$s_!frPR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9a0c8ab-17b5-42da-af65-f5beacfe95d2_1054x182.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>product calculation expressed algebraically</em></p><p>After doing some modulo arithmetic, as shown in the figure above, we can arrive at the equation <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;5&quot;,&quot;id&quot;:&quot;b6mmdnigyb&quot;}" data-component-name="InlineLatexToDOM"></span>. Note how the higher powers of <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2&quot;,&quot;id&quot;:&quot;rpfpga18dv&quot;}" data-component-name="InlineLatexToDOM"></span> are reduced because of the modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{256}&quot;,&quot;id&quot;:&quot;p2z75q6mzs&quot;}" data-component-name="InlineLatexToDOM"></span> in step 2. Finally, the reduced powers are grouped in step 3. The same thing is implemented below on line 63. We can now ignore the elements between <code>product[16]</code> and <code>product[30]</code> in our initial array.</p><p>Finally, we call the carry function twice. It is good enough to account for carry bits and ensure each array element doesn&#8217;t exceed the 16-bit size.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4WCl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4WCl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 424w, https://substackcdn.com/image/fetch/$s_!4WCl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 848w, https://substackcdn.com/image/fetch/$s_!4WCl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 1272w, https://substackcdn.com/image/fetch/$s_!4WCl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4WCl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png" width="1080" height="759" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:759,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;mul&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="mul" title="mul" srcset="https://substackcdn.com/image/fetch/$s_!4WCl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 424w, https://substackcdn.com/image/fetch/$s_!4WCl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 848w, https://substackcdn.com/image/fetch/$s_!4WCl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 1272w, https://substackcdn.com/image/fetch/$s_!4WCl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3440a2c5-fbad-4f8c-990c-79108cb17094_1080x759.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>The multiplication method for finite fields</em></p><h2>Fermat&#8217;s Little Theorem</h2><p>In Finite Field arithmetic, in place of division we have the modular inverse. The modular inverse of <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;a&quot;,&quot;id&quot;:&quot;q2fn3g0bzm&quot;}" data-component-name="InlineLatexToDOM"></span> is <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;b&quot;,&quot;id&quot;:&quot;ebbphldb3f&quot;}" data-component-name="InlineLatexToDOM"></span> if by multiplying <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;a&quot;,&quot;id&quot;:&quot;qv2dt4689q&quot;}" data-component-name="InlineLatexToDOM"></span> with <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;b&quot;,&quot;id&quot;:&quot;q5exm8487i&quot;}" data-component-name="InlineLatexToDOM"></span> in the given modulo, we get <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;1&quot;,&quot;id&quot;:&quot;t1mkdrgcr1&quot;}" data-component-name="InlineLatexToDOM"></span> (multiplicative identity of the field).</p><p><a href="https://en.wikipedia.org/wiki/Fermat%27s_little_theorem">Fermat&#8217;s little theorem</a> says the following. Here, <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;0xlmq97i96&quot;}" data-component-name="InlineLatexToDOM"></span> is a prime and <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;a&quot;,&quot;id&quot;:&quot;oue9gyb3nz&quot;}" data-component-name="InlineLatexToDOM"></span> is any integer.</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;a^{p-1} \\equiv 1 \\mod p&quot;,&quot;id&quot;:&quot;94w8v2qs41&quot;}" data-component-name="LatexBlockToDOM"></div><p>For our purpose, <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p = 2^{255} - 19&quot;,&quot;id&quot;:&quot;4t0fl34wvg&quot;}" data-component-name="InlineLatexToDOM"></span>. We can use the formula to find the inverse of a given field element.</p><h2>Modular inverse</h2><p>Using the theorem, we can see that:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;a^{-1} \\equiv a^{p-2}\\mod p&quot;,&quot;id&quot;:&quot;4wsye74ma6&quot;}" data-component-name="LatexBlockToDOM"></div><p>Essentially, we need to calculate <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;a^{p-2} \\space mod \\space p&quot;,&quot;id&quot;:&quot;h7tcaskgsj&quot;}" data-component-name="InlineLatexToDOM"></span> where <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;a&quot;,&quot;id&quot;:&quot;y31kh6ftyx&quot;}" data-component-name="InlineLatexToDOM"></span> is the given field element. And <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p-2&quot;,&quot;id&quot;:&quot;lbthx3jeg8&quot;}" data-component-name="InlineLatexToDOM"></span> is <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{255 - 19 - 2}&quot;,&quot;id&quot;:&quot;9qcvybahec&quot;}" data-component-name="InlineLatexToDOM"></span>. In hex, <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{255 - 21}&quot;,&quot;id&quot;:&quot;teamsz42qo&quot;}" data-component-name="InlineLatexToDOM"></span> is represented as:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iuBs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iuBs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 424w, https://substackcdn.com/image/fetch/$s_!iuBs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 848w, https://substackcdn.com/image/fetch/$s_!iuBs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 1272w, https://substackcdn.com/image/fetch/$s_!iuBs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iuBs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png" width="359" height="203" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:203,&quot;width&quot;:359,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;hex&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="hex" title="hex" srcset="https://substackcdn.com/image/fetch/$s_!iuBs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 424w, https://substackcdn.com/image/fetch/$s_!iuBs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 848w, https://substackcdn.com/image/fetch/$s_!iuBs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 1272w, https://substackcdn.com/image/fetch/$s_!iuBs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a95dfcb-e922-4712-9dcc-9627ebf177be_359x203.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>bytes in </em><span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;nrz415ou9d&quot;}" data-component-name="InlineLatexToDOM"></span><em> i.e. </em><span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{255} - 21&quot;,&quot;id&quot;:&quot;6dc4jde63c&quot;}" data-component-name="InlineLatexToDOM"></span><em> shown in hexadecimal</em></p><p>The hex notation makes it easy to see that besides the first and the last byte, all other bytes are ff (i.e., all 8 bits of a byte are 1). If we look closer at the first and the last byte, we notice that 0x7f = 01111111 and 0xeb = 11101011. It means that all the bits of <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p-2&quot;,&quot;id&quot;:&quot;fzddtladck&quot;}" data-component-name="InlineLatexToDOM"></span> are 1 except the 2nd, 4th, and the most significant bit.</p><p>Here is the inverse algorithm. We iterate in a loop <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;254&quot;,&quot;id&quot;:&quot;dcjl024aqw&quot;}" data-component-name="InlineLatexToDOM"></span> times and maintain an accumulator in the result variable. We will initialize this accumulator with the input (line 91).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wize!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wize!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 424w, https://substackcdn.com/image/fetch/$s_!wize!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 848w, https://substackcdn.com/image/fetch/$s_!wize!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 1272w, https://substackcdn.com/image/fetch/$s_!wize!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wize!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png" width="1456" height="631" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:631,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;inverse&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="inverse" title="inverse" srcset="https://substackcdn.com/image/fetch/$s_!wize!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 424w, https://substackcdn.com/image/fetch/$s_!wize!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 848w, https://substackcdn.com/image/fetch/$s_!wize!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 1272w, https://substackcdn.com/image/fetch/$s_!wize!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F887b7621-3f71-425b-afaa-3c0440138ba1_1610x698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>The inverse method for finite fields</em></p><p>In every iteration, we will square the accumulator and reassign the value. Further, if the bit is set for an index (that is, every index except the 2nd and 4th), then we also multiply the accumulator with the input value.</p><p>To understand how the algorithm works, we can take a smaller example. Let&#8217;s say we want to calculate the modular inverse of 3 in the prime field where <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;b3phjbbs52&quot;}" data-component-name="InlineLatexToDOM"></span> is 13. In this case, <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;a = 3&quot;,&quot;id&quot;:&quot;zln5dkujo4&quot;}" data-component-name="InlineLatexToDOM"></span> and <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p - 2 = 11&quot;,&quot;id&quot;:&quot;qso79znp21&quot;}" data-component-name="InlineLatexToDOM"></span>. The binary representation for 11 is 1011. We will initialize the result with 3, skip the most significant bit, and iterate 3 times for the remaining bits: <code>011</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7U1p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7U1p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 424w, https://substackcdn.com/image/fetch/$s_!7U1p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 848w, https://substackcdn.com/image/fetch/$s_!7U1p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 1272w, https://substackcdn.com/image/fetch/$s_!7U1p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7U1p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png" width="1456" height="459" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:459,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;inverse table&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="inverse table" title="inverse table" srcset="https://substackcdn.com/image/fetch/$s_!7U1p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 424w, https://substackcdn.com/image/fetch/$s_!7U1p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 848w, https://substackcdn.com/image/fetch/$s_!7U1p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 1272w, https://substackcdn.com/image/fetch/$s_!7U1p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396521cc-fcd2-48d8-bb92-7e7016f19cb3_1574x496.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Mod inverse table</em></p><p><em>Note: all the multiplications in the above table are in mod 13. We can quickly verify our result in a Python shell</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eFMd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eFMd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 424w, https://substackcdn.com/image/fetch/$s_!eFMd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 848w, https://substackcdn.com/image/fetch/$s_!eFMd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 1272w, https://substackcdn.com/image/fetch/$s_!eFMd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eFMd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png" width="1456" height="212" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:212,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;python shell&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="python shell" title="python shell" srcset="https://substackcdn.com/image/fetch/$s_!eFMd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 424w, https://substackcdn.com/image/fetch/$s_!eFMd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 848w, https://substackcdn.com/image/fetch/$s_!eFMd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 1272w, https://substackcdn.com/image/fetch/$s_!eFMd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc0761b0-ac8e-496a-8c78-446592c3695d_2034x296.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>Mod inverse in python</em></p><p>With that, we are done with the arithmetic operations. Next, we will focus on transforming between the two data types we discussed earlier.</p><h2>Unpacking</h2><p>As the name suggests, the unpack function will convert a packed representation (byte array) to an unpacked one. This is straightforward. We start by creating a new Field element. Initialize it with 0 values. Next, we iterate through all 16 elements and update them. We combine two adjacent bytes from the packed byte array into a 16-bit value. To do so, we multiply the 2nd byte by <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^8&quot;,&quot;id&quot;:&quot;waet796wxj&quot;}" data-component-name="InlineLatexToDOM"></span> and add them together.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B7Xj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B7Xj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 424w, https://substackcdn.com/image/fetch/$s_!B7Xj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 848w, https://substackcdn.com/image/fetch/$s_!B7Xj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 1272w, https://substackcdn.com/image/fetch/$s_!B7Xj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B7Xj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png" width="1456" height="319" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/939470db-efd1-4336-9e33-8acccde1301d_2352x516.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:319,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;unpack&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="unpack" title="unpack" srcset="https://substackcdn.com/image/fetch/$s_!B7Xj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 424w, https://substackcdn.com/image/fetch/$s_!B7Xj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 848w, https://substackcdn.com/image/fetch/$s_!B7Xj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 1272w, https://substackcdn.com/image/fetch/$s_!B7Xj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F939470db-efd1-4336-9e33-8acccde1301d_2352x516.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>Unpacking the byte array to operate on field elements</em></p><p>Finally, we make sure that the most significant bit is zero. We do this by taking the last element modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{15}&quot;,&quot;id&quot;:&quot;geio63yw4h&quot;}" data-component-name="InlineLatexToDOM"></span>, since, in our prime field arithmetic, every number is less than <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;7cwmpc5epu&quot;}" data-component-name="InlineLatexToDOM"></span> (i.e., <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2^{255-19}&quot;,&quot;id&quot;:&quot;f63ikwywt1&quot;}" data-component-name="InlineLatexToDOM"></span>).<sup>[3]</sup></p><h2>Bit Swap</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CDdm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CDdm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 424w, https://substackcdn.com/image/fetch/$s_!CDdm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 848w, https://substackcdn.com/image/fetch/$s_!CDdm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 1272w, https://substackcdn.com/image/fetch/$s_!CDdm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CDdm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png" width="1456" height="423" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:423,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;bitswap&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="bitswap" title="bitswap" srcset="https://substackcdn.com/image/fetch/$s_!CDdm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 424w, https://substackcdn.com/image/fetch/$s_!CDdm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 848w, https://substackcdn.com/image/fetch/$s_!CDdm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 1272w, https://substackcdn.com/image/fetch/$s_!CDdm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F498fe944-b056-476b-93ea-9e497c3d94c8_2102x610.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>bit swapping</em></p><p>Before we start with the pack function, we need a swap function. It will take two Field elements and swap their bits only if the respective bit of the third argument is 1.</p><p>Notice the <code>i64</code> variable <code>c</code>. Due to the bitwise negation, it will have all its bits set to 1 when the 3rd argument (<code>b</code>) is 1, and all the bits will be 0 when the <code>b</code> is 0. We can print it out to see the memory representation. <sup>[4]</sup></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xhJI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xhJI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 424w, https://substackcdn.com/image/fetch/$s_!xhJI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 848w, https://substackcdn.com/image/fetch/$s_!xhJI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 1272w, https://substackcdn.com/image/fetch/$s_!xhJI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xhJI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png" width="1456" height="537" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:537,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;rs shell&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="rs shell" title="rs shell" srcset="https://substackcdn.com/image/fetch/$s_!xhJI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 424w, https://substackcdn.com/image/fetch/$s_!xhJI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 848w, https://substackcdn.com/image/fetch/$s_!xhJI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 1272w, https://substackcdn.com/image/fetch/$s_!xhJI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cdbe86-d107-41fc-88a4-46698e7ef5d0_1994x736.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>bit pattern for variable </em><code>c</code><em> in bitswap</em></p><p>The bitwise XOR operation will only result in 1 when both of its inputs are different. For each item in the array, we will initialize a temporary variable (line 106). Each bit in this variable will only be set if the corresponding bits of the 3rd argument are set (bitwise and), and the bits of <code>p</code> and <code>q</code> are different (bitwise xor).</p><p>Hence <code>t</code> will capture the differences in the bits of <code>p</code> and <code>q</code>. Its bits will be set where the bits of <code>p</code> and <code>q</code> don&#8217;t match. Finally, if required, the bitwise XOR with t on lines 107 and 108 will flip the bits of <code>p</code> and <code>q</code>.</p><h2>Packing</h2><p>Packing the Field element array back to the byte array is tricky. We start by first ensuring that none of the elements overflow. We do this by calling the carry function three times, as discussed before.</p><p>Recall that earlier, we only reduced our calculations by modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2p&quot;,&quot;id&quot;:&quot;b7vawj3bux&quot;}" data-component-name="InlineLatexToDOM"></span>. It means that the input value in the pack function can lie between <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;0&quot;,&quot;id&quot;:&quot;9n3ug7ihq1&quot;}" data-component-name="InlineLatexToDOM"></span> and <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2p&quot;,&quot;id&quot;:&quot;rwh5t1uq36&quot;}" data-component-name="InlineLatexToDOM"></span>. The next step should be to reduce the input value by modulo <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;0n13d5a594&quot;}" data-component-name="InlineLatexToDOM"></span>. Before we do that, notice that only three possible cases exist. The input value can lie within one of these buckets: <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;[0, p)&quot;,&quot;id&quot;:&quot;r3isg26pj8&quot;}" data-component-name="InlineLatexToDOM"></span>, <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;[p-2p)&quot;,&quot;id&quot;:&quot;bmj8v6rueh&quot;}" data-component-name="InlineLatexToDOM"></span>, <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;[2p-2^{256})&quot;,&quot;id&quot;:&quot;wngma8znjb&quot;}" data-component-name="InlineLatexToDOM"></span>. In the first case, we can pack the input value. In the latter two cases, we must first subtract the input value by <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;mm2piss3mk&quot;}" data-component-name="InlineLatexToDOM"></span> and <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;2p&quot;,&quot;id&quot;:&quot;5ja2zaf5dy&quot;}" data-component-name="InlineLatexToDOM"></span>, respectively.</p><p>We want a constant time algorithm. It cannot depend on the size of the input (i.e. result of our calculation). To find the correct bucket we will subtract by <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;p&quot;,&quot;id&quot;:&quot;kwgwdc7bgz&quot;}" data-component-name="InlineLatexToDOM"></span> two times from the result and store our result in an intermediate variable. If the value becomes negative after the first subtraction, we will do the second subtraction anyway but pack the original value (discard the result of the subtract operation). If it becomes negative after the second subtraction, we will use the first subtraction&#8217;s result (discarding the second subtraction&#8217;s result). Otherwise, we will pack the output of the second subtraction.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cA1u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cA1u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 424w, https://substackcdn.com/image/fetch/$s_!cA1u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 848w, https://substackcdn.com/image/fetch/$s_!cA1u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 1272w, https://substackcdn.com/image/fetch/$s_!cA1u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cA1u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png" width="1456" height="917" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e56571ca-b222-4af5-b538-da525ef80709_2512x1582.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:917,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;pack&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="pack" title="pack" srcset="https://substackcdn.com/image/fetch/$s_!cA1u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 424w, https://substackcdn.com/image/fetch/$s_!cA1u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 848w, https://substackcdn.com/image/fetch/$s_!cA1u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 1272w, https://substackcdn.com/image/fetch/$s_!cA1u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe56571ca-b222-4af5-b538-da525ef80709_2512x1582.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Packing the result into a byte array</em></p><p>We can tell a value is negative if the last item of the field element array is wider than 16 bits. Similar to how we calculate carry bits.</p><p>Here, we will use the swap function. If the value is negative (carry = 1), we will not swap the intermediate result of the subtraction in <code>temp</code> with the input. If the value becomes negative in first iteration, it will also be negative after the second iteration. We won&#8217;t swap again and pack the input. However, if the value is not negative after the subtraction, we will change the original value with the result of the subtraction and proceed with the second subtraction.</p><h2>Conclusion</h2><p>With all these functions in place, we have completed the finite field arithmetic required for understanding elliptic curve operations. In subsequent posts, we will use these concepts to implement the Ed25519 signatures.</p><h2>Notes</h2><ol><li><p>This <a href="https://www.amazon.com/Code-Book-Science-Secrecy-Cryptography/dp/0385495323?crid=Z9SSVQ0AJNXG&amp;keywords=the+code+book&amp;qid=1702534870&amp;sprefix=the+code+book,aps,347&amp;sr=8-1">book</a> has an excellent account of the impact of using and breaking cipher systems throughout history (see the code book)</p></li><li><p>Check out chapters 4 &amp; 5 from the <a href="https://github.com/LeastAuthority/moonmath-manual">moon math manual</a> to better understand fields, groups, rings, and elliptic curves.</p></li><li><p>Bitwise &amp; operation is <a href="https://stackoverflow.com/a/6670853/3548148">equivalent</a> to taking mod of a power of 2.</p></li><li><p>Check <a href="https://en.wikipedia.org/wiki/Two%27s_complement">2s complement</a> binary representation.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[CRDTs in a Nutshell]]></title><description><![CDATA[Conflict Free Replicated Data Types]]></description><link>https://www.avichalp.me/p/2023-05-07-crdts-in-a-nutshell</link><guid isPermaLink="false">https://www.avichalp.me/p/2023-05-07-crdts-in-a-nutshell</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sun, 07 May 2023 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!anRP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>CRDT: Conflict-Free Replicated Data Type</h2><p><a href="https://hal.inria.fr/inria-00555588/document">CRDTs</a> are shared data structures with superpowers. They enable independent modification and still stay in sync. It means that if two users, Alice and Bob, decide to change a key in a CRDT-based hash map, they don&#8217;t need to coordinate beforehand. Alice can change the value of key &#8220;foo&#8221; to 1, while Bob can make it 3. Eventually, when Alice and Bob sync, it is <a href="https://martin.kleppmann.com/papers/crdt-isabelle-oopsla17.pdf">guaranteed</a> that neither of their changes will be lost. Moreover, the shared data structure will not be corrupted. It will eventually converge to a single value that Alice and Bob agree on.</p><p>This post will look at the theoretical underpinning of CRDTs. We will implement two different CRDTs: GCounter (or Grow only counter) and LWW set (Last Writer Wins set). We will also analyze their applications, compare them with the main alternative: Operational Transformations and understand their limitations.</p><h2>CRDTs Theory</h2><p>Thanks to <a href="http://jtfmumm.com/blog/2015/11/17/crdt-primer-1-defanging-order-theory/">order theory</a>, CRDTs are robust to data corruption amid concurrent edits and converge to a canonical value over time. There are a few concepts at work here. First is the notion of <em>order</em>. Second is the concept of a join or <em>merge</em>. The third is <em>semilattice</em>.</p><h4>Order</h4><p>An order is a binary relation. For example, we can say, in the set of integers 2 &lt; 3. The less than operator here is the order. An order could be total or partial. A less than operator is a total order over a set of integers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!anRP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!anRP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 424w, https://substackcdn.com/image/fetch/$s_!anRP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 848w, https://substackcdn.com/image/fetch/$s_!anRP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 1272w, https://substackcdn.com/image/fetch/$s_!anRP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!anRP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png" width="1456" height="496" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:496,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;total order ints&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="total order ints" title="total order ints" srcset="https://substackcdn.com/image/fetch/$s_!anRP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 424w, https://substackcdn.com/image/fetch/$s_!anRP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 848w, https://substackcdn.com/image/fetch/$s_!anRP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 1272w, https://substackcdn.com/image/fetch/$s_!anRP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d7ae90b-21b1-41f1-9dac-57e9d016bbff_1956x666.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>A totally ordered set of integers</em></p><p>An example of a partial order is the &#8220;located-in&#8221; relation. Consider a set {USA, NYC, Germany, Berlin}. NYC is located in USA, and Berlin in Germany. We cannot compare USA and Germany with the located-in operator. Neither USA is located in Germany, nor Germany is located in the USA.</p><p>In an ordered set, an upper bound is an element greater than or equal to any other element. The join or merge operation on two elements is the least upper bound in such a set.</p><p>For example, in a set of integers, the join of 2 and 5 will be 5. There&#8217;s no integer smaller than 5 that&#8217;s an upper bound on both 2 and 5. 7 is an upper bound on 2 and 5, but it&#8217;s not the least upper bound since 5&#8804;7.</p><p>Recall that the less than and equal operator is a total order for a set of integers. A curious property of total order is that joining two elements will result in one of the two elements. It is because every element can be directly compared to every other element.</p><p>It is not valid for a partial order. Let&#8217;s extend our set of locations from above: {North America, USA, NYC, SF, Europe, Germany, Berlin, Munich} Here, the join operation on &#8220;NYC&#8221; and &#8220;SF&#8221; cannot produce either &#8220;NYC&#8221; or &#8220;SF&#8221; because the two are incomparable. The &#8220;USA&#8221; and &#8220;North America&#8221; are the upper bounds for &#8220;NYC&#8221; and &#8220;SF&#8221;. &#8220;USA&#8221; is the least upper bound. It means that the join operation on &#8220;SF&#8221; and &#8220;NYC&#8221; results in &#8220;USA&#8221;.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GcwW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GcwW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 424w, https://substackcdn.com/image/fetch/$s_!GcwW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 848w, https://substackcdn.com/image/fetch/$s_!GcwW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 1272w, https://substackcdn.com/image/fetch/$s_!GcwW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GcwW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png" width="1064" height="1304" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1304,&quot;width&quot;:1064,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;partial order locations&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="partial order locations" title="partial order locations" srcset="https://substackcdn.com/image/fetch/$s_!GcwW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 424w, https://substackcdn.com/image/fetch/$s_!GcwW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 848w, https://substackcdn.com/image/fetch/$s_!GcwW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 1272w, https://substackcdn.com/image/fetch/$s_!GcwW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b57dcc2-96a5-4f68-b4dd-0ba3d5e0fddc_1064x1304.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>A partially ordered set of locations</em></p><h4>Join</h4><p>The join or merge operation in our pre-defined set with an order must follow the three algebraic rules. It should be commutative, associative, and idempotent.</p><p><strong>Commutativity</strong> means it doesn&#8217;t matter in which order we join two elements. It is similar to how it doesn&#8217;t matter in which order we add or multiply two integers.</p><p><strong>Associativity</strong> means if we want to join three elements, we can pick any two at a time and then join the result with the remaining element.</p><p><strong>Idempotence</strong> means that we can join an element with itself any number of times, and we will still end up with the same element.</p><h4>Semilattice</h4><p>A set with an order is a join semilattice if we can take any two elements from the set and find a join for them. It is easier to see it in the case of the total order, for example, the set of integers and the less than and equals operator. For any two elements, the least upper bound will be one or the other of those two integers.</p><p>It is not straightforward for the partial order. Again, consider our set of locations. We cannot perform a join on &#8220;USA&#8221; and &#8220;Germany&#8221; because there is no upper bound. Both of these countries are incomparable. This set and the corresponding located-in order don&#8217;t form a join semilattice. However, if we add &#8220;Earth&#8221; to this set, it will become a join-semilattice.</p><p>Here is another example of the difference between total order and partial order. It is more abstract but more familiar. A binary search tree is totally ordered, whereas a binary heap is partially ordered. In a binary search tree, every parent node must be bigger than its left child and smaller than the right child. This property is responsible for the total order in this data structure. In a max heap, every parent element must be bigger than both of its children. However, the children remain relatively unordered. Both data structures are ubiquitous, but each has a different purpose. A binary search tree can quickly find an element. The time it takes is proportional to the logarithm of the number of elements in the tree. On the other hand, a heap is instrumental in quickly finding the extreme (min or max) elements in constant time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IYyM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IYyM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 424w, https://substackcdn.com/image/fetch/$s_!IYyM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 848w, https://substackcdn.com/image/fetch/$s_!IYyM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 1272w, https://substackcdn.com/image/fetch/$s_!IYyM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IYyM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png" width="1456" height="1232" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1232,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;partial order locations 2&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="partial order locations 2" title="partial order locations 2" srcset="https://substackcdn.com/image/fetch/$s_!IYyM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 424w, https://substackcdn.com/image/fetch/$s_!IYyM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 848w, https://substackcdn.com/image/fetch/$s_!IYyM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 1272w, https://substackcdn.com/image/fetch/$s_!IYyM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae3d436-2b84-4a7b-9f1c-f5f8cf790eef_1550x1312.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>A partially ordered set of locations</em></p><p>According to <a href="https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type">Wikipedia</a>, state-based CRDTs:</p><blockquote><p>send their full local state to other replicas, where the states are merged by a function which must be commutative, associative, and idempotent. The merge function provides a join for any pair of replica states, so the set of all states forms a semilattice. The update function must monotonically increase the internal state according to the same partial order rules as the semilattice.</p></blockquote><p>It raises a question. How CRDTs deal with a partial order? How can two replicas be merged that cannot be compared? This is, in fact, the most intriguing case when concurrent modification leads to conflicts.</p><p>This scenario is analogous to &#8220;merge conflicts&#8221; in git. When two developers modify the same line of code in different commits, there is a conflict when they merge their code. Generally, developers resolve conflicts offline following a specification.</p><p>Similarly, concurrent edits create a conflict in a CRDT. For example, if Alice and Bob are writing a letter to Charlie. They might start at the same time. Alice might type the first line as &#8220;Hi Charlie&#8221;. Bob, in his editor, may type it as &#8220;Hello Charlie&#8221;. In this case, the CRDT-based text editing software won&#8217;t be able to automatically converge on a value. In such cases, the end-user has to intervene. Alternatively, applications may use a heuristic. For example, the editor can produce the first line as &#8220;HiHello Charlie&#8221;. Later, either Bob or Alice can fix the word &#8220;HiHello&#8221; to something sensible.</p><p>The values in CRDTs increase monotonically according to some order. CRDTs diverge until they eventually converge. Having briefly looked at order theory, we can see that CRDTs converge mathematically towards the least upper bound of all possible values.</p><p>Intuitively we can see that the state is merging. As the nodes sync, they update their local value based on the value they see in the received message. The final shared state is equivalent to the result of some correct sequential execution.</p><p>The most fascinating bit is that CRDTs converge to a consensus value without using any consensus algorithm like <a href="https://raft.github.io/">Raft</a>, <a href="https://en.wikipedia.org/wiki/Paxos_(computer_science)">Paxos</a>, <a href="https://www.scs.stanford.edu/nyu/03sp/sched/bfs.pdf">PBFT</a>, etc. It means that any new state update can execute immediately. Network latency or faults won&#8217;t slow down the system.</p><h2>Types of CRDTs</h2><p>There are two types of CRDTs: state-based and operation based. Both are theoretically equivalent. However, when it comes to implementation, they offer different trade-offs.</p><p>The state-based CRDTs are easier to implement. They do not require any guarantees from the underlying network. The problem is that they are generally inefficient. The entire state of every replica is eventually transmitted over the network.</p><p>The operation-based CRDTs only transmit the update operation and hence consume less bandwidth. However, such CRDTs require a reliable underlying network. The operations must be kept from being dropped or duplicated and delivered in a causal order.</p><h2>CRDT Examples</h2><p>Some examples of CRDTs are: G counter, PN counter, G set, 2 Phase set, Last Writer Wins set, OR set, etc. For collaborative text editing use cases, generally, sequential CRDTs are used as described in RGA and WOOT, etc. Below are simple implementations of a G counter and an LWW set.</p><h4>G counter</h4><p>A grow-only counter is the simplest CRDT. It can only increase in one direction. A use case for such a data structure could be to track the number of &#8220;plays&#8221; for a video or a song.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QeT2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QeT2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 424w, https://substackcdn.com/image/fetch/$s_!QeT2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 848w, https://substackcdn.com/image/fetch/$s_!QeT2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 1272w, https://substackcdn.com/image/fetch/$s_!QeT2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QeT2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png" width="1300" height="650" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:650,&quot;width&quot;:1300,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;G counter implementation&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="G counter implementation" title="G counter implementation" srcset="https://substackcdn.com/image/fetch/$s_!QeT2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 424w, https://substackcdn.com/image/fetch/$s_!QeT2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 848w, https://substackcdn.com/image/fetch/$s_!QeT2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 1272w, https://substackcdn.com/image/fetch/$s_!QeT2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0574fc0-82d4-4d68-868c-bfec79bac969_1300x650.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>A Gcounter implementation in Go</em></p><p>The counter is implemented as an integer-to-integer hash map. The map has an entry for every other replica that this copy knows about. When an actor hears from another, it merges their value into the counter using the merge function.</p><p>The Merge function iterates through the received counter and updates the keys if it is not present in the current replica or its value is lower than the received value. The maximum observed value is chosen because that is the least upper bound on a set of integers.</p><p>The Value function returns the current value of the counter. The point to note here is that the system&#8217;s value is the sum of all observed counters. It makes sense. Ideally, the value should be the total number of increment operations that all the replicas in the system have seen in aggregate.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!npWu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!npWu!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 424w, https://substackcdn.com/image/fetch/$s_!npWu!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 848w, https://substackcdn.com/image/fetch/$s_!npWu!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!npWu!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!npWu!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif" width="640" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;LWW set implementation2&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="LWW set implementation2" title="LWW set implementation2" srcset="https://substackcdn.com/image/fetch/$s_!npWu!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 424w, https://substackcdn.com/image/fetch/$s_!npWu!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 848w, https://substackcdn.com/image/fetch/$s_!npWu!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!npWu!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb61aada9-69e3-4474-a457-e559d58eefdf_640x480.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>source: <a href="http://jtfmumm.com/blog/2015/11/24/crdt-primer-2-convergent-crdts/">http://jtfmumm.com/blog/2015/11/24/crdt-primer-2-convergent-crdts/</a></em></p><p>One might find it more intuitive to implement a counter as an integer instead of a hash map, but that design has a flaw. Imagine this scenario. A system has 3 replicas of a counter with values 3, 2, and 1. It means that the system, in total, has seen 6 increments. When node 1 syncs with node 2, both will update their counters to the maximum of each other&#8217;s value. Their new shared value will become 3. When node 3 syncs with the other two, it will update its counter value to 3. This is a problem. We are expecting the counter to be 6, not 3.</p><h4>LWW set</h4><p>Let&#8217;s look at another CRDT, the Last Writer Wins Set. The semantics is as the name suggests. The set allows you to add or remove any item.</p><p>Under the hood, such as set maintains two different sets. One for additions and the other for removals (called the tombstone set). An item is a member when the following two conditions hold. One, it is in the &#8220;add&#8221; set. Second, it is not in the remove set or was added in the remove set before it was added in the &#8220;add&#8221; set.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RMWk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RMWk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 424w, https://substackcdn.com/image/fetch/$s_!RMWk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 848w, https://substackcdn.com/image/fetch/$s_!RMWk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 1272w, https://substackcdn.com/image/fetch/$s_!RMWk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RMWk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png" width="1456" height="693" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;LWW set implementation1&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="LWW set implementation1" title="LWW set implementation1" srcset="https://substackcdn.com/image/fetch/$s_!RMWk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 424w, https://substackcdn.com/image/fetch/$s_!RMWk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 848w, https://substackcdn.com/image/fetch/$s_!RMWk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 1272w, https://substackcdn.com/image/fetch/$s_!RMWk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd12934-1a92-479c-bcf9-1729ec96a403_1583x753.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HNky!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HNky!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 424w, https://substackcdn.com/image/fetch/$s_!HNky!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 848w, https://substackcdn.com/image/fetch/$s_!HNky!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 1272w, https://substackcdn.com/image/fetch/$s_!HNky!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HNky!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png" width="1456" height="693" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;LWW set implementation2&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="LWW set implementation2" title="LWW set implementation2" srcset="https://substackcdn.com/image/fetch/$s_!HNky!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 424w, https://substackcdn.com/image/fetch/$s_!HNky!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 848w, https://substackcdn.com/image/fetch/$s_!HNky!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 1272w, https://substackcdn.com/image/fetch/$s_!HNky!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a39b6c-9ce5-4e34-a96e-7d003c76dc26_1583x753.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>LWW set implementation in Go</em></p><p>Such a set can have an &#8220;add&#8221; or a &#8220;remove&#8221; bias. When the timestamps are equal, bias resolves the conflict. Note that a timestamp collision is likely to happen after two replicas merge.</p><h2>Operational Transform</h2><p>CRDTs offer an approach for achieving eventual consistency in distributed systems. They are designed to handle conflicts between concurrent updates to the same data, ensuring that all replicas eventually reach the same state. It makes CRDTs a handly tool to implement collaborative software such as text editors. However, it is crucial to note that the current state of the art collaborative editors, such as Google Docs, does not use CRDTs. Instead, it uses <a href="https://josephg.com/blog/crdts-go-brrr/">Operational Transform</a> algorithms. Both Operational Transform and CRDTs-based algorithms strive to converge independent data modifications.</p><p>The Operational Transform algorithm, in a <a href="https://youtu.be/x7drE24geUw?t=228">nutshell</a>, works by sending the indices at which the edit was made to other nodes. The received index must be transformed if the local copy has that index occupied. Index transformations happen in a central server. The server keeps the authoritative copy of the data that users are working on.</p><p>Operation Transforms are battle tested. However, they are less flexible when it comes to network architecture. It relies on a centralized server for sequencing edits to prevent unexpected data races. CRDTs don&#8217;t share this limitation because they are a local data structure. Software built on CRDTs can talk to other instances over a p2p connection. No coordination is required.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3s4l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3s4l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 424w, https://substackcdn.com/image/fetch/$s_!3s4l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 848w, https://substackcdn.com/image/fetch/$s_!3s4l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 1272w, https://substackcdn.com/image/fetch/$s_!3s4l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3s4l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png" width="1333" height="445" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:445,&quot;width&quot;:1333,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;LWW set implementation2&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="LWW set implementation2" title="LWW set implementation2" srcset="https://substackcdn.com/image/fetch/$s_!3s4l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 424w, https://substackcdn.com/image/fetch/$s_!3s4l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 848w, https://substackcdn.com/image/fetch/$s_!3s4l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 1272w, https://substackcdn.com/image/fetch/$s_!3s4l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F972c8f50-0c87-4100-870c-26a8dbdfe149_1333x445.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>OT vs CRDT network topology</em></p><p>The central Operational Transform server can become a performance bottleneck when a large number of users use it at the same time. On the other hand, writing p2p applications may be challenging. Also, notice that p2p networking is not required to use CRDTs. It works as well in a client-server architecture.</p><h2>CRDT Limitations</h2><p>CRDTs guarantee convergence, but not without cost. One of the main issues with CRDTs is that they could get memory hungry. Based on the examples discussed above, one might have spotted a pattern. These data structures only accrete. For example, a GSet keeps adding new elements without ever deleting anything. A Two-Phase set uses a tombstone set to record retractions.</p><p>CRDTs need to store the history of all edits. Garbage collection is not trivial. It is impossible to know when a disconnected node might come back online and wants to merge all the changes to arrive at the current system state.</p><p>There are some heuristics for garbage collection, but only with trade-offs. For instance, such GC techniques might require synchronization, which hurts performance. It is hard to implement CRDTs-based algorithms in resource-constrained environments such as edge computers, IoT devices, etc.</p><h2>In Closing</h2><p>In this post, we explored Conflict-Free Replicated Data Types (CRDTs), shared data structures that enable independent modifications while remaining in sync. Using order theory concepts, CRDTs ensure convergence to a single value over time without using consensus protocols. We also looked at some simple CRDT implementations, such as GCounter and LWW set, and discussed their applications and limitations. CRDTs offer flexibility in network architecture but can be memory-intensive since they store edit histories.</p>]]></content:encoded></item><item><title><![CDATA[Sabbatical 2022]]></title><description><![CDATA[Projects done during 2022 break]]></description><link>https://www.avichalp.me/p/2023-02-26-sabbatical-2022</link><guid isPermaLink="false">https://www.avichalp.me/p/2023-02-26-sabbatical-2022</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sun, 26 Feb 2023 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Sabbatical 2022</h2><p>After seven years of heads down building stuff, I took a break at the end of 2021. I planned a full 1-year sabbatical for the year 2022. This post is a collection of projects that I did during that time.</p><p>I didn&#8217;t intend to finish most of them or make them production ready. Instead, these half-baked prototypes aim to help me build intuition about complex topics. I develop a deeper understanding when I implement the concepts I am learning.</p><div><hr></div><p><a href="https://github.com/avichalp/solidity-contracts">Gradual Dutch Auctions</a></p><p>Nov 2022</p><p>Inspired by the <a href="https://www.paradigm.xyz/2022/04/gda">Gradual Dutch Auction</a> spec, I wanted to <a href="https://github.com/avichalp/solidity-contracts/tree/master/src/GDA">explore</a> the mechanism. Paradigm&#8217;s blog post describes two novel auction mechanisms suitable for fungible and non fungible tokens. I quickly <a href="https://github.com/avichalp/solidity-contracts/blob/master/src/GDA/DiscreteGDA.sol">implemented</a> and <a href="https://github.com/avichalp/solidity-contracts/blob/master/test/foundry/DiscreteGDA.t.sol">tested</a> the basic functionality thanks to the original post&#8217;s precise specification and reference implementations. The blog had all the details about the pricing function. All that was left was to implement the math equations in solidity.</p><p>It led to another rabbit hole. That is to understand how math libraries work in solidity, especially WAD arithmetic. I first started using <a href="https://github.com/avichalp/solidity-contracts/blob/master/test/foundry/DiscreteGDA.t.sol">PRBMath</a> to implement Discrete GDA and continuous GDA contracts. Soon after, I familiarized myself with <a href="https://medium.com/coinmonks/math-in-solidity-part-1-numbers-384c8377f26d">various</a> <a href="https://2&#960;.com/">techniques</a> to implement mathematical functions in solidity. Finally, I replaced the PRB math library with my <a href="https://github.com/avichalp/solidity-contracts/blob/master/src/Mathutil.sol">custom implementation</a> of <code>muldiv</code>, <code>exp</code>, <code>pow</code> etc., for fixed-point numbers in the format 59x18 (using the last 18 digits for decimals). I still need to optimize these functions for gas usage. This may be a topic for a future project.</p><div><hr></div><p><a href="https://github.com/avichalp/crdts">CRDTs</a></p><p>Sept 2022</p><p>The project&#8217;s purpose is to go through the <a href="https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type">CRDTs</a> theory and implements basic CRDTs as specified <a href="https://hal.inria.fr/inria-00555588/document">here</a>.</p><p>Currently, this repo contains the implementation for G Counter, PN Counter, G Set, 2PSet, LWW set, OR Set, and an experimental mix of 2P Set with vector clocks.</p><p>This repo also has code for vector clocks with basic functionality such as incrementing and merging different clocks, including benchmarking for these operations.</p><p>In the future, this will be a playground to experiment with more complex CRDT-based algorithms such as RGA and WOOT. And even more complex sequential CRDTs such as trees and graphs.</p><div><hr></div><p><a href="https://github.com/avichalp/toy-evm">Toy EVM</a></p><p>Aug 2022</p><p>The goal of this project is to build the EVM from scratch. This project doesn&#8217;t aim to be feature complete, performant, or production ready.</p><p>The specification in the Ethereum Yellow Paper is extremely rigorous. At the same time, it is a dry read and difficult to understand.</p><p>With this project, I want to create a playground to tinker with EVM primitives. The main purpose is to understand the internals and the core concepts underpinning the EVM.</p><div><hr></div><p><a href="https://github.com/avichalp/solidity-contracts">Solidity Contracts</a></p><p>June 2022</p><p>This repo is a collection of solidity contracts. The main purpose of this project is to be a playground for experimenting with different defi primitives on EVM based chains.</p><p>The contracts are compiled and tested using hardhat. Typechain is used to generate Typescript types for the solidity contracts, which makes it convenient for writing tests and scripts.</p><p><a href="https://github.com/avichalp/solidity-contracts/blob/master/contracts/StakingPool.sol">Staking Pool</a> is a contract that allows users to deposit and withdraw ETH or native tokens of other EVM chains. It also allows an admin to add funds to this contract to distribute the rewards to incentivize the depositors. The rewards that an individual depositor receives are proportional to their deposited stake.</p><p>The <a href="https://github.com/avichalp/solidity-contracts/blob/master/contracts/StakingToken.sol">Staking Token</a> contract is similar to Staking Pool contract it but also mints ERC20 tokens for the depositors. Later, the depositors can later redeem their sTokens for the native tokens they deposited plus the rewards accrued.</p><div><hr></div><p><a href="https://github.com/avichalp/damn-vulnerable-defi">Damn Vulnerable DeFi CTF</a></p><p>May 2022</p><p>Damn Vulnerable DeFi is a set of challenges for practicing the security aspect of smart contracts.</p><p>The challenges demonstrate using DeFi primitives like flash loans, price oracles, governance, lending pools, etc. Most puzzles expose a vulnerable protocol design or an implementation issue.</p><p>These puzzles are more advanced than the Ethernaut CTFs. My goal in practicing these challenges is to better understand the primitives, common attack vectors, and common solidity mistakes.</p><p>While working on these problems, I found that tracing function calls and trying to call the public functions with different values often led to the right idea. In particular, I often followed these steps:</p><ul><li><p>Understand the problem well enough to be able to draw a diagram to trace all interactions, such as function calls and event emissions.</p></li><li><p>Drawing the call stack for successive function calls.</p></li><li><p>Deploy the contracts locally and add logs, especially around constraints (require statements).</p></li></ul><div><hr></div><p><a href="https://github.com/avichalp/ethernaut-ctf">Ethernaut CTF</a></p><p>Feb 2022</p><p>Ethernaut CTF is the collection of &#8220;capture the flag&#8221; puzzles. These are targeted towards solidity or EVM beginners. Most of the puzzles in this collection are inspired by actual exploits that happened in the wild.</p><p>Each puzzle exposes some idiosyncratic behavior in the EVM. Smart Contracts in EVM are a different paradigm; not understanding how EVM works often leads to writing vulnerable contracts.</p><p>My goal in solving these puzzles is to familiarize myself with common gotchas in the ethereum virtual machine. I also want to understand common attack vectors in smart contracts.</p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Distributed Clocks]]></title><description><![CDATA[Exploring time and clocks in distributed systems]]></description><link>https://www.avichalp.me/p/2022-10-06-distributed-clocks</link><guid isPermaLink="false">https://www.avichalp.me/p/2022-10-06-distributed-clocks</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Thu, 06 Oct 2022 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZZRb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In 2017, at midnight of new years eve, Cloudflare&#8217;s DNS had an <a href="https://blog.cloudflare.com/how-and-why-the-leap-second-affected-cloudflare-dns">outage</a>. The root cause of the crash was intriguing. An API that explicitly <a href="https://golang.org/pkg/math/rand/#Int63n">panics</a> on negative input was unknowingly given a negative integer. It was the difference between a higher and a lower timestamp. Assuming that substracting a lower timestamp from a higher one will yield a positive number sounds reasonable. The only problem is that it is wrong. It is not a valid assumption because sometimes time moves backward in computers.</p><p>In this post, we will look at the problem of time measurement and clock synchronization. We will understand why keeping clocks in sync is the paramount issue in distributed systems. We will also look at the challenges of synchronizing the clocks across the network. We will briefly cover the different types of clocks and standards for measuring time and their inconsistencies.</p><p>Finally, we will end by taking a look at a couple of widely deployed clock synchronization protocols. How they tackle the clock synchronization problem and the different trade-offs that they make.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZZRb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZZRb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 424w, https://substackcdn.com/image/fetch/$s_!ZZRb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 848w, https://substackcdn.com/image/fetch/$s_!ZZRb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 1272w, https://substackcdn.com/image/fetch/$s_!ZZRb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZZRb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png" width="516" height="519" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:519,&quot;width&quot;:516,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;clocks header&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="clocks header" title="clocks header" srcset="https://substackcdn.com/image/fetch/$s_!ZZRb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 424w, https://substackcdn.com/image/fetch/$s_!ZZRb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 848w, https://substackcdn.com/image/fetch/$s_!ZZRb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 1272w, https://substackcdn.com/image/fetch/$s_!ZZRb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff48aa9eb-5f99-4e52-b081-0efcc6dc382b_516x519.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Timekeeping</h2><p>Before we look at how computers tell time, we will briefly examine how time is measured. In general, there are two broad types of clocks: astronomical clocks and atomic clocks.</p><p>The stability of a clock means how consistently it measures a unit of time.</p><p>Astronomical clocks are instrumental in applications related to navigation and astronomy because they match the earth&#8217;s rotation. However, they are less stable. Atomic clocks are more stable but don&#8217;t precisely match the earth&#8217;s rotation.</p><p>More stable atomic clocks tend to be expensive, bulky, and hard to maintain. The usual wall clocks and computers that use quartz crystal oscillations are more prone to <a href="https://en.wikipedia.org/wiki/Clock_drift">drifting</a>. Environmental factors such as room temperature affect how fast quartz crystal oscillates. Quartz clocks can easily drift by 50 microseconds per second (50ppm).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1m24!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1m24!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 424w, https://substackcdn.com/image/fetch/$s_!1m24!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 848w, https://substackcdn.com/image/fetch/$s_!1m24!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 1272w, https://substackcdn.com/image/fetch/$s_!1m24!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1m24!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png" width="1456" height="967" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:967,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;atomic clock&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="atomic clock" title="atomic clock" srcset="https://substackcdn.com/image/fetch/$s_!1m24!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 424w, https://substackcdn.com/image/fetch/$s_!1m24!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 848w, https://substackcdn.com/image/fetch/$s_!1m24!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 1272w, https://substackcdn.com/image/fetch/$s_!1m24!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd50e258-2d24-4260-8988-c79d94929ab1_2700x1793.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>NIST&#8217;s ultra-stable ytterbium lattice atomic clock. Credit: Burrus/NIST</em></p><h2>Unix Time</h2><p>Generally, computers keep time using the Unix time standard. It is defined as the number of seconds elapsed since the Unix epoch. The Unix epoch is <code>00:00:00 UTC</code> on <code>1 January 1970</code>. According to Unix time, each day contains 86400 seconds. The <a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a> standard is based on atomic clock reading, but it also periodically adjusts itself to sync with the earth&#8217;s rotational period.</p><p>As measured in UTC, a day could be longer than 84600 seconds. The speed of the earth&#8217;s rotation slows down gradually over time. Hence an astronomical day can have more than 86400 seconds when measured from an atomic clock.</p><p>To compensate for this drift, UTC has a standard practice. It occasionally adds a <a href="https://en.wikipedia.org/wiki/Leap_second">leap second</a> to UTC time at midnight. The leap second was introduced in 1972. Earth&#8217;s rotation speed also varies in response to climatic and geological events. That is why UTC leap seconds are irregularly spaced and unpredictable.</p><p>When the leap second is added, the UTC time goes from <em>23:59:59</em> to <em>23:59:60</em> and then finally to <em>00:00:00</em>. After accounting for a leap second, a UTC day can be 84600 or 84601 seconds long. Another problem is that there is no way to represent the 60th second that UTC introduces in the Unix time. The Unix time simply repeats the last second to work around this limitation. The Unix time goes from <em>23:59:59</em> to <em>23:59:59</em> and finally to <em>00:00:00</em> to account for a leap second.</p><p>An alternative to adding leap second is to <a href="https://developers.google.com/time/smear">smear</a> it. This technique recommends slowing down the clock for a longer duration instead of adding a second at one moment, such as midnight. For example, imagine that a leap second is announced for December 2022. In this case, we will slow down the clock at <code>2022-12-31 12:00:00 UTC</code> and through <code>2023-01-01 12:00:00 UTC</code>. One advantage of smearing the leap second over a long duration is that it keeps the frequency change small. The change for the smear is about 11.6 ppm. This is within the manufacturing and thermal errors of most machines&#8217; quartz oscillators.</p><p>Unix timestamp is essentially a number such as 1664955216. It is amenable to computers because we can represent it as an unsigned integer. However, it is not easily readable by humans.</p><p>Another common alternative to Unix time is <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>. It was first proposed in 1988 and has been updated several times. It incorporates the elements of the 24-hour clock, a calendar, and a way of describing the timezone offset. For the notation, ISO 8601 uses Arabic numerals and specifically chosen characters such as &#8220;T, W, Z, -, and &#8220;: .&#8221;Such affordances make this representation more human-friendly. The purpose of ISO 8601 is to provide a straightforward method of representing calendar dates and times for global communication. We can convert between ISO 8601 and Unix time using the <a href="https://en.wikipedia.org/wiki/Gregorian_calendar">Georgian calendar</a>.</p><h2>Clock synchronization</h2><p>Most computers don&#8217;t have access to expensive atomic clocks. Instead, they rely on their hardware clocks. These clocks generally use humble tools like a quartz crystal for timekeeping. The operating system implements a system clock using the hardware clock. The software clock is set by the hardware when the system boots. The kernel delivers interrupts at dynamic intervals. It keeps the system clock updated.</p><p>Clock synchronization is an even more challenging problem for distributed systems. A distributed system is a set of computers that communicates by passing messages to each other and do not have access to a central clock. The individual nodes must obtain some common notion of time. No node will agree on the current time if the local clocks drift freely.</p><p>The purpose of designing distributed systems is often to coordinate real-time activities such as running factories, hospitals, and aircraft, recording inventory in databases, maintaining balances in bank accounts, etc. If the system&#8217;s clock is not in sync with the real time, none of these systems can function.</p><h2>Network Time Protocol</h2><p>NTP or Network Time Protocol is a <a href="https://www.youtube.com/watch?v=mAyW-4LeXZo">clock synchronization</a> mechanism. It uses precise GPS receivers and atomic clocks to minimize drift. At this point, NTP is a widely adopted protocol. Most operating system ships with a pre-installed NTP daemon. The computer must connect to a centrally maintained NTP server such as time.apple.com to use it. As per the pre-defined configuration, the NTP daemon polls the time servers regularly to keep their clocks in sync with the network time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eJb8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eJb8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 424w, https://substackcdn.com/image/fetch/$s_!eJb8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 848w, https://substackcdn.com/image/fetch/$s_!eJb8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 1272w, https://substackcdn.com/image/fetch/$s_!eJb8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eJb8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png" width="1306" height="958" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:958,&quot;width&quot;:1306,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;atomic clock&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="atomic clock" title="atomic clock" srcset="https://substackcdn.com/image/fetch/$s_!eJb8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 424w, https://substackcdn.com/image/fetch/$s_!eJb8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 848w, https://substackcdn.com/image/fetch/$s_!eJb8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 1272w, https://substackcdn.com/image/fetch/$s_!eJb8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044a5761-bfe6-4968-8c2e-b90832448cd1_1306x958.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>NTP server setting in MacOS</em></p><p><a href="https://en.wikipedia.org/wiki/Network_Time_Protocol">NTP</a> is a UDP-based protocol. It works by relaying timestamps between different time servers across the globe over a packet-switched network like the internet. NTP organizes time servers in layers. Layer 0 only has the devices that keep the most accurate time, such as expensive atomic clocks and GPS receivers. The servers in layer 1 use layer 0 devices to sync their clocks. The servers in layer 2 use the servers in layer 1, and this goes on. NTP&#8217;s goal is to reduce the clocks skew as much as possible<sup>1</sup>. However, even NTP-enabled servers can skew 100-200 milliseconds in UTC time.</p><p>NTP requires a reliable underlying network to function correctly. If the nodes don&#8217;t have access to sufficient upstream or downstream bandwidth, the clocks might be off. To work around random network delays, NTP clients usually query multiple servers and poll one server multiple times before resetting their clock.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6qhQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6qhQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 424w, https://substackcdn.com/image/fetch/$s_!6qhQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 848w, https://substackcdn.com/image/fetch/$s_!6qhQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 1272w, https://substackcdn.com/image/fetch/$s_!6qhQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6qhQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png" width="1456" height="1301" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1301,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;atomic clock&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="atomic clock" title="atomic clock" srcset="https://substackcdn.com/image/fetch/$s_!6qhQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 424w, https://substackcdn.com/image/fetch/$s_!6qhQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 848w, https://substackcdn.com/image/fetch/$s_!6qhQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 1272w, https://substackcdn.com/image/fetch/$s_!6qhQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd94d52e5-144a-4209-9dd9-ed9c81a96f43_1920x1716.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>NTP server architecture</em></p><p>Notice that there is no way to measure the round-trip latency without having access to a global clock. It means that NTP needs to make a reasonable assumption about the network. It assumes that upstream and downstream network latency is the same<sup>2</sup>.</p><p>After an NTP client receives the network time, it calculates the skew locally. If the local clock is off by too much, then the client patches its current time. If the difference is insignificant, then the client adjusts the local clock rate to ensure that the local clock can catch up with the network time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pr9Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pr9Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 424w, https://substackcdn.com/image/fetch/$s_!pr9Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 848w, https://substackcdn.com/image/fetch/$s_!pr9Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 1272w, https://substackcdn.com/image/fetch/$s_!pr9Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pr9Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png" width="1175" height="1162" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1162,&quot;width&quot;:1175,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;atomic clock&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="atomic clock" title="atomic clock" srcset="https://substackcdn.com/image/fetch/$s_!pr9Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 424w, https://substackcdn.com/image/fetch/$s_!pr9Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 848w, https://substackcdn.com/image/fetch/$s_!pr9Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 1272w, https://substackcdn.com/image/fetch/$s_!pr9Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9942cd-6640-4cc0-932d-6c1f4b1fb214_1175x1162.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>NTP clock skew calculation</em></p><p>Here is another problem. The NTP client can jump to a lower timestamp if the local clock is significantly ahead of the network time. It means that we cannot assume that the timestamps issued in our system are monotonic.</p><p>Operating systems generally give access to a wall clock and a monotonic clock. The wall clock can tell the &#8220;time of the day&#8221; according to the Unix time, but it may jump. The &#8220;monotonic clock&#8221; doesn&#8217;t jump but cannot tell the current time. The monotonic clock returns time passed since an arbitrary point in the past, such as when the machine booted. To calculate the absolute time difference between two instances in a process, use the monotonic clock. The difference between two monotonic clock timestamps on the same device will never be negative<sup>3</sup>. In summary, the wall clock is for telling time, and the monotonic clock is for measuring time.</p><p>Programming languages offer different APIs for monotonic and non-monotonic clocks. For example, in the JVM, the timestamps given by <code>system.currentTimeMillis</code> is not monotonic.</p><p>This takes us back to the Cloudflare outage. <a href="https://github.com/golang/go/issues/12914#issuecomment-277335863">Before</a> <code>Go version 1.9</code>, the <code>time.Now()</code> function didn&#8217;t return a monotonic timestamp. That is why, during a leap second, when Unix time froze for one second, the difference between the two timestamps that were only a few milliseconds apart produced a negative value crashing the application<sup>4</sup>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZT30!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZT30!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 424w, https://substackcdn.com/image/fetch/$s_!ZT30!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 848w, https://substackcdn.com/image/fetch/$s_!ZT30!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 1272w, https://substackcdn.com/image/fetch/$s_!ZT30!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZT30!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png" width="1456" height="538" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:538,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;atomic clock&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="atomic clock" title="atomic clock" srcset="https://substackcdn.com/image/fetch/$s_!ZT30!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 424w, https://substackcdn.com/image/fetch/$s_!ZT30!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 848w, https://substackcdn.com/image/fetch/$s_!ZT30!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 1272w, https://substackcdn.com/image/fetch/$s_!ZT30!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa79bde6d-cc3f-4d6b-bff3-b54a28fe41c2_2848x1052.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Cloudflare DNS outage 2017: root cause</em></p><p>Besides getting access to both astronomical and atomic time, there is another reason to have two different time sources. It makes the system robust. The GPS receivers may have an issue with their antenna, radio interference may block the signal, etc. On the other hand, atomic clocks in the data center may fail in ways uncorrelated to atomic clocks in the GPS satellites and other atomic clocks in different data centers. For example, clocks can significantly drift over long periods due to frequency error.</p><p>NTP works well in practice, but it is not perfect. It has its own set of problems. As we saw, NTP can make the clock jump forward and backward. It makes timestamps non-monotonic. Another issue with the NTP protocol is that it is centralized. The &#8220;network time&#8221; depends on the clocks at the top layer. It makes those clocks in layer 0 a central point of failure. Also, NTP needs a reliable network to function. It cannot reduce the clock drift at a node if it loses the network connection. It may also happen that the NTP client on the node crashes or a firewall accidentally blocks NTP traffic. In such cases, NTP will not work. The system will again suffer from clock skew.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V1t8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V1t8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 424w, https://substackcdn.com/image/fetch/$s_!V1t8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 848w, https://substackcdn.com/image/fetch/$s_!V1t8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 1272w, https://substackcdn.com/image/fetch/$s_!V1t8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V1t8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png" width="1268" height="898" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:898,&quot;width&quot;:1268,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;ntp tweet&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="ntp tweet" title="ntp tweet" srcset="https://substackcdn.com/image/fetch/$s_!V1t8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 424w, https://substackcdn.com/image/fetch/$s_!V1t8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 848w, https://substackcdn.com/image/fetch/$s_!V1t8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 1272w, https://substackcdn.com/image/fetch/$s_!V1t8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F259f8643-a390-4dc8-a7ea-417af850095c_1268x898.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em><a href="https://twitter.com/sadserver">@sadserver</a> on twitter</em></p><h2>TrueTime</h2><p>Google&#8217;s TrueTime provides an order of magnitude improvement in clock synchronization compared to NTP. Similar to NTP, TrueTime uses the same time sources. That is a combination of atomic clocks and GPS clocks. However, organized in a different architecture.</p><p>TrueTime is built using expensive atomic clocks, GPS receivers, low latency data center connections, and extensive network engineering.</p><p>TrueTime timestamps are different. Instead of representing an instance, it represents an interval. This interval is a timestamp with an estimated error margin of calculated real-world time. There is a guarantee that the &#8220;actual&#8221; time must lie within the given interval.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JwCQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JwCQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 424w, https://substackcdn.com/image/fetch/$s_!JwCQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 848w, https://substackcdn.com/image/fetch/$s_!JwCQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 1272w, https://substackcdn.com/image/fetch/$s_!JwCQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JwCQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png" width="1123" height="622" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:622,&quot;width&quot;:1123,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;ntp tweet&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="ntp tweet" title="ntp tweet" srcset="https://substackcdn.com/image/fetch/$s_!JwCQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 424w, https://substackcdn.com/image/fetch/$s_!JwCQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 848w, https://substackcdn.com/image/fetch/$s_!JwCQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 1272w, https://substackcdn.com/image/fetch/$s_!JwCQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca30120-6b32-486c-9f71-25da6858af3d_1123x622.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>TrueTime Timestamp</em></p><p>There are two sources of error or uncertainty in the network clock. First, it could be that a particular node knows its clock is drifting and adjusts for the drift as an error. The second is the unpredictable network latency. Notice that sophisticated engineering efforts can reduce the latter to a certain extent.</p><p>Google ensures that the network latency is minimized by running TureTime entirely on their private <a href="https://en.wikipedia.org/wiki/Wide_area_network">Wide Area Network</a>. That is, it does not rely on other 3rd party internet infrastructure for routing packets because it could be <a href="https://arxiv.org/abs/1409.6526">flaky</a>.</p><p>Google has atomic clocks and GPS receivers in each data center. To synchronize the clocks on every server within the data center TrueTime classify the servers into two categories. The first type of server has access to high-end timekeeping devices. The other servers do not have direct access to these clocks. They use their own hardware clocks. However, they regularly synchronize their local clocks with the time servers within the same or nearby data centers.</p><p>The longer the servers don&#8217;t check in with the time servers, the more uncertain the network time becomes. As soon as the nodes synchronize their clocks with the time server, the uncertainty in TrueTime goes down.</p><p>Google has managed to keep the uncertainty window low by ensuring non-timekeeping nodes sync with the timekeeping nodes every 30 seconds. The worst-case clock skew in NTP is about 100s of milliseconds, whereas TrueTime promises an uncertainty interval of a maximum of 7ms under normal network conditions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XL-3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XL-3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 424w, https://substackcdn.com/image/fetch/$s_!XL-3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 848w, https://substackcdn.com/image/fetch/$s_!XL-3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 1272w, https://substackcdn.com/image/fetch/$s_!XL-3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XL-3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png" width="1456" height="752" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:752,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;ntp tweet&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="ntp tweet" title="ntp tweet" srcset="https://substackcdn.com/image/fetch/$s_!XL-3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 424w, https://substackcdn.com/image/fetch/$s_!XL-3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 848w, https://substackcdn.com/image/fetch/$s_!XL-3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 1272w, https://substackcdn.com/image/fetch/$s_!XL-3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca984ecd-58c8-42f1-a0da-f43a8be86ebb_2122x1096.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Source: Martin Kleppmann&#8217;s Distributed Systems <a href="https://www.youtube.com/playlist?list=PLeKd45zvjcDFUEv_ohr_HdUFe97RItdiB">Lecture Series</a></em></p><p>It is worth noting that TrueTime doesn&#8217;t guarantee the perfect globally synchronized clock. However, timestamps with uncertainty intervals can be as good.</p><p>Take the example of <a href="http://static.googleusercontent.com/media/research.google.com/en/us/archive/spanner-osdi2012.pdf">Google Spanner</a>. It is a highly distributed <a href="https://en.wikipedia.org/wiki/ACID">ACID</a>-compliant database. The Spanner database was the first substantial use case for TrueTime. Using TrueTime timestamps, Spanner can provide transaction isolation (I in &#8220;ACID&#8221;) in the following way.</p><p>If two timestamps do not overlap, Spanner can be sure that the time on one timestamp is, in fact, earlier than the time on the other timestamp across all nodes in the network. However, if they overlap, Spanner pauses for the entire uncertainty interval. Recall that the maximum uncertainty window is only 7ms. Due to the small uncertainty interval, the database can simply wait before committing a new transaction without considerable performance degradation. It ensures that every node in the Spanner network has observed the first transaction before the second without ambiguity.</p><p>A final note about TrueTime is it can suffer from partitions too. Network partitions are not <a href="https://aphyr.com/posts/288-the-network-is-reliable">uncommon</a>. During such an event, TrueTime&#8217;s uncertainty interval increases. It leads to degraded performance in the systems such as Spanner that rely on TrueTime for clock synchronization. However, these systems can still function correctly with a low throughput until the partition heals<sup>5</sup>.</p><h2>Conclusion</h2><p>Computers need access to real physical time for various purposes. Operating systems need to know how long a process has been active for context switching. Databases need to attach a timestamp to the transactions for concurrency control. Applications need access to the current time for logging events and errors for debugging. Applications also need timestamps to record statistics for benchmarking. DNS needs timestamps for renewing the domain mappings. Browsers need to know the current time to validate the TLS certificates. Distributed applications need synchronized time for coordinating real-world activities such as running airplanes, factories, and hospitals.</p><p>We started the post by describing the clock synchronization problem in distributed systems. We examined the differences between atomic and astronomical clocks and the inconsistencies in different time measurement standards. We briefly discussed the definition of the most common standard for timekeeping in computers: UTC and Unix Time.</p><p>Towards the end, we looked at two clock synchronization protocols: NTP and TrueTime. We compared their performance. We also understood the trade-off space for keeping the clocks consistent across the network.</p><h2>Notes</h2><ol><li><p>Clock skew cannot be zero even if there is no drift. It is <a href="https://groups.csail.mit.edu/tds/papers/Lynch/ic84.pdf">proved</a> that in realistic networks, even if the clocks all run at the same rate as real time and there are no failures since there is some uncertainty in the message delivery time, it is impossible to synchronize the clocks.</p></li><li><p>If the upstream and downstream latency is the same, then we can calculate the delays as half of the difference between two timestamps (when clients start a request and when it receives a response from the time server).</p></li><li><p>Note that two monotonic timestamps are not comparable if they come from two different devices.</p></li><li><p>The cause of the error was <code>rand.Int63n()</code> function which <a href="https://pkg.go.dev/math/rand#Int63n">panics</a> if its argument is negative.</p></li><li><p>This observation is in line with Barbara Liskov&#8217;s <a href="https://dl.acm.org/doi/pdf/10.1145/112600.112601">finding</a> that globally synchronized clocks can improve the performance of a distributed system by reducing communication overhead.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[Rollups & Optimism]]></title><description><![CDATA[Exploring rollups on Ethereum]]></description><link>https://www.avichalp.me/p/2022-07-31-rollups-and-optimism</link><guid isPermaLink="false">https://www.avichalp.me/p/2022-07-31-rollups-and-optimism</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sun, 31 Jul 2022 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1cep!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1cep!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1cep!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 424w, https://substackcdn.com/image/fetch/$s_!1cep!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 848w, https://substackcdn.com/image/fetch/$s_!1cep!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!1cep!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1cep!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png" width="1217" height="1104" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1104,&quot;width&quot;:1217,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;rollup&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="rollup" title="rollup" srcset="https://substackcdn.com/image/fetch/$s_!1cep!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 424w, https://substackcdn.com/image/fetch/$s_!1cep!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 848w, https://substackcdn.com/image/fetch/$s_!1cep!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!1cep!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa18e775c-e640-4b1e-aff2-be0f0e7006df_1217x1104.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Optimistic Rollup Architecture</em></p><p>Optimistic Rollups sound too good to be true. Without compromising security guarantees, an ORU could scale transactions on a blockchain. It can increase the chain&#8217;s throughput by leveraging fraud proofs and off-chain computation.</p><p>The supply and demand of <a href="https://www.aniccaresearch.tech/blog/ethereum-blockspace-who-gets-what-and-why">blockspace</a> determine the transaction fee for using a permissionless blockchain. Since blockspace is scarce, whales often outbid others. It means that Ethereum could price out many of its most loyal users at a time of high traffic.</p><p>By compressing the computation, rollups can fit more transactions in the same number of blocks, reducing congestion and making the blockchain more <a href="https://medium.com/@adlerjohn/the-why-s-of-optimistic-rollup-7c6a22cbb61a">affordable</a>.</p><p>Optimism implements the generic idea of an <a href="https://research.paradigm.xyz/rollups">optimistic rollup</a> on Ethereum. In this post, we will look at basic primitives underlying the Optimistic Rollup design and zoom in on the core components of Optimism&#8217;s architecture.</p><h2>Layer 2 Alternatives</h2><p>Since the early days of Ethereum, it was clear that 13-second <a href="https://ycharts.com/indicators/ethereum_average_block_time">block time</a> is slow. Adjusting parameters such as block size (or block gas limit) only can, at best, be a short-term solution.</p><p>Before the Ethereum community aligned itself towards a rollup-centric <a href="https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698">roadmap</a>, they explored various solutions in parallel. Most notably <a href="https://ethereum.org/en/developers/docs/scaling/state-channels/">state channels</a>, side chains, and <a href="https://haseebq.com/the-life-and-death-of-plasma/">plasma</a>. Compared to rollups, all of them come with certain limitations.</p><p>A state channel is like a bar tab. Two parties can make countless transactions with each other offline. Only the last one, where one party wants to exit, must settle on-chain. It works well for micro-transactions, for example, <a href="https://filecoin.io/blog/posts/how-storage-and-retrieval-deals-work-on-filecoin/#the-retrieval-deal-flow">incrementally</a> paying a storage service to retrieve a large file.</p><p>In a State Channel, only a fixed set of parties could transact. New parties cannot be added to the existing channels. Also, for many use cases, it requires high upfront capital.</p><p>A side chain is an independent blockchain that routinely checkpoints with the main chain. The side chain is responsible for its own security and hence doesn&#8217;t benefit from the already established security faculty of the base chain. This begs the question, how censorship-resistant could a side chain be?</p><p>Plasma has a dynamic set of transactors and doesn&#8217;t need upfront capital. It is like a side chain that is anchored within Ethereum. Still, it doesn&#8217;t inherit the security from the base chain. It is not fully censorship-resistant.</p><p>Moreover, channels, side chains, and plasma do not guarantee data availability<sup>1</sup>. These solutions put the burden of security in the users&#8217; own hands. Plasma and State Channels require users to store their transaction history. If the system cheats, the user should be able to produce evidence to the main chain to settle the dispute. Side Chains rely on their own validators for security. In a nutshell, state channels are not general-purpose, and plasma and side chains are not secure enough.</p><h2>Rollups Overview</h2><p><a href="https://vitalik.ca/general/2021/01/05/rollup.html">Rollups</a> are at a sweet spot in the scalability versus security trade-off space. It can inherit the security of the main chain. Intuitively, a rollup is an ordered mempool (an ordered set of transactions) combined with a general-purpose virtual machine. Any computation that EVM can execute, a rollup can run it too.</p><p>There are two varieties of Rollups: optimistic rollups and ZK rollups. As the name suggests, ZK rollups are built using <a href="https://medium.com/matter-labs/optimistic-vs-zk-rollup-deep-dive-ea141e71e075">Zero-Knowledge magic</a>. Covering them is beyond the scope of this post.</p><p>On the other hand, Optimistic Rollups only require implementing the challenge verification game. It builds upon two assumptions.</p><ol><li><p>At least one node verifies the computation that the sequencer executes (1:N <a href="https://vitalik.ca/general/2020/08/20/trust.html">trust model</a>). In case of a dispute, the verifier generates a fraud-proof.<sup>2</sup></p></li><li><p>The underlying blockchain is secure and decentralized. That means it is resistant to censorship and block reorganizations.</p></li></ol><p>Traditional side chains are independent blockchains but commit the block hashes to the main chain. A rollup is a blockchain that is tightly <a href="https://ethresear.ch/t/minimal-viable-merged-consensus/5617">coupled</a> with its main chain. A valid rollup block eventually ends up on the main chain as long as it is not under a <a href="https://en.wikipedia.org/wiki/Sybil_attack">Sybil attack</a>.</p><p>Rollups publish the block data on-chain, but transactions remain unverified for some time (a trial window, for example, 2 weeks). During this time, blocks are <a href="https://vitalik.ca/general/2019/08/28/hybrid_layer_2.html">tentatively</a> accepted.</p><p>The sequencer &#8220;rolls up&#8221; the computation required to execute transactions and publishes their results on-chain. The overall throughput increases because every other node on the main chain doesn&#8217;t have to re-execute the unrolled transactions to verify it.</p><p>A tentative block is up for a challenge by an independent verifier. If the challenger could prove, within the trial window, that a particular block is indeed invalid, it will earn a bounty<sup>3</sup>. At the same time, the sequencer (block producer) has to pay the penalty.</p><p>Unlike the other layer 2 solutions, rollups publish the entire transaction data on-chain to ensure &#8220;data availability&#8221;. Storing raw data on the blockchain is cheaper than performing computation over that data. Optimistic Rollup implementation such as Optimism and Arbitrum optimally <a href="https://medium.com/ethereum-optimism/the-road-to-sub-dollar-transactions-part-2-compression-edition-6bb2890e3e92">compresses</a> the transaction data, so they don&#8217;t have to overpay for L1 gas.</p><h2>Bridging</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!quzj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!quzj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 424w, https://substackcdn.com/image/fetch/$s_!quzj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 848w, https://substackcdn.com/image/fetch/$s_!quzj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 1272w, https://substackcdn.com/image/fetch/$s_!quzj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!quzj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png" width="561" height="811" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:811,&quot;width&quot;:561,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;bridging example&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="bridging example" title="bridging example" srcset="https://substackcdn.com/image/fetch/$s_!quzj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 424w, https://substackcdn.com/image/fetch/$s_!quzj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 848w, https://substackcdn.com/image/fetch/$s_!quzj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 1272w, https://substackcdn.com/image/fetch/$s_!quzj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75f026c3-8b68-4794-95e7-43fc6584c8a1_561x811.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>SOL tokens in Uniswap on Ethereum</em></p><p>A rollup has a separate blockchain. It is important to note that most users only care about applications and their assets. A rollup is only helpful if it seamlessly interoperates with the underlying chain. An end-user should be able to bring their assets to the rollup chain and withdraw back to the main chain. The rollup and the application deployed on it should support common uses like lending, borrowing, trading assets, voting on proposals, etc.</p><p>In the context of blockchains, bridging means locking up an asset on one side and then minting a proxy representation on the other. The proxy token can trade on the other blockchain like any other token and remains redeemable for the original asset. For example, the <a href="https://wormholenetwork.com/">Wormhole</a> bridge between Ethereum and Solana enables defi users to trade a representation of the Solana token with any other Ethereum based token on Uniswap.</p><p>The security of cross-chain bridges is a <a href="https://old.reddit.com/r/ethereum/comments/rwojtk/ama_we_are_the_efs_research_team_pt_7_07_january/hrngyk8/">complicated</a> matter on its own. It is well known that the current bridge architectures are <a href="https://www.reuters.com/technology/white-hat-hacker-has-returned-nearly-all-600-million-crypto-tokens-taken-tuesday-2021-08-12/">not</a> <a href="https://twitter.com/samczsun/status/1489044939732406275?s=20&amp;t=FmUfVpKSviWAHsFnWO_OtQ">secure</a> enough relative to the money they carry. Unlike cross-chain L1 to L1 bridging, L1 to Rollup bridging is safe against issues related to consensus because of shared security. However, users are still vulnerable to the risks associated with execution while bridging their assets from L1 to a Rollup.</p><h2>Million Dollar Bug Bounty</h2><p>In February 2022, Saurik <a href="https://www.saurik.com/optimism.html">uncovered</a> a critical bug in Optimism&#8217;s execution environment (OVM). Which led to a well-deserved bug bounty of more than $2m! This bug would have allowed a malicious hacker to print an unlimited amount of &#8220;bridged&#8221; Ethereum tokens (OETH). Fortunately, it was never exploited.</p><p>One of the reasons why this bug was lurking in the system was that Optimism&#8217;s execution environment was not <a href="https://github.com/ethereum-optimism/optimism/issues/2604#issuecomment-1135493017">fully</a> compatible with Ethereum&#8217;s. This event motivated the team to double down EVM equivalence. Since then Optimism team has addressed the issue. It will be deployed in their latest bedrock release.</p><h2>EVM Equivalence</h2><p>The execution layer is the core of a rollup. Rollups can scale transactions because it relaxes the requirement of every network participant having to run each piece of computation. Instead, it allows a dedicated node (the sequencer) to execute transactions and create a proof. Every node in the network can verify that the block producer is not cheating. Also, a rollup must submit all the transaction data on-chain. If the sequencer disappears, another node can take over.</p><p>Notice that Ethereum doesn&#8217;t require that rollup&#8217;s execution environment comply with the EVM. The only requirement is that the Rollups post the compressed transaction data on the chain. However, the sequencer can execute code in any programming language or VM if it produces the required chunk of bytes.</p><p><a href="https://docs.fuel.sh/v1.1.0/Concepts/Fundamentals/Fuel%20Overview.html">Fuel</a> is a perfect example. Similar to Optimism and <a href="https://arbitrum.io/">Arbitrum</a>, it is an Optimistic rollup. However, it has its own VM that can execute transactions in parallel. Offers a UTXO-based transaction model similar to bitcoin. Provides a Rust-inspired programming language called <a href="https://github.com/FuelLabs/sway">Sway</a> that promises a safer contract development method.</p><p>With that said, we can now turn to the numerous benefits that EVM equivalence offers. It can prevent compatibility-related bugs like the one described above. Also, EVM equivalence can offer a better developer experience in different ways.</p><p>Contract developers can reuse their existing code. They don&#8217;t have to re-write their applications from scratch while migrating from Ethereum to Optimism. While doing so, they also gain access to many mature Solidity or <a href="https://github.com/vyperlang/vyper">Vyper</a> focussed <a href="https://github.com/crytic/slither">tools</a>, <a href="https://github.com/ethers-io/ethers.js/">libraries</a>, and <a href="https://github.com/foundry-rs/foundry">frameworks</a>.</p><p>In recent years the security community has developed a set of best practices for auditing solidity-based contracts. It is hard to find reputed auditors to review the solidity code. With an unfamiliar language, it is going to be even more complicated.</p><h2>Optimism Architecture</h2><p>We don&#8217;t need to go into tiny details at this point. In the following paragraphs, we will examine a few essential components of Optimism&#8217;s architecture. That should be enough to understand the whole system at a higher level.</p><h3>Canonical Transaction Chain</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mK1v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mK1v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 424w, https://substackcdn.com/image/fetch/$s_!mK1v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 848w, https://substackcdn.com/image/fetch/$s_!mK1v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 1272w, https://substackcdn.com/image/fetch/$s_!mK1v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mK1v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png" width="1246" height="830" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:830,&quot;width&quot;:1246,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mK1v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 424w, https://substackcdn.com/image/fetch/$s_!mK1v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 848w, https://substackcdn.com/image/fetch/$s_!mK1v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 1272w, https://substackcdn.com/image/fetch/$s_!mK1v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a0ec8d3-d34d-4d50-a632-762b565e079d_1246x830.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The CTC is a contract on Ethereum L1. It contains an append-only log of transactions (the L2 blockchain) ready to be applied to the current L2 state.</p><p>It includes two important data structures (queue and batches) and two methods (enqueue and appendSequencerBatch) we should zoom in on.</p><h4>enqueue:</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!a_oW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!a_oW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 424w, https://substackcdn.com/image/fetch/$s_!a_oW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 848w, https://substackcdn.com/image/fetch/$s_!a_oW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 1272w, https://substackcdn.com/image/fetch/$s_!a_oW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!a_oW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png" width="1456" height="817" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:817,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;CTC&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="CTC" title="CTC" srcset="https://substackcdn.com/image/fetch/$s_!a_oW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 424w, https://substackcdn.com/image/fetch/$s_!a_oW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 848w, https://substackcdn.com/image/fetch/$s_!a_oW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 1272w, https://substackcdn.com/image/fetch/$s_!a_oW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f74aaf7-1843-4a89-bbb6-4704926e24bf_1494x838.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Canonical Transaction Chain contract</em></p><p>As the name suggests, this method adds transactions to the queue. These transactions are not batched yet. There is no restriction on who calls this it. If the transaction is enqueued, the sequencer is bound to roll it up.</p><p>There is a possibility that the sequencer could become malicious. It may start to censor users&#8217; transactions. In such a scenario, a user can force the sequencer to include their transaction by directly adding it to the queue.</p><p>However, we should note that when the sequencer adds transactions to the queue, an individual user only pays the amortized gas cost. If an individual directly adds a transaction to the queue, it will be as expensive as an ordinary L1 transaction.</p><h4>appendSequencerBatch:</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GQFS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GQFS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 424w, https://substackcdn.com/image/fetch/$s_!GQFS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 848w, https://substackcdn.com/image/fetch/$s_!GQFS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 1272w, https://substackcdn.com/image/fetch/$s_!GQFS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GQFS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png" width="1456" height="650" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:650,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;appendSequencerBatch&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="appendSequencerBatch" title="appendSequencerBatch" srcset="https://substackcdn.com/image/fetch/$s_!GQFS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 424w, https://substackcdn.com/image/fetch/$s_!GQFS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 848w, https://substackcdn.com/image/fetch/$s_!GQFS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 1272w, https://substackcdn.com/image/fetch/$s_!GQFS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa05fee62-809f-4e6e-bbd7-ed34ebe646b2_1912x854.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>appendSequencerBatch method</em></p><p>The appendSequencerBatch method picks up transactions from the queue and rolls them up into a batch. The batches data structure is a ring buffer that defines the order of the transactions. Under the hood, the <a href="https://github.com/ethereum-optimism/optimism/blob/master/packages/contracts/contracts/L1/rollup/ChainStorageContainer.sol">ChainStorageContainer</a> library implements it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sTh2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sTh2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 424w, https://substackcdn.com/image/fetch/$s_!sTh2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 848w, https://substackcdn.com/image/fetch/$s_!sTh2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 1272w, https://substackcdn.com/image/fetch/$s_!sTh2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sTh2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png" width="1456" height="704" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2850717a-98a5-4684-87e9-e4a853840134_1494x722.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:704,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;CTC&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="CTC" title="CTC" srcset="https://substackcdn.com/image/fetch/$s_!sTh2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 424w, https://substackcdn.com/image/fetch/$s_!sTh2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 848w, https://substackcdn.com/image/fetch/$s_!sTh2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 1272w, https://substackcdn.com/image/fetch/$s_!sTh2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2850717a-98a5-4684-87e9-e4a853840134_1494x722.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Only the sequencer can call appendSequencerBatch</em></p><p>Only the sequencer can call this function. Once a transaction is batched, it will eventually be included in the blockchain. However, at this point, it is only tentative. It is not safe to consider it <em>final</em> until the challenge period is over.</p><h3>Data Transport Layer Service</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R9hf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R9hf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 424w, https://substackcdn.com/image/fetch/$s_!R9hf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 848w, https://substackcdn.com/image/fetch/$s_!R9hf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!R9hf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!R9hf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png" width="1372" height="1524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1524,&quot;width&quot;:1372,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DTL&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DTL" title="DTL" srcset="https://substackcdn.com/image/fetch/$s_!R9hf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 424w, https://substackcdn.com/image/fetch/$s_!R9hf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 848w, https://substackcdn.com/image/fetch/$s_!R9hf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!R9hf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9792cd41-f139-4ad5-b7e6-d20e50cafc6b_1372x1524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Data Transport Layer</em></p><p><a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/data-transport-layer">Data Transport Layer</a> is a typescript service that runs within the Optimism node. Ethereum nodes download new blocks from the peer-to-peer network. In the case of Optimism, the DLT service monitors Optimism&#8217;s L1 contracts to download new blocks.</p><p>When the DTL detects a new relevant event on the L1 blockchain, it downloads the corresponding transactions. It inspects these transactions to reconstruct the blocks in the standard Ethereum block <a href="https://ethereum.org/en/developers/docs/blocks/#block-anatomy">format</a>.</p><p>The L2 blocks are stored in the DTL&#8217;s database and exposed via HTTP APIs. sequencers and verifiers can download these blocks and proceed with the execution. After executing, the sequencer proposes the new state by adding it to the SCC contract. If the verifier finds the computation incorrect, it creates a fraud-proof.</p><h3>SCC</h3><p>The State Commitment Chain (SCC) is an L1 contract. It contains a list of proposed state roots called batches. Similar to batches in CTC, it is implemented using the ChainStorageContainer.</p><p>The batch elements here have a 1:1 correspondence with transactions in the CTC. Each one represents a unique state root. Each state root results from the sequencer applying the canonical transactions one by one over the last batch element.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Yj0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Yj0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 424w, https://substackcdn.com/image/fetch/$s_!1Yj0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 848w, https://substackcdn.com/image/fetch/$s_!1Yj0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 1272w, https://substackcdn.com/image/fetch/$s_!1Yj0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Yj0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png" width="1239" height="528" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:528,&quot;width&quot;:1239,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;SCC&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="SCC" title="SCC" srcset="https://substackcdn.com/image/fetch/$s_!1Yj0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 424w, https://substackcdn.com/image/fetch/$s_!1Yj0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 848w, https://substackcdn.com/image/fetch/$s_!1Yj0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 1272w, https://substackcdn.com/image/fetch/$s_!1Yj0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8525a982-d09d-444a-87ab-6f8d89a4cec1_1239x528.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>State roots and Transaction batches</em></p><p>There are three essential methods in SCC.</p><h4>appendStateBatch:</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HfLX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HfLX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 424w, https://substackcdn.com/image/fetch/$s_!HfLX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 848w, https://substackcdn.com/image/fetch/$s_!HfLX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 1272w, https://substackcdn.com/image/fetch/$s_!HfLX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HfLX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png" width="1456" height="434" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:434,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;SCC&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="SCC" title="SCC" srcset="https://substackcdn.com/image/fetch/$s_!HfLX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 424w, https://substackcdn.com/image/fetch/$s_!HfLX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 848w, https://substackcdn.com/image/fetch/$s_!HfLX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 1272w, https://substackcdn.com/image/fetch/$s_!HfLX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7dd489f-4a42-4129-b94a-a1ba4fef27d6_2132x636.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>appendStateBatch method</em></p><p>Anyone can enqueue a transaction in CTC, but only the sequencer can propose a state root in SCC by calling this function. The sequencer asserts that the proposed state root is correct by appending a new state batch.</p><h4>deleteStateBatch:</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j-Eb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j-Eb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 424w, https://substackcdn.com/image/fetch/$s_!j-Eb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 848w, https://substackcdn.com/image/fetch/$s_!j-Eb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 1272w, https://substackcdn.com/image/fetch/$s_!j-Eb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j-Eb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png" width="1456" height="484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:484,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;SCC&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="SCC" title="SCC" srcset="https://substackcdn.com/image/fetch/$s_!j-Eb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 424w, https://substackcdn.com/image/fetch/$s_!j-Eb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 848w, https://substackcdn.com/image/fetch/$s_!j-Eb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 1272w, https://substackcdn.com/image/fetch/$s_!j-Eb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b7018ad-fb12-4acb-bb74-a15d31c1fe6a_1920x638.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>deleteStateBatch method</em></p><p>Transactions enqueued in the CTC are valid Ethereum transactions. A sequencer can only cheat by proposing an <em>inconsistent</em> state root (for example, the one where they reward themselves $1B). In that case, a verifier can detect fraud by independently executing the transactions.</p><p>If the verifier finds and proves the fault within the challenge window, it can delete the faulty state by calling this function.</p><p>The verifier gets a bounty for its service, and the sequencer incurs a penalty for attempting to cheat. The Sequences eventually proposes new batches to replace the deleted state roots.</p><p>Notice that the CTC batch doesn&#8217;t roll back even after the verifier deletes the corresponding SCC batch. The fault proving-verification game doesn&#8217;t alter the order of transactions in CTC.</p><h4>verifyStateCommitment:</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uMAU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uMAU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 424w, https://substackcdn.com/image/fetch/$s_!uMAU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 848w, https://substackcdn.com/image/fetch/$s_!uMAU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 1272w, https://substackcdn.com/image/fetch/$s_!uMAU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uMAU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png" width="1456" height="633" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:633,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;SCC&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="SCC" title="SCC" srcset="https://substackcdn.com/image/fetch/$s_!uMAU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 424w, https://substackcdn.com/image/fetch/$s_!uMAU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 848w, https://substackcdn.com/image/fetch/$s_!uMAU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 1272w, https://substackcdn.com/image/fetch/$s_!uMAU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a02e59-f246-4bd0-9338-015000b4407a_1954x850.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>verifyStateCommitment method</em></p><p>Batches in the SCC finalize if they remain unchallenged until the end of the challenge period. This function doesn&#8217;t change the state. It only returns true or false. With the given state batch and a <a href="https://en.wikipedia.org/wiki/Merkle_tree">Merkle</a> proof, this function verifies the inclusion of a transaction. Any contract on Ethereum can call it to determine the status of any transaction on Optimism.</p><h3>Standard Bridge</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BsBF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BsBF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 424w, https://substackcdn.com/image/fetch/$s_!BsBF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 848w, https://substackcdn.com/image/fetch/$s_!BsBF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 1272w, https://substackcdn.com/image/fetch/$s_!BsBF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BsBF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png" width="1281" height="1026" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1026,&quot;width&quot;:1281,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Standard Bridge&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Standard Bridge" title="Standard Bridge" srcset="https://substackcdn.com/image/fetch/$s_!BsBF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 424w, https://substackcdn.com/image/fetch/$s_!BsBF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 848w, https://substackcdn.com/image/fetch/$s_!BsBF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 1272w, https://substackcdn.com/image/fetch/$s_!BsBF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7e30d03-e23c-4c7c-959f-f96eb89bcdbe_1281x1026.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Optimism&#8217;s Standard Bridging Protocol</em></p><p>Optimism&#8217;s bridge <a href="https://review.mirror.xyz/-Pjf5ss6cAWdy5J7i6VigzMbiSWU3Lllw6y-FV2c6k4">protocol</a> has two central contracts: <a href="https://github.com/ethereum-optimism/optimism/blob/master/packages/contracts/contracts/L1/messaging/L1StandardBridge.sol">Layer1StandardBridge</a> and <a href="https://github.com/ethereum-optimism/optimism/blob/master/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol">Layer2StandardBridge</a>. The Standard Bridge contracts connect L1 and L2 applications. It is possible to deploy your own bridge. However, Optimism&#8217;s bridging protocol provides a standard way of passing messages and assets around. Developers can make asynchronous calls between the two layers. It is worth noting that safely relaying a message from L2 to L1 takes at least 7-14 days (challenge period).</p><h2>Known Issues, Criticisms, and Caveats</h2><p>Until now, in this post, we looked at all the benefits that rollups provide. How it can meaningfully increase the throughput of a blockchain without compromising on security. Rollups will play a significant role in making blockchains ready for mainstream adoption. However, in engineering, there are no benefits without inherent cost. This section will look at common issues related to rollups.</p><p>The first and most obvious criticism is a high withdrawal time. Withdrawing tokens from an optimistic rollup back to the main chain takes a long time. The 7-14 day withdrawal time is due to the challenge period. The challenge verification game is inherent to the security of an optimistic protocol. Unfortunately, there is no way around it.</p><p>Optimistic rollups treat the underlying blockchain as a court. The layer one chain doesn&#8217;t have to execute undisputed transactions. It only has to run the disputed ones. The challenge period is crucial because we want network participants to have enough time to gather evidence against the misbehaving sequencer. We want the verifiers to catch a sequencer trying to sneak in an invalid final state.</p><p>There also exist cross-rollup <a href="https://help.hop.exchange/hc/en-us/articles/4405172445197-What-is-Hop-Protocol-">bridges</a>. These protocols can significantly reduce users&#8217; withdrawal time without risking their funds. In essence, these bridges use money markets to provide an early withdrawal to a user. In exchange, the user gives the bridge the right to withdraw their original tokens. The bridging protocol takes a small fee for its service. It is worth highlighting that ZK rollups don&#8217;t suffer from this limitation. Since ZK rollups rely on <a href="https://medium.com/starkware/validity-proofs-vs-fraud-proofs-4ef8b4d3d87a">validity</a> <a href="https://medium.com/starkware/validity-proofs-vs-fraud-proofs-strike-back-4d0bf90eed15">proofs</a> instead of fraud proofs, there is no challenge verification game and hence no challenge period.</p><p>Rollups are not secure against the base chain re-orgs. Such attacks undermine the security of the underlying blockchain. In such an event, there is no guarantee of a canonical transaction ordering. As we saw earlier, rollups (and layer 2 in general) rely on the base layer being secure against chain reorganizations. Economic security is the most crucial feature of a blockchain. Trying to scale an insecure chain is putting more funds at risk.</p><p>There are some <a href="https://twitter.com/bkiepuszewski/status/1540793357680517121?s=20&amp;t=KLALPAtICpMKFcQ_14vssA">concerns</a> regarding the centralization of sequencers. Currently, most rollups, including Optimism, Arbitrum, StarkNet, etc., have a centralized sequencer. It is worth emphasizing that a centralized sequencer cannot censor its user. As we saw, users can force the rollup to include their transactions. <a href="https://en.wikipedia.org/wiki/Liveness">Liveness</a> remains an issue until rollups move to an architecture with a decentralized sequencer. The centralized sequencer may go down, and a new one may not come online in time. In such cases, the L2 blockchain will stall. A centralized sequencer also gains exclusive access to the <a href="https://research.paradigm.xyz/MEV">MEV</a>. Other network participants may not consider it fair.</p><p>A relatively uncommon but relevant concern is rollup token incentive design. Optimism charges its user a gas fee in ETH tokens. However, one can imagine a rollup implementation that uses its own token for execution fee payment. Such an implementation will increase the transaction throughput on the underlying chain and hence deserves revenue.</p><p>At the same, its token may compete with the native asset of the layer 1 chain. Such an incentive design could be parasitic to the layer 1 chain. Increased demand for layer 2 tokens in the free market could come at the cost of the L1 native token. This can, in turn, lead to reduced security of a proof of stake-based layer one chain.</p><p>There are a couple of UX-related criticisms. For instance, bridging to a different network adds friction to the user flow. Moving tokens to layer 2 could be tedious to users who are used to a smooth 1-click user experience. Also, unlike ZK rollups, optimistic rollups don&#8217;t add any feature to enhance transaction privacy. ZK rollups can give privacy as a side effect together with increased throughput.</p><h2>Conclusion</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l0l2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l0l2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 424w, https://substackcdn.com/image/fetch/$s_!l0l2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 848w, https://substackcdn.com/image/fetch/$s_!l0l2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 1272w, https://substackcdn.com/image/fetch/$s_!l0l2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l0l2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png" width="1195" height="458" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:458,&quot;width&quot;:1195,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Optimism-gas-fee&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Optimism-gas-fee" title="Optimism-gas-fee" srcset="https://substackcdn.com/image/fetch/$s_!l0l2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 424w, https://substackcdn.com/image/fetch/$s_!l0l2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 848w, https://substackcdn.com/image/fetch/$s_!l0l2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 1272w, https://substackcdn.com/image/fetch/$s_!l0l2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36eff938-64f8-41e2-a2ac-22a2ad8dbf9f_1195x458.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Gas Fee on Optimism for Uniswap trades and ETH transfers</em></p><p>We started this post by highlighting the supply constraints on the blockspace. We looked at various layer 2 solutions that we have in our toolbox. We briefly went through the security and decentralization properties of each of them. We also analyzed the trade-offs these solutions make to provide higher scalability.</p><p>Then we narrowed our focus to Rollups and further narrowed it down to the optimistic variant. We understood the core primitive that optimistic rollups are built on. That is the Fraud proofs and the challenge-verification game between the centralized layer 2 block producer and the independent transaction verifiers.</p><p>We briefly looked at what bridging means in the context of blockchains. We also pointed out how Optimism got lucky regarding a critical vulnerability. A compatibility issue between Optimism&#8217;s execution environment and the EVM led to a counterfeiting bug. Fortunately, before this vulnerability could be exploited, a whitehat hacker jumped in to save the day. We evaluated Optimism&#8217;s decision to pursue EVM equivalence instead of building a new execution environment from scratch.</p><p>Towards the end, we zoomed in on a few components in Optimism&#8217;s architecture. We saw how different contracts and RPC services interact with each other to implement the complex optimistic rollup design. Finally, we ended the post by looking at some known concerns and caveats related to rollups.</p><h2>Notes</h2><ol><li><p>Data Availability is one of the most notorious <a href="https://www.youtube.com/watch?v=OJT_fR7wexw">problems</a> in the blockchain space. It is hard to describe it as a side note. The description deserves an entire post. In summary, it entails preventing attacks where some network participants withhold transaction data to fool participants that don&#8217;t keep the whole history of the chain.</p></li><li><p><a href="https://medium.com/offchainlabs/the-cheater-checking-problem-why-the-verifiers-dilemma-is-harder-than-you-think-9c7156505ca1">Verifier&#8217;s Dilemma</a>: There is a monetary incentive for independently verifying the rollup computation. However, suppose every network participant thinks that someone else will be vigilant because there is an incentive, and no one actually is. In that case, a malicious sequencer will be able to steal money. Optimistic Rollups are safe if there is at least an independent verifier.</p></li><li><p>A poorly implemented bounty mechanism could cause a security issue. For example, consider this scenario. The sequencer posts a 50 ETH bond upfront to earn the right to produce blocks. Then the sequencer publishes a fraudulent state, and a verifier notices it and publishes a dispute. If successful, the protocol will take away 50ETH from the Sequence&#8217;s bond and give it to the verifier. In this case, the sequencer can front run the verifier by publishing a dispute, disputing himself. By doing so, the sequencer can get back its initial capital.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[Core Async Essentials]]></title><description><![CDATA[Exploring core async channels]]></description><link>https://www.avichalp.me/p/2020-06-30-core-async-essentials</link><guid isPermaLink="false">https://www.avichalp.me/p/2020-06-30-core-async-essentials</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Tue, 30 Jun 2020 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Wp5K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>INTRODUCTION</h3><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wp5K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wp5K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!Wp5K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!Wp5K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!Wp5K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wp5K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png" width="1200" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wp5K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!Wp5K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!Wp5K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!Wp5K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bb7e495-8a98-4570-867b-90aa58727806_1200x600.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Core Async is a Clojure/Script library for async programming. Tony Hoare&#8217;s Communicating Sequential Processes <sup>1</sup> was influential in its development. It is a tool to model concurrent (not parallel) tasks. Parallel tasks are independent of each other; that is, they do not require coordination. They can be modelled deterministically and executed simultaneously. Concurrent tasks, on the other hand, require coordination among workers <sup>2</sup>.</p><p>Workers are, in the core async context, either producers or consumers. On JVM, these are actual threads or lightweight, cooperatively scheduled threads called <em>go blocks</em> <sup>3</sup>. In single-threaded environments such as <code>nodejs</code> or the browser, <code>go</code> blocks are the only choice for workers. <code>Go</code> blocks are scheduled on a fixed-size thread pool. By default, the <a href="https://github.com/clojure/core.async/blob/91e132b8ffa90af9eaa21d8e5c4e78369fdfea1a/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L16-L20">size of this thread pool is 8</a>.</p><p>The golden rule of async programming is: <strong>never block the event loop</strong>. While working with <code>go</code> blocks, make sure they are free of blocking operations. A blocking operation in a <code>go</code> block will block the underlying executor<sup>4</sup>.</p><p>A worker has to wait if the producing or consuming operation is pending. You can choose to implement this wait as <em>blocking</em> or <em>parking</em>. The only way these workers continue execution is when the worker, on the other end, completes a pending operation.</p><h3>ANATOMY OF A CHANNEL</h3><div><hr></div><p>A channel in core async is like a baggage carousel at the airport. Travellers are the consumer, and airline staff are the producers. If the carousel is full, the staff cannot put any more bags on it. They have to wait until some travellers take their stuff out. If the carousel is empty, the passenger cannot take their baggage. They have to wait for the bags to arrive. Channel, like the carousel, acts as a rendezvous point between the producers and the consumers. Data put on the channel is added to its buffer. Size of the buffer is customizable, but <strong>unbounded buffers are not allowed</strong>.</p><p>Internally a channel maintains three queues. The <code>puts</code> and <code>takes</code> to enqueue all pending put and take operations. And the buffer to hold the data. The put and the take operations use a channel level mutex to make these operations thread-safe. Both <code>put!</code> and <code>take!</code> functions accepts a (callback) handler. It runs when these operations complete. When they complete immediately, then the handler runs on the same thread. Otherwise, it executes asynchronously.</p><h3>PUT OPERATION</h3><div><hr></div><p><strong>A put operation on the channel completes immediately when there is a pending take operation waiting on the other end or when there is capacity in the buffer.</strong> Otherwise, the put operation has to wait in the <code>puts</code> queue. An unbuffered (same as a buffer of size 0) channel can queue <a href="https://github.com/clojure/core.async/blob/33eca77c4a5c38a04e4c0e692c51bbff12200448/src/main/clojure/cljs/core/async/impl/channels.cljs#L86">only </a><code>MAX-QUEUE-SIZE</code><a href="https://github.com/clojure/core.async/blob/33eca77c4a5c38a04e4c0e692c51bbff12200448/src/main/clojure/cljs/core/async/impl/channels.cljs#L86"> put operations</a>. The default value of <code>MAX-QUEUE-SIZE</code> is 1024.</p><pre><code><code>(require '[cljs.core.async :as a]
&#9;&#9;  '[cljs.pprint :as pprint])


;; to inspect a channel
(defn inspect-unbuffered-channel
  [ch]
&#9;(pprint/print-table
&#9;  [{:pending-puts  (-&gt; ch .-puts .-length)
&#9;&#9;:pending-takes (-&gt; ch .-takes .-length)}]))


;; putting 1025 items in the channel
(let [ch (a/chan)]
  (dotimes [i 1025] ; &lt;== make it 1024 to fix the ERROR
&#9;(a/put! ch i))
&#9;(inspect-unbuffered-channel ch))

</code></code></pre><p>Exceeding this limit leads to an exception when the channel uses the default, fixed-size buffer. This Behaviour is, of course, customizable. For example, a Sliding or a Dropping buffers drops the data upon reaching the limit.</p><p>For a channel with a buffer of size 1, we can put 1025 values.</p><pre><code><code>;; to inspect channel and its buffer
(defn inspect-buffered-channel
&#9;[ch]
&#9;(pprint/print-table
&#9; [{:pending-puts  (-&gt; ch .-puts .-length)
&#9;   :pending-takes (-&gt; ch .-takes .-length)
&#9;   :buf-size      (-&gt; ch .-buf .-n)
&#9;   :buf-items     (-&gt; ch .-buf .-buf .-length)}]))


(let [ch-with-buf-1 (a/chan 1)]

  (prn "The first put!")
  (a/put! ch-with-buf-1 :something-useless)
  (inspect-buffered-channel ch-with-buf-1)

  (prn "More puts")
  (dotimes [i 1024] ; &lt;== Make it 1025 to CRASH
&#9;(a/put! ch-with-buf-1 i))
  (inspect-buffered-channel ch-with-buf-1))
</code></code></pre><p>The first <code>put!</code> completes immediately filling up the buffer of size 1. The rest 1024 put operations get queued. Adding one more pending <code>put!</code> will lead to an overflow.</p><p>A summary of different <code>put!</code> scenarios.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FmoW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FmoW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 424w, https://substackcdn.com/image/fetch/$s_!FmoW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 848w, https://substackcdn.com/image/fetch/$s_!FmoW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!FmoW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FmoW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FmoW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 424w, https://substackcdn.com/image/fetch/$s_!FmoW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 848w, https://substackcdn.com/image/fetch/$s_!FmoW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!FmoW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233a3cad-a4b2-4f6d-a04f-ee3c9f1a7ffb_1600x1600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>TAKE OPERATION</h3><div><hr></div><p><strong>A take operation completes immediately when the buffer is not empty or when there is a pending put operation on the channel</strong>. On completion, the provided handler is run.</p><p>In the following example, we can see there is one item in the buffer because <code>put!</code> was completed immediately. Then we take it out of the channel.</p><pre><code><code>;; Channel with a buffer of size 1
(let [ch (a/chan 1)]
  (a/put! ch :the-first-thing)

  ;; print contents of the channel
  (prn "contents of the channel:")
  (inspect-buffered-channel ch)

  (a/take! ch #(prn %)))
</code></code></pre><p>When the buffer is empty, in the following example, a <code>take!</code> operation has to wait for the <code>put!</code> operation on the channel to complete. On inspecting the channel, we can see the pending <code>take!</code>. Putting on the channel completes it.</p><pre><code><code>(let [ch (a/chan 1)]
  (a/take! ch #(prn %))

  (prn "contents of the channel:")
  (inspect-unbuffered-channel ch)

  (a/put! ch :an-item))
</code></code></pre><p>When a <code>take</code> operation cannot complete, it gets queued up in the <code>takes</code> queue. At max, this queue can accommodate <a href="https://github.com/clojure/core.async/blob/33eca77c4a5c38a04e4c0e692c51bbff12200448/src/main/clojure/cljs/core/async/impl/channels.cljs#L141">only </a><code>MAX-QUEUE-SIZE</code><a href="https://github.com/clojure/core.async/blob/33eca77c4a5c38a04e4c0e692c51bbff12200448/src/main/clojure/cljs/core/async/impl/channels.cljs#L141"> pending </a><code>take</code><a href="https://github.com/clojure/core.async/blob/33eca77c4a5c38a04e4c0e692c51bbff12200448/src/main/clojure/cljs/core/async/impl/channels.cljs#L141"> operations</a>. By default, like with <code>puts</code> queue, this value is 1024. Any <code>take</code> operation after that, without a <code>put</code> in the meantime will cause an exception.</p><pre><code><code>(let [ch (a/chan)]
  ;; Take 1024 times on a channel with empty buffer
  (dotimes [i 1024]  ; &lt;== Make it 1023 to fix the ERROR
&#9;(a/take! ch #(prn %)))

  ;; See whats in the channel
  (prn "contents of the channel:")
  (inspect-unbuffered-channel ch)

  ;; This take! will cause an exception
  (a/take! ch #(prn %)))

</code></code></pre><p>A summary of different <code>take!</code> scenarios.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LBbn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LBbn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 424w, https://substackcdn.com/image/fetch/$s_!LBbn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 848w, https://substackcdn.com/image/fetch/$s_!LBbn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!LBbn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LBbn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LBbn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 424w, https://substackcdn.com/image/fetch/$s_!LBbn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 848w, https://substackcdn.com/image/fetch/$s_!LBbn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!LBbn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c0366e1-3fe3-4357-8e79-ac437fd883b5_1600x1600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>CLOSING A CHANNEL</h3><p>Metamorphically, the close operation is like putting the lid on a container with a faucet. No more stuff can be put into it. But it can be taken out until the container is empty. The <code>close!</code> function closes the channel. After it is closed, it no longer accepts any new put operations.</p><pre><code><code>(def chan (a/chan))

(a/put! chan :foo)

;; closing the channel
(a/close! chan)

;; put! is rejected, returns `false`
(a/put! chan :bar)
</code></code></pre><p>Data in the channel after it is closed can be taken until it is drained.</p><pre><code><code>(a/take! chan #(prn "we got back:" %))
</code></code></pre><p>A <code>take!</code> operation on a closed channel that is drained completes with nil.</p><pre><code><code>&#9;(a/take! chan #(prn "take completed with:" %))
</code></code></pre><p>If there are pending <code>take!</code> operations, on closing the channel, they will complete by receiving <code>nil</code> values.</p><pre><code><code>(let [ch (a/chan)]

  (a/take! ch #(prn "take completed with: " %))

  ;; close the channel without putting anything
  (a/close! ch))
</code></code></pre><p>The <code>timeout</code> function returns a channel that closes itself after <code>t</code> milliseconds.</p><pre><code><code>(let [c (a/timeout 1000)] ; &lt;== Make it 3000 &amp; count to 3
  (a/take! c #(prn "Channel has closed returning-&gt; " %)))
</code></code></pre><p>The pending <code>take!</code> operation completes after the channel is closed. It receives <code>nil</code> from the channel.</p><h3>NOTES</h3><div><hr></div><ol><li><p><a href="https://en.wikipedia.org/wiki/Communicating_sequential_processes">Communicating Sequential Processes</a></p></li><li><p>A clear distinction made between concurrency and parallelism in the book Joy of Clojure by Chris Houser and Michael Fogus.</p></li></ol><blockquote><p>Parallelism refers to partitioning a task into multiple parts, each run at the same time. Typically, parallel tasks work toward an aggregate goal and the result of one doesn&#8217;t affect the behaviour of any other parallel task, thus maintaining determinacy. Concurrency refers to the execution of disparate tasks at roughly the same time, each sharing a common resource. The results of concurrent tasks often affect the behaviour of other concurrent tasks, and therefore contain an element of nondeterminism.</p></blockquote><ol><li><p><code>core.async/go</code> a macro that, through <em><a href="https://en.wikipedia.org/wiki/Inversion_of_control">inversion of control</a></em>, converts synchronous block of code to an async block of code.</p></li><li><p>Go blocks run on a fixed size thread pool. Due to an accidental blocking operation, for example, a blocking HTTP request, inside the go block the thread that runs it will be tied up waiting for this operation to complete. This means this thread is now effectively of the pool. If 8 such blocking operations run at the same time, it can freeze the whole process bringing down the production system (how do I even know that :) )</p></li></ol>]]></content:encoded></item><item><title><![CDATA[A Few Notes on Probability Theory]]></title><description><![CDATA[Notes on probability theory]]></description><link>https://www.avichalp.me/p/2019-12-22-notes-on-probability-theory</link><guid isPermaLink="false">https://www.avichalp.me/p/2019-12-22-notes-on-probability-theory</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sun, 22 Dec 2019 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7gP9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Textbook examples in probability theory books tend to deal with artificial problems like tossing a coin or throwing a die. In toy experiments like these, one outcome is entirely independent of the other. In such cases, it is relatively easy to analyze the probabilities of individual events. For example, it is easy to see that a fair coin turns up heads half of the times on average.</p><p>Let&#8217;s take the example of two coin tosses. Let&#8217;s label the event of getting heads in the first toss as A and second as B. Then the probability of A and B happening together is defined to be the intersection of A and B:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;A \\cap B&quot;,&quot;id&quot;:&quot;d9ccab38cb&quot;}" data-component-name="LatexBlockToDOM"></div><p>This can be visualized using a Venn diagram:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7gP9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7gP9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 424w, https://substackcdn.com/image/fetch/$s_!7gP9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 848w, https://substackcdn.com/image/fetch/$s_!7gP9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 1272w, https://substackcdn.com/image/fetch/$s_!7gP9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7gP9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png" width="600" height="335" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:335,&quot;width&quot;:600,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Set Intersecion&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Set Intersecion" title="Set Intersecion" srcset="https://substackcdn.com/image/fetch/$s_!7gP9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 424w, https://substackcdn.com/image/fetch/$s_!7gP9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 848w, https://substackcdn.com/image/fetch/$s_!7gP9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 1272w, https://substackcdn.com/image/fetch/$s_!7gP9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F019bfb86-cd0d-4117-a959-a5794fab5fec_600x335.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Now we reason that since the first coin toss does not impact the second coin toss in any way so the intersection of two probabilities must be the same as their product:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_A \\times P_B&quot;,&quot;id&quot;:&quot;dsejeri9dv&quot;}" data-component-name="LatexBlockToDOM"></div><p>In this case, the probability of getting two heads in a row will be:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;{1 \\over 2} \\times {1 \\over 2} = {1 \\over 4}&quot;,&quot;id&quot;:&quot;4l080s1hyx&quot;}" data-component-name="LatexBlockToDOM"></div><p>So that means:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_A \\cap P_B = P_A \\times P_B&quot;,&quot;id&quot;:&quot;0lkcgsw4r5&quot;}" data-component-name="LatexBlockToDOM"></div><p><strong>But this result does not always hold. In fact, it rarely holds outside of trivial textbook examples.</strong></p><h3>CONDITIONAL PROBABILITY</h3><div><hr></div><p>Imagine you want to analyze the probability for it to rain today, and you already know that it rained yesterday. Intuitively you know that raining a day before makes it more likely to rain on the present day.</p><p>It is a conditional analysis. Conditional probability is defined as the probability of event A happening given that event B has already happened. If A and B are two coin tosses as described earlier, then what is the probability of the second coin landing heads if the first has already landed heads? It is straightforward. We know one toss doesn&#8217;t affect the other, so it is the same:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_{B|A} = P_B&quot;,&quot;id&quot;:&quot;mi4f0wc6y9&quot;}" data-component-name="LatexBlockToDOM"></div><p>But in the case of the rain, as we saw before, raining a day earlier makes it more likely to rain on the present day. That means:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_{A|B} &amp;gt; P_B&quot;,&quot;id&quot;:&quot;e8fssel14j&quot;}" data-component-name="LatexBlockToDOM"></div><p>In such a case of dependence, conditional probability is defined as the ratio of the probability of observing both A and B to the probability of observing event B (independent of A).</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_{A|B} = \\frac{P_A \\cap P_B}{P_B}&quot;,&quot;id&quot;:&quot;5v9phft7n7&quot;}" data-component-name="LatexBlockToDOM"></div><p>Represented in the Venn diagram as:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pgfm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pgfm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 424w, https://substackcdn.com/image/fetch/$s_!Pgfm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 848w, https://substackcdn.com/image/fetch/$s_!Pgfm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 1272w, https://substackcdn.com/image/fetch/$s_!Pgfm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Pgfm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png" width="600" height="335" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:335,&quot;width&quot;:600,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Set Intersecion&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Set Intersecion" title="Set Intersecion" srcset="https://substackcdn.com/image/fetch/$s_!Pgfm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 424w, https://substackcdn.com/image/fetch/$s_!Pgfm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 848w, https://substackcdn.com/image/fetch/$s_!Pgfm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 1272w, https://substackcdn.com/image/fetch/$s_!Pgfm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe892e9d4-c001-4de3-ba4a-4ac0cef4268c_600x335.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>BAYES THEOREM</h3><div><hr></div><p>From set theory, we understand that set intersection is commutative. That is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;A \\cap B = B \\cap A&quot;,&quot;id&quot;:&quot;mv6jufijyk&quot;}" data-component-name="LatexBlockToDOM"></div><p>In this context, it implies:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_{A|B} \\times P_B = P_{B|A} \\times P_A&quot;,&quot;id&quot;:&quot;80s29mdgoc&quot;}" data-component-name="LatexBlockToDOM"></div><p>This result looks very close to a fundamental theorem of high applicability. Bayes theorem is abstract and counterintuitive. I always found it difficult to grasp it fully. Let alone applying it in real problems. But it can be constructed relatively easily using simple equations as we saw above.</p>]]></content:encoded></item><item><title><![CDATA[The Unselfconscious Way Of Building]]></title><description><![CDATA[Notes on the book: Notes on the Synthesis of Form by Christopher Alexander]]></description><link>https://www.avichalp.me/p/2019-09-28-the-unselfconscious-way-of-building</link><guid isPermaLink="false">https://www.avichalp.me/p/2019-09-28-the-unselfconscious-way-of-building</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sat, 28 Sep 2019 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Here are some notes on <em><a href="https://en.wikipedia.org/wiki/Notes_on_the_Synthesis_of_Form">Notes on the Synthesis of Form</a></em>.</p><p>Christopher Alexander, like in <em><a href="https://en.wikipedia.org/wiki/The_Timeless_Way_of_Building">The Timeless Way of Building</a></em>, talks about the design process in the abstract. But the book imparts concrete understanding.</p><p>There is an artificial distinction between the two design processes. The selfconscious and the unselfconscious process. Design, be it wireframes, blueprints or software, aims to solve a problem. The solution doesn&#8217;t exist in a vacuum. Context is vital. Take an example of the human body. It is a design the evolution came up with. The cells exist and functions within the context of the organisms. And organisms within species.</p><p>What is the problem? Here, the definition of the problem is a <em>misfit</em> between the form and its environment. The misfit is not resolved unless the form satisfies its environment and vice versa.</p><p>In the unselfconscious process, the designer is just an agent of change. The process is self-organizing. It relies on immediate feedback from the surrounding. Consider how an Eskimo builds an Igloo. If its too warm inside (a misfit!) the designer just digs a hole. He did not do elaborate planning before digging a hole. Contrast this with a Skyscraper. A large team of engineers and architects put a significant effort to deliver a project of such magnificence. We plan it to perfection. In a top-down fashion. And if a fault is detected in the building, we need an expert to deal with it. A layperson has no role here.</p><p>Preexisting knowledge and directness of action are essential properties of the unselfconscious process. The Eskimo intuitively knew that he needs to dig a hole. The unselfconscious process of design, unlike architecture or engineering, is not taught academically. The skill is specific to the context. And perhaps, it is passed down as a tradition. Trial and error play an important role here. Repeated trial and error leads to a position of a fit between the artefact and its context. It may take a long time to reach this equilibrium between the environment and the form.</p><p>In the unselfconscious culture, change for the sake of change is discouraged. Once the system starts to work, it is left untouched. Until something changes in the context, causing a misfit. A complex system built this way is naturally divided into subsystems such that when one subsystem is modified, there is no cascading effect on others<sup>1</sup>. This localizes the error and as a result, make the system, as a whole, more robust.</p><p>The process of maintaining and evolving software can be unselfconscious. The project will grow into a robust and functional product if the maintainer fixes bugs and only add features that are absolutely necessary to solve its user&#8217;s problems. The user, like the Eskimo from the earlier example, has to be in the loop. Giving the developers feedback, raising flags or better submitting a patch.</p><p>Decoupling of subsystems is the most significant point of leverage in software. If done correctly there is a massive gain in maintainability. Also, thoughtful decoupling removes the chance of cascading effects of tweaking the sub-components. Which makes iterations cheap. More iterations in less time imply a <strong>dynamic equilibrium</strong> can be reached faster between the solution and the context in which the problem exists.</p><p>On the other hand, there is the selfconscious process. It is not guided by the immediate feedback from the environment. It is the process of intellectualization. In the book, the author offers an example of designing a kettle. You start by gathering the requirements. Quantitive or qualitative. For example, its capacity, the temperature it heats to, how much it costs, and how should it look etc. A subtle point about requirements: you will only notice when it is not satisfied. Each requirement is an invariant of the problem. It defines the context. The more invariants, the lower the chance of satisfying all of them at once. For a high number of requirements, the likelihood of meeting all of them at once will be extremely low<sup>2</sup>. This makes it challenging to produce forms that work. The designer, when working in the selfconscious paradigm, must rely on rigorous formal methods.</p><h3>NOTES</h3><div><hr></div><ol><li><p>The tight feedback loop will enforce a more modular design. And modularity will ensure quick modification of subsystems.</p></li><li><p>For <code>n</code> independent requirements we can estimate the likelihood to satisfy all of them at once will be: <span class="latex-inline" data-attrs="{&quot;persistentExpression&quot;:&quot;1/2^n&quot;,&quot;id&quot;:&quot;ryxw91vw21&quot;}" data-component-name="InlineLatexToDOM"></span></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Tinkering With WebAssembly]]></title><description><![CDATA[An attempt to parse PDFs in C & WebAssembly]]></description><link>https://www.avichalp.me/p/2019-06-30-tinkering-with-webassembly</link><guid isPermaLink="false">https://www.avichalp.me/p/2019-06-30-tinkering-with-webassembly</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Sun, 30 Jun 2019 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Working with PDFs on the web is annoying. Let&#8217;s imagine a niche use case. We want to take a snapshot of a part of our web app. Also, export it as a PDF. Traditionally, if you are not relying on a 3rd party API, you send HTML document as a string to the server to convert it to the PDF format. Then download the PDF and render it on the client. Support of document conversion in the JS ecosystem is not as good as in Haskell, C or C++. Pandoc, written in Haskell, is a general purpose document conversion tool. Similarly, <code>libwkhtmltox</code> is a set of C and C++ libraries that converts HTML to PDF format. Document conversion on the server works well but doesn&#8217;t scale for a large number of clients because such conversions are computation expensive.</p><p>Since 2017 WASM ecosystem is maturing at a rapid pace. It is also gaining traction. Autocad is ported to run in the browsers. PSPDFKIT, a company that offers a document conversion SDK, have <a href="https://pspdfkit.com/blog/2017/webassembly-a-new-hope/">cross compiled their 500000 lines c++ pdf conversion codebase to target WASM</a>. Products like Google Earth and Figma are using WebAssembly in production. I have seen some Haskell cross compilers out there that target WASM. So, in theory, Pandoc can be cross-compiled to target WASM for general purpose document conversion in the browser.</p><p>For the use case that I described above, I am trying to use <code>libwkthmltox</code>, a C library, to convert an HTML document to PDF in the browser. I want to leverage this battle-tested C library with minimal glue code in C to solve my problem. The glue code exposes an API that takes in a pointer to a string (UTF-8 encoded HTML document) and returns another pointer that contains PDF formatted document. JS runtime and WASM runtime share memory indirectly using a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory">linear memory model</a>. We can use this feature to pass pointers around.</p><p>Emscripten is a compiler toolchain that does all the heavy lifting. It compiles C code first to LLVM bitcode using Clang then finally output a <code>.wasm</code> file along with boilerplate HTML and js.</p><p>Forget about the document conversion for a minute. Then solving this problem becomes simply a matter of string manipulation. Here is a function in C that takes a string concatenate it with another string and returns the new string. <code>EMSCRIPTEN_KEEPALIVE</code> macro comes from <code>emscripten.h</code> header file. It tells Emscripten to preserve this function while tree shaking.</p><pre><code><code>
const char* EMSCRIPTEN_KEEPALIVE get_string(char* input_str) {
&#9;char str[] = "Hello, ";
&#9;return strcat(str, input_str);
}
</code></code></pre><p>After transpiling C to WASM using Emscripten, from the Browser (boilerplate HTML and js code generated by Emscripten takes care of loading the WASM module in the browser) we can call the <code>get_string</code> function like this:</p><pre><code><code>
UTF8ToString(Module._get_string(allocateUTF8("World!")))
// "Hello, World!"
</code></code></pre><p>This contrived example is easy to write and run, but real challenge appears when I try to use the <code>libwkthmltox</code> library for actual document conversion. Emscripten documentation says, in the &#8220;using libraries&#8221; section, that to use 3rd party libraries, you need to build them to LLVM bitcode and then link them. For libraries that have a straightforward build process, it is not hard to do. <a href="https://developers.google.com/web/updates/2018/03/emscripting-a-c-library">Here</a> is an excellent example of compiling <code>libwebp</code>, a c library for image compression, to WASM. However, compiling <code>libwkhtmltox</code> is not straightforward. It even has a separate repository just for building for different architectures. It uses a patched version of Qt. During the build, It compiles Qt from the source too.</p><p>At this stage, I am stuck.</p>]]></content:encoded></item><item><title><![CDATA[Information Diet]]></title><description><![CDATA[What to read and how much?]]></description><link>https://www.avichalp.me/p/2018-12-12-information-diet</link><guid isPermaLink="false">https://www.avichalp.me/p/2018-12-12-information-diet</guid><dc:creator><![CDATA[Avichal]]></dc:creator><pubDate>Wed, 12 Dec 2018 00:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SZEU!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5e858c7-6df4-490a-bd19-a4150d4268bd_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>How much information is a lot of information? My main information sources these days are twitter and a handful of newsletter subscriptions. They work pretty well in keeping me informed about topics I fancy. Mostly technology, programming, computer science, complex adaptive systems a little bit of econ and sometimes philosophy. Interesting links that I find on twitter I send to my inbox. Instapaper, pocket and such products never worked for me. When I am not keeping up with the reading list in my inbox it keeps on growing. An increasing number of unread emails makes me anxious. It is like having pending homework assignments. Reading is supposed be fun but cleaning up the inbox is no fun.</p><p>So here is a new information diet plan that I am trying out. I will expire the unread current edition of the newsletters when the next one reaches my inbox. Expiring weekly newsletter at end of the week and daily newsletters at the end of the day. Newsletters mostly contain &#8220;newsy&#8221; stuff which is better read fresh. Most news events lose relevance as time passes. Do you pile up the newspapers to read them all on weekends because of FOMO? This should keep unread-list in check. For the links that I find on Twitter. It is better to skim through it once before sending it for later. This way I avoid click baits. Skimming the writeup also gives some context before actual reading. Adding this context to the email is helpful for later. Sometimes while going through my to-read list I find few items that I am no longer interested in. I archive those. Other times I find few items may not be useful immediately I archive them too. A guiding principle I tend to follow, read on &#8216;on demand basis&#8217;, read something that you need right now rather than reading about things that you might need in future.</p><p>Books are another source of consumption. Even more demanding in terms of time and attention. Some days I have time other days I don&#8217;t. That has to be okay. With many great books out there it is important to be able to pick up good books for yourself. Different books appeal to different people. Here is a great model, borrowed from <a href="https://twitter.com/patrickc?lang=en">Patrick Collison</a>:</p><blockquote><p>at every moment you should be reading the best book you know of in the world. I don&#8217;t mean ... the absolute best for everyone, but the best book for you. As soon as you discover something that seems more interesting or more important or whatever, you should absolutely discard your current book in favor of that, because any other algorithm necessarily results in you reading &#8220;worse stuff over time.</p></blockquote><p>I think this is great advice.</p><p>What about the other sources like the Orange Website, Reddit et al? Overtime I am losing my appetite for Hacker News. I don&#8217;t read it that often. There were times when Hacker News was the morning routine. Partly because I don&#8217;t want to follow newsy stuff, instead I want to chase specific topics. Partly because of general toxicity in the threads and a lot of misinformation in the comments. Sometimes I still open up and follow one of the stories if I find something interesting.</p><p>A big question that remains unanswered. What is the goal of reading? Reading cannot be a goal in itself. People are reading all the time. Twitter, blogs, news websites, books and whatnot. What are they looking for? Just fear of missing out doesn&#8217;t seem like a reasonable answer too. There has to be something more concrete to be gained from groking all the stuff. Some people say it is curiosity. To me &#8216;curiosity&#8217; is an abstract term. I don&#8217;t know what it means. It may mean different things to different people. Is curiosity a property of humans? Why are some people more curious and others less so? I don&#8217;t know the answers to these questions. But there is one pithy aphorism that drives the point home for me.</p><blockquote><p>The universe rewards us for understanding it and punishes us for not understanding it. When we understand the universe, our plans work and we feel good. Conversely, if we try to fly by jumping off a cliff and flapping our arms the universe will kill us.&#8221;</p><p>-- Jack Cohen &amp; Ian Stewart</p></blockquote><p>If this is true then everyone in the universe is trying to learn about it as much as they can. Reading is probably the second best way to learn. Only after direct experiences. With a huge amount of information readily available ability to filter through them to find illuminating resources is even more valuable.</p>]]></content:encoded></item></channel></rss>