<?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:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by coltcivers on Medium]]></title>
        <description><![CDATA[Stories by coltcivers on Medium]]></description>
        <link>https://medium.com/@coltcivers?source=rss-42e144bdd171------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*LhHu3u60vV124QYugQYxSg.jpeg</url>
            <title>Stories by coltcivers on Medium</title>
            <link>https://medium.com/@coltcivers?source=rss-42e144bdd171------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 23:28:24 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@coltcivers/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Geth Tales | Part 1]]></title>
            <link>https://medium.com/@coltcivers/geth-tales-part-1-53eec120c242?source=rss-42e144bdd171------2</link>
            <guid isPermaLink="false">https://medium.com/p/53eec120c242</guid>
            <category><![CDATA[evm]]></category>
            <category><![CDATA[p2p]]></category>
            <category><![CDATA[ethereum]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[node]]></category>
            <dc:creator><![CDATA[coltcivers]]></dc:creator>
            <pubDate>Thu, 20 Oct 2022 16:25:16 GMT</pubDate>
            <atom:updated>2022-11-05T02:02:25.896Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Travel diary of an individual seeking for knowledge</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fGXjuvF4qIIEvm4r.jpg" /></figure><h4>Context:</h4><p>I’m planning this series of short explanatory articles as a way to write down knowledge on various technical/non-technical subjects I’m currently interested in, whilst allowing me to share thoughts that may be helpful to other individuals studying those same topics.</p><p>This first part will cover some portions of the <strong>ethereum P2P layer</strong>, seen through the prism of the <strong>Geth codebase</strong> (<a href="https://github.com/ethereum/go-ethereum">https://github.com/ethereum/go-ethereum</a>), as we’ll try to demistify it in order to obtain a more higher-view of these critical protocols.</p><h4>1. Understanding the ethereum P2P communication layer:</h4><p>Considering the ethereum network as a living organism, a simple analogy would be to think of the different nodes composing its complex structure as cells : each devoted to multiple/different tasks (archiving state trace, relaying data to other peers, validating…), those actors achieve to maintain an incentive-led and truly-decentralized infrastructure.</p><p>Let’s directly dig down to the Node object, as it is described in Geth :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/910/1*8_5eI5guZGYbP2HfeOm3AA.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/node/node.go">https://github.com/ethereum/go-ethereum/blob/master/node/node.go</a></figcaption></figure><p>The fields that are here attracting our attention are :</p><ul><li>config</li><li>server</li></ul><p>The config (*Config object) struct contains, among other elements, the instance name of the node, its identifier, the data directory path, and more specifically the node P2P networking configuration.</p><p>The p2p networking config object holds different parameters, that are set in order for the node p2p server to maintain specific options as long as it is running :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*xls6Vo_64rH_yHNx8vtxEA.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/p2p/server.go">https://github.com/ethereum/go-ethereum/blob/master/p2p/server.go</a></figcaption></figure><p>Nothing realy fancy here, some simple specifications related to peers connectivity (max peers allowed, static nodes (aka maintained peers that are directly reconnected following disconnections), trusted nodes, peers database, etc…), but what interest us for the moment is the BootStrapNodes field (v5 refers to the latest version of the node discovery protocol, we’ll soon be back at it).</p><p>BootStrapping Nodes are nodes maintained by the Ethereum Foundation, that are only taking part in the network discovery protocol. When initializing your client, it will automaticaly handshake then establish a connection to those nodes, using them as anchors points that will then allow its peers discovery.</p><p>As you can observe, they are directly hardcoded in the Geth params :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*azhnq0Kv78ulcIG7Kqbi9Q.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go">https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go</a></figcaption></figure><p>Obtaining initial peers is a great start, but as previously discussed bootnodes are just a way to bootstrap your peers discovery, as they do not relay blockchain data.</p><p>How to reach other parts of the network, in order to communicate with different participants and synchronize your client data ? Requesting relative peers infos from the connected bootnodes, then handshaking them in order to establish a connection would appear as the most logical path to follow, but then what ? Do we have to follow this procedure in a pseudo-random fashion, picking closest peers and storing them locally ?</p><p>It is in fact not the case, thanks to the Ethereum Discovery Protocol, aka the native implementation of a Kademlia-like DHT.</p><h4>2. Node Discovery protocol :</h4><p>Kademlia is a distributed hash-table model theorized by Petar Maymounkov and David Mazières, in their initial research paper : <a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf</a>.</p><p>As a quick summary of the eth kademlia implementation :</p><ul><li>Every node within the network has a cryptographic identity (a key on the secp256k1 elliptic curve) : those keys are used to compute the “distance” between two nodes, applying the bitwise XOR operator on the keccak256 of both keys, taken as the number. The “distance” should not be considered as “physical” distance : it is only a value allowing nodes to be compared, and indexed as table entries.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/275/1*5VPmgYzG1n6kCY8ogsjm5A.png" /><figcaption><a href="https://www.loginradius.com/blog/engineering/how-does-bitwise-xor-work/">https://www.loginradius.com/blog/engineering/how-does-bitwise-xor-work</a></figcaption></figure><ul><li>The peers detection process is called Recursive Lookup. The initiator (aka searching peer) starts by picking the α (client-hardcoded concurrency factor, in geth it is 3) closest peers from the target it knows, and sends them a FindNode packet, asking them to return their 16 closests-peers (neighbors).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/528/1*zX7wBHW1yYvftstZcSx9DQ.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/p2p/discover/table.go">https://github.com/ethereum/go-ethereum/blob/master/p2p/discover/table.go</a></figcaption></figure><ul><li>The initiated Lookup loop will then send peer requests to yet unreached peers among the previously discovered ones, until it reaches the initially-specified k amount of closest peers, while keep adding them to its local table.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/594/1*7B-_QwIzParYjcbdipbDLg.png" /><figcaption><a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/689/1*QgdgZ5FRB6-FB96wkdToYg.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/p2p/discover/table.go">https://github.com/ethereum/go-ethereum/blob/master/p2p/discover/table.go</a></figcaption></figure><p>For each node to store all of the network participants informations would be an inneficient, slow and costly process, same goes for a global and centralized infrastructure.</p><p>The Kademlia indexing structure theorized in order to solve this scalability issue is, as we previously mentioned, called a “Table” : each node within the network maintain its own version, regularly verifying neighboors liveness / requesting node records to assert versions validity.</p><p>In order to acquire a deeper understanding of Kademlia, I’d advise you to read this great article from Kevin Leffew :</p><p><a href="https://medium.com/coinmonks/a-brief-overview-of-kademlia-and-its-use-in-various-decentralized-platforms-da08a7f72b8f">A Brief Overview of Kademlia, and its use in various decentralized platforms</a></p><p>While we’re breaking down those steps in a linear fashion to ease their understanding, let’s keep in mind that some parts are in fact running concurrently. It is for example the case each time a connection between two peers is established : a Status message is sent from both clients, and following receipts validation an Ethereum Session is opened between them, allowing the transmission of other messages.</p><p>This exchanges facilitating protocol is called the <strong>Ethereum Wire Protocol</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*esC3orri94PAeMBY.jpg" /></figure><h4>3. The Ethereum Wire Protocol / Snapshot Protocol</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CMTlYkG_wRtgpRBg-fhbMw.png" /><figcaption>Ethereum Wire Protocol + Ethereum Snapshot Protocol tasks</figcaption></figure><p>Once an Ethereum Session is established between two peers, three high-level tasks can be performed within it :</p><p>(<em>Edit : Post Merge, the block propagation is now done through the Consensus layer. As we’re today only focused on the EL, I’ll describe the pre-Merge propagation as it is still used by some Geth forks.)</em></p><p><strong>Block propagation</strong> : two-step process allowing block data distribution within the network.</p><p>At the moment a NewBlock announcement is received from a peer, the client verifies the block header validity, applying multiple checks (including gas limit, gas used within the block, timestamp, block height, etc…) and exclusions (in POS, block nonce is always null, and there is no uncle blocks anymore), comparing received values to the Beacon engine data (consensus client). Following this validity check, the block is imported, and all the transactions it contains are executed, allowing the client to compute the chain <strong>post state </strong>(but we’ll keep that for an upcoming episode of our series ;) .</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/1*7k_eYimFbMPzikGNUqtsaw.png" /></figure><p>It will then relay the block to a small fraction of its peers (this amount usually corresponds to the square root of the total number of peers he’s connected to), having completed its duty as link.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hQQj8Eq2c3DWmEpGNF_lpA.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/eth/protocols/eth/broadcast.go">https://github.com/ethereum/go-ethereum/blob/master/eth/protocols/eth/broadcast.go</a></figcaption></figure><p><strong>Transaction exchange : </strong>nodes within the network must propagate pending transactions in order to relay them to validators, wich will then pick them for inclusion within the blockchain.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/855/1*3o5iRIrjeom_iCxfBpH9Mg.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/core/tx_pool.go">https://github.com/ethereum/go-ethereum/blob/master/core/tx_pool.go</a></figcaption></figure><p>Following an Ethereum session opening, both peers must synchronize their <strong>transaction pool</strong>. A transaction pool is a local structure keeping track of a set of pending transactions the node has knowledge of, and that are waiting for inclusion : it can, depending on different client limits / implementations, contain up to many txs (e.g. thousands).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1010/1*uGOPtOOCOP5RJBJgM7Yw2Q.png" /></figure><p>A “NewPooledTransactionHahes” mesage is sent from both ends, containing all pooled txs from both nodes. They then apply multiple filters for each of those transactions , allowing them to discard invalid or already knows txs from the tx pool.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/926/1*hV8rfHJ_9Fu-7JNcGaIBug.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/core/tx_pool.go">https://github.com/ethereum/go-ethereum/blob/master/core/tx_pool.go</a></figcaption></figure><p>With the validity checks being :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/887/1*GdNRAyn9nUAlfhT1uwz_bQ.png" /><figcaption><a href="https://github.com/ethereum/go-ethereum/blob/master/core/tx_pool.go">https://github.com/ethereum/go-ethereum/blob/master/core/tx_pool.go</a></figcaption></figure><p><strong>Chain synchronization: </strong>nodes participating in the eth protocol are expected to have knowledge of the complete chain of blocks, from the genesis block to latest. It is obtained by downloading it from other peers, following the sending of a Status message that includes the hash of the latest block they have knowledge of, and their TTD (total difficulty).</p><p>The client with the lowest TTD will then continuously download block headers from the other peer, using the “GetBlockHeaders” message.</p><p>Till recently, <strong>State synchronization</strong> was realised directly through the <strong>eth protocol </strong>, as a part of the Chain synchronization module. This task is now performed by the <strong>Ethereum Snapshot Protocol, </strong>running alongside eth and retrieving continuous segments of accounts from the Ethereum state trie, or segments of storage slots from a particular storage trie.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/789/1*wK1DL19ZqvMbVVjbREtBpw.png" /><figcaption><a href="https://medium.com/@eiki1212/ethereum-state-trie-architecture-explained-a30237009d4e">https://medium.com/@eiki1212/ethereum-state-trie-architecture-explained-a30237009d4e</a></figcaption></figure><p>That concludes the first part of our Geth series. As I wanted to maintain a short format for the p2p topic, I tried my best not to dig too deep into the client tech layer in order to keep this accessible : the upcoming episode will focus on the Geth implementation of the EVM, explaining more in-depth concepts in a detailled way.</p><p>Don’t hesitate to contact me on Twitter (<a href="https://twitter.com/Coltcivers_Alt">https://twitter.com/Coltcivers_Alt</a>), for any feedback or questions !</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=53eec120c242" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>