<?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"><channel><title><![CDATA[The Polyglot Programmer]]></title><description><![CDATA[The Polyglot Programmer]]></description><link>https://hashblog.thepolyglotprogrammer.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1724399203392/9bc2fe9a-0e53-4dd9-962f-a6c2af51b572.png</url><title>The Polyglot Programmer</title><link>https://hashblog.thepolyglotprogrammer.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 03:21:17 GMT</lastBuildDate><atom:link href="https://hashblog.thepolyglotprogrammer.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Crafting a Blockchain in Go and Rust: A Comparative Journey — Blocks and Transactions [Part 2]]]></title><description><![CDATA[Projects available on Github:
View on Github (Pull Requests are Welcome) — Rust Version
View on Github (Pull Requests are Welcome) — Go Version
<- Part 1- Crafting a Blockchain in Go and Rust: A Comparative Journey — Private keys, Public Keys and Sig...]]></description><link>https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-blocks-and-transactions-part-2-1897aca38c27</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-blocks-and-transactions-part-2-1897aca38c27</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Cryptocurrency]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Sun, 01 Sep 2024 15:05:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725202664771/2c913bf5-3d5e-40e6-a8bf-6ac080408431.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-projects-available-on-github">Projects available on Github:</h3>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">View on Github (Pull Requests are Welcome) — Rust Version</a></p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">View on Github (Pull Requests are Welcome) — Go Version</a></p>
<p><a target="_blank" href="https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-private-keys-public-keys-and-signatures-part-1">&lt;- Part 1- Crafting a Blockchain in Go and Rust: A Comparative Journey — Private keys, Public Keys and Signatures</a></p>
<p>In this post, we’ll dive into the implementation of fundamental blockchain components: the block header, the block itself, and transaction. These elements are crucial for constructing a blockchain, as they form the building blocks of the distributed ledger. We’ll explore the initial implementations in Go and Rust, the challenges encountered with encoding, and how I ultimately achieved deterministic encoding using <a target="_blank" href="https://protobuf.dev/">Protocol Buffers (protobuf)</a>.</p>
<h3 id="heading-the-importance-of-headers-blocks-and-transactions">The Importance of Headers, Blocks, and Transactions</h3>
<p><strong>Headers</strong>: The header in a blockchain block contains metadata about the block, such as the previous block hash, the timestamp, version, height, nonce and the hash of transactions. It is critical for linking blocks together, ensuring integrity, and enabling quick verification.</p>
<p><strong>Blocks</strong>: A block consists of the header, the block signature a public key to verify the signature and a list of transactions. Each block encapsulates a set of transactions that have been validated and recorded in the blockchain.</p>
<p><strong>Transactions</strong>: Transactions are the basic units of value transfer in the blockchain. They include the sender’s and receiver’s addresses, the amount transferred, some arbitrary piece of data I decided to add to it, and a digital signature to verify authenticity.</p>
<h3 id="heading-initial-implementations-in-go-and-rust">Initial Implementations in Go and Rust</h3>
<p>Initially, I implemented the blockchain using the core data structures and native encoding libraries specific to each language. At first, I didn’t give much thought to the implications of using different encoding libraries — after all, bytes are bytes, right? However, I soon realised that to achieve deterministic behavior across both implementations, I needed to rethink that approach. But more on that in a moment.</p>
<p>For now let’s look at the data structures initially implemented.</p>
<h4 id="heading-go-implementation">Go Implementation:</h4>
<pre><code class="lang-go"><span class="hljs-comment">// types/hash.go</span>
<span class="hljs-comment">// Hash represents the 32-byte hash of a block.</span>
<span class="hljs-keyword">type</span> Hash [HashSize]<span class="hljs-keyword">byte</span>

<span class="hljs-comment">// core/block.go</span>
<span class="hljs-comment">// Header represents the header of a block in the blockchain.</span>
<span class="hljs-keyword">type</span> Header <span class="hljs-keyword">struct</span> {
    PrevBlockHash types.Hash <span class="hljs-comment">// Hash of the previous block</span>

    TxHash types.Hash <span class="hljs-comment">// Hash of the transactions in the block</span>
    Version <span class="hljs-keyword">uint32</span> <span class="hljs-comment">// Version of the block</span>
    Height <span class="hljs-keyword">uint64</span> <span class="hljs-comment">// Height of the block in the blockchain</span>
    Timestamp <span class="hljs-keyword">int64</span> <span class="hljs-comment">// Timestamp of the block</span>

    Nonce <span class="hljs-keyword">uint64</span> <span class="hljs-comment">// Nonce used to mine the block</span>
    Difficulty <span class="hljs-keyword">uint8</span> <span class="hljs-comment">// Difficulty used to mine the block</span>
}

<span class="hljs-comment">// Block represents a block in the blockchain.</span>
<span class="hljs-keyword">type</span> Block <span class="hljs-keyword">struct</span> {
    *Header

    Transactions []*Transaction
    PublicKey crypto.PublicKey
    Signature *crypto.Signature

    <span class="hljs-comment">// Cached version of the header hash</span>
    hash types.Hash
}

<span class="hljs-comment">// core/transaction.go</span>
<span class="hljs-comment">// Transaction represents a transaction in the blockchain.</span>
<span class="hljs-keyword">type</span> Transaction <span class="hljs-keyword">struct</span> {
    From crypto.PublicKey <span class="hljs-comment">// Public key of the sender</span>
    To crypto.PublicKey <span class="hljs-comment">// Public key of the receiver</span>
    Value <span class="hljs-keyword">uint64</span> <span class="hljs-comment">// Amount to transfer</span>
    Data []<span class="hljs-keyword">byte</span> <span class="hljs-comment">// Arbitrary data</span>
    Signature *crypto.Signature <span class="hljs-comment">// Signature of the transaction</span>
    Nonce <span class="hljs-keyword">int64</span> <span class="hljs-comment">// Nonce of the transaction</span>

    <span class="hljs-comment">// hash of the transaction</span>
    hash types.Hash
}
</code></pre>
<p><strong>Encoding with Go:</strong></p>
<p>At first, I chose to use the <a target="_blank" href="https://pkg.go.dev/encoding/gob">Gob package</a> in Go for encoding the structures. Gob it is often the preferred way when communicating between Go programs since it is Go’s native binary encoding library, designed for efficient serialisation and deserialisation. Gob’s performance is great, but again, mainly or only used for communicating between Go programs, since we are developing one Blockchain Node in Go and another Blockchain Node in Rust, come to think of it may not have been the best choice.</p>
<h4 id="heading-rust-implementation">Rust Implementation:</h4>
<pre><code class="lang-rust"><span class="hljs-comment">// types/hash.rs</span>
<span class="hljs-meta">#[derive(PartialEq, Debug, Serialize, Deserialize, Clone, Copy)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Hash</span></span> {
    <span class="hljs-keyword">pub</span> hash: [<span class="hljs-built_in">u8</span>; HASH_SIZE],
}

<span class="hljs-comment">// core/block.rs</span>
<span class="hljs-meta">#[derive(Debug, Serialize, Deserialize)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Header</span></span> {
    <span class="hljs-keyword">pub</span> previous_block_hash: [<span class="hljs-built_in">u8</span>; <span class="hljs-number">32</span>],

    <span class="hljs-keyword">pub</span> tx_hash: <span class="hljs-built_in">Option</span>&lt;hash::Hash&gt;,
    <span class="hljs-keyword">pub</span> version: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> height: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> timestamp: <span class="hljs-built_in">u32</span>,

    <span class="hljs-keyword">pub</span> nonce: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> difficulty: <span class="hljs-built_in">u8</span>,
}

<span class="hljs-meta">#[derive(Debug, Serialize, Deserialize)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Block</span></span> {
    header: Header,
    transactions: <span class="hljs-built_in">Vec</span>&lt;Transaction&gt;,
    <span class="hljs-meta">#[serde(default, skip_serializing_if = <span class="hljs-meta-string">"Option::is_none"</span>, skip_deserializing)]</span>
    public_key: <span class="hljs-built_in">Option</span>&lt;PublicKey&gt;,
    <span class="hljs-meta">#[serde(default, skip_serializing_if = <span class="hljs-meta-string">"Option::is_none"</span>, skip_deserializing)]</span>
    signature: <span class="hljs-built_in">Option</span>&lt;SignatureWrapper&gt;,

    <span class="hljs-comment">// Cached version of the header hash</span>
    <span class="hljs-meta">#[serde(default, skip_serializing_if = <span class="hljs-meta-string">"Option::is_none"</span>, skip_deserializing)]</span>
    hash: <span class="hljs-built_in">Option</span>&lt;hash::Hash&gt;,
}

<span class="hljs-comment">// core/transaction.rs</span>
<span class="hljs-meta">#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Transaction</span></span> {
    <span class="hljs-keyword">pub</span> from: <span class="hljs-built_in">Option</span>&lt;PublicKey&gt;,
    <span class="hljs-keyword">pub</span> to: <span class="hljs-built_in">Option</span>&lt;PublicKey&gt;,
    <span class="hljs-keyword">pub</span> value: <span class="hljs-built_in">u64</span>,
    <span class="hljs-keyword">pub</span> data: <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">u8</span>&gt;,
    <span class="hljs-keyword">pub</span> signature: <span class="hljs-built_in">Option</span>&lt;SignatureWrapper&gt;,
    <span class="hljs-keyword">pub</span> nonce: <span class="hljs-built_in">u64</span>,

    <span class="hljs-comment">// Cached version of the transaction hash</span>
    <span class="hljs-keyword">pub</span> hash: <span class="hljs-built_in">Option</span>&lt;hash::Hash&gt;,
}
</code></pre>
<p><strong>Encoding with Rust:</strong></p>
<p>For Rust I decided to with <a target="_blank" href="https://crates.io/crates/bincode">Bincode</a>, which is a binary encoder / decoder implementation in Rust. Bincode is a compact encoder / decoder pair that uses a binary zero-fluff encoding scheme. The size of the encoded object will be the same or smaller than the size that the object takes up in memory in a running Rust program.</p>
<p>In addition to exposing two simple functions (one that encodes to <code>Vec&lt;u8&gt;</code>, and one that decodes from <code>&amp;[u8]</code>), binary-encode exposes a Reader/Writer API that makes it work perfectly with other stream-based APIs such as Rust files, network streams.</p>
<p>But again, <code>Bincode</code> can be quite fast but I ran into the same problem I had with Go <code>Glob</code> package, meaning <code>Bincode</code> although quite popular, it does not have an implementation for Go, as far as I know, so the results would be different and not really deterministic and would ended with the same block being encoded differently on different Blockchain Nodes, which cannot happen.</p>
<h3 id="heading-encountering-the-problem-non-deterministic-encoding"><strong>Encountering the Problem: Non-Deterministic Encoding</strong></h3>
<h4 id="heading-the-issue"><strong>The Issue</strong></h4>
<p>Despite the success in serialising the structures, I encountered a significant issue: the encoded results were not deterministic. This means that the same data structures were being encoded differently in Go and Rust.</p>
<h4 id="heading-implications"><strong>Implications</strong></h4>
<p>For a blockchain where different nodes (potentially written in different languages) need to communicate and validate blocks and transactions consistently, non-deterministic encoding is a critical flaw. <strong>It could lead to a situation where nodes disagree on the validity of a block simply because of differences in how data is serialised.</strong></p>
<h3 id="heading-the-need-for-deterministic-encoding"><strong>The Need for Deterministic Encoding</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725202661332/37689545-aa7f-457c-af47-589bf0802e22.jpeg" alt /></p>
<h4 id="heading-why-determinism-matters"><strong>Why Determinism Matters?</strong></h4>
<p>In a blockchain network, all nodes must agree on the state of the ledger. If two nodes encode the same block differently, they might calculate different hashes for that block, leading to a consensus failure.</p>
<h4 id="heading-serialisation-format-requirements"><strong>Serialisation Format Requirements</strong>:</h4>
<p>For cross-language compatibility and determinism, the serialisation format needs to:</p>
<ul>
<li><p>Be consistent across different implementations.</p>
</li>
<li><p><strong>Preserve the exact byte order.</strong></p>
</li>
<li><p>Be well-documented and widely supported.</p>
</li>
</ul>
<h3 id="heading-switching-to-protocol-buffers-protobuf"><strong>Switching to Protocol Buffers (Protobuf)</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725202663216/8fe7b02b-9232-4b8a-bf7b-d80e463b339f.jpeg" alt /></p>
<h4 id="heading-why-protobuf"><strong>Why Protobuf?</strong></h4>
<p>I decided to switch to Protocol Buffers (protobuf) for encoding because it is a language-neutral, platform-neutral extensible mechanism for serialising structured data. It’s widely used in systems that require deterministic encoding across different environments, including many blockchain projects, and it’s quite performant.</p>
<h4 id="heading-implementation-details"><strong>Implementation Details</strong></h4>
<p><strong>Defining the Protobuf Schema</strong>:</p>
<p>For that we need to create a .proto file that represents your Go and Rust structs. I usually create a folder named <code>proto/</code> and saved it in there. Here’s what the .proto file might look like:</p>
<pre><code class="lang-plaintext">syntax = "proto3";

package proto;

option go_package = "github.com/joaoh82/marvinblockchain/proto";

// Header represents the header of a block in the blockchain.
message Header {
    bytes prev_block_hash = 1;
    bytes tx_hash = 2;
    uint32 version = 3;
    uint64 height = 4;
    int64 timestamp = 5;
    uint64 nonce = 6;
    uint32 difficulty = 7;
}

// Transaction represents a transaction in the blockchain.
message Transaction {
    bytes from = 1;
    bytes to = 2;
    uint64 value = 3;
    bytes data = 4;
    bytes signature = 5;
    int64 nonce = 6;
    bytes hash = 7;
}

// Block represents a block in the blockchain.
message Block {
    Header header = 1;
    repeated Transaction transactions = 2;
    bytes public_key = 3;
    bytes signature = 4;
    bytes hash = 5;
}
</code></pre>
<p><strong>Generating Code from the Protobuf Schema:</strong></p>
<p><strong>Go:</strong></p>
<p>First, make sure you have the Protocol Buffers compiler (protoc) and the Go plugin for it installed:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install protoc (if not already installed)</span>
brew install protobuf

<span class="hljs-comment"># Install the Go plugin for protoc</span>
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
</code></pre>
<p>Now, generate the Go code:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Generating the actual code</span>
rm -rf proto/*.pb.go
protoc --go_out=. --go_opt=paths=source_relative \
proto/*.proto
</code></pre>
<p>This command above generates a .pb.go file in the same directory, which contains the Go structs and methods for serialisation and deserialisation.</p>
<p><strong>Rust:</strong></p>
<p>For Rust, you also need to install <code>protoc</code> and the <code>protobuf-compiler</code>. And it can be installed, at least on <code>mac</code>, the same way as above:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install protoc (if not already installed)</span>
brew install protobuf
</code></pre>
<p>On <code>linux</code> you can check out my github actions scripts in the Rust repo:</p>
<pre><code class="lang-bash">sudo apt-get update
sudo apt-get install -y protobuf-compiler
cargo install protobuf-codegen
</code></pre>
<p><strong>Add Dependencies</strong></p>
<p>Update your Cargo.toml to include the necessary dependencies.</p>
<pre><code class="lang-ini"><span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">prost</span> = <span class="hljs-string">"0.13.1"</span>
<span class="hljs-attr">prost-types</span> = <span class="hljs-string">"0.13.1"</span>
<span class="hljs-section">[build-dependencies]</span>
<span class="hljs-attr">prost-build</span> = <span class="hljs-string">"0.13.1"</span>
</code></pre>
<p><strong>Write a Build Script</strong></p>
<p>In Rust, you need to create a <code>build.rs</code> file to instruct Cargo to compile the Protobuf definitions using the <a target="_blank" href="https://crates.io/crates/prost">prost</a> crate. Note that you need to create the <code>build.rs</code> file in the root of the project, at the same level you have your <code>Cargo.toml</code> .</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    prost_build::compile_protos(&amp;[<span class="hljs-string">"src/proto/types.proto"</span>], &amp;[<span class="hljs-string">"src/proto"</span>])
    .expect(<span class="hljs-string">"Failed to compile proto"</span>);
}
</code></pre>
<p><strong>Where is the protobuf generated rust file?</strong></p>
<p>Important note here is that the the file generated by <code>prost</code> will not go in the same directory as the <code>*.proto</code> file, but in reality it will go in the <code>target/[environment]/build/[build-hash]/out</code> , which makes sense, because with <code>prost</code> the file is actually generated at build time.</p>
<p><strong>Generate Rust Code from Protobuf</strong></p>
<p>When you run <code>cargo build</code>, the <code>build.rs</code> script will compile your <code>.proto</code> file and generate the corresponding Rust code. This generated code will be placed in the <code>OUT_DIR directory</code>.</p>
<p>More on <code>OUT_DIR</code> and <code>Build Scripts</code> you can find it <a target="_blank" href="https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script">here</a>.</p>
<p>Now that you have the generated code, you can use it in your Rust application:</p>
<p><strong>Include the Generated Code</strong> <strong>in your Rust project</strong></p>
<p><code>include!(concat!(env!("OUT_DIR"), "/proto.rs"));</code></p>
<p>I actually created a file named <code>mod.rs</code> inside the <code>proto/</code> directory and added the following content. This way I can follow the same pattern as my Go project and access the proto types via the the <code>proto module</code> .</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> prost;
<span class="hljs-keyword">use</span> prost::{Enumeration, Message};

include!(<span class="hljs-built_in">concat!</span>(<span class="hljs-built_in">env!</span>(<span class="hljs-string">"OUT_DIR"</span>), <span class="hljs-string">"/proto.rs"</span>));
</code></pre>
<h3 id="heading-testing-and-verifying-determinism"><strong>Testing and Verifying Determinism</strong></h3>
<p>To test it, since there is no networking layer yet, I had to take a more manual route. So I basically wrote a snippet of code in Go and Rust to generate a Block with a Transaction in it, signed everything and then checked the serialisation output of both languages.</p>
<p>Later on, after we add a networking layer and the Node can actually communicate, I create some integration test so we can have a more robust testing framework.</p>
<h4 id="heading-go-snippet">Go Snippet:</h4>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">BlockSerialization</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Block Serialization"</span>)

    mnemonicTo := <span class="hljs-string">"all wild paddle pride wheat menu task funny sign profit blouse hockey"</span>
    <span class="hljs-comment">// Generate a new private key from the mnemonic</span>
    privateKeyTo, _ := crypto.NewPrivateKeyfromMnemonic(mnemonicTo)
    <span class="hljs-comment">// fmt.Println("private key TO:", privateKeyTo)</span>
    publicKeyTo := privateKeyTo.PublicKey()
    <span class="hljs-comment">// fmt.Println("public key TO:", publicKeyTo)</span>
    addressTo := publicKeyTo.Address()
    fmt.Println(<span class="hljs-string">"address TO:"</span>, addressTo)

    mnemonicFrom := <span class="hljs-string">"hello wild paddle pride wheat menu task funny sign profit blouse hockey"</span>
    <span class="hljs-comment">// Generate a new private key from the mnemonic</span>
    privateKeyFrom, _ := crypto.NewPrivateKeyfromMnemonic(mnemonicFrom)
    <span class="hljs-comment">// fmt.Println("private key FROM:", privateKeyFrom)</span>
    publicKeyFrom := privateKeyFrom.PublicKey()
    <span class="hljs-comment">// fmt.Println("public key FROM:", publicKeyFrom)</span>
    addressFrom := publicKeyFrom.Address()
    fmt.Println(<span class="hljs-string">"address FROM:"</span>, addressFrom)

    header := &amp;proto.Header{
        PrevBlockHash: <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">byte</span>, <span class="hljs-number">32</span>),
        TxHash: <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">byte</span>, <span class="hljs-number">32</span>),
        Version: <span class="hljs-number">1</span>,
        Height: <span class="hljs-number">1</span>,
        Timestamp: <span class="hljs-number">1627483623</span>,
        Nonce: <span class="hljs-number">12345</span>,
        Difficulty: <span class="hljs-number">10</span>,
    }

    block := &amp;proto.Block{
        Header: header,
        Transactions: []*proto.Transaction{},
        PublicKey: publicKeyFrom.Bytes(),
        Signature: []<span class="hljs-keyword">byte</span>{},
        Hash: []<span class="hljs-keyword">byte</span>{},
    }

    tx := &amp;proto.Transaction{
        From: publicKeyFrom.Bytes(),
        To: publicKeyTo.Bytes(),
        Value: <span class="hljs-number">1000</span>,
        Data: []<span class="hljs-keyword">byte</span>(<span class="hljs-string">"Transaction data"</span>),
        Signature: <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">byte</span>, <span class="hljs-number">64</span>),
        Nonce: <span class="hljs-number">123</span>,
        Hash: <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">byte</span>, <span class="hljs-number">32</span>),
    }
    core.SignTransaction(&amp;privateKeyFrom, tx)
    core.AddTransaction(block, tx)

    core.SignBlock(&amp;privateKeyFrom, block)

    bBlock, _ := core.SerializeBlock(block)
    fmt.Println(<span class="hljs-string">"GO: Block WITH TRANSACTIONS hex:"</span>, hex.EncodeToString(bBlock))

}
</code></pre>
<h4 id="heading-rust-snippet">Rust Snippet:</h4>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">block_serialization</span></span>() -&gt; <span class="hljs-built_in">Result</span>&lt;(), <span class="hljs-built_in">Box</span>&gt; {
<span class="hljs-built_in">println!</span>(<span class="hljs-string">"Block Serialization"</span>);

<span class="hljs-keyword">let</span> mnemonic_to = <span class="hljs-string">"all wild paddle pride wheat menu task funny sign profit blouse hockey"</span>;
<span class="hljs-keyword">let</span> private_key_to = crypto::keys::get_private_key_from_mnemonic(&amp;mnemonic_to).unwrap();
<span class="hljs-keyword">let</span> public_key_to = private_key_to.public_key();
<span class="hljs-keyword">let</span> address_to = public_key_to.address();
<span class="hljs-built_in">println!</span>(<span class="hljs-string">"address to: {}"</span>, address_to.to_string());

<span class="hljs-keyword">let</span> mnemonic_from = <span class="hljs-string">"hello wild paddle pride wheat menu task funny sign profit blouse hockey"</span>;
<span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> private_key_from = crypto::keys::get_private_key_from_mnemonic(&amp;mnemonic_from).unwrap();
<span class="hljs-keyword">let</span> public_key_from = private_key_from.public_key();
<span class="hljs-keyword">let</span> address_from = public_key_from.address();
<span class="hljs-built_in">println!</span>(<span class="hljs-string">"address from: {}"</span>, address_from.to_string());

<span class="hljs-comment">// Create an instance of Header</span>
<span class="hljs-keyword">let</span> header = proto::Header {
    prev_block_hash: [<span class="hljs-number">0</span>; <span class="hljs-number">32</span>].to_vec(),
    tx_hash: [<span class="hljs-number">0</span>; <span class="hljs-number">32</span>].to_vec(),
    version: <span class="hljs-number">1</span>,
    height: <span class="hljs-number">1</span>,
    timestamp: <span class="hljs-number">1627483623</span>,
    nonce: <span class="hljs-number">12345</span>,
    difficulty: <span class="hljs-number">10</span>,
};

<span class="hljs-comment">// Create an instance of Block</span>
<span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> block = proto::Block {
    header: <span class="hljs-literal">Some</span>(header),
    transactions: <span class="hljs-built_in">vec!</span>[],
    public_key: public_key_from.to_bytes().to_vec(),
    signature: <span class="hljs-built_in">vec!</span>[],
    hash: <span class="hljs-built_in">vec!</span>[],
};

<span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> tx = proto::Transaction {
    from: public_key_from.to_bytes().to_vec(),
    to: public_key_to.to_bytes().to_vec(),
    value: <span class="hljs-number">1000</span>,
    data: <span class="hljs-string">b"Transaction data"</span>.to_vec(),
    signature: [<span class="hljs-number">0</span>; <span class="hljs-number">64</span>].to_vec(),
    nonce: <span class="hljs-number">123</span>,
    hash: [<span class="hljs-number">0</span>; <span class="hljs-number">32</span>].to_vec(),
};
<span class="hljs-keyword">let</span> _ = core::transaction::sign_transaction(&amp;<span class="hljs-keyword">mut</span> private_key_from, &amp;<span class="hljs-keyword">mut</span> tx).unwrap();
core::block::add_transaction(&amp;<span class="hljs-keyword">mut</span> block, tx);

core::block::sign_block(&amp;<span class="hljs-keyword">mut</span> private_key_from, &amp;<span class="hljs-keyword">mut</span> block).unwrap();

<span class="hljs-built_in">println!</span>(<span class="hljs-string">"RUST: Block WITH TRANSACTIONS hex: {:?}"</span>, hex::encode(core::block::serialize_block(block.clone()).unwrap()));

<span class="hljs-literal">Ok</span>(())
}
</code></pre>
<h4 id="heading-output-and-comparison">Output and Comparison:</h4>
<pre><code class="lang-markdown"><span class="hljs-section">## Not signed Block with signed transactions:</span>
<span class="hljs-section">### RUST:</span>
<span class="hljs-code">```
"0a530a20000000000000000000000000000000000000000000000000000000000000000012201d2f60156a6850a588d6cddd106af296316f5593a0f9f0b67ceac0c552e838f01801200128e7db85880630b960380a12bf010a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e1220e15af3cd7d9c09ebaf20d1f97ea396c218b66037cdf8e30db0ebd7bb373df56d18e80722105472616e73616374696f6e20646174612a400ba42f94db0f3ebe75e2e40fccbc7e8915510724c18769b8ad939ca44bdec82179da5bd7e7ae7079a6985ee58e77b85e74e3d76ff2c87f85723327e588220c02307b3a204c5836ec9395a4c7dee4fa71e0b2fcadfff90a747e75126fe8df184ae42c7fb61a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e"
```</span>
<span class="hljs-section">### GO:</span>
<span class="hljs-code">```
0a530a20000000000000000000000000000000000000000000000000000000000000000012201d2f60156a6850a588d6cddd106af296316f5593a0f9f0b67ceac0c552e838f01801200128e7db85880630b960380a12bf010a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e1220e15af3cd7d9c09ebaf20d1f97ea396c218b66037cdf8e30db0ebd7bb373df56d18e80722105472616e73616374696f6e20646174612a400ba42f94db0f3ebe75e2e40fccbc7e8915510724c18769b8ad939ca44bdec82179da5bd7e7ae7079a6985ee58e77b85e74e3d76ff2c87f85723327e588220c02307b3a204c5836ec9395a4c7dee4fa71e0b2fcadfff90a747e75126fe8df184ae42c7fb61a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e
```</span>

<span class="hljs-section">## Signed block:</span>
<span class="hljs-section">### RUST:</span>
<span class="hljs-code">```
"0a530a20000000000000000000000000000000000000000000000000000000000000000012201d2f60156a6850a588d6cddd106af296316f5593a0f9f0b67ceac0c552e838f01801200128e7db85880630b960380a12bf010a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e1220e15af3cd7d9c09ebaf20d1f97ea396c218b66037cdf8e30db0ebd7bb373df56d18e80722105472616e73616374696f6e20646174612a400ba42f94db0f3ebe75e2e40fccbc7e8915510724c18769b8ad939ca44bdec82179da5bd7e7ae7079a6985ee58e77b85e74e3d76ff2c87f85723327e588220c02307b3a204c5836ec9395a4c7dee4fa71e0b2fcadfff90a747e75126fe8df184ae42c7fb61a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e2240131940f20739fb191ff1c4c439e0a5f93b8e25b5c1850a500bfac644ae451a14e8c3bd691854463494ba5b2ba831c39faa583ce0b1c62ca972db8b47c2cc32082a20389bef0d3f0712e3fc5660262c61b9a2feee6475a3a01e35d9f52b2af40b932c"
```</span>
<span class="hljs-section">### GO:</span>
<span class="hljs-code">```
0a530a20000000000000000000000000000000000000000000000000000000000000000012201d2f60156a6850a588d6cddd106af296316f5593a0f9f0b67ceac0c552e838f01801200128e7db85880630b960380a12bf010a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e1220e15af3cd7d9c09ebaf20d1f97ea396c218b66037cdf8e30db0ebd7bb373df56d18e80722105472616e73616374696f6e20646174612a400ba42f94db0f3ebe75e2e40fccbc7e8915510724c18769b8ad939ca44bdec82179da5bd7e7ae7079a6985ee58e77b85e74e3d76ff2c87f85723327e588220c02307b3a204c5836ec9395a4c7dee4fa71e0b2fcadfff90a747e75126fe8df184ae42c7fb61a20ec319b757d96d2516e6ace0932923098e5b18226a45818a279adba351149938e2240131940f20739fb191ff1c4c439e0a5f93b8e25b5c1850a500bfac644ae451a14e8c3bd691854463494ba5b2ba831c39faa583ce0b1c62ca972db8b47c2cc32082a20389bef0d3f0712e3fc5660262c61b9a2feee6475a3a01e35d9f52b2af40b932c
```</span>
</code></pre>
<p>You can copy and paste those values in any code editor to check if they are the same, and as you will see the hashes of each encoded blocks are the same before and after digitally signing it.</p>
<p>As always, the full source code is available on Github:</p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">View on Github (Pull Requests are Welcome) — Rust Version</a></p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">View on Github (Pull Requests are Welcome) — Go Version</a></p>
<h3 id="heading-what-have-i-learned-from-all-this">What have I learned from all this?</h3>
<p>On this post we set out to implement Blocks and Transactions for the blockchain and encounter our first set of problems when trying to make a blockchain across two different programming languages.</p>
<p>Building a blockchain that operates across different programming languages, such as Go and Rust, introduces several challenges related to language interoperability. These challenges arise from differences in how each language handles data structures, serialisation, concurrency, and more. Here are some key issues you may encounter:</p>
<h4 id="heading-serialization-and-encoding-differences"><strong>Serialization and Encoding Differences</strong>:</h4>
<ul>
<li><p><strong>Data Representation</strong>: Different languages often represent and serialize data differently. For example, the way Go’s Gob and Rust’s Bincode handle binary encoding can lead to non-deterministic outputs, even if the input data structures are identical. This discrepancy becomes a critical issue in a blockchain network, where consistency across nodes is paramount.</p>
</li>
<li><p><strong>Byte Order (Endianness)</strong>: Some languages might use different byte orders (big-endian vs. little-endian) when encoding data. If not handled properly, this can result in different hashes for the same data, leading to consensus failures in a blockchain system.</p>
</li>
<li><p><strong>Floating-Point Precision</strong>: Some languages might handle floating-point arithmetic differently, which can lead to subtle bugs when data is shared between systems.</p>
</li>
</ul>
<h4 id="heading-concurrency-models"><strong>Concurrency Models</strong>:</h4>
<ul>
<li><p><strong>Concurrency and Parallelism</strong>: Go uses goroutines and channels for concurrency, which is quite different from Rust’s ownership-based concurrency model. When building a system where components written in different languages need to interact, ensuring that these concurrency models work seamlessly together can be difficult.</p>
</li>
<li><p><strong>Thread Safety</strong>: Rust emphasises thread safety through its ownership and borrowing system, whereas Go’s garbage collector and goroutines provide a different approach to managing memory and concurrency. Integrating components across these languages may require additional effort to ensure that memory is safely managed.</p>
</li>
</ul>
<h4 id="heading-error-handling-and-type-systems"><strong>Error Handling and Type Systems</strong>:</h4>
<ul>
<li><p><strong>Type Systems</strong>: Go’s type system is relatively straightforward and less strict compared to Rust’s, which has a more complex and expressive type system. This can make it challenging to translate data and logic between the two languages, especially when dealing with complex types or ensuring type safety.</p>
</li>
<li><p><strong>Error Handling</strong>: Rust’s approach to error handling using Result and Option types differs significantly from Go’s use of error interfaces. Integrating these systems can require additional layers of abstraction or adaptation to ensure that errors are handled consistently across the entire system.</p>
</li>
</ul>
<p>4. <strong>Tooling and Ecosystem Differences</strong>:</p>
<ul>
<li><p><strong>Build and Deployment</strong>: Managing builds and deployments across multiple languages can complicate the development workflow. Each language has its own build tools, package managers, and deployment pipelines, which need to be integrated seamlessly.</p>
</li>
<li><p><strong>Debugging and Testing</strong>: Debugging a system that spans multiple languages can be cumbersome, as it may require different tools and approaches. Similarly, testing across languages requires ensuring that test cases are consistent and that any language-specific behaviors are accounted for.</p>
</li>
</ul>
<h4 id="heading-importance-of-standards"><strong>Importance of Standards</strong></h4>
<p>Given the challenges of language interoperability and determinism, adhering to well-established and cross-compatible standards becomes crucial in distributed systems like blockchains. Here’s why:</p>
<p>1. <strong>Ensuring Consistency</strong>:</p>
<ul>
<li><p><strong>Deterministic Behavior</strong>: Standards like Protocol Buffers (protobuf) enforce consistent data serialisation across different languages. By using a common format, you ensure that the same data structure is encoded and decoded identically, regardless of the programming language. This determinism is vital in blockchains, where even a small discrepancy can lead to a fork in the network.</p>
</li>
<li><p><strong>Cross-Language Compatibility</strong>: Standards like protobuf are designed to work seamlessly across many programming languages. This means you can define your data structures once and generate compatible code for both Go and Rust (as well as many other languages), ensuring that all nodes in your blockchain network interpret the data in the same way.</p>
</li>
</ul>
<p>2. <strong>Facilitating Integration</strong>:</p>
<ul>
<li><strong>Interoperable Protocols</strong>: Using standardized protocols like gRPC (which leverages protobuf for message serialization) allows different components of your system, potentially written in different languages, to communicate effectively. This interoperability reduces the risk of errors and simplifies the integration process.</li>
</ul>
<p>Although I mentioned gRPC here, but when we get to the networking part you will see that I actually decided to go with <code>libp2p</code> instead. But we will get to that.</p>
<ul>
<li><strong>Interoperability with Other Systems</strong>: By adhering to widely-adopted standards, your blockchain can easily integrate with other systems, tools, and services that also support these standards. This is especially important if your blockchain needs to interact with external systems or be compatible with existing infrastructure.</li>
</ul>
<p>3. <strong>Simplifying Development and Maintenance</strong>:</p>
<ul>
<li><p><strong>Unified Tooling</strong>: Standards like protobuf come with a rich set of tools and libraries that make development easier. For example, you can use protoc to automatically generate serialisation code in multiple languages, reducing the likelihood of human error and speeding up the development process.</p>
</li>
<li><p><strong>Easier Debugging and Troubleshooting</strong>: When all parts of a system adhere to the same standards, it simplifies debugging and troubleshooting. For instance, if you know that both Go and Rust nodes are using the same protobuf schema, you can be confident that any discrepancies in behavior are not due to serialization issues.</p>
</li>
</ul>
<p>4. <strong>Community and Support</strong>:</p>
<ul>
<li><p><strong>Wide Adoption</strong>: Standards like protobuf, libp2p and gRPC have large, active communities and are supported by major technology companies. This means you benefit from ongoing improvements, extensive documentation, and a wealth of community knowledge.</p>
</li>
<li><p><strong>Future-Proofing</strong>: By using widely-adopted standards, you ensure that your project remains compatible with future developments and can leverage new tools and technologies as they become available.</p>
</li>
</ul>
<h3 id="heading-final-thoughts"><strong>Final thoughts</strong></h3>
<p>In a project where we are building a blockchain in two different languages, like Go and Rust, overcoming language interoperability challenges is critical to ensuring that all nodes work harmoniously. Leveraging well-established standards like protobuf not only resolves potential discrepancies but also ensures that our system is robust, scalable, and maintainable in the long term. By doing so, we are laying a solid foundation for our blockchain to succeed across different platforms and environments.</p>
<p>Don’t forget to <strong>Like</strong> and <strong>Subscribe</strong> to be notified about the next posts in the series and also <strong>STAR</strong> the projects on Github to follow what is going on over there.</p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">View on Github (Pull Requests are Welcome) — Rust Version</a></p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">View on Github (Pull Requests are Welcome) — Go Version</a></p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Crafting a Blockchain in Go and Rust: A Comparative Journey — Private keys, Public Keys and Signatures [Part 1]]]></title><description><![CDATA[Projects available on Github:
View on Github (Pull Requests are Welcome) — Rust Version
View on Github (Pull Requests are Welcome) — Go Version
<- Part 0 — Crafting a Blockchain in Go and Rust: A Comparative Journey — Introduction and Overview
Part 2...]]></description><link>https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-private-keys-public-keys-and-signatures-part-1</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-private-keys-public-keys-and-signatures-part-1</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[Open Source]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Fri, 23 Aug 2024 07:11:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396381382/f3c59425-c337-4755-a12f-8121253aee9e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-projects-available-on-github">Projects available on Github:</h4>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">View on Github (Pull Requests are Welcome) — Rust Version</a></p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">View on Github (Pull Requests are Welcome) — Go Version</a></p>
<p><a target="_blank" href="https://thepolyglotprogrammer.hashnode.dev/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-introduction-and-overview-part-0-e63dedee6b06">&lt;- Part 0 — Crafting a Blockchain in Go and Rust: A Comparative Journey — Introduction and Overview</a></p>
<p><a target="_blank" href="https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-blocks-and-transactions-part-2-1897aca38c27?showSharer=true">Part 2 - Crafting a Blockchain in Go and Rust: A Comparative Journey — Blocks and Transactions -&gt;</a></p>
<p>This episode is about private keys, public keys, signatures and adding a CLI interface to the Blockchain.</p>
<p>Today I will walk you through the initials steps I took to start building a Blockchain in both Go and Rust, and while I do that I’ll also try to lay out some of the differences and intricacies between the two programming languages. The plan is to go over the <strong>CLI Interface</strong> and why I already added one so early in the game, also cover the <strong>generation of private and public keys</strong> as well as being able to <strong>sign chunks of data and verifying with those same keys</strong>.</p>
<p>After reading this you will have a good understanding on why I decided to add a CLI interface before I even had anything done in my project and also learn about the steps I took to generate the private and public key, as well as sign and signature verification with both programming languages, Go and Rust.</p>
<p>Who knows? Maybe by the end I’ll even reveal which one is my favorite so far.</p>
<p>But a heads up, this is not a step by step tutorial, I’ll try to explain my thought process and some of decisions I took, but I will not explain line by line of the code. The code is on Github (<a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">Go</a> / <a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">Rust</a>), and I am happy to answer any questions, so feel free to reach out.</p>
<h3 id="heading-cli-interface">CLI INTERFACE</h3>
<p>On this section of the article I want to first explain why I decided to add a CLI Interface, even if it didn’t do much at first, so early in the game. And why I believe it will make my life so much easier as the project progresses.</p>
<p>I am also going to talk briefly about the different implementations, packages and crates I choose for such task, and why I did not go with the standard library.</p>
<h4 id="heading-lets-start-with-the-why">Let’s start with the why!</h4>
<blockquote>
<p>“why are you wasting time with this at this stage in the process?”</p>
</blockquote>
<p>I actually received the same question when I did my database project (<a target="_blank" href="https://github.com/joaoh82/rust_sqlite">SQLRite</a>) and the first thing I did was add a REPL interface that didn’t do anything, just echoed commands.</p>
<p>And the reason is because I wanted to have an interface ready too call out features of my application without having to pull up some hacky code on my <code>main.go</code> or <code>main.rs</code> for example. And it also forces me to design my code in a way where everything is decoupled and any dependencies I need for anything, they need to be injected it.</p>
<p>Yes, don’t worry, I also have unit tests for a lot of the code that runs every time I push to Github (or manually), but still, I like to have a way to interface directly with my application. And by having a basic CLI interface setup I can easily add commands to it, take arguments and call whatever I want in the application. I can even make the CLIs a different binary if i want, which can be really handy in the future.</p>
<h4 id="heading-adding-a-cli-interface-to-go">Adding a CLI Interface to Go</h4>
<p>As I mentioned I decided not to use the Standard Library for this because although the Go and Rust standard library provides all the essential building blocks for working with command-line arguments, flags, and interacting with the operating system. I am already imagining having commands, sub-commands, multiple arguments and flags, for example:</p>
<p>Using the CLI to restore the blockchain address from a mnemonic phrase:</p>
<pre><code class="lang-bash">&gt; ./marvin-blockchain address restore --mnemonic <span class="hljs-string">'unhappy describe tuna century because antique close trash bike bread crater notable'</span>
address: f650a946e9ddedcf9ba36105eba9a59d5dd0992d
</code></pre>
<p>But I also can have the sub-command <code>create</code> under <code>address</code> , to create a new blockchain address and mnemonic:</p>
<pre><code class="lang-bash">&gt; ./marvin-blockchain address create
Generating new address...
mnemonic: interest issue wolf swap father predict define exercise coral forum depart slide
address: 9b1c6518c0906db58f39e5c1410b02b7e486ef80
</code></pre>
<p>And if I had to build that from scratch with just the standard library would take focus out of the main target of the project, which is to create a blockchain and not a CLI application from scratch.</p>
<p>That said, I looked into a couple of options of CLI packages for Go. The top 3 ones I looked into it were <a target="_blank" href="https://github.com/urfave/cli">urfave/cli</a>, <a target="_blank" href="https://github.com/alecthomas/kong">alecthomas/kong</a> and finally <a target="_blank" href="https://github.com/spf13/cobra">spf13/cobra</a> which I ended up picking. All of them were alright, I guess <code>urfave/cli</code> and <code>alecthomas/kong</code> are lighter libraries, but at the end of the day I went with <code>cobra</code> for being more feature rich, it is battle tested by a lot of other big cli applications out there and it is the one I am more familiar with.</p>
<h4 id="heading-adding-a-cli-interface-to-rust">Adding a CLI Interface to Rust</h4>
<p>For Rust the reasoning was the same on why not to use the Standard Library, so I won’t spent time explaining again.</p>
<p>What is worth mentioning is that in the case of Rust I only looked at one crate, and that was <a target="_blank" href="https://crates.io/crates/clap">Clap</a>. I have used Clap before, it is a battle tested Crate used by a number of large projects and it’s API is super easy to use. On top of being super feature rich. So for me it was a no brainer in choosing Clap for Rust.</p>
<h3 id="heading-generating-the-private-key-and-public-key">Generating the private key and public key</h3>
<p>One of the first things to look at when generating a key pair is to look at which digital signature algorithm to choose from and on this section we will dive into a couple of these algorithms, explain how they work, highlight their differences, explain the reasoning behind the one I choose and also dive a little into each of the implementations with Go and Rust.</p>
<p>By the end of this section you should have at least have a high level understanding of these algorithms and also have a good understanding of the ground work I am laying down that will be used later on during the development of the blockchain.</p>
<h4 id="heading-what-were-our-choices">What were our choices?</h4>
<p>The two most used algorithms for digital signatures in the blockchain space are the Elliptic Curve Digital Signature Algorithm (ECDSA) with the secp256k1 curve and the Edwards-curve Digital Signature Algorithm (EdDSA) with the curve25519 curve, aka ed25519.</p>
<h4 id="heading-ecdsa-with-secp256k1">ECDSA with secp256k1</h4>
<p>ECDSA is a widely adopted asymmetric cryptographic algorithm used for digital signatures. It operates on elliptic curves and provides a secure mechanism for verifying the authenticity and integrity of data. The secp256k1 curve, specifically, is a popular elliptic curve <strong>used in Bitcoin</strong> and several other cryptocurrencies.</p>
<p>The secp256k1 curve has a specific mathematical structure that allows for efficient cryptographic operations. It is defined by the equation y² = x³ + 7 and operates over the finite field of prime numbers. ECDSA with secp256k1 utilizes the properties of this curve to generate public and private key pairs, sign messages, and verify signatures. <strong>It offers a high level of security and efficiency for cryptographic operations</strong>.</p>
<h4 id="heading-eddsa-with-curve25519">EdDSA with curve25519</h4>
<p>EdDSA is another cryptographic algorithm based on elliptic curves, specifically the Edwards curves. It was designed to provide improved security, simplicity, and performance compared to earlier algorithms like ECDSA. One commonly used Edwards curve is the curve25519. Oh and it was invented after Bitcoin was created.</p>
<p>Curve25519 is an elliptic curve defined by the equation <code>-x² + y² = 1 — (121665/121666) \ *x² * y²</code>. It operates over the prime field and is known for its efficiency and security properties. EdDSA with curve25519 leverages this curve to generate key pairs, sign messages, and verify signatures.</p>
<p>The main advantage of EdDSA is its resistance to certain types of side-channel attacks, improved performance, and enhanced security features. <strong>It has gained popularity in various blockchain platforms and cryptographic applications.</strong></p>
<h4 id="heading-differences-between-ecdsa-secp256k1-and-eddsa-curve25519">Differences between ECDSA secp256k1 and EdDSA curve25519</h4>
<p>While both ECDSA with secp256k1 and EdDSA with curve25519 provide secure digital signatures, they differ in several aspects:</p>
<ol>
<li><p>Curve Structure: ECDSA secp256k1 operates on the secp256k1 elliptic curve, while EdDSA curve25519 utilizes the curve25519 Edwards curve. These curves have different mathematical equations and properties.</p>
</li>
<li><p>Key Generation: ECDSA secp256k1 and EdDSA curve25519 have different mechanisms for key generation. ECDSA generates key pairs using the secp256k1 curve, while EdDSA uses the curve25519 curve.</p>
</li>
<li><p>Performance: EdDSA with curve25519 is generally more efficient in terms of computational resources and offers faster signature generation compared to ECDSA secp256k1. It achieves this efficiency through the use of twisted Edwards curves.</p>
</li>
<li><p>Security Features: EdDSA is designed to provide enhanced security against certain types of attacks, such as certain side-channel attacks. It incorporates additional security measures compared to ECDSA.</p>
</li>
</ol>
<p><strong>So, which one I went with?</strong></p>
<p>3…2…1… And the winner is?!!!</p>
<h4 id="heading-eddsa-with-curve25519-aka-ed25519">EdDSA with curve25519, AKA ed25519!</h4>
<p>And here is why. To be honest in my opinion and based on my very limited knowledge of cryptography there isn’t a strong enough reason to switch in either direction, both of them are cryptographic algorithms widely used for digital signatures in blockchain applications.</p>
<p><strong>So I basically made the choice based of two things:</strong></p>
<ul>
<li><strong>What do I have more experience and exposure with?</strong></li>
</ul>
<p>The answer to this one would be definitely <code>ed25519</code> .</p>
<ul>
<li><strong>Do I have stable and battle tested packages and crates that I could use?</strong></li>
</ul>
<p>And based on my previous answer I just had to find to make sure I stable enough libraries for both languages, Go and Rust. And the answer is yes.</p>
<p>For Go there is an implementation of<code>ed25519</code> that is part of the Standard Library and can be found at <code>[crypto/ed25519](https://pkg.go.dev/crypto/ed25519)</code> And if the case of Rust we there is an excellent native Ed25519 implementation called <code>[ed25519-dalek](https://crates.io/crates/ed25519-dalek)</code> . Which has fast and efficient ed25519 EdDSA key generations, signing, and verification in pure Rust.</p>
<p>With the libraries chosen I will now talk about the APIs I created for both Go and Rust and will see that they are actually pretty similar. At a high level this is what you will find on both codebases.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396377601/c38c15c1-af2d-4c4d-bf2d-acc59289a620.png" alt /></p>
<h4 id="heading-go-api-implementation">Go API Implementation</h4>
<p><strong>Constants used throughout:</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">const</span> (
    privateKeySize = ed25519.PrivateKeySize <span class="hljs-comment">// 64</span>
    publicKeySize = ed25519.PublicKeySize <span class="hljs-comment">// 32</span>
    signatureSize = ed25519.SignatureSize <span class="hljs-comment">// 64</span>
    seedSize = <span class="hljs-number">32</span>
    addressSize = <span class="hljs-number">20</span>
)
</code></pre>
<p><strong>Private Key Implementation:</strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// PrivateKey represents a private key for the Ed25519 signature scheme.</span>
<span class="hljs-keyword">type</span> PrivateKey <span class="hljs-keyword">struct</span> {
    key ed25519.PrivateKey
}

<span class="hljs-comment">// GetMnemonicFromEntropy generates a new mnemonic from a given entropy.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">GetMnemonicFromEntropy</span><span class="hljs-params">(entropy []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">string</span></span> {...}

<span class="hljs-comment">// NewPrivateKeyfromMenmonic creates a new private key from a given mnemonic.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewPrivateKeyfromMnemonic</span><span class="hljs-params">(mnemonic <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">PrivateKey</span></span> {...}

<span class="hljs-comment">// SeedFromMnemonic creates a new seed from a given mnemonic.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">SeedFromMnemonic</span><span class="hljs-params">(mnemonic <span class="hljs-keyword">string</span>)</span> []<span class="hljs-title">byte</span></span> {...}

<span class="hljs-comment">// NewPrivateKeyfromString creates a new private key from a given hex string.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewPrivateKeyfromString</span><span class="hljs-params">(s <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">PrivateKey</span></span> {...}

<span class="hljs-comment">// NewPrivateKeyFromSeed creates a new private key from a given seed byte slice.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewPrivateKeyFromSeed</span><span class="hljs-params">(seed []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">PrivateKey</span></span> {...}

<span class="hljs-comment">// Bytes creates a new private key from a byte slice.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *PrivateKey)</span> <span class="hljs-title">Bytes</span><span class="hljs-params">()</span> []<span class="hljs-title">byte</span></span> {...}

<span class="hljs-comment">// Sign signs the data with the private key.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *PrivateKey)</span> <span class="hljs-title">Sign</span><span class="hljs-params">(data []<span class="hljs-keyword">byte</span>)</span> *<span class="hljs-title">Signature</span></span> {...}

<span class="hljs-comment">// PublicKey returns the public key for the private key.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *PrivateKey)</span> <span class="hljs-title">PublicKey</span><span class="hljs-params">()</span> *<span class="hljs-title">PublicKey</span></span> {...}
</code></pre>
<p><strong>Public Key Implementation:</strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// PublicKey represents a public key for the Ed25519 signature scheme.</span>
<span class="hljs-keyword">type</span> PublicKey <span class="hljs-keyword">struct</span> {
    key ed25519.PublicKey
}

<span class="hljs-comment">// Address returns the address for the public key.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *PublicKey)</span> <span class="hljs-title">Address</span><span class="hljs-params">()</span> <span class="hljs-title">Address</span></span> {...}

<span class="hljs-comment">// Bytes creates a new public key from a byte slice.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *PublicKey)</span> <span class="hljs-title">Bytes</span><span class="hljs-params">()</span> []<span class="hljs-title">byte</span></span> {...}
</code></pre>
<p><strong>Signature Implementation:</strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// Signature represents a signature for the Ed25519 signature scheme.</span>
<span class="hljs-keyword">type</span> Signature <span class="hljs-keyword">struct</span> {
    value []<span class="hljs-keyword">byte</span>
}

<span class="hljs-comment">// Bytes creates a new signature from a byte slice.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(s *Signature)</span> <span class="hljs-title">Bytes</span><span class="hljs-params">()</span> []<span class="hljs-title">byte</span></span> {---}

<span class="hljs-comment">// Verify verifies the signature of the data with the public key.</span>
<span class="hljs-comment">// It returns true if the signature is valid, and false otherwise.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(s *Signature)</span> <span class="hljs-title">Verify</span><span class="hljs-params">(publicKey *PublicKey, data []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">bool</span></span> {...}
</code></pre>
<p><strong>Address Implementation:</strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// Address represents an address for the Ed25519 signature scheme.</span>
<span class="hljs-keyword">type</span> Address <span class="hljs-keyword">struct</span> {
    value []<span class="hljs-keyword">byte</span>
}

<span class="hljs-comment">// Bytes creates a new address from a byte slice.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(a *Address)</span> <span class="hljs-title">Bytes</span><span class="hljs-params">()</span> []<span class="hljs-title">byte</span></span> {...}

<span class="hljs-comment">// String returns the address as a hex string.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(a Address)</span> <span class="hljs-title">String</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {...}
</code></pre>
<h4 id="heading-rust-api-implementation">Rust API Implementation</h4>
<p><strong>Constants used throughout:</strong></p>
<pre><code class="lang-rust"><span class="hljs-keyword">const</span> PRIVATE_KEY_SIZE: <span class="hljs-built_in">usize</span> = ed25519_dalek::SECRET_KEY_LENGTH;
<span class="hljs-keyword">const</span> PUBLIC_KEY_SIZE: <span class="hljs-built_in">usize</span> = ed25519_dalek::PUBLIC_KEY_LENGTH;
<span class="hljs-keyword">const</span> SIGNATURE_SIZE: <span class="hljs-built_in">usize</span> = ed25519_dalek::SIGNATURE_LENGTH;
<span class="hljs-keyword">const</span> ADDRESS_SIZE: <span class="hljs-built_in">usize</span> = <span class="hljs-number">20</span>;
<span class="hljs-keyword">const</span> SEED_SIZE: <span class="hljs-built_in">usize</span> = <span class="hljs-number">32</span>;
</code></pre>
<p><strong>Private Key Implementation:</strong></p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">PrivateKey</span></span> {
    <span class="hljs-keyword">pub</span> key: SigningKey,
}

<span class="hljs-comment">/// new_entropy generates a new 16 byte entropy</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">new_entropy</span></span>() -&gt; [<span class="hljs-built_in">u8</span>; <span class="hljs-number">16</span>] {...}

<span class="hljs-comment">/// get_mnemonic_from_entropy generates a new mnemonic from the given entropy</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">get_mnemonic_from_entropy</span></span>(entropy: &amp;[<span class="hljs-built_in">u8</span>; <span class="hljs-number">16</span>]) -&gt; <span class="hljs-built_in">String</span> {...}

<span class="hljs-comment">/// get_seed_from_mnemonic generates a new seed from the given mnemonic</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">get_seed_from_mnemonic</span></span>(mnemonic: &amp;<span class="hljs-built_in">str</span>) -&gt; [<span class="hljs-built_in">u8</span>; SEED_SIZE] {...}

<span class="hljs-comment">/// get_private_key_from_mnemonic generates a new private key from the given mnemonic</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">get_private_key_from_mnemonic</span></span>(mnemonic: &amp;<span class="hljs-built_in">str</span>) -&gt; PrivateKey {...}

<span class="hljs-comment">/// new_private_key_from_string generates a new private key from the given private key string</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">new_private_key_from_string</span></span>(private_key: &amp;<span class="hljs-built_in">str</span>) -&gt; PrivateKey {...}

<span class="hljs-comment">/// new_private_key_from_seed generates a new private key from the given seed</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">new_private_key_from_seed</span></span>(seed: &amp;[<span class="hljs-built_in">u8</span>; <span class="hljs-number">32</span>]) -&gt; PrivateKey {...}

<span class="hljs-comment">/// generate_private_key generates a new private key with a random seed</span>
<span class="hljs-comment">/// (Good for testing purposes)</span>
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">generate_private_key</span></span>() -&gt; PrivateKey {...}

<span class="hljs-keyword">impl</span> PrivateKey {
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">sign</span></span>(&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">self</span>, data: &amp;[<span class="hljs-built_in">u8</span>]) -&gt; SignatureWrapper {...}

    <span class="hljs-comment">/// Sign a message with the private key</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">to_bytes</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; [<span class="hljs-built_in">u8</span>; PRIVATE_KEY_SIZE] {...}

    <span class="hljs-comment">/// Sign a message with the private key</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">public_key</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; PublicKey {...}
}
</code></pre>
<p><strong>Public Key Implementation:</strong></p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">PublicKey</span></span> {
    <span class="hljs-keyword">pub</span> key: VerifyingKey,
}

<span class="hljs-keyword">impl</span> PublicKey {
    <span class="hljs-comment">// to_bytes creates a new public key from a byte slice.</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">to_bytes</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; [<span class="hljs-built_in">u8</span>; PUBLIC_KEY_SIZE] {...}

    <span class="hljs-comment">/// address returns the address for the public key.</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">address</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; Address {...}
}
</code></pre>
<p><strong>SignatureWrapper Implementation:</strong></p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">SignatureWrapper</span></span> {
    <span class="hljs-keyword">pub</span> signature: Signature,
}

<span class="hljs-keyword">impl</span> SignatureWrapper {
    <span class="hljs-comment">/// Convert the signature to bytes</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">to_bytes</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; [<span class="hljs-built_in">u8</span>; SIGNATURE_SIZE] {...}

    <span class="hljs-comment">/// Verify a message with the public key</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">verify</span></span>(&amp;<span class="hljs-keyword">self</span>, data: &amp;[<span class="hljs-built_in">u8</span>], public_key: &amp;PublicKey) -&gt; <span class="hljs-built_in">bool</span> {...}
</code></pre>
<p><strong>Address implementation:</strong></p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Address</span></span> {
    <span class="hljs-keyword">pub</span> value: [<span class="hljs-built_in">u8</span>; ADDRESS_SIZE],
}

<span class="hljs-keyword">impl</span> Address {
    <span class="hljs-comment">/// Convert the address to a string in hex format</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">to_string</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; <span class="hljs-built_in">String</span> {...}

    <span class="hljs-comment">/// Convert the address to bytes</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">to_bytes</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; [<span class="hljs-built_in">u8</span>; ADDRESS_SIZE] {...}
}
</code></pre>
<p>The full code you will find it on Github (<a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">Go</a> / <a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">Rust</a>), but I will talk about some key points and some of the differences so far between Go and Rust. Also bare in mind that this code will probably be refactored and improved also as the project evolves.</p>
<h3 id="heading-signing-and-veryfing">Signing and Veryfing</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396379212/dd159b2d-d81c-44f6-9f53-9fbfae6adb1f.jpeg" alt /></p>
<p>The good thing of planing and building a good API is that you are laying the ground work for what is to come, and you are making things easier for yourself. And this is exactly the case here.</p>
<p>At the end of the day everything in a blockchain is just a chunk of bytes, and that could be a transaction, a block or some other piece of private information. What that is doesn’t really matter, what matters is that you are able to <code>Sign</code> and <code>Verify</code> with your Private Key and Public Key. So here we go.</p>
<p>I think the best way to exemplify is just to show the Unit Test I created that does exactly that:</p>
<p><strong>Go:</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">TestPrivateKeySign</span><span class="hljs-params">(t *testing.T)</span></span> {
    privateKey := GeneratePrivateKey() <span class="hljs-comment">// Generates a private key</span>
    publicKey := privateKey.PublicKey() <span class="hljs-comment">// Retrives the public key</span>
    invalidPrivateKey := GeneratePrivateKey() <span class="hljs-comment">// Generates another private key</span>
    invalidPublicKey := invalidPrivateKey.PublicKey() <span class="hljs-comment">// Retrievs another public key</span>

    data := []<span class="hljs-keyword">byte</span>(<span class="hljs-string">"hello, world"</span>) <span class="hljs-comment">// Any data converted into a []byte</span>
    <span class="hljs-comment">// Signs the data with your PrivateKey and generates a Signature Type</span>
    signature := privateKey.Sign(data)

    <span class="hljs-comment">// Check that the signature is the correct size</span>
    assert.Equal(t, signatureSize, <span class="hljs-built_in">len</span>(signature.value))

    <span class="hljs-comment">// Check that the signature is valid</span>
    assert.True(t, signature.Verify(publicKey, data)) <span class="hljs-comment">// Returns True</span>

    <span class="hljs-comment">// Check that the signature is invalid</span>
    assert.False(t, signature.Verify(invalidPublicKey, data)) <span class="hljs-comment">// Returns False</span>
}
</code></pre>
<p><strong>Rust:</strong></p>
<pre><code class="lang-rust"><span class="hljs-meta">#[test]</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">test_private_key_sign</span></span>() {
    <span class="hljs-comment">// Generates a private key</span>
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> private_key = generate_private_key();
    <span class="hljs-comment">// Retrives the public key</span>
    <span class="hljs-keyword">let</span> public_key: PublicKey = private_key.public_key();
    <span class="hljs-comment">// Generates another private key</span>
    <span class="hljs-keyword">let</span> invalid_private_key = generate_private_key();
    <span class="hljs-comment">// Retrievs another public key</span>
    <span class="hljs-keyword">let</span> invalid_public_key: PublicKey = invalid_private_key.public_key();

    <span class="hljs-keyword">let</span> data = <span class="hljs-string">b"hello world"</span>; <span class="hljs-comment">// Any data converted into a []byte</span>
    <span class="hljs-comment">// Signs the data with your PrivateKey and generates a SignatureWrapper Type</span>
    <span class="hljs-keyword">let</span> signature = private_key.sign(data);

    <span class="hljs-comment">// Verify the signature size</span>
    <span class="hljs-built_in">assert_eq!</span>(SIGNATURE_SIZE, signature.signature.to_bytes().len());

    <span class="hljs-comment">// Verify the signature - Return True</span>
    <span class="hljs-built_in">assert_eq!</span>(<span class="hljs-literal">true</span>, signature.verify(data, &amp;public_key));

    <span class="hljs-comment">// Verify the signature is invalid - Return False</span>
    <span class="hljs-built_in">assert_eq!</span>(<span class="hljs-literal">false</span>, signature.verify(data, &amp;invalid_public_key));
}
</code></pre>
<p>As you can see we just made use of the API that we created so far and very easily we were able to sign and verify a chunk of data.</p>
<p>By now you can start to see how this can all come together. Since when we create a Private and Public Key we can also output a Mnemonic phrase, we can easily retrieve the Private Key from that Mnemonic again in the future and use that to sign transactions, blocks and etc. And that is why is so important for you to keep your Mnemonic Secrets from your wallet actually secret. If someone gets their hand on that, they basically own your wallet.</p>
<p>(Obviously there other security mechanisms that can also be used, but just in case, store your Mnemonic phrase in a place no one will find.</p>
<h3 id="heading-comparing-go-and-rust">Comparing Go and Rust</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396380448/2426b4e2-c616-48b8-a449-a41bcb377cd5.jpeg" alt /></p>
<p>One of the things you may have already noticed is that the way we declare methods is very different between Go and Rust. When it comes to the definition no matter the language, they are always going to be similar. This is the one I use.</p>
<p>Methods are similar to functions but methods are defined within the context of a user defined type and provide a way to add behavior to those user-defined types. The way they are declared are slightly different between the two languages. Let’s look at a live example:</p>
<p>Let’s look at the implementation of the method to <code>sign</code> a chunk of data that is associated with the user defined type <code>Private Key</code> .</p>
<p><strong>In Go:</strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// Sign signs the data with the private key.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *PrivateKey)</span> <span class="hljs-title">Sign</span><span class="hljs-params">(data []<span class="hljs-keyword">byte</span>)</span> *<span class="hljs-title">Signature</span></span> {
    <span class="hljs-keyword">return</span> &amp;Signature{
        value: ed25519.Sign(p.key, data),
    }
}
</code></pre>
<p><strong>In Rust:</strong></p>
<pre><code class="lang-rust"><span class="hljs-keyword">impl</span> PrivateKey {
    <span class="hljs-comment">/// Sign a message with the private key</span>
    <span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">sign</span></span>(&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">self</span>, data: &amp;[<span class="hljs-built_in">u8</span>]) -&gt; SignatureWrapper {
        SignatureWrapper {
            signature: <span class="hljs-keyword">self</span>.key.sign(data),
        }
    }
}
</code></pre>
<p>Don’t mind the implementation of the method it self, since that is not the focus right now. But do you notice the differences?</p>
<p>In Go, all you need to do it to add that extra parameter that is declared between the keyword <code>func</code> and the function name, and also enclose that with parentheses. You also have the option of making that a reference value or a pointer value, usually depending on wether or not you will be updating any values of the instance.</p>
<p>Now in Rust you do not need that extra parameter, at least not in the same place. But you do need that the first parameter is always <code>&amp;self</code>, which represents the instance of the user defined type the method is being called on. And on top of that all your <code>methods</code> associated with that user defined type need to within an <code>impl</code> block. The <code>&amp;self</code> is actually short for <code>self: &amp;Self</code>. Within an <code>impl</code> block, the type <code>Self</code> is an alias for the type that the <code>impl</code> block is for. Methods must have a parameter named <code>self</code> of type <code>Self</code> for their first parameter, so Rust lets you abbreviate this with only the name <code>self</code> in the first parameter spot. Note that we still need to use the <code>&amp;</code> in front of the <code>self</code> shorthand to indicate that this method borrows the <code>Self</code> instance.</p>
<p>If you have trouble understanding ownership in Rust I highly recommend reading <a target="_blank" href="https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html">this chapter in The Rust Programming Language Book.</a></p>
<h4 id="heading-what-now">What now?!</h4>
<p>On this post we have walked through which packages and crates I used for my CLI interface as well as why I decided to add it to the project at this stage. We also talked about the two most widely use digital signature algorithms used by blockchains today and why I decided to go with the <code>ed25519</code> for this project. After that I explained what was built so far related to the key pair generation and also how to easily <code>sign</code> and <code>verify</code> chunks of data with those same key pairs. And to end it all out we finished with a quick comparison of Go and Rust and how the two languages approach declaring and implementing methods.</p>
<p>Don’t forget to <strong>Like</strong> and <strong>Subscribe</strong> here on <strong>Medium</strong> to be notified about the next posts in the series and also <strong>STAR</strong> the projects on Github to follow what is going on over there.</p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">View on Github (Pull Requests are Welcome) — Rust Version</a></p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">View on Github (Pull Requests are Welcome) — Go Version</a></p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Crafting a Blockchain in Go and Rust: A Comparative Journey — Introduction and Overview [Part 0]]]></title><description><![CDATA[No you did not misread the title and also no the title is not a clickbait title to get you to click. This is just one of those ideas that sound awesome when you have them and after a while the become even more awesome!
Part 1 — Crafting a Blockchain ...]]></description><link>https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-introduction-and-overview-part-0-e63dedee6b06</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-introduction-and-overview-part-0-e63dedee6b06</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Cryptography]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Sun, 11 Aug 2024 22:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396159095/10afbff1-1dec-4245-867e-548147363b42.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>No you did not misread the title and also no the title is not a clickbait title to get you to click. This is just one of those ideas that sound awesome when you have them and after a while the become even more awesome!</p>
<p><a target="_blank" href="https://thepolyglotprogrammer.hashnode.dev/crafting-a-blockchain-in-go-and-rust-a-comparative-journey-private-keys-public-keys-and-signatures-part-1">Part 1 — Crafting a Blockchain in Go and Rust: A Comparative Journey — Private keys, Public Keys and Signatures -&gt;</a></p>
<blockquote>
<p>What I cannot create, I do not understand. — Richard Feynman</p>
</blockquote>
<p>Anyway, yes I decided to write from scratch a Blockchain in both Go and Rust.</p>
<h3 id="heading-introduction">Introduction</h3>
<p>In order to do this I need to emphasise the importance of understanding difference between the two languages and how this comparative journey can highlight their strengths and weaknesses.</p>
<p>The goal is to implement the same blockchain in both languages, but taking advantage of what each language has to offer so the implementation, libraries used may differ but the goal is to be able to offer the same features and user experience in both.</p>
<h3 id="heading-motivation">Motivation</h3>
<p>Programmers love to compare programming languages. “This one is faster”, “That one is easier to understand”, “Ohh but this other one is typed and you gotta have types”. Well, I actually believe that every programming language has a purpose and there is no silver bullet. You just gotta use the best tool for the job.</p>
<p>With that in mind, have you ever watched Ocean’s Twelve? The one where the thieve challenges Ocean’s Crew to steal the same object, because it would be the only way to definitively decide who is the better thieve.</p>
<p>Well, this is where I got the idea from. I love Go, but I also love Rust and I wanted to build a blockchain from scratch to better understand the in’s and out’s of a blockchain at a deeper level, like I did before with my <a target="_blank" href="https://github.com/joaoh82/rust_sqlite">SQLRite project</a> where I build a database from scratch in Rust.</p>
<p>These types of projects, specially a blockchain, are great because they touch a wide range of topics from proper understanding of data structures, cryptography, networking, distributed computing, consensus algorithms, EVM’s and the list goes on.</p>
<p>How addresses are actually generated and secured?</p>
<p>What is the best consensus algorithm?</p>
<p>Any networking limitations?</p>
<p>How is the data stored and is there a better way?</p>
<p>What do I need to make it EVM compatible?</p>
<p>Can I actually get to a point where I can deploy a EVM Compatible smart contract on my own blockchain?</p>
<p>Well, these are some of the questions I aim to answer along the way, and there are a lot more.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396156961/3e420c94-db89-4ca4-8f64-c48117d830e8.png" alt /></p>
<h3 id="heading-what-to-expect">What to expect</h3>
<p>I wrote down a list of features and also somewhat of a Roadmap, based on my initial research and expectation but of course that is subject to change since I am diving into unexplored waters here (for me at least). With that said, I am open to any suggestions and even contributions of whoever want to lend a hand, as long as some knowledge is also shared in the process. It’s all welcome!</p>
<h4 id="heading-here-it-is">Here it is!</h4>
<h4 id="heading-features-wip">Features (WIP)</h4>
<ul>
<li><p>Proof of Work (PoW) Consensus Mechanism (Subject to Change)</p>
</li>
<li><p>Peer-to-Peer (P2P) Networking</p>
</li>
<li><p>Storage and Persistence</p>
</li>
<li><p>Transaction and Block Validation</p>
</li>
<li><p>Smart Contract Support via EVM Compatibility</p>
</li>
<li><p>JSON-RPC API</p>
</li>
<li><p>Comprehensive Unit Tests and Benchmarks</p>
</li>
</ul>
<h3 id="heading-roadmap-wip">Roadmap (WIP)</h3>
<p><strong>Not necessary prioritized in the order of development</strong></p>
<p>[ ] Add CLI support for ease of interaction<br />[ ] Implement the basic blockchain data structure<br />[ ] Proof of Work (PoW) consensus mechanism<br />[ ] Peer-to-Peer (P2P) networking implementation (transport layer)<br />[ ] Basic transaction and block validation<br />[ ] Storage and persistence for blockchain data<br />[ ] EVM integration for smart contract support<br />[ ] JSON-RPC API implementation<br />[ ] Advanced transaction handling and validation<br />[ ] Enhanced security measures and best practices<br />[ ] Performance benchmarking and optimization<br />[ ] Comprehensive documentation and examples<br />[ ] Implement wallet functionalities<br />[ ] Improve EVM compatibility and support<br />[ ] Add more consensus mechanisms (e.g., PoS)<br />[ ] Implement light client support<br />[ ] Improve network protocol for better scalability<br />[ ] Develop a robust test suite for security and performance<br />[ ] Integration with Ethereum development tools<br />[ ] Develop a block explorer<br />[ ] Implement governance mechanisms<br />[ ] Cross-chain interoperability solutions<br />[ ] Improve documentation and developer guides</p>
<p>Sorry if some of the Roadmap does not make much sense now, but creating a blockchain from scratch is no small task so there is a lot in my mind right now and I am trying to keep things fairly organised, but well, not everything will be perfect at first. The goal is to get the ball rolling and keep re-iterating again and again and adjust as we go.</p>
<p>At the time of publishing this, there is not much to see yet other than a very nice README, since I’ve been focusing mostly on research, but if you want to follow the project don’t forget to CLAP this post and also STAR the projects on Github.</p>
<p>I wonder which project will get more stars…</p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-rust">View on Github (Pull Requests are Welcome) — Rust Version</a></p>
<p><a target="_blank" href="https://github.com/joaoh82/marvin-blockchain-go">View on Github (Pull Requests are Welcome) — Go Version</a></p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Rust Smart Pointers]]></title><description><![CDATA[On this post I intend to walk down memory lane a bit to understand what exactly are Smart Pointers? Where do they come from? And of course, how do they work?
Very simply, a smart pointer is an abstract data type that simulates a pointer while providi...]]></description><link>https://hashblog.thepolyglotprogrammer.com/undestanding-rust-smart-pointers-660d59715ab9</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/undestanding-rust-smart-pointers-660d59715ab9</guid><category><![CDATA[Rust]]></category><category><![CDATA[pointers]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Sat, 22 Apr 2023 22:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396288785/e36e83a3-d53c-4939-b4f8-1c2a24474292.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>On this post I intend to walk down memory lane a bit to understand what exactly are Smart Pointers? Where do they come from? And of course, how do they work?</p>
<p>Very simply, a <a target="_blank" href="https://en.wikipedia.org/wiki/Smart_pointer">smart pointer</a> is an <a target="_blank" href="https://en.wikipedia.org/wiki/Abstract_data_type">abstract data type</a> that simulates a pointer while providing added features, such as automatic memory management and bounds checking. These are intended to reduce bugs caused by the misuse of pointers, while retaining efficiency.</p>
<p>Before we talk about how Rust deals with Smart Pointers, let’s go back a little and take a look at the history and where smart pointers came from.</p>
<h3 id="heading-a-little-bit-of-history">A little bit of history</h3>
<p>Smart pointers were first popularized in the programming language <a target="_blank" href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> during the first half of the 1990s as rebuttal to criticisms of C++’s lack of <a target="_blank" href="https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29">automatic garbage collection</a>.</p>
<p>Even though the concept of smart pointers was popularized with C++, especially the <a target="_blank" href="https://en.wikipedia.org/wiki/Reference_counting">reference-counted</a> type of smart pointers, the immediate predecessor of one of the languages that inspired C++’s design had reference-counted references built into the language. C++ was inspired in part by Simula67 and Simula67’s ancestor was Simula I. Insofar as Simula I’s <em>element</em> is analogous to C++’s pointer without <em>null</em>, and insofar as Simula I’s process with a dummy-statement as its activity body is analogous to C++’s <em>struct.</em> Simula I had reference counted elements (i.e., pointer-expressions that house indirection) to processes (i.e., records) no later than September 1965, as shown in the quoted paragraphs below.</p>
<blockquote>
<p>Processes can be referenced individually. Physically, a process reference is a pointer to an area of memory containing the data local to the process and some additional information defining its current state of execution.</p>
</blockquote>
<p>Because C++ borrowed <a target="_blank" href="https://en.wikipedia.org/wiki/Simula">Simula</a>’s approach to memory allocation — the <em>new</em> keyword when allocating a process/record to obtain a fresh <em>element</em> to that process/record — it is not surprising that C++ eventually resurrected Simula’s reference-counted smart-pointer mechanism within <em>element</em> as well.</p>
<h3 id="heading-smart-pointers-in-c">Smart Pointers in C++</h3>
<p>Very simply, a smart pointer in C++ is a class with overloaded operators, which behaves like a conventional pointer. Yet, it supplies additional value by ensuring proper and timely destruction of dynamically allocated and facilitates a well-defined object lifecycle.</p>
<h4 id="heading-the-problem-with-using-conventional-raw-pointers-in-c">The Problem with Using Conventional (Raw) Pointers in C++</h4>
<p>Unlike many other programming languages, C++ provides full flexibility to the programmer in memory allocation, deallocation and management. Unfortunately, this flexibility is a double-edged sword. On one side it makes C++ a powerful language, but on the other hand it allows the programmer to create problems related to memory-management., such as memory leaks, specially when dynamically allocated objects are not released at the right time.</p>
<p><strong>Here is an example:</strong></p>
<pre><code class="lang-cpp">SomeClass* pointerData = anObject.GetData();

pointerData-&gt;DoSomething();
</code></pre>
<p>In the above example, there is no obvious way to tell whether the memory pointer to <code>pointerData</code></p>
<ul>
<li><p>Was allocated on the <code>heap</code> , and needs to be <code>deallocated</code></p>
</li>
<li><p>Is the responsibility of the called to <code>deallocate</code></p>
</li>
<li><p>Will <code>pointerData</code> be automatically be destroyed by the object’s <code>destructor</code></p>
</li>
</ul>
<p>You could say something like. <em>“The programmer just has to be careful and follow proper best practices”</em>. In an ideal world that would be enough, but as you probably already know, in the real world it isn’t. That is why we need some mechanisms to protect us from ourselves.</p>
<h4 id="heading-how-do-smart-pointers-help-in-c">How do Smart Pointers Help in C++?</h4>
<p>Just to be clear, even with all the conventional pointer and conventional memory management techniques, the C++ programmer is not forced to use any of them when he needs to manage data on the heap/free store. The programmer can choose a smarter way to allocate and manage dynamic data by adopting the use of smart pointers in his programs:</p>
<pre><code class="lang-cpp">smart_pointer smartPointerData = anObject.GetData();
smartPointerData-&gt;Display();
(*smartPointerData).Display();

<span class="hljs-comment">// No need to worry about deallocation</span>
<span class="hljs-comment">// The Smart Pointer destructor will take care of that for you.</span>
</code></pre>
<p>By looking at it, smart pointers may behave like a conventional pointer, but in reality they supply useful features via their <code>overloaded operators</code> and <code>destructors</code> to ensure that dynamically allocated data is destroyed in a timely manner.</p>
<h4 id="heading-types-of-smart-pointers-in-c">Types of Smart Pointers in C++</h4>
<p>The management of the memory resource (that is, the ownership model implemented) is what sets smart pointer classes apart. Smart Pointers will decide what to do with the resource when they are copied and assigned to. The simplest implementation often results in not the best performance, whereas the fastest ones might not suit all applications. At the end, it is up to the programmer to understand its needs before he or she decides to use it in his or hers program.</p>
<p>The classification of smart pointers in C++ is basically the classification of their memory resource management strategies. These are:</p>
<ul>
<li><p>Deep copy</p>
</li>
<li><p>Copy and Write (COW)</p>
</li>
<li><p>Reference counted</p>
</li>
<li><p>Reference linked</p>
</li>
<li><p>Destructive copy</p>
</li>
</ul>
<p>I am not going to dive into what each of these are, because although the concepts are similar, they are C++ related and I think this is enough of C++ for now. Otherwise we will start to get too much into the weeds of C++ which was not the purpose of this post. The purpose until now was to give a little bit of background on where Smart Pointers are and where they came from.</p>
<p><strong>Now it is time to dig into Rust Smart Pointers!!</strong></p>
<h3 id="heading-smart-pointers-in-rust">Smart Pointers in Rust</h3>
<p>We have been talking about Smart Pointers this, Smart Pointers that, but what about a <a target="_blank" href="https://en.wikipedia.org/wiki/Pointer_%28computer_programming%29">Pointers</a>.</p>
<h4 id="heading-what-in-the-hell-is-a-pointer"><strong>What in the hell is a Pointer?</strong></h4>
<p>Well, a <em>pointer</em> is a variable that contains an address in memory, It points to, or refers to some other data, so the <em>pointer</em> <em>variable</em> it self does not contain the actual data. You can think of it like an arrow to that value.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396285604/40ad799f-2070-4c09-8ab8-3c54b1dd88f8.png" alt /></p>
<p>pointer variable pointer_to_value referencing a point in memory with a value</p>
<p>Let me try to explain with an example. Let’s imagine that our friend John Smith has invited me to visit him at this house and he lives in one of those Gated Communities and our friend gives us the address of the community.</p>
<p>So now we know the general location where he lives, just like your program knows generally where the temporary data for your application would be stored in memory, being the Stack or the Heap.</p>
<p>Once we get to the gated community, we need to retrieve the specific address of his house so when we get to the front gate, we ask the guard in which house our friend John Smith lives. The guard has stored the address to our friend’s house, just like your application would request the address to a specific piece of data from a <em>pointer variable.</em></p>
<p>Pointers are quite simple in theory, they simply point us to the address where our data is in memory, much like the guard points us to our friends house in the gated community.</p>
<p>Alright, that is enough about pointers in general.</p>
<h4 id="heading-what-about-pointers-in-rust">What about pointers in Rust?</h4>
<p>Well, Rust has two regular types of pointers called <em>references</em>. They are recognized by <em>ampersand</em> in front of the variable name.</p>
<p><code>&amp;</code> for an <em>immutable</em> reference. (which is the default behaviour by the way)</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">my_function</span></span>(my_variable: &amp;<span class="hljs-built_in">String</span>) {
    <span class="hljs-comment">// do something</span>
}

&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">for</span> a mutable reference.

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">my_function</span></span>(my_mutable_variable: &amp;<span class="hljs-keyword">mut</span> <span class="hljs-built_in">String</span>) {
    <span class="hljs-comment">// do something</span>
}
</code></pre>
<p>References to a value don’t actually own the value (usually), the just borrow it. In other words, the reference can disappear and the value it pointed at will still exist. This is related to the concept of <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html"><em>Ownership</em></a> in Rust, which I am not going to get into because this rabbit hole is already gone too deep and we need to start climbing our way out.</p>
<h4 id="heading-finally-smart-pointers-in-rust">Finally! Smart Pointers in Rust!</h4>
<p>The references I explained above are regular pointers, that only point to some piece of data, but they don’t do much else. Smart Pointers in Rust are actually data structures that not only act like a pointer, but also have additional metadata and extra features. <em>Features that a regular pointer would not have.</em></p>
<p><strong>You could say that they are smart cookies…</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396287197/7fd3ed1a-d3a2-426c-9334-e61f2c710c84.jpeg" alt /></p>
<p>Smart Pointer studying up</p>
<p>Smart Pointers are usually implemented using structs.</p>
<p>One difference between regular references and Smart Pointers in Rust is that references only borrow the data, while in most cases a smart pointer will own the data they point to. In other words, when the smart pointer gets dropped, the data they point to gets dropped.</p>
<p>Another important point is that a Smart Pointers implement the <code>[Deref](https://doc.rust-lang.org/std/ops/trait.Deref.html)</code> and <code>[Drop](https://doc.rust-lang.org/std/ops/trait.Drop.html)</code> traits. The <code>[Deref](https://doc.rust-lang.org/std/ops/trait.Deref.html)</code> trait allows an instance of the smart pointer struct to behave like a reference so you can write code that works with either references or Smart Pointers. The <code>[Drop](https://doc.rust-lang.org/std/ops/trait.Drop.html)</code> trait allows you to customize the code that is run when an instance of the Smart Pointer goes out of scope, which can be very useful.</p>
<p>I am not going into detail into every type of Smart Pointer in Rust. But I do want to cover the most common ones existing in the standard library at least.</p>
<ul>
<li><p><code>Box&lt;T&gt;</code> for always allocating values on the heap</p>
</li>
<li><p><code>Rc&lt;T&gt;</code>, a reference counting type that enables multiple ownership</p>
</li>
<li><p><code>Ref&lt;T&gt;</code> and <code>RefMut&lt;T&gt;</code>, accessed through <code>RefCell&lt;T&gt;</code>, a type that enforces the borrowing rules at runtime instead of compile time (to be avoided when possible).</p>
</li>
</ul>
<h4 id="heading-box">Box</h4>
<p><strong>Box</strong> is the most simple Smart Pointer and it is used to store data on the heap and not on the stack, even when the data size is known at compile time. The Box Smart Pointer it self will be stored on the Stack, but the data it points to will be stored on the Heap.</p>
<p>Box comes in handy when working with recursive types for example. At compile time the Rust compiler wants to know how much space will be required by a type, and that becomes difficult when working with recursion as in theory, it can be infinite. So, we use Box type to provide the size of the type so that compiler knows how much memory is to be allocated.</p>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">List</span></span> {
    Cons(<span class="hljs-built_in">i32</span>, <span class="hljs-built_in">Box</span>),
    Nil,
}

<span class="hljs-keyword">use</span> List::{Cons, Nil};

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> list = Cons(<span class="hljs-number">1</span>,
        <span class="hljs-built_in">Box</span>::new(Cons(<span class="hljs-number">2</span>,
            <span class="hljs-built_in">Box</span>::new(Cons(<span class="hljs-number">3</span>,
                <span class="hljs-built_in">Box</span>::new(Nil))))));
}
</code></pre>
<p>In the above example, the <strong>Cons</strong> variant needs the size of <em>i32</em> plus space to store the box pointer data. By using the box we have broken the infinite recursive chain and compiler can now figure out the size of List.</p>
<h4 id="heading-rc">Rc</h4>
<p>Rc stands for <em>Reference Counted,</em> and is this type of Smart Pointer is used to enable multiple ownership of the data, which by default is not allowed by the <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#ownership-rules">Ownership Rust model</a>. The <strong>Rc</strong> smart pointer type keeps track of the number of references to a value from which we can know how many places our variable is being used. If the reference count gets down to zero then the value is not used anywhere so the value can be cleaned up safely from memory without causing any trouble.</p>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">List</span></span> {
    Cons(<span class="hljs-built_in">i32</span>, Rc),
    Nil,
}

<span class="hljs-keyword">use</span> List::{Cons, Nil};
<span class="hljs-keyword">use</span> std::rc::Rc;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> a = Rc::new(Cons(<span class="hljs-number">5</span>, Rc::new(Cons(<span class="hljs-number">10</span>, Rc::new(Nil)))));
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"count after creating a = {}"</span>, Rc::strong_count(&amp;a));
    <span class="hljs-keyword">let</span> b = Cons(<span class="hljs-number">3</span>, Rc::clone(&amp;a));
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"count after creating b = {}"</span>, Rc::strong_count(&amp;a));
    {
        <span class="hljs-keyword">let</span> c = Cons(<span class="hljs-number">4</span>, Rc::clone(&amp;a));
        <span class="hljs-built_in">println!</span>(<span class="hljs-string">"count after creating c = {}"</span>, Rc::strong_count(&amp;a));
    }
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"count after c goes out of scope = {}"</span>, Rc::strong_count(&amp;a));
}
</code></pre>
<p>Outputs:</p>
<p>count after creating a = 1<br />count after creating b = 2<br />count after creating c = 3<br />count after c goes out of scope = 2</p>
<p>Here we can see that the <em>Rc</em> count is 1 when we create variable <strong>a</strong>, after that, when we create another variable <strong>b</strong> by cloning variable <strong>a</strong>, the count goes up by 1 to 2. Similarly, when we create another variable <strong>c</strong> by again cloning variable <strong>a</strong>, the count further goes up by 1 to 3. After <strong>c</strong> goes out of scope count goes down by 1 to 2.</p>
<h4 id="heading-refcell">RefCell</h4>
<p><strong>RefCell</strong> is what makes it possible to work with the Interior Mutability Pattern which is a design pattern in Rust that allows you to mutate data even when there are one or more immutable references to the data, which goes completely against the borrowing rules declared in the Ownership model. To be able to do that, the pattern uses unsafe code inside a data structure to bend Rust’s rules about mutation and borrowing.</p>
<p>If you are interesting in learning more about working with unsafe code, you can check it out the book <a target="_blank" href="https://doc.rust-lang.org/stable/nomicon/index.html">The Rustonomicon.</a></p>
<p>A common way to use <em>Refcell</em> is in combination with <em>Rc</em> which is a reference counter. If we have multiple owners of some data and we want to give access to mutate data then we have to use <em>Rc</em> that hold a <em>Refcell</em>.</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(Debug)]</span>
<span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">List</span></span> {
    Cons(Rc, Rc),
    Nil,
}

<span class="hljs-keyword">use</span> List::{Cons, Nil};
<span class="hljs-keyword">use</span> std::rc::Rc;
<span class="hljs-keyword">use</span> std::cell::RefCell;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> value = Rc::new(RefCell::new(<span class="hljs-number">5</span>));

    <span class="hljs-keyword">let</span> a = Rc::new(Cons(Rc::clone(&amp;value), Rc::new(Nil)));

    *value.borrow_mut() += <span class="hljs-number">10</span>;

    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"a after = {:?}"</span>, a);
    }
</code></pre>
<p>Outputs:</p>
<p>a after = Cons(RefCell { value: 15 }, Nil)</p>
<p>In the example above, we have created an instance of <em>Rc&lt;Refcell&gt;</em> and store it in a variable named <strong>value</strong> and also we created a list <strong>a</strong> with a <strong>cons</strong> variant that holds the value. We cloned <strong>value</strong> so that both <strong>a</strong> and <strong>value</strong> have ownership of inner cell which has a value of 5 rather than transferring ownership from <strong>value</strong>. After that, we add 10 in <strong>value</strong> by calling <strong>borrow_mut()</strong> on <strong>value</strong> and this method return <strong>RefMut smart pointer</strong> and we use <em>reference</em> operator on it to change the inner value of it.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>One of my favorite quotes is “What I cannot create, I do not understand” from Richard Feynman and of course that you are not going to re-create everything and start reinventing the wheel over and over again. But I do believe that it is of the most importance to at least understand how things work up to a certain level. I hope that by understanding what are Smart Pointers, where they came from and what are the different types of it, you can use this knowledge to design better system and make better decisions in the future.</p>
<p>Another nice quote that I like is “<strong>Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” from Linus Torvalds,</strong> and Smart Pointers are basically a specific type of data structure that relates to data in a certain way, so understanding can only make you a better programer and I hope I could help at least a little.</p>
<p><strong>Don’t forget to follow and hit that clap if you like the content.</strong></p>
<h4 id="heading-additional-sources">Additional sources:</h4>
<ul>
<li><p><a target="_blank" href="https://doc.rust-lang.org/stable/nomicon/index.html">The Rustonomicon.</a></p>
</li>
<li><p><a target="_blank" href="https://doc.rust-lang.org/book/title-page.html">The Rust Programming Book</a></p>
</li>
<li><p>Book <a target="_blank" href="https://www.amazon.com/gp/product/0789757745/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;tag=thepolyglotpr-20&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=0789757745&amp;linkId=a4b72e4ee2ce207468785db9cc6e3631">Sams Teach Yourself C++ in One Hour a Day</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mastering Smart Pointers in C++]]></title><description><![CDATA[In modern C++ programming, memory management is a crucial aspect of writing efficient, maintainable, and bug-free code. The C++ Standard Library provides powerful tools called smart pointers that help manage the lifetime of objects and prevent issues...]]></description><link>https://hashblog.thepolyglotprogrammer.com/mastering-smart-pointers-in-c-35163911e861</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/mastering-smart-pointers-in-c-35163911e861</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[C++]]></category><category><![CDATA[programming languages]]></category><category><![CDATA[Computer Science]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Wed, 12 Apr 2023 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396164543/2ebc1d3c-8642-4948-9dfd-562c3e651fdb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In modern C++ programming, memory management is a crucial aspect of writing efficient, maintainable, and bug-free code. The C++ Standard Library provides powerful tools called smart pointers that help manage the lifetime of objects and prevent issues such as memory leaks or dangling pointers.</p>
<p>In this blog post, we’ll explore three essential smart pointers: <code>std::unique_ptr</code>, <code>std::shared_ptr</code>, and <code>std::weak_ptr</code>. We'll discuss what they are, how they work, and when to use them, complete with code examples and use cases.</p>
<h3 id="heading-stduniqueptr-exclusive-ownership">std::unique_ptr: Exclusive Ownership</h3>
<p><code>std::unique_ptr</code> represents exclusive ownership of a dynamically allocated object. It ensures that there is only one <code>std::unique_ptr</code> pointing to an object at any given time. When the <code>std::unique_ptr</code> goes out of scope or is explicitly reset, the object it points to is automatically deleted.</p>
<p><code>std::unique_ptr</code> is useful when you want to enforce a single-owner policy and ensure automatic deletion of the object once it is no longer needed. <code>std::unique_ptr</code> cannot be copied, but it can be moved, which transfers ownership of the underlying object to another <code>std::unique_ptr</code>.</p>
<h4 id="heading-example">Example:</h4>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;memory&gt;</span></span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span> 
{</span>
<span class="hljs-keyword">public</span>:
    MyClass() 
    { 
      <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"MyClass constructor\n"</span>; 
    }

    ~MyClass() 
    { 
      <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"MyClass destructor\n"</span>; 
    }
};

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> 
</span>{
    <span class="hljs-function"><span class="hljs-built_in">std</span>::<span class="hljs-built_in">unique_ptr</span>&lt;MyClass&gt; <span class="hljs-title">uptr</span><span class="hljs-params">(<span class="hljs-keyword">new</span> MyClass())</span></span>;
    <span class="hljs-comment">// Transfer ownership</span>
    <span class="hljs-built_in">std</span>::<span class="hljs-built_in">unique_ptr</span>&lt;MyClass&gt; another_uptr = <span class="hljs-built_in">std</span>::move(uptr); 
}
</code></pre>
<p>In this example, <code>uptr</code> takes exclusive ownership of the dynamically allocated <code>MyClass</code> object. When we move <code>uptr</code> to <code>another_uptr</code>, the ownership is transferred, and the <code>MyClass</code> object is automatically destroyed when <code>another_uptr</code> goes out of scope.</p>
<h3 id="heading-stdsharedptr-shared-ownership">std::shared_ptr: Shared Ownership</h3>
<p><code>std::shared_ptr</code> represents shared ownership of a dynamically allocated object. Multiple <code>std::shared_ptr</code>s can point to the same object, and the object is automatically deleted when the last <code>std::shared_ptr</code> that points to it goes out of scope or is reset.</p>
<p><code>std::shared_ptr</code> uses reference counting to keep track of the number of shared_ptrs referencing the object. When the reference count becomes zero, the object is deleted. <code>std::shared_ptr</code> is useful when you want to share ownership of an object among multiple entities and ensure automatic deletion once all the shared_ptrs go out of scope or are reset.</p>
<h4 id="heading-example-1">Example:</h4>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;memory&gt;</span></span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span> 
{</span>
<span class="hljs-keyword">public</span>:
    MyClass() 
    { 
      <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"MyClass constructor\n"</span>; 
    }
    ~MyClass() 
    { 
      <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"MyClass destructor\n"</span>; 
    }
};

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">use_shared_ptr</span><span class="hljs-params">(<span class="hljs-built_in">std</span>::<span class="hljs-built_in">shared_ptr</span>&lt;MyClass&gt; sptr)</span> 
</span>{
    <span class="hljs-comment">// Do something with sptr</span>
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> 
</span>{
    <span class="hljs-function"><span class="hljs-built_in">std</span>::<span class="hljs-built_in">shared_ptr</span>&lt;MyClass&gt; <span class="hljs-title">sptr1</span><span class="hljs-params">(<span class="hljs-keyword">new</span> MyClass())</span></span>;
    <span class="hljs-comment">// Share ownership</span>
    <span class="hljs-built_in">std</span>::<span class="hljs-built_in">shared_ptr</span>&lt;MyClass&gt; sptr2 = sptr1; 

    use_shared_ptr(sptr1);
}
</code></pre>
<p>In this example, <code>sptr1</code> and <code>sptr2</code> share ownership of the <code>MyClass</code> object. When both <code>sptr1</code> and <code>sptr2</code> go out of scope, the object is automatically destroyed.</p>
<h3 id="heading-stdweakptr-non-owning-reference">std::weak_ptr: Non-owning Reference</h3>
<p><code>std::weak_ptr</code> is used in conjunction with <code>std::shared_ptr</code>. It holds a non-owning reference to a shared object, meaning it does not contribute to the reference count.</p>
<p>The primary use of <code>std::weak_ptr</code> is to break circular references between shared_ptrs, which can lead to memory leaks. To access the underlying object, you need to convert the <code>std::weak_ptr</code> to a <code>std::shared_ptr</code> by calling its <code>lock()</code> method. If the object has already been deleted, the <code>lock()</code> method returns an empty <code>std::shared_ptr</code>.</p>
<h4 id="heading-example-2">Example:</h4>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;memory&gt;</span></span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span> 
{</span>
<span class="hljs-keyword">public</span>:
    MyClass() 
    { 
      <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"MyClass constructor\n"</span>; 
    }
    ~MyClass() 
    { 
      <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"MyClass destructor\n"</span>; 
    }
};

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">use_weak_ptr</span><span class="hljs-params">(<span class="hljs-built_in">std</span>::weak_ptr&lt;MyClass&gt; wptr)</span> 
</span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">auto</span> locked_sptr = wptr.lock()) 
    {
        <span class="hljs-comment">// Use locked_sptr, which is a std::shared_ptr</span>
        <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"Object still exists\n"</span>;
    } 
    <span class="hljs-keyword">else</span> 
    {
        <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"Object has been deleted\n"</span>;
    }
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> 
</span>{
    <span class="hljs-function"><span class="hljs-built_in">std</span>::<span class="hljs-built_in">shared_ptr</span>&lt;MyClass&gt; <span class="hljs-title">sptr</span><span class="hljs-params">(<span class="hljs-keyword">new</span> MyClass())</span></span>;
    <span class="hljs-built_in">std</span>::weak_ptr&lt;MyClass&gt; wptr = sptr;

    use_weak_ptr(wptr);

    <span class="hljs-comment">// Release ownership</span>
    sptr.reset(); 

    use_weak_ptr(wptr);
}
</code></pre>
<p>In this example, <code>wptr</code> holds a non-owning reference to the <code>MyClass</code> object. We can use the <code>lock()</code> method to temporarily access the object through a shared_ptr. When the shared_ptr <code>sptr</code> is reset and releases ownership, <code>wptr</code> becomes invalid, and the <code>lock()</code> method returns an empty shared_ptr.</p>
<h3 id="heading-conclusion">Conclusion:</h3>
<p><code>std::unique_ptr</code>, <code>std::shared_ptr</code>, and <code>std::weak_ptr</code> are powerful tools for managing object lifetimes in C++ applications. Each of these smart pointers serves a specific purpose: <code>std::unique_ptr</code> for exclusive ownership, <code>std::shared_ptr</code> for shared ownership with reference counting, and <code>std::weak_ptr</code> for non-owning references to shared objects.</p>
<p>By understanding and using these smart pointers, you can write more efficient, maintainable, and bug-free code in your C++ projects.</p>
<p>Happy developing!</p>
<p><strong>Be sure to leave a LIKE and of course comments are always welcome!</strong></p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Rust on Kubernetes: A Beginner’s Guide to Developing and Deploying Rust Applications]]></title><description><![CDATA[Rust is a powerful and safe systems programming language that has been gaining popularity among developers due to its emphasis on safety, speed, and concurrency. Kubernetes, on the other hand, is an open-source container orchestration platform that a...]]></description><link>https://hashblog.thepolyglotprogrammer.com/rust-on-kubernetes-a-beginners-guide-to-developing-and-deploying-rust-applications-825bd7b5df66</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/rust-on-kubernetes-a-beginners-guide-to-developing-and-deploying-rust-applications-825bd7b5df66</guid><category><![CDATA[Rust]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[containers]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Sun, 26 Mar 2023 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396260292/a2967f72-7612-4669-b83e-ac562412d4be.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://www.rust-lang.org/"><strong>Rust</strong></a> is a powerful and safe systems programming language that has been gaining popularity among developers due to its emphasis on safety, speed, and concurrency. <a target="_blank" href="https://kubernetes.io/"><strong>Kubernetes</strong></a>, on the other hand, is an open-source container orchestration platform that automates deploying, scaling, and managing containerized applications. By combining <strong>Rust</strong> and <strong>Kubernetes</strong>, you can create highly performant, scalable, and secure applications that are easy to deploy and manage.</p>
<p>In this blog post, we’ll walk through the process of developing and deploying a simple Rust application on Kubernetes. This tutorial is aimed at beginner to intermediate Rust developers who want to learn more about using Rust with Kubernetes.</p>
<h4 id="heading-here-are-some-prerequisites">Here are some prerequisites…</h4>
<ul>
<li><p>Basic understanding of <a target="_blank" href="https://www.rust-lang.org/">Rust</a> programming and the Rust toolchain</p>
</li>
<li><p>Familiarity with <a target="_blank" href="https://www.docker.com/">Docker</a> and containerisation</p>
</li>
<li><p>Some experience with <a target="_blank" href="https://kubernetes.io/">Kubernetes</a> and its concepts</p>
</li>
</ul>
<h3 id="heading-lets-get-started">Let's get started!</h3>
<h4 id="heading-step-1-creating-a-simple-rust-application">Step 1: Creating a simple Rust application</h4>
<p>First, let’s create a simple Rust application that serves an HTTP endpoint. We’ll use the <code>[warp](https://github.com/seanmonstar/warp)</code> web framework for this purpose. Create a new Rust project using <code>cargo</code>:</p>
<pre><code class="lang-bash">$ cargo new rust_on_k8s
$ <span class="hljs-built_in">cd</span> rust_on_k8s
</code></pre>
<p>Add the following dependencies to your <code>Cargo.toml</code> file:</p>
<pre><code class="lang-ini"><span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">warp</span> = <span class="hljs-string">"0.3"</span>
<span class="hljs-attr">tokio</span> = { version = <span class="hljs-string">"1"</span>, features = [<span class="hljs-string">"full"</span>] }
</code></pre>
<p>Now, let's go and replace the contents of <code>src/main.rs</code> with the following code:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> warp::Filter;

<span class="hljs-meta">#[tokio::main]</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> hello = warp::path!(<span class="hljs-string">"hello"</span> / <span class="hljs-built_in">String</span>)
    .map(|name| <span class="hljs-built_in">format!</span>(<span class="hljs-string">"Hello, {}!"</span>, name));

    <span class="hljs-keyword">let</span> routes = hello;
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Starting server at 127.0.0.1:8000"</span>);
    warp::serve(routes).run(([<span class="hljs-number">127</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>], <span class="hljs-number">8000</span>)).<span class="hljs-keyword">await</span>;
}
</code></pre>
<p>This simple application in only 10 lines of code (counting empty lines :P), listens on port 8000 and echos with a greeting when you visit <code>/hello/your_name</code>.</p>
<p>To test the application, run and try to access using your browser:</p>
<p><code>$ cargo run</code></p>
<h4 id="heading-step-2-dockerizing-the-rust-application">Step 2: Dockerizing the Rust application</h4>
<p>To deploy our Rust application on Kubernetes, we need to containerize it using Docker. Create a <code>Dockerfile</code> in the root of the project with the following content:</p>
<p># Using the official Rust image as a builder</p>
<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> rust:<span class="hljs-number">1.58</span> as builder

<span class="hljs-keyword">WORKDIR</span><span class="bash"> /usr/src/app</span>

<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>

<span class="hljs-keyword">RUN</span><span class="bash"> cargo build --release</span>

<span class="hljs-comment"># Using a minimal image for the runtime</span>
<span class="hljs-keyword">FROM</span> debian:buster-slim

<span class="hljs-keyword">COPY</span><span class="bash"> --from=builder /usr/src/app/target/release/rust_on_k8s /usr/<span class="hljs-built_in">local</span>/bin/rust_on_k8s</span>

<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"rust_on_k8s"</span>]</span>
</code></pre>
<p>Build the Docker image:</p>
<p><code>$ docker build -t rust_on_k8s:latest .</code></p>
<h4 id="heading-step-3-deploying-the-rust-application-on-kubernetes">Step 3: Deploying the Rust application on Kubernetes</h4>
<p>To deploy the Rust application on Kubernetes, create a file named <code>rust_on_k8s.yaml</code> with the following content:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">rust-on-k8s</span>
<span class="hljs-attr">spec:</span>
    <span class="hljs-attr">replicas:</span> <span class="hljs-number">3</span>
<span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">rust-on-k8s</span>
<span class="hljs-attr">template:</span>
<span class="hljs-attr">metadata:</span>
    <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">rust-on-k8s</span>
<span class="hljs-attr">spec:</span>
    <span class="hljs-attr">containers:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">image:</span> <span class="hljs-string">rust_on_k8s:latest</span>
        <span class="hljs-attr">name:</span> <span class="hljs-string">rust-on-k8s</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8000</span>

<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">rust-on-k8s</span>
<span class="hljs-attr">ports:</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
<span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
<span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
<span class="hljs-attr">spec:</span>
    <span class="hljs-attr">selector:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">rust-on-k8s</span>
    <span class="hljs-attr">type:</span> <span class="hljs-string">LoadBalancer</span>
</code></pre>
<p>This <strong>YAML</strong> file defines a <strong>Deployment</strong> and a <strong>Service</strong>. The <strong>Deployment</strong> specifies that we want three replicas of our Rust application, each running in a separate container. The <strong>Service</strong> creates a load balancer to distribute incoming traffic evenly among the replicas and expose the application on port 80.</p>
<p>Before applying this configuration, you need to push the Docker image to a container registry accessible by your Kubernetes cluster. For example, you can use Docker Hub, Google Container Registry, or Amazon Elastic Container Registry.</p>
<p><strong>Here is some information on docker push:</strong> <a target="_blank" href="https://docs.docker.com/engine/reference/commandline/push/">https://docs.docker.com/engine/reference/commandline/push/</a></p>
<p>Assuming you’ve pushed the Docker image to Docker Hub, update the `image` field in the `rust_on_k8s.yaml` file to point to the correct image:</p>
<p>containers:<br /><code>- name: rust-on-k8s   image: your_dockerhub_username/rust_on_k8s:latest   ports:   - containerPort: 8000</code></p>
<p>Now, apply the configuration to your Kubernetes cluster:</p>
<p><code>$ kubectl apply -f rust_on_k8s.yaml</code></p>
<p>After a few moments, your Rust application should be up and running on Kubernetes. You can check the status of the deployment and service with the following commands:</p>
<p><code>$ kubectl get deployments   $ kubectl get services</code></p>
<p>When the service shows an external IP address, you can access the Rust application by navigating to <code>[http://EXTERNAL_IP/hello/your_name](http://EXTERNAL_IP/hello/your_name.)</code><a target="_blank" href="http://EXTERNAL_IP/hello/your_name.">.</a></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this blog post, we walked you through creating a simple Rust application, containerising it with Docker, and deploying it on Kubernetes. Of course that the application we developed and deploy is quite simple and in a production large scale environment there is a lot more we would need to worry about, but at least here we managed to cover the base that you can build on top of.</p>
<p>By combining Rust’s safety and performance with Kubernetes’ scalability and ease of management, you can easily build powerful, secure, and reliable applications for modern cloud environments.</p>
<p>Keep experimenting and learning about Rust and Kubernetes to unlock their full potential, and don’t forget to share your knowledge with the community!</p>
<p>Happy developing!</p>
<p><strong>Be sure to leave a LIKE and of course comments are always welcome!</strong></p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Switching From C++ to Rust]]></title><description><![CDATA[A Practical Approach
I’ve been writing C++ on and off professionally for maybe 10 years now, and started to use Rust about 2 to 3 years ago.
Here I’d like to share my experience and thoughts on the transition between the two languages with code examp...]]></description><link>https://hashblog.thepolyglotprogrammer.com/switching-from-c-to-rust-a48141cb80da</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/switching-from-c-to-rust-a48141cb80da</guid><category><![CDATA[Rust]]></category><category><![CDATA[C++]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[programming languages]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Thu, 23 Mar 2023 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396257978/4cf2cfaa-ddaa-4798-bce7-af07f1b6333d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A Practical Approach</p>
<p>I’ve been writing C++ on and off professionally for maybe 10 years now, and started to use Rust about 2 to 3 years ago.</p>
<p>Here I’d like to share my experience and thoughts on the transition between the two languages with code examples to illustrate the differences.</p>
<p><strong>Disclaimer:</strong> This article is not a C++ vs Rust comparison. It’s just my personal experience and opinions about things that are important to me, not the engineering community in general.</p>
<h3 id="heading-the-type-of-work-you-do-influences-your-perception">The type of work you do influences your perception</h3>
<p>I think that the type of work you do highly influences your perception about a language and technology.</p>
<p>With C++, I have spent a lot of my time writing tools for different systems and in the most recent years I have dove into game development with C++ also. Both of these applications can be very different in the way they assume ownership, manage memory, use system calls and interact with the kernel. The user experience is also very different depending on the case, where some case performance matters a lot more than others.</p>
<p>As for Rust I started my experience working on Open Source projects and took upon myself to develop an entire database from scratch which is the perfect application for the language, since memory management and ownership are critical for any database engine.</p>
<p>You can find the project here: <a target="_blank" href="https://github.com/joaoh82/rust_sqlite">https://github.com/joaoh82/rust_sqlite</a></p>
<h3 id="heading-now-to-the-important-points">Now to the important points:</h3>
<h4 id="heading-memory-safety-ownership-and-borrowing">Memory Safety: Ownership and Borrowing</h4>
<p>One of the most well-known features of Rust is its memory safety guarantees. To illustrate this difference, let’s consider a simple example in C++ and Rust.</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// C++</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">foo</span><span class="hljs-params">(<span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&amp; vec)</span> </span>{
    vec.push_back(<span class="hljs-number">42</span>);
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; vec = {<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>};
    foo(vec);
    <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; vec.back() &lt;&lt; <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> #<span class="hljs-meta-keyword">include</span></span>
</code></pre>
<pre><code class="lang-rust"><span class="hljs-comment">// Rust</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">foo</span></span>(vec: &amp;<span class="hljs-keyword">mut</span> <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">i32</span>&gt;) {
    vec.push(<span class="hljs-number">42</span>);
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> vec = <span class="hljs-built_in">vec!</span>[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
    foo(&amp;<span class="hljs-keyword">mut</span> vec);
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{}"</span>, vec.last().unwrap());
}
</code></pre>
<p>The Rust code is more verbose, but it’s also more explicit about the ownership and borrowing of resources. The <code>&amp;mut</code> keyword in Rust ensures that the <code>vec</code> reference is mutable, and there's no risk of accidentally modifying the original data.</p>
<h4 id="heading-the-compiler">The Compiler:</h4>
<p>Error messages from both C++ and Rust compilers can be daunting and necessitate effort to comprehend and address appropriately. However, the underlying reasons for this vary between the two languages.</p>
<p>In C++, error messages can be so lengthy that their size is measured in kilobytes. An infinite scroll feature in your terminal emulator becomes essential, as the compiler generates copious amounts of text. Over time, you develop an intuition for whether it’s more productive to read the error message or scrutinize your code based on the message’s size. Generally, the larger the error, the more effective it is to simply examine your code. Resolving this issue may necessitate altering the way C++ templates are defined.</p>
<p>Conversely, in Rust, encountering a compiler error (after addressing any glaring typos) often spells trouble. These errors typically suggest that you need to modify your code structure or invest time in refining lifetimes to ensure memory safety. While this process can be time-consuming and frustrating, it’s crucial to heed the compiler’s guidance. Embracing this humbling experience often results in superior code. Additionally, Rust’s error messages are concise enough to fit on a single screen, which is a pleasant bonus.</p>
<h4 id="heading-build-system-cargo">Build System: Cargo</h4>
<p>Rust’s build system, Cargo, is a breath of fresh air compared to C++’s disparate build systems. To demonstrate this, let’s look at a simple example of adding a dependency.</p>
<p>In Rust, you just need to add a line in the <code>Cargo.toml</code> file:</p>
<pre><code class="lang-ini"><span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">serde</span> = <span class="hljs-string">"1.0.130"</span>
</code></pre>
<p>In C++, you’d need to modify your build files, which could be CMake, Bazel, or something else, often requiring more steps and knowledge of each build system.</p>
<h4 id="heading-type-system-generics-and-enums">Type System: Generics and Enums</h4>
<p>Rust’s type system allows for more expressive and safe code. Let’s look at an example of generics with traits in Rust compared to templates in C++.</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// C++</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>

<span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">typename</span> T&gt;
<span class="hljs-function">T <span class="hljs-title">add</span><span class="hljs-params">(T a, T b)</span> </span>{
    <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>) &lt;&lt; <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<pre><code class="lang-rust"><span class="hljs-comment">// Rust</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">add</span></span>&lt;T: std::ops::Add&lt;Output = T&gt;&gt;(a: T, b: T) -&gt; T {
    a + b
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{}"</span>, add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
}
</code></pre>
<p>In Rust, traits clearly indicate the contract expected from the type, making the code easier to understand and reason about.</p>
<p>Enums in Rust are also more powerful than their C++ counterparts. Here’s an example using the <code>Result</code> enum:</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// C++</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdexcept&gt;</span></span>

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">divide</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{
    <span class="hljs-keyword">if</span> (b == <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">throw</span> <span class="hljs-built_in">std</span>::runtime_error(<span class="hljs-string">"Division by zero"</span>);
    }
    <span class="hljs-keyword">return</span> a / b;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">try</span> {
        <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; divide(<span class="hljs-number">10</span>, <span class="hljs-number">0</span>) &lt;&lt; <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
    } <span class="hljs-keyword">catch</span> (<span class="hljs-keyword">const</span> <span class="hljs-built_in">std</span>::runtime_error&amp; e) {
        <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cerr</span> &lt;&lt; <span class="hljs-string">"Error: "</span> &lt;&lt; e.what() &lt;&lt; <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<pre><code class="lang-rust"><span class="hljs-comment">// Rust</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">divide</span></span>(a: <span class="hljs-built_in">i32</span>, b: <span class="hljs-built_in">i32</span>) -&gt; <span class="hljs-built_in">Result</span>&lt;<span class="hljs-built_in">i32</span>, &amp;<span class="hljs-symbol">'static</span> <span class="hljs-built_in">str</span>&gt; {
    <span class="hljs-keyword">if</span> b == <span class="hljs-number">0</span> {
        <span class="hljs-literal">Err</span>(<span class="hljs-string">"Division by zero"</span>)
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-literal">Ok</span>(a / b)
    }
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">match</span> divide(<span class="hljs-number">10</span>, <span class="hljs-number">0</span>) {
        <span class="hljs-literal">Ok</span>(result) =&gt; <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{}"</span>, result),
        <span class="hljs-literal">Err</span>(e) =&gt; eprintln!(<span class="hljs-string">"Error: {}"</span>, e),
    }
}
</code></pre>
<p>In Rust, the <code>Result</code> enum is used as a common way to express fallible computations, making error handling more consistent and predictable across different libraries.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In conclusion, transitioning from C++ to Rust has been a positive experience for me. To be honest, I haven’t really transitioned I just now have Rust also under my belt as I have C++, since I still use both extensively. That said, rust’s memory safety guarantees, powerful type system, and consistent build system have made my day-to-day developer experience more enjoyable. While Rust’s syntax may be more verbose, the benefits it provides in terms of safety and expressiveness are well worth it.</p>
<p>Happy developing!</p>
<p><strong>Be sure to leave a CLAP and of course comments are always welcome!</strong></p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Rust Macros the right way]]></title><description><![CDATA[On this blog post I am going to talk about Macros, well Rust Macros, not the type of Macros you see on the picture above, so if you came in here looking for a tutorial on how much carbs, fats and proteins to ingest every day I am sorry to disappoint ...]]></description><link>https://hashblog.thepolyglotprogrammer.com/rust-macros-the-right-way-65a9ba8780bc</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/rust-macros-the-right-way-65a9ba8780bc</guid><category><![CDATA[Rust]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[programming languages]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Thu, 14 Jul 2022 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396282638/a9926710-8a21-42bc-b28c-f5b413a7c602.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>On this blog post I am going to talk about Macros, well Rust Macros, not the type of Macros you see on the picture above, so if you came in here looking for a tutorial on how much carbs, fats and proteins to ingest every day I am sorry to disappoint you. But back lets get back on track here, I would like to talk about specifically what are Macros? What type of Macros there are in Rust? And when to use them?</p>
<p>So the plan here is to start by defining what are Macros in a more general context and within the Rust language. Once we understand what they are we are going to take a deeper dive into the different types of macros we have in the Rust Programming Language and maybe throw in some examples in there, because theory without practice just does not stick. And to finish off the post I am going to talk about when to use Macros and some knows use cases out there.</p>
<h3 id="heading-what-are-macros">What are Macros?</h3>
<p>In a more general context a Macro is just a shorthand for a programming term: macroinstruction. In the most basic terms, a macro is a way to automate a simple task. They can be used in a variety of different ways, from Microsoft Excel Macros to Automating tasks on your operating system.</p>
<h4 id="heading-what-are-macros-in-the-context-of-rust-programming">What are Macros in the context of Rust programming?</h4>
<p>A quote directly out of the <a target="_blank" href="https://doc.rust-lang.org/book/ch19-06-macros.html">Rust Book</a>, "Fundamentally, macros are a way of writing code that writes other code, which is known as <em>metaprogramming</em>." A lot of times in our day to day we write the exact same code over and over again and Macros are useful for reducing the amount of code you have to write and maintain, also helps to keep your code cleaner (if you use it right), which is also one of the roles of functions. However, macros have some additional powers that functions don’t, that we will get into it later in the blog post.</p>
<p>Let's look at an example. If you have been using Rust for more than a day you probably used the Macro <em>println!,</em> which as you may know prints a formatted text and add a <em>\n (new line)</em> at the end for you.</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello there."</span>)
}
</code></pre>
<p>But have you ever stoped to think what goes on behind the scenes when you write that? Have you ever thought about what you would have to do to actually print a text to the console with the <em>println!</em> macro? Well, if you would like to print a list of text without using the <em>println!</em> this is one way you could do it.</p>
<pre><code class="lang-rust"><span class="hljs-comment">// use Write trait that contains write() function  </span>
<span class="hljs-keyword">use</span> std::io::Write;  

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {  
    std::io::stdout().write(<span class="hljs-string">b"Hello, world!\n"</span>).unwrap();  
}
</code></pre>
<p>Can you imagine having to write all that every time you needed to print one single line of text to the console? No thanks!</p>
<p>Well, and if you are curious, this is what the <em>println!</em> macro definition actually looks like:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[macro_export]</span>  
<span class="hljs-meta">#[stable(feature = <span class="hljs-meta-string">"rust1"</span>, since = <span class="hljs-meta-string">"1.0.0"</span>)]</span>  
<span class="hljs-meta">#[cfg_attr(not(test), rustc_diagnostic_item = <span class="hljs-meta-string">"println_macro"</span>)]</span>  
<span class="hljs-meta">#[allow_internal_unstable(print_internals, format_args_nl)]</span>  
<span class="hljs-built_in">macro_rules!</span> println {  
    () =&gt; {  
        $crate::<span class="hljs-built_in">print!</span>(<span class="hljs-string">"\n"</span>)  
    };  
    ($($arg:tt)*) =&gt; {{  
        $crate::io::_print($crate::format_args_nl!($($arg)*));  
    }};  
}
</code></pre>
<p>Reference: <a target="_blank" href="https://doc.rust-lang.org/src/std/macros.rs.html#101">https://doc.rust-lang.org/src/std/macros.rs.html#101</a></p>
<p>Even the macro is using Macros! Wow! But well, after you have that down, you life you get a lot easier for sure.</p>
<h3 id="heading-different-types-of-macros">Different Types of Macros</h3>
<p>Rust has two types of macros:</p>
<ol>
<li><strong>Declarative macros</strong> sometimes referred to as "macros by example", “<code>macro_rules!</code> macros,” or just plain “macros”. <em>Declarative macros</em> enable you to write something similar to a match expression that operates on the Rust code you provide as arguments. It uses the code you provide to generate code that replaces the macro invocation.</li>
</ol>
<p>We have already looked at a real example on how the <em>println!</em> is defined, but now lets look at how to define one of our own.</p>
<pre><code class="lang-rust"><span class="hljs-comment">// use macro_rules! {}</span>
<span class="hljs-built_in">macro_rules!</span> add{
    <span class="hljs-comment">// match like arm for macro</span>
    ($a:expr,$b:expr)=&gt;{
        <span class="hljs-comment">// macro expand to this code</span>
        {
            <span class="hljs-comment">// $a and $b will be templated using the value/variable provided to macro</span>
            $a+$b
        }
    }
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>(){
    <span class="hljs-comment">// call to macro, $a=1 and $b=2</span>
    add!(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>);
}
</code></pre>
<p>This code creates a macro that adds two numbers. The annotation <code>[[macro_rules!]](https://doc.rust-lang.org/rust-by-example/macros.html)</code> is used with the name of the macro, <code>add</code>, and the body of the macro.</p>
<p>The macro doesn’t really add two numbers, it just replaces itself with the code to add two numbers <strong>at compile time</strong>. Very similar to a match statement in this case the macro definition will look for the pattern that matches the parameters passed.</p>
<ol>
<li><strong>Procedural macros</strong> allow you to operate on the abstract syntax tree (AST) of the Rust code it is given. <em>Procedural macros</em> act more like functions in a sense. They accept some code as an input, operate on the code, and outputs some other piece of code matching against any pattern and replacing the code just like declarative macros do.</li>
</ol>
<p>The three kinds of procedural macros:</p>
<ul>
<li><p>Attribute-like macros</p>
</li>
<li><p>Custom derive macros</p>
</li>
<li><p>Function-like macros (not covered on this blog post, unfortunetely)</p>
</li>
</ul>
<p>Let's take a quick look into each of them…</p>
<p>To write a procedural macro, first we start by creating a project using <code>cargo new my-macro-lib --lib</code>. Once the project is ready, update the <code>Cargo.toml</code> to notify cargo the project will create procedural macros.</p>
<pre><code class="lang-ini"><span class="hljs-comment"># Cargo.toml</span>
<span class="hljs-section">[lib]</span>
<span class="hljs-attr">proc-macro</span> = <span class="hljs-literal">true</span>
</code></pre>
<p>Now we are all set to venture into procedural macros.</p>
<h4 id="heading-attribute-macros">Attribute macros:</h4>
<p><em>Attribute-like</em> macros helps you to create a custom attribute that attaches itself to an item and allows you to manipulate that item. Ohh and It can also take arguments!</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[some_attribute(some_argument)]</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">my_task</span></span>(){
<span class="hljs-comment">// some code</span>
}
</code></pre>
<p>In the above code, <code>some_attribute</code> is an attribute macro. It manipulates the function <code>my_task</code>.</p>
<p>The function that defines a procedural macro takes a <code>TokenStream</code> as an input and produces a <code>TokenStream</code> as an output. The <code>TokenStream</code> type is defined by the <code>proc_macro</code> crate that we included above in the <code>Cargo.toml</code> and represents a sequence of tokens. This is the core of the macro: the source code that the macro is operating on makes up the input <code>TokenStream</code>, and the code the macro produces is the output <code>TokenStream</code>. To write a procedural macro, we also need to write our parser to parse <code>TokenStream</code>. The Rust community has a very good crate, <code>[syn](https://docs.rs/syn/1.0.53/syn/)</code>, for parsing <code>TokenStream</code>.</p>
<h4 id="heading-custo-derive-macros">Custo Derive macros:</h4>
<p>As you’ve seen Rust provides a mechanism called “derive” that lets you implement traits easily. Let's look at a quick example:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(Debug)]</span>  
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Point</span></span> {  
    x: <span class="hljs-built_in">i32</span>,  
    y: <span class="hljs-built_in">i32</span>,  
}
</code></pre>
<p>That is a lot simpler then, don't you think?</p>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Point</span></span> {  
    x: <span class="hljs-built_in">i32</span>,  
    y: <span class="hljs-built_in">i32</span>,  
}
</code></pre>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> std::fmt;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-keyword">impl</span> fmt::<span class="hljs-built_in">Debug</span> <span class="hljs-keyword">for</span> Point {  
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">fmt</span></span>(&amp;<span class="hljs-keyword">self</span>, f: &amp;<span class="hljs-keyword">mut</span> fmt::Formatter) -&gt; fmt::<span class="hljs-built_in">Result</span> {  
        <span class="hljs-built_in">write!</span>(f, <span class="hljs-string">"Point {{ x: {}, y: {} }}"</span>, <span class="hljs-keyword">self</span>.x, <span class="hljs-keyword">self</span>.y)  
    }  
}
</code></pre>
<p>Rust includes several traits that you can derive in his codebase, but it also lets you define your own.</p>
<p>Let’s build a very simple trait, and derive it with a custom derive.</p>
<p>The first thing we need to do is start a new crate for our project.</p>
<pre><code class="lang-rust">$ cargo new --bin hello-world
</code></pre>
<p>All we want is to be able to call <code>hello_world()</code> on a derived type. Something like this:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(HelloWorld)]</span>  
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Pancakes</span></span>;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {  
    Pancakes::hello_world();  
}
</code></pre>
<p>With some kind of nice output, like <code>Hello, World! My name is Pancakes!</code>.</p>
<p>Let's start by writing what the use of our macro would look like from the user's perspective. Our <code>src/main.rs</code> would look like this:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[macro_use]</span>  
<span class="hljs-keyword">extern</span> <span class="hljs-keyword">crate</span> hello_world_derive;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">trait</span> <span class="hljs-title">HelloWorld</span></span> {  
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">hello_world</span></span>();  
}
</code></pre>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(HelloWorld)]</span>  
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">FrenchToast</span></span>;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(HelloWorld)]</span>  
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Waffles</span></span>;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {  
    FrenchToast::hello_world();  
    Waffles::hello_world();  
}
</code></pre>
<p>With that we would expect the output:</p>
<pre><code class="lang-rust">Hello, World! My name is FrenchToast  
Hello, World! My name is Waffles
</code></pre>
<p>Great. Now that we know what we want let's write the procedural macro. At the moment, procedural macros need to be in their own library crate. As such, there’s a convention; for a crate named <code>foo</code>, a custom derive procedural macro is called <code>foo-derive</code>. Let's start a new crate called <code>hello-world-derive</code> inside our <code>hello-world</code> project.</p>
<pre><code class="lang-rust">$ cargo new hello-world-derive --lib
</code></pre>
<p>To make sure that our <code>hello-world</code> crate is able to find this new crate we've created, we'll add it to our toml:</p>
<pre><code class="lang-rust">[dependencies]  
hello-world-derive = { path = <span class="hljs-string">"hello-world-derive"</span> }
</code></pre>
<p>Now let's look at the source of our <code>hello-world-derive</code> crate, here's one way it could look like:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">extern</span> <span class="hljs-keyword">crate</span> proc_macro;  
<span class="hljs-keyword">extern</span> <span class="hljs-keyword">crate</span> syn;  
<span class="hljs-meta">#[macro_use]</span>  
<span class="hljs-keyword">extern</span> <span class="hljs-keyword">crate</span> quote;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> proc_macro::TokenStream;
</code></pre>
<pre><code class="lang-rust"><span class="hljs-meta">#[proc_macro_derive(HelloWorld)]</span>  
<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">hello_world</span></span>(input: TokenStream) -&gt; TokenStream {  
    <span class="hljs-comment">// Construct a string representation of the type definition  </span>
    <span class="hljs-keyword">let</span> s = input.to_string();  

    <span class="hljs-comment">// Parse the string representation  </span>
    <span class="hljs-keyword">let</span> ast = syn::parse_derive_input(&amp;s).unwrap();
</code></pre>
<pre><code class="lang-rust"> <span class="hljs-comment">// Build the impl  </span>
    <span class="hljs-keyword">let</span> gen = impl_hello_world(&amp;ast);  

    <span class="hljs-comment">// Return the generated impl  </span>
    gen.parse().unwrap()  
}
</code></pre>
<p>There is a lot going on here I know. Here we are making use of two crates: <code>[syn](https://crates.io/crates/syn)</code> and <code>[quote](https://crates.io/crates/quote)</code>. As you may have noticed, <code>input: TokenSteam</code> is immediately converted to a <code>String</code>. This <code>String</code> is a string representation of the Rust code for which we are deriving <code>HelloWorld</code>. At the moment, the only thing you can do with a <code>TokenStream</code> is convert it to a string, as far as I know at least (I may be wrong).</p>
<p>What we really need is to be able to <em>parse</em> Rust code into something usable. This is where <code>syn</code> comes to play. The other crate we've introduced is <code>quote</code>. It's essentially the dual of <code>syn</code> as it will make generating Rust code really easy. Remember? Input and Output…</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396281029/c7edbd23-636f-4554-aeb0-30522705afdc.jpeg" alt /></p>
<p>What we are doing here is we are taking a <code>String</code> of the Rust code for the type we are deriving, parsing it using <code>syn</code>, constructing the implementation of <code>hello_world</code> (using <code>quote</code>), then passing it back to Rust compiler.</p>
<p>One last note: you’ll see some <code>unwrap()</code>s there. If you want to provide an error for a procedural macro, then you should <code>panic!</code> with the error message, unfortunately. In this case, I am trying to keep it as simple as possible.</p>
<p>Awesome, we got this far, now let’s write <code>impl_hello_world(&amp;ast)</code>.</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">impl_hello_world</span></span>(ast: &amp;syn::DeriveInput) -&gt; quote::Tokens {  
    <span class="hljs-keyword">let</span> name = &amp;ast.ident;  
    quote! {  
        <span class="hljs-keyword">impl</span> HelloWorld <span class="hljs-keyword">for</span> #name {  
            <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">hello_world</span></span>() {  
                <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello, World! My name is {}"</span>, <span class="hljs-built_in">stringify!</span>(#name));  
            }  
        }  
    }  
}
</code></pre>
<p>So this is where quotes comes in. The <code>ast</code> argument is a struct that gives us a representation of our type (which can be either a <code>struct</code> or an <code>enum</code>). Check out the <a target="_blank" href="https://docs.rs/syn/0.11.11/syn/struct.DeriveInput.html">docs</a>, there is some useful information there. If you have worked with any type of parsing before, you may be familiar with ASTs. We are able to get the name of the type using <code>ast.ident</code>. The <code>quote!</code> macro (I know, a macro within a macro, feels we are in that inception movie, anyway…) lets us write up the Rust code that we wish to return and convert it into <code>Tokens</code>. <code>quote!</code> lets us use some really cool templating mechanics; we simply write <code>#name</code> and <code>quote!</code> will replace it with the variable named <code>name</code>. You can even do some repetition similar to regular macros work. You should check out the <a target="_blank" href="https://docs.rs/quote">docs</a> for a good introduction.</p>
<p>So I think that’s it. Oh, well, we do need to add dependencies for <code>syn</code> and <code>quote</code> in the <code>Cargo.toml</code> for <code>hello-world-derive</code>.</p>
<pre><code class="lang-rust">[dependencies]  
syn = <span class="hljs-string">"0.11.11"</span>  
quote = <span class="hljs-string">"0.3.15"</span>
</code></pre>
<pre><code class="lang-rust">[lib]  
proc-<span class="hljs-keyword">macro</span> = <span class="hljs-literal">true</span>
</code></pre>
<p>Ok so now, let’s compile <code>hello-world</code>. Executing <code>cargo run</code> now yields:</p>
<pre><code class="lang-rust">Hello, World! My name is FrenchToast  
Hello, World! My name is Waffles
</code></pre>
<p>That is it! We have built our first macro. I know it doesn't really do much, but we were able to show what it can do and now the ball is on your court.</p>
<h3 id="heading-when-to-use-macros">When to use Macros?</h3>
<p>One of the advantages of using macros is that they don’t evaluate their arguments eagerly like functions do, which is one of the motivations to use macros other than functions.</p>
<p>A general <em>rule of thumb</em> is that macros can be used in situations where functions fail to provide the desired solution, where you have code that is quite repetitive, or in cases where you need to inspect the structure of your types and <strong>generate code at compile time</strong>. Taking examples from real use cases, Rust macros are used in a lot of cases, such as the following:</p>
<ul>
<li><p>Augmenting the language syntax by creating custom <strong>Domain-Specific Languages</strong> (<strong>DSLs</strong>)</p>
</li>
<li><p>Writing compile time serialization code, like serde does</p>
</li>
<li><p>Moving computation to compile-time, thereby reducing runtime overhead</p>
</li>
<li><p>Writing and generating boilerplate code for repetitive tasks.</p>
</li>
</ul>
<p>Lately I have been diving a lot into game development, specially with Unreal Engine and C++ and I guess that is why Macros were brought up to my attention so much. On game development with Unreal and C++ macros are a huge part of the development, they not only help keep you code clean and to the point, but also improve you productivity by a lot. Just like they do it in Rust.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this blog post we covered what are Macros in a more general context and also in the Rust programming language, we looked at the different types of Macros and also at some simple implementation examples and to finish it off we talked about when to use macros to help solve your coding problems and how it can help you to keep you code clean, organised and keep your productivity high.</p>
<p>I hope I was able to spike your interest on this topic and I curious to see how you will use macros from now on. Feel free to send me so I can take a look!</p>
<h4 id="heading-like-the-post-how-about-a-like">Like the post? How about a LIKE?</h4>
]]></content:encoded></item><item><title><![CDATA[Using Field Attributes with serde.rs]]></title><description><![CDATA[use serde::{Serialize, Deserialize};

/// Represents the Discord information as
/// returned from the API
///
#[derive(Debug, Serialize, Deserialize)]
pub struct DiscordUser {
    pub photo_url: String,
    pub username: String,
    pub id: String,
}...]]></description><link>https://hashblog.thepolyglotprogrammer.com/using-field-attributes-with-serde-rs-89d9c477ecf7</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/using-field-attributes-with-serde-rs-89d9c477ecf7</guid><category><![CDATA[Rust]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Sat, 24 Jul 2021 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396293169/d9f49038-5d74-48fd-b895-4d4c740ede91.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<pre><code class="lang-rust"><span class="hljs-keyword">use</span> serde::{Serialize, Deserialize};

<span class="hljs-comment">/// Represents the Discord information as</span>
<span class="hljs-comment">/// returned from the API</span>
<span class="hljs-comment">///</span>
<span class="hljs-meta">#[derive(Debug, Serialize, Deserialize)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">DiscordUser</span></span> {
    <span class="hljs-keyword">pub</span> photo_url: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> username: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> id: <span class="hljs-built_in">String</span>,
}
</code></pre>
<p>Frequently associated with JSON serializing and deserializing, <a target="_blank" href="https://serde.rs/">serde.rs</a> can actually handle a wide range of formats:</p>
<p>The following is a partial list of data formats that have been implemented for Serde by the community (<em>list copied from serde.rs documentation</em>).</p>
<ul>
<li><p><a target="_blank" href="https://github.com/serde-rs/json">JSON</a>, the ubiquitous JavaScript Object Notation used by many HTTP APIs.</p>
</li>
<li><p><a target="_blank" href="https://github.com/servo/bincode">Bincode</a>, a compact binary format used for IPC within the Servo rendering engine.</p>
</li>
<li><p><a target="_blank" href="https://github.com/pyfisch/cbor">CBOR</a>, a Concise Binary Object Representation designed for small message size without the need for version negotiation.</p>
</li>
<li><p><a target="_blank" href="https://github.com/dtolnay/serde-yaml">YAML</a>, a self-proclaimed human-friendly configuration language that ain’t markup language.</p>
</li>
<li><p><a target="_blank" href="https://github.com/3Hren/msgpack-rust">MessagePack</a>, an efficient binary format that resembles a compact JSON.</p>
</li>
<li><p><a target="_blank" href="https://github.com/alexcrichton/toml-rs">TOML</a>, a minimal configuration format used by <a target="_blank" href="http://doc.crates.io/manifest.html">Cargo</a>.</p>
</li>
<li><p><a target="_blank" href="https://github.com/birkenfeld/serde-pickle">Pickle</a>, a format common in the Python world.</p>
</li>
<li><p><a target="_blank" href="https://github.com/ron-rs/ron">RON</a>, a Rusty Object Notation.</p>
</li>
<li><p><a target="_blank" href="https://github.com/zonyitoo/bson-rs">BSON</a>, the data storage and network transfer format used by MongoDB.</p>
</li>
<li><p><a target="_blank" href="https://github.com/flavray/avro-rs">Avro</a>, a binary format used within Apache Hadoop, with support for schema definition.</p>
</li>
<li><p><a target="_blank" href="https://github.com/callum-oakley/json5-rs">JSON5</a>, a superset of JSON including some productions from ES5.</p>
</li>
<li><p><a target="_blank" href="https://github.com/jamesmunns/postcard">Postcard</a>, a no_std and embedded-systems friendly compact binary format.</p>
</li>
<li><p><a target="_blank" href="https://docs.rs/serde_qs">URL</a> query strings, in the x-www-form-urlencoded format.</p>
</li>
<li><p><a target="_blank" href="https://github.com/softprops/envy">Envy</a>, a way to deserialize environment variables into Rust structs. <em>(deserialization only)</em></p>
</li>
<li><p><a target="_blank" href="https://github.com/softprops/envy-store">Envy Store</a>, a way to deserialize <a target="_blank" href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html">AWS Parameter Store</a> parameters into Rust structs. <em>(deserialization only)</em></p>
</li>
<li><p><a target="_blank" href="https://github.com/rotty/lexpr-rs">S-expressions</a>, the textual representation of code and data used by the Lisp language family.</p>
</li>
<li><p><a target="_blank" href="https://docs.rs/zvariant">D-Bus</a>’s binary wire format.</p>
</li>
<li><p><a target="_blank" href="https://github.com/google/flatbuffers/tree/master/rust/flexbuffers">FlexBuffers</a>, the schemaless cousin of Google’s FlatBuffers zero-copy serialization format.</p>
</li>
<li><p><a target="_blank" href="https://github.com/P3KI/bendy">Bencode</a>, a simple binary format used in the BitTorrent protocol.</p>
</li>
<li><p><a target="_blank" href="https://docs.rs/serde_dynamo">DynamoDB Items</a>, the format used by <a target="_blank" href="https://docs.rs/rusoto_dynamodb">rusoto_dynamodb</a> to transfer data to and from DynamoDB.</p>
</li>
<li><p><a target="_blank" href="https://github.com/Canop/deser-hjson">Hjson</a>, a syntax extension to JSON designed around human reading and editing. <em>(deserialization only)</em></p>
</li>
</ul>
<p>As you can see the list of data formats accepted can be quite extensive.</p>
<h3 id="heading-but-what-exactly-is-serialization-and-deserialization">But what exactly is Serialization and Deserialization?</h3>
<p>Well, in computing, <a target="_blank" href="https://en.wikipedia.org/wiki/Serialization">serialization</a> is the process of translating a data structure or object state into a format that can be stored (for example, in a file system or memory data buffer) or transmitted (for example over a network) and able to reconstructed later.</p>
<p>The process of serializing an object is also called <a target="_blank" href="https://en.wikipedia.org/wiki/Marshalling_%28computer_science%29">marshalling</a> an object in some situations. As you can imagine the opposite operation, extracting a data structure from a series of bytes, or doing the reverse process, is <strong>deserialization</strong>, also called unmarshalling.</p>
<h4 id="heading-ok-now-that-we-got-the-basics-out-of-the-way-lets-find-out-how-to-use-a-serders-field-attribute-to-solve-a-real-problem">Ok! Now that we got the basics out of the way, let’s find out how to use a serde.rs Field Attribute to solve a real problem.</h4>
<p>Let’s start with a very basic example. In this example we will be working with a <a target="_blank" href="https://en.wikipedia.org/wiki/JSON">JSON</a> payload, that not only is human readable and easier to understand but also probably one of the most common use cases in the day to day of a developer.</p>
<p>Here we have a really basic example, where we create a object based on a struct type, serialize it to a string and then deserialize it from the string. Pretty straight forward interaction I would say.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> serde::{Serialize, Deserialize};

<span class="hljs-comment">/// The `Person` struct is the entry point into the program.</span>
<span class="hljs-meta">#[derive(Serialize, Deserialize, Debug)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Person</span></span> {
    name: <span class="hljs-built_in">String</span>,
    age: <span class="hljs-built_in">u32</span>,
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello, serde.rs Field Attributes Example!"</span>);

    <span class="hljs-comment">// Create a `Person` struct.</span>
    <span class="hljs-keyword">let</span> person = Person { name: <span class="hljs-string">"Josh"</span>.to_string(), age: <span class="hljs-number">32</span> };
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Person: {:?}"</span>, person);

    <span class="hljs-comment">// Serialize the `Person` struct to a string.</span>
    <span class="hljs-keyword">let</span> serialized = serde_json::to_string(&amp;person).unwrap();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Person Serialized: {}"</span>, serialized);

    <span class="hljs-comment">// Deserialize the `Person` struct from a string.</span>
    <span class="hljs-keyword">let</span> deserialized:Person = serde_json::from_str(&amp;serialized).unwrap();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Deserialized: {:?}"</span>, deserialized);
}
</code></pre>
<p>When you run you should get something like this:</p>
<pre><code class="lang-bash">Hello, serde.rs Field Attributes Example!
Person: Person { name: <span class="hljs-string">"Josh"</span>, age: 32 }
Person Serialized: {<span class="hljs-string">"name"</span>:<span class="hljs-string">"Josh"</span>,<span class="hljs-string">"age"</span>:32}
Deserialized: Person { name: <span class="hljs-string">"Josh"</span>, age: 32 }
</code></pre>
<p><strong>Great right! Where could this go wrong?</strong> Well, in this scenario not much could go wrong because you are controlling all the parts, you are creating an object with all the necessary data and you know you have all you need. But in a real life project you would probably receive a <a target="_blank" href="https://en.wikipedia.org/wiki/JSON">JSON</a> payload as a response from some request, where-ever that may be.</p>
<p>But what if we change this code a bit to simulate a piece of the information missing when we try to deserialize it, or as you may also know it, unmarshall the data.</p>
<p>Example:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> serde::{Serialize, Deserialize};

<span class="hljs-comment">/// The `Person` struct is the entry point into the program.</span>
<span class="hljs-meta">#[derive(Serialize, Deserialize, Debug)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Person</span></span> {
    name: <span class="hljs-built_in">String</span>,
    age: <span class="hljs-built_in">u32</span>,
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello, serde.rs Field Attributes Example!"</span>);

    <span class="hljs-keyword">let</span> serialized = <span class="hljs-string">"{\"name\":\"Josh\"}"</span>.to_string();

    <span class="hljs-comment">// Deserialize the `Person` struct from a string.</span>
    <span class="hljs-keyword">let</span> deserialized:Person = serde_json::from_str(&amp;serialized).unwrap();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Deserialized: {:?}"</span>, deserialized);
}
</code></pre>
<p>In this example we got rid of the serializing from a struct to string part, because we only want to focus on the deserializing part, simulating a JSON payload that would arrive from somewhere else. As you can see, our <em>payload</em> is missing one value, the <code>age</code> , so let’s see what happens when we run this code.</p>
<p>Hello, serde.rs Field Attributes Example!<br />thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("missing field `age`", line: 1, column: 15)', src/main.rs:16:65<br />note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396291994/09cc4e27-c3cd-43d9-9bc0-f77209e0595d.jpeg" alt /></p>
<p>WOW! What happened?! Well, as you can probably see from the error message, the <code>main</code> thread panicked because tried initializing our struct object with a missing value, in this case <code>age</code> . But what can we do here?</p>
<p>Some programming language, more high level language could take of this automatically for us, by maybe omitting the value all together or just assigning a zero value for missing properties, but Rust will not do that out of the box for us, we need to tell it what to do in this case.</p>
<p>We have two options here:</p>
<p>The first approach and more straight forward and simple is to just tell <code>serde</code> to use the <code>Default::default()</code> value for a specific property that might be missing. Here’s how that would work.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> serde::{Serialize, Deserialize};

<span class="hljs-comment">/// The `Person` struct is the entry point into the program.</span>
<span class="hljs-meta">#[derive(Serialize, Deserialize, Debug)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Person</span></span> {
    name: <span class="hljs-built_in">String</span>,
    <span class="hljs-meta">#[serde(default)]</span>
    age: <span class="hljs-built_in">u32</span>,
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello, serde.rs Field Attributes Example!"</span>);

    <span class="hljs-keyword">let</span> serialized = <span class="hljs-string">"{\"name\":\"Josh\"}"</span>.to_string();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Serialized: {}"</span>, serialized);

    <span class="hljs-comment">// Deserialize the `Person` struct from a string.</span>
    <span class="hljs-keyword">let</span> deserialized:Person = serde_json::from_str(&amp;serialized).unwrap();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Deserialized: {:?}"</span>, deserialized);
}
</code></pre>
<p>In the above code you can see that we add the <a target="_blank" href="https://serde.rs/field-attrs.html#default">Field Attribute “default</a>” in the property <code>age</code> . By doing this we are telling <code>serde</code> to use the <code>Default::default()</code> value for the property, in case the value is not present.</p>
<p>When you run you should get something like this:</p>
<pre><code class="lang-bash">Hello, serde.rs Field Attributes Example!
Serialized: {<span class="hljs-string">"name"</span>:<span class="hljs-string">"Josh"</span>}
Deserialized: Person { name: <span class="hljs-string">"Josh"</span>, age: 0 }
</code></pre>
<p>Ok, this works fine, but what if you have other plans for the default value of a property. For instance, for sake of argument, let’s say that we only count age in integers so a baby for example could have 0 years until is turns 1. But if you receive a payload with a age missing, you do not want the Default value of an integer assigned to it, because it could mean it is a new born baby with 0 years. So let’s say that in this case you want to assign a <code>-1</code> to a missing <code>age</code> value.</p>
<p>This is how I would do it:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> serde::{Serialize, Deserialize};

<span class="hljs-comment">/// The `Person` struct is the entry point into the program.</span>
<span class="hljs-meta">#[derive(Serialize, Deserialize, Debug)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Person</span></span> {
    name: <span class="hljs-built_in">String</span>,
    <span class="hljs-meta">#[serde(default = <span class="hljs-meta-string">"missing_value"</span>)]</span>
    age: <span class="hljs-built_in">i32</span>,
}

<span class="hljs-comment">/// The `missing value` function is called to get the default value for the field `age`.</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">missing_value</span></span>() -&gt; <span class="hljs-built_in">i32</span> {
    -<span class="hljs-number">1</span>
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello, serde.rs Field Attributes Example!"</span>);

    <span class="hljs-keyword">let</span> serialized = <span class="hljs-string">"{\"name\":\"Josh\"}"</span>.to_string();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Serialized: {}"</span>, serialized);

    <span class="hljs-comment">// Deserialize the `Person` struct from a string.</span>
    <span class="hljs-keyword">let</span> deserialized:Person = serde_json::from_str(&amp;serialized).unwrap();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Deserialized: {:?}"</span>, deserialized);
}
</code></pre>
<p>Let me explain what is going on here. If we get a payload with the value of <code>age</code> missing, instead of just assigning <code>Default::default()</code> , <code>serde</code> will call the function <code>missing_value</code> to get the default value for that property. In this case we are returning <code>-1</code> .</p>
<p>So when we run this code we should get this:</p>
<pre><code class="lang-bash">Hello, serde.rs Field Attributes Example!
Serialized: {<span class="hljs-string">"name"</span>:<span class="hljs-string">"Josh"</span>}
Deserialized: Person { name: <span class="hljs-string">"Josh"</span>, age: -1 }
</code></pre>
<p>As you may have noticed we also changed the <code>age</code> type from a <code>u32</code> to a <code>i32</code> , since we had to take a negative value.</p>
<p>And voila! We solved the problem of receiving a JSON payload with a missing value by adding just a couple of lines of code.</p>
<p>Of course this scenario was over simplified and the goal was to show how you can manipulate the serialization and deserialization by using <a target="_blank" href="http://serde.rs">serde.rs</a> Field Attributes.</p>
<p>I just wanted to quickly also show a solution to the <code>missing field</code> problem when deserializing a JSON payload with serde.rs and Rust without the use of any boilerplate code:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> serde::{Serialize, Deserialize};

<span class="hljs-comment">/// The `Person` struct is the entry point into the program.</span>
<span class="hljs-meta">#[derive(Serialize, Deserialize, Debug)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Person</span></span> {
    name: <span class="hljs-built_in">String</span>,
    age: <span class="hljs-built_in">Option</span>,
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Hello, serde.rs Field Attributes Example!"</span>);

    <span class="hljs-keyword">let</span> serialized = <span class="hljs-string">"{\"name\":\"Josh\"}"</span>.to_string();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Serialized: {}"</span>, serialized);

    <span class="hljs-comment">// Deserialize the `Person` struct from a string.</span>
    <span class="hljs-keyword">let</span> deserialized:Person = serde_json::from_str(&amp;serialized).unwrap();
    <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Deserialized: {:?}"</span>, deserialized);
}
</code></pre>
<p>In the above example you can see all I did was to wrap the type of my <code>age</code> property in an <code>Option&lt;T&gt;</code> . But doing that, when I run this code with my missing value, this is the result:</p>
<p>Hello, serde.rs Field Attributes Example!<br />Serialized: {"name":"Josh"}<br />Deserialized: Person { name: "Josh", age: None }</p>
<p>On this post I showed only one example of the <a target="_blank" href="https://serde.rs/field-attrs.html">Field Attributes available</a> on <code>serde.rs</code> , but I highly recommend exploring all the other options, since they might help solve a lot of day to day problems and in a very simple and straight forward way.</p>
<p>That is all folks!</p>
<p><strong>Don’t forget to follow and hit that LIKE if you like the content.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Rust vs Python on Data Science, but why not both?]]></title><description><![CDATA[There is no discussion that Python is one of the most popular programming languages for Data Scientists— and it makes sense. Python and more specifically Python Package Index (PyPI) has an impressive number of data science libraries and packages, lik...]]></description><link>https://hashblog.thepolyglotprogrammer.com/rust-vs-python-on-data-science-but-why-not-both-d5f98080f632</link><guid isPermaLink="true">https://hashblog.thepolyglotprogrammer.com/rust-vs-python-on-data-science-but-why-not-both-d5f98080f632</guid><category><![CDATA[Python]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Data Science]]></category><dc:creator><![CDATA[João Henrique Machado Silva]]></dc:creator><pubDate>Sat, 06 Feb 2021 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396374556/58139863-81aa-42c9-9bf1-fef4c8d20e3a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There is no discussion that Python is one of the most popular programming languages for Data Scientists— and it makes sense. Python and more specifically Python Package Index (<a target="_blank" href="https://pypi.org/">PyPI</a>) has an impressive number of data science libraries and packages, like for example <a target="_blank" href="https://pypi.org/project/numpy/">NumPy</a>, <a target="_blank" href="https://pypi.org/project/scipy/">SciPy</a>, <a target="_blank" href="https://pypi.org/project/pandas2/">Pandas</a>, <a target="_blank" href="https://pypi.org/project/matplotlib/">Matplotlib</a> and the list goes on and on. So you put that together with a massive developer community, plus a language with relatively low learning curve (sorry if you got offended by this last part, it is what it is, get over it), makes Python a great choice for Data Science.</p>
<p>After taking a better look into some of these libraries I found out that a lot of them are actually implemented in C and C++ for obvious reasons, better performance over all, and providing foreign function interfaces (<a target="_blank" href="https://en.wikipedia.org/wiki/Foreign_function_interface">FFIs</a>) or Python bindings so you can call those functions form Python it self. It's no secret that pure Python is not the most performant of programming languages, I don't know the exact number and hey don't go quoting me on it, but I heard that in some cases Python can be 100x slower than C or C++. Anyway, getting back to the point, these lower level languages implementations have better execution time and also memory management. Putting these two together makes everything more scalable and therefore cheaper also. So if you can have a more performant code to accomplish data science tasks and the integrate them with your Python code, why not?</p>
<p><strong>This is where Rust comes in!</strong> The Rust Language is known for a lot of things and based on what I described on the previous paragraph is aligns quite well with languages like C and C++. In fact, performant wise Rust is directly comparable with C and C++ and in a lot of ways is even better because it provides total (or almost) memory safety, extensive thread safety and no runtime overhead, which makes it for a perfect candidate for Data Science related problems. Lots and lots of data processing.</p>
<p>On this post, my plan is to take a simple task and compare it between 5 difference scenarios:</p>
<ul>
<li><p>Pure Python Code</p>
</li>
<li><p>Python Code using data science libraries</p>
</li>
<li><p>Python Code invoking Pure Rust code compiled into a lib.</p>
</li>
<li><p>[Update] Python with NumPy and <a target="_blank" href="https://numba.pydata.org/">Numba</a></p>
</li>
<li><p>[Update] Python with Numpy and NumExpr</p>
</li>
</ul>
<h3 id="heading-here-it-is-our-data-science-poc">Here it is, our Data Science POC</h3>
<p>Well, since data science is very broad subject and I am definitely not the expert on it, I decided to go with simple data science task that is to compute the information <a target="_blank" href="https://en.wikipedia.org/wiki/Entropy_%28information_theory%29">entropy</a> for a byte sequence. This is formula for calculating entropy in bit (source: <a target="_blank" href="https://en.wikipedia.org/wiki/Entropy_%28information_theory%29">Wikipedia: Entropy</a>)</p>
<blockquote>
<p><em>H(X)</em>\=-𝚺i <em>P</em>x(<em>x</em>i) <em>log2P</em>x(<em>x</em>i)</p>
<p>In information theory, the entropy of a random variable is the average level of "information", "surprise", or "uncertainty" inherent in the variable's possible outcomes.</p>
</blockquote>
<p>Anyway, this is a somewhat simple task but quite used tool in the world of data science and machine learning and it is used as a basis for technique such as feature selection, building decision trees, and, more generally, fitting classification models. Anyhow, this is what we are going to do.</p>
<p>Based on our formula ("our formula", haha), to compute the entropy of a random variable X, we first count the occurrences of each possible byte value (Xi) and divide by the total number of occurrences to calculate the probabilities of a particular value, Xi, occurring (<em>P</em>x(Xi)). Then we calculate the negative of the weighted sum of the probability of a particular value, Xi, occurring (<em>P</em>x(Xi)) and so-called self-information (log2Px(xi)). The log with base 2 is because we are working with bits, so we use the notation log2.</p>
<p>I know this is a simplistic assessment and my goal here is not to attack Python or any of the Python popular data science libraries. The goal is just to see how Rust would do against them, even on a simple scenario like this. And who knows what the future might bring?!</p>
<p>In these tests we will compile Rust into a custom C library that we can import from Python. All tests are ran on a macOS Catalina.</p>
<h4 id="heading-pure-python">Pure Python</h4>
<p>We can start by creating a new file called <code>entropy.py</code> where we will have our main code. On this first part we will import the standard library module <code>math</code> and use it to create a new function to calculate the entropy of a <a target="_blank" href="https://www.geeksforgeeks.org/python-bytearray-function/">bytearray</a>. This function is not optimized in any way and provides a baseline for our perfomance measurements.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> math

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">compute_entropy_pure_python</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-string">"""Compute entropy on bytearray `data`."""</span>
    counts = [<span class="hljs-number">0</span>] * <span class="hljs-number">256</span>
    entropy = <span class="hljs-number">0.0</span>
    length = len(data)

    <span class="hljs-keyword">for</span> byte <span class="hljs-keyword">in</span> data:
        counts[byte] += <span class="hljs-number">1</span>

    <span class="hljs-keyword">for</span> count <span class="hljs-keyword">in</span> counts:
        <span class="hljs-keyword">if</span> count != <span class="hljs-number">0</span>:
            probability = float(count) / length
            entropy -= probability * math.log(probability, <span class="hljs-number">2</span>)

    <span class="hljs-keyword">return</span> entropy
</code></pre>
<h4 id="heading-python-with-data-science-libraries-numpy-and-scipy">Python with Data Science Libraries (NumPy and Scipy)</h4>
<p>Here we will just continue on the same file as before, <code>entropy.py</code> and add a couple of imports and another function, but this time making use of the libraries we imported. As you can imagine, SciPy already has a function that calculates entropy. We will just use NumPy <code>unique()</code> function to calculate the byte frequencies first. To be honest comparing the performance of SciPy's functions against pure python is not even fair, but who said that life is fair, so let's keep going.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">from</span> scipy.stats <span class="hljs-keyword">import</span> entropy <span class="hljs-keyword">as</span> scipy_entropy

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">compute_entropy_scipy_numpy</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-string">"""Compute entropy on bytearray `data` with SciPy and NumPy."""</span>
    counts = np.bincount(bytearray(data), minlength=<span class="hljs-number">256</span>)
    <span class="hljs-keyword">return</span> scipy_entropy(counts, base=<span class="hljs-number">2</span>)
</code></pre>
<h4 id="heading-python-with-numpy-and-numbahttpsnumbapydataorg">Python with NumPy and <a target="_blank" href="https://numba.pydata.org/">Numba</a></h4>
<p>The first version of this experiment I actually include this one, but thanks to the amazing open source community I got a PR on the github repo that included this one, and man, this was a nice surprise. This is where being a subject matter expert on the subject, in this case Data Science, is very important. Originally I did the experience bringing my knowledge on programming languages, with very little knowledge on Data Science. Numba translates Python functions to optimized machine code at runtime using the industry-standard LLVM compiler library. Numba-compiled numerical algorithms in Python can even approach the speeds of C or FORTRAN. Anyway, now it seems we are having a fair fight! Let's add this function to our <code>entropy.py</code> .</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> numba

<span class="hljs-meta">@numba.njit</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">compute_entropy_numpy_numba</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-string">"""Compute entropy on bytearray `data`. using Numba"""</span>
    counts = np.zeros(<span class="hljs-number">256</span>, dtype=np.uint64)
    entropy = <span class="hljs-number">0.0</span>
    length = len(data)

    <span class="hljs-keyword">for</span> byte <span class="hljs-keyword">in</span> data:
        counts[byte] += <span class="hljs-number">1</span>

    <span class="hljs-keyword">for</span> count <span class="hljs-keyword">in</span> counts:
        <span class="hljs-keyword">if</span> count != <span class="hljs-number">0</span>:
            probability = float(count) / length
            entropy -= probability * np.log2(probability)

    <span class="hljs-keyword">return</span> entropy
</code></pre>
<h4 id="heading-python-with-rust">Python with Rust</h4>
<p>Now the fun part! Sorry! Just kidding, Python is also fun.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396371368/a7b67a3b-e645-48c3-9f7d-3912a6d20db6.jpeg" alt /></p>
<p>Now we will go step by step into the Rust implementation and necessary steps to make Rust work with Python.</p>
<p>First step is to create a new Rust Library project. I did it in the same directory of my <code>entropy.py</code> file, to make things easier.</p>
<p><code>$ cargo new rust_entropy --lib</code></p>
<p>This will create a new directory called <code>rust_entropy</code> tell <a target="_blank" href="https://doc.rust-lang.org/cargo/guide/">Cargo</a> to create new lib project.</p>
<p>Now we need to make some necessary modifications to our <code>Cargo.toml</code> manifest file.</p>
<p><strong>Cargo.toml</strong></p>
<pre><code class="lang-ini"><span class="hljs-section">[package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"rust_entropy"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">authors</span> = [<span class="hljs-string">"YOUR NAME "</span>]
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2018"</span>

<span class="hljs-section">[lib]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"rust_entropy_lib"</span>
<span class="hljs-attr">crate-type</span> = [<span class="hljs-string">"dylib"</span>]

<span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">cpython</span> = { version = <span class="hljs-string">"0.5.2"</span>, features = [<span class="hljs-string">"extension-module"</span>] }
<span class="hljs-attr">pyo3</span> = { version = <span class="hljs-string">"0.12.1"</span>, features = [<span class="hljs-string">"python3"</span>] }
</code></pre>
<p>Here we are defining the library name and crate-type as well as defining some dependencies necessary to make the Rust code work together with Python. In this case <a target="_blank" href="https://crates.io/crates/cpython">cpython</a> and <a target="_blank" href="https://crates.io/crates/pyo3">pyo3</a>, both available on <a target="_blank" href="http://crates.io">crates.io</a>, the Rust Package Registry, like NPM but better! I also used Rust v1.48.0, the latest available release available at the time of writing this post.</p>
<p>The Rust code implementation is fairly straightforward. Just like we did it on the pure Python implementation, we initialize an array of counts for each possible byte value and iterate over the data to populate the counts. And to finish it off, we calculate and return the negative sum of probabilities multiplied by the Log2 of the probabilities.</p>
<p><strong>lib.rs</strong></p>
<pre><code class="lang-rust"><span class="hljs-comment">/// Compute entropy on byte array (Pure Rust)</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">compute_entropy_pure_rust</span></span>(data: &amp;[<span class="hljs-built_in">u8</span>]) -&gt; <span class="hljs-built_in">f64</span> {
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> counts = [<span class="hljs-number">0</span>; <span class="hljs-number">256</span>];
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> entropy = <span class="hljs-number">0_f64</span>;
    <span class="hljs-keyword">let</span> length = data.len() <span class="hljs-keyword">as</span> <span class="hljs-built_in">f64</span>;

    <span class="hljs-comment">// collect byte counts</span>
    <span class="hljs-keyword">for</span> &amp;byte <span class="hljs-keyword">in</span> data.iter() {
        counts[<span class="hljs-built_in">usize</span>::from(byte)] += <span class="hljs-number">1</span>;
    }

    <span class="hljs-comment">// make entropy calculation</span>
    <span class="hljs-keyword">for</span> &amp;count <span class="hljs-keyword">in</span> counts.iter() {
        <span class="hljs-keyword">if</span> count != <span class="hljs-number">0</span> {
            <span class="hljs-keyword">let</span> probability = <span class="hljs-built_in">f64</span>::from(count) / length;
            entropy -= probability + probability.log2();
        }
    }

    entropy
}
</code></pre>
<p>The chunk of the work os done! Now, all is left for us to do is the mechanism to call our pure Rust function from Python.</p>
<p>First we will import some packages into our <code>lib.rs</code></p>
<p><code>use cpython::{py_fn, py_module_initializer, PyResult, Python};</code></p>
<p>Next thing to do is to include in our <code>lib.rs</code> a CPython aware function to call our pure Rust function. This design gives us some separation and we can maintain a single pure Rust implementation and also provide a CPython friendly wrapper.</p>
<pre><code class="lang-rust"><span class="hljs-comment">/// Rust-CPython aware function</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">compute_entropy_cpython</span></span>(_: Python, data: &amp;[<span class="hljs-built_in">u8</span>]) -&gt; PyResult {
    <span class="hljs-keyword">let</span> _gil = Python::acquire_gil();
    <span class="hljs-keyword">let</span> entropy = compute_entropy_pure_rust(data);
    <span class="hljs-literal">Ok</span>(entropy)
}
</code></pre>
<p>We also need to use <code>[py_module_initializer](https://github.com/dgrunwald/rust-cpython)!</code> macro to actually initialize the Python Module and expose the Rust function to an external python application. Also in our <code>lib.rs</code> .</p>
<pre><code class="lang-rust"><span class="hljs-comment">// initialize Python module and add Rust CPython aware function</span>
py_module_initializer!(
    rust_entropy_lib,
    initrust_entropy_lib,
    PyInit_rust_entropy_lib,
    |py, m | {
        m.add(py, <span class="hljs-string">"__doc__"</span>, <span class="hljs-string">"Entropy module implemented in Rust"</span>)?;
        m.add(
            py,
            <span class="hljs-string">"compute_entropy_cpython"</span>,
            py_fn!(py, compute_entropy_cpython(data: &amp;[<span class="hljs-built_in">u8</span>])
        ))?;
        <span class="hljs-literal">Ok</span>(())
    }
);
</code></pre>
<p>Now let's compile this code and generate a library so we can use on our Python code.</p>
<p><code>$ cargo build --release</code></p>
<p>If you are on macOS like I was, you will need to create a file called <code>config</code> and add it to a directory called <code>.cargo</code> (which you also may need to create) inside your Rust project, with the following content:</p>
<pre><code class="lang-ini"><span class="hljs-section">[target.x86_64-apple-darwin]</span>
<span class="hljs-attr">rustflags</span> = [
<span class="hljs-string">"-C"</span>, <span class="hljs-string">"link-arg=-undefined"</span>,
<span class="hljs-string">"-C"</span>, <span class="hljs-string">"link-arg=dynamic_lookup"</span>,
]
</code></pre>
<p>This will generate a file called <strong>librust_entropy_lib.dylib</strong> inside <code>./target/release</code> directory. To make things easier copy this file to where your <code>entropy.py</code> file is and rename it to <strong>rust_entropy_lib.so.</strong></p>
<h4 id="heading-calling-our-rust-code-from-python">Calling our Rust Code from Python</h4>
<p>Now it's time to finally call our Rust implementation from Python, in our case the <code>entropy.py</code> file again. The first thing to do is to add an import to our newly created library to the top of our Python file <code>entropy.py</code>.</p>
<p><code>import rust_entropy_lib</code></p>
<p>Then all we have to do is call the exported library function we specified earlier when we initialized the Python module with the <code>py_module_initializer!</code> macro in our Rust code. Again, in our <code>entropy.py</code> file.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">compute_entropy_rust_from_python</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-string">"""Compute entropy on bytearray `data` with Rust."""</span>
    <span class="hljs-keyword">return</span> rust_entropy_lib.compute_entropy_cpython(data)
</code></pre>
<p>At this point, we have a single Python module that includes functions to call all of our entropy calculation implementations.</p>
<h3 id="heading-now-its-game-on-performance-tests">Now it's game on! (Performance tests)</h3>
<p>We measured the execution time of each function implementation with pytest benchmarks computing entropy over 1 million random bytes. All implementations were presented with the same data. The benchmark tests (also included in <code>entropy.py</code>) are shown below.</p>
<pre><code class="lang-python"><span class="hljs-comment"># ### BENCHMARKS ###</span>
<span class="hljs-comment"># generate some random bytes to test w/ NumPy</span>
NUM = <span class="hljs-number">1000000</span>
VAL = np.random.randint(<span class="hljs-number">0</span>, <span class="hljs-number">256</span>, size=(NUM, ), dtype=np.uint8)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_pure_python</span>(<span class="hljs-params">benchmark</span>):</span>
    <span class="hljs-string">"""Test pure Python."""</span>
    benchmark(compute_entropy_pure_python, VAL)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_pure_numpy_numba</span>(<span class="hljs-params">benchmark</span>):</span>
    <span class="hljs-string">"""Test implementation using Numba."""</span>
    benchmark(compute_entropy_numpy_numba, VAL)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_python_scipy_numpy</span>(<span class="hljs-params">benchmark</span>):</span>
    <span class="hljs-string">"""Test pure Python with SciPy."""</span>
    benchmark(compute_entropy_scipy_numpy, VAL)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_rust</span>(<span class="hljs-params">benchmark</span>):</span>
    <span class="hljs-string">"""Test Rust implementation called from Python."""</span>
    benchmark(compute_entropy_rust_from_python, VAL)
</code></pre>
<p>And for a different scenario, I made a separate script for each method for calculating entropy and added them to the root of the project, same directory lever as our <code>entropy.py</code> .</p>
<p><strong>entropy_pure_python.py</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> entropy

<span class="hljs-comment"># test.img is binary file generate with</span>
<span class="hljs-comment"># dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10] for 10Mb</span>
<span class="hljs-comment"># just a set of random bytes generate for testing purposes</span>
<span class="hljs-keyword">with</span> open(<span class="hljs-string">'test.img'</span>, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> f:
DATA = f.read()

<span class="hljs-comment"># Here we just repeat the calculations 100 times, for our pure python method</span>
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(<span class="hljs-number">100</span>):
    entropy.compute_entropy_pure_python(DATA)
</code></pre>
<p><strong>entropy_python_data_science.py</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> entropy

<span class="hljs-comment"># test.img is binary file generate with</span>
<span class="hljs-comment"># dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10] for 10Mb</span>
<span class="hljs-comment"># just a set of random bytes generate for testing purposes</span>
<span class="hljs-keyword">with</span> open(<span class="hljs-string">'test.img'</span>, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> f:
DATA = f.read()

<span class="hljs-comment"># Here we just repeat the calculations 100 times, for our python using NumPy and SciPy</span>
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(<span class="hljs-number">100</span>):
    entropy.compute_entropy_scipy_numpy(DATA)
</code></pre>
<p><strong>entropy_rust.py</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> entropy

<span class="hljs-comment"># test.img is binary file generate with</span>
<span class="hljs-comment"># dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10] for 10Mb</span>
<span class="hljs-comment"># just a set of random bytes generate for testing purposes</span>
<span class="hljs-keyword">with</span> open(<span class="hljs-string">'test.img'</span>, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> f:
DATA = f.read()

<span class="hljs-comment"># Here we just repeat the calculations 100 times, for our Python using Rust</span>
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(<span class="hljs-number">100</span>):
    entropy.compute_entropy_rust_from_python(DATA)
</code></pre>
<p>The test.img file is just a randomly generated binary file with the following command (for a 10Mb file):</p>
<p><code>dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10]</code></p>
<p>And the script repeats the calculations 100 times in order to simplify capturing memory usage data.</p>
<h4 id="heading-script-results">Script Results:</h4>
<pre><code class="lang-bash"><span class="hljs-comment"># entropy_pure_python.py</span>

$ gtime python entropy_pure_python.py
74.70user 0.64system 1:13.92elapsed 101%CPU (0avgtext+0avgdata 60180maxresident)k
0inputs+0outputs (436major+14770minor)pagefaults 0swaps

<span class="hljs-comment"># entropy_python_data_science.py</span>

$ gtime python entropy_python_data_science.py
5.61user 1.15system 0:05.37elapsed 126%CPU (0avgtext+0avgdata 151896maxresident)k
0inputs+0outputs (2074major+36061minor)pagefaults 0swaps

<span class="hljs-comment"># entropy_rust.py</span>

$ gtime python entropy_rust.py
3.01user 0.53system 0:02.06elapsed 171%CPU (0avgtext+0avgdata 60104maxresident)k
0inputs+0outputs (2074major+13115minor)pagefaults 0swaps
</code></pre>
<p>I used GNU time application to measure the performance of the scripts above.</p>
<h4 id="heading-benchmark-test-results">Benchmark Test Results:</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724396372753/ddad65f9-b815-4e02-8ec3-a7efb80a972d.png" alt /></p>
<p><code>pytest entropy.py</code></p>
<p>As you can see, both SciPy/NumPy and Rust implementations shown really strong performances, easily outperforming the Pure Python version. I was actually pleasantly surprised by how close the SciPy/NumPy performance was from the Rust implementation. But the results confirmed what I already expected from the start. Pure python is incredibly slower and not even in the same ball park as Rust, and implementations done in Rust can compete head to head with those already optimized in Python and probably written in C (even in this super simple benchmark).</p>
<p>On a side note, since it was added after, the run with <a target="_blank" href="https://numba.pydata.org/">Numba</a> brought a really good insight. <a target="_blank" href="https://numba.pydata.org/">Numba</a> fares very well, and <em>just</em> edges out Rust on my machine, and the effort to achieve it was low. All you have to do is import the library into your project and apply the decorators to the functions, and let Numba do the rest.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>This being the first time I try Rust on a data science task I was truly impressed with the performance of invoking Rust from Python. I have done it before with other languages like C or Go, but never with Rust, so it was a good exercise. And based on our brief and simple test, our Rust implementation performance can go head to head with any underlying C code running on SciPy and NumPy packages. Rust is ready for battle for efficient processing at scale. <strong>Bring it on!</strong></p>
<p>Rust was not only performant in execution time, as you can see in the script tests above, but the memory overhead was minimum. As I mentioned at the beginning of the post, having a good execution time and memory utilization make it ideal for scalability. That said, the performance of SciPy and NumPy were not bad, actually the were right behind, but I ran tests with 1Mb files and 10Mb file and what I noticed is that the difference grows as the data size grows. On top of that, Rust provides additional benefits the C and C++ do not, like memory and thread safety, making Rust real attractive.</p>
<p>If we are talking only about performance, C can offer similar execution times, but it does not have the memory safety and definitely not the thread safety. Choices, right?! That is what life is all about.</p>
<p>Ok, you can achieve those by using external libraries for C, but the onus of getting it right in entirely on you, the developer. Rust checks for memory safety, thread safety, race conditions all on compile time, plus the standard library offers a range of tools for concurrency, including channels, locks and reference counting.</p>
<p>I am not here to try to convince you to rewrite all these libraries and port everything to Rust, I can barely convince the guys at the company I work at to use Rust. Plus, some of these libraries like NumPy and SciPy are already heavily optimized packages with a lot of support from the community. All I am saying is that there is a lot out there in the world and would not hurt to start using Rust and <strong>maybe rewriting some pure python that isn't already optimized into a high performance library.</strong></p>
<p>My take is that Rust would be a great alternative for Data Science given its speed and safety guarantees. What do you think?</p>
<p>If you like the post <strong>how about a like?</strong></p>
<p>For more content like this, <strong>subscribing</strong> would not be a bad idea.</p>
<p><strong>Github repo</strong>: <a target="_blank" href="https://github.com/joaoh82/python_rust_data_science_bench">https://github.com/joaoh82/python_rust_data_science_bench</a></p>
<p>Additional Resources:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/dgrunwald/rust-cpython">https://github.com/dgrunwald/rust-cpython</a></p>
</li>
<li><p><a target="_blank" href="https://gist.github.com/ssokolow/34ce62a0d98054810c488a7f0d3fd4e0">https://gist.github.com/ssokolow/34ce62a0d98054810c488a7f0d3fd4e0</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>