<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>{🌩} Coding Up A Storm</title>
    <description>Jordan Andrews's website and blog.</description>
    <link>https://codingupastorm.github.io/</link>
    <atom:link href="https://codingupastorm.github.io/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Prodzilla: From Zero to Prod with Rust and Shuttle</title>
        <description>&lt;p&gt;I’ve been working on &lt;a href=&quot;https://github.com/prodzilla/prodzilla&quot;&gt;Prodzilla&lt;/a&gt;, a modern synthetic monitoring tool built in Rust. I wanted to share how it’s different to existing tools, why I’ve built it in Rust and how you can host it for free on Shuttle, and what I hope to achieve in the long-term.&lt;/p&gt;

&lt;h2 id=&quot;what-zilla&quot;&gt;What-zilla?&lt;/h2&gt;

&lt;p&gt;Synthetic monitoring is a staple component in the testing and observability of SaaS products - probing services in production to ensure they’re up and working as expected. Many synthetic monitoring tools exist, which generally shallowly check connectivity to an endpoint - they rarely support the testing of real system behavior.&lt;/p&gt;

&lt;p&gt;As a synthetic monitoring tool Prodzilla is unique in a couple of key ways. Firstly, it focuses on testing complex user flows in the way a real user would, by allowing chained requests, user authentication, and use of response body values in subsequent requests.&lt;/p&gt;

&lt;p&gt;Secondly, it optimizes for human readability, allowing the creation and verification of these complex flows with just yaml, rather than requiring written code. This yaml file is all that’s needed to have a multi-step user flow scheduled to be tested every 60 seconds, assert that the system behavior is as expected, and notify you if it’s not. I hope to make this more human readable over time, both in yaml and via UI.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;stories&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;get-ip-info&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;get-ip&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://api.ipify.org/?format=json&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;http_method&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GET&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;get-location&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://ipinfo.io/$/geo&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;http_method&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GET&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;expectations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Body&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Contains&lt;/span&gt; 
            &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Australia&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;initial_delay&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;60&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;alerts&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://my.site/notify&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As for why I’ve built this: We should all be testing more in production. Once an engineering faux-pas, testing in production is now more of a sign of sophistication than a sin. I wrote more about this in another article, &lt;a href=&quot;https://codingupastorm.dev/2023/11/07/why-im-shifting-left/&quot;&gt;‘Everyone’s Talking About Shifting Left - Here’s Why I’m Shifting Right’&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Prodzilla is a synthetic monitoring tool right now. Over time I want to deliver a range of tools designed to help everyone test in production. More on that below.&lt;/p&gt;

&lt;h2 id=&quot;why-rust&quot;&gt;Why Rust?&lt;/h2&gt;

&lt;p&gt;Using Rust for Prodzilla was a very deliberate decision - for the following reasons.&lt;/p&gt;

&lt;h3 id=&quot;performance-and-predictability&quot;&gt;Performance and Predictability&lt;/h3&gt;

&lt;p&gt;The primary reason for choosing Rust was that I wanted to be proud of Prodzilla performance-wise. A synthetic checker is a nice, compartmentalized project, it shouldn’t need significant overhead. It should be able to run on virtually anything, and it should be cheap. Rust is of course known for its low-memory and high-speed. What really won me over is this oft-cited table from a &lt;a href=&quot;https://greenlab.di.uminho.pt/wp-content/uploads/2017/10/sleFinal.pdf&quot;&gt;2017 paper&lt;/a&gt; that describes the relative energy efficiency of programming languages:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/language-table.png&quot; alt=&quot;A table listing Rust as the most energy-efficient programming languae&quot; style=&quot;display:block; margin-left:auto; margin-right:auto&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is a contrived measurement, but it’s a function of execution time and memory consumption - and Rust is just behind C!&lt;/p&gt;

&lt;p&gt;Yet despite such strength in performance, Rust behaves like a high level language for general http client / server functionality. In some ways it feels like getting a performance boost “for free”.&lt;/p&gt;

&lt;p&gt;Given I was building a monitoring tool, and also one that I’m going to release publicly and tie my name to, I also wanted it to be maximally predictable and reliable itself. Generally this is all referenced under the umbrella of “memory safety”, but I have continually found the compiler is protecting me from doing dumb things - for example catching iterator invalidation, or ensuring that Prodzilla’s execution state can be shared across threads.&lt;/p&gt;

&lt;h3 id=&quot;community&quot;&gt;Community&lt;/h3&gt;

&lt;p&gt;Alongside the technical reasons though, I’ve been following and learning Rust for a few years, and I really like the Rust community. It’s hard to ignore Rust repeatedly &lt;a href=&quot;https://survey.stackoverflow.co/2023/&quot;&gt;topping the StackOverflow developer survey&lt;/a&gt; in languages developers want to use more, or &lt;a href=&quot;https://discord.com/blog/why-discord-is-switching-from-go-to-rust&quot;&gt;spicy articles from Discord&lt;/a&gt; about the benefits of porting a service from Go to Rust.&lt;/p&gt;

&lt;p&gt;Moreover, I especially like where Rust is right now in the web space. It really feels like there’s a lot of smart people working on the next generation of web development tools - it feels like the place to be. There are a range of great open-source web dev tools that are just reaching critical levels of maturity. &lt;a href=&quot;https://github.com/tokio-rs/axum&quot;&gt;Axum&lt;/a&gt;, which I used to build Prodzilla, feels ready for out of the box web dev, and is crazy-performant, as I write about later. More recently available is &lt;a href=&quot;https://github.com/loco-rs/loco&quot;&gt;Loco&lt;/a&gt;, a Rails-like framework for building web applications in Rust that’s picking up steam. And in dev-tooling and hosting there’s &lt;a href=&quot;https://github.com/shuttle-hq/shuttle&quot;&gt;Shuttle&lt;/a&gt;, a 1-line hosting solution for Rust backends.&lt;/p&gt;

&lt;p&gt;I saw all of this happening and wanted to contribute.&lt;/p&gt;

&lt;p&gt;It’s not just open-source tools either; it feels like there is real industry traction here too, with &lt;a href=&quot;https://www.theregister.com/2024/01/31/microsoft_seeks_rust_developers/&quot;&gt;Microsoft looking for Rust engineers&lt;/a&gt; to rewrite parts of Office 365, and &lt;a href=&quot;https://engineering.fb.com/2022/07/27/developer-tools/programming-languages-endorsed-for-server-side-use-at-meta/&quot;&gt;Meta endorsing Rust internally&lt;/a&gt; for backend engineering.&lt;/p&gt;

&lt;h2 id=&quot;the-learning-curve&quot;&gt;The Learning Curve&lt;/h2&gt;

&lt;p&gt;Before Prodzilla, I’d read &lt;a href=&quot;https://doc.rust-lang.org/book/&quot;&gt;‘The Book’&lt;/a&gt; a couple of times, and had made my way through Rustlings, but hadn’t yet built a serious project in Rust.&lt;/p&gt;

&lt;h3 id=&quot;faster-than-expected&quot;&gt;Faster Than Expected&lt;/h3&gt;
&lt;p&gt;Knowing the performance and safety benefits of using Rust, I expected to find it much slower than languages like Kotlin, C#, or Golang to build a real project in. Surprisingly, across the board I found that I was generally moving fast. Some small syntactic sugar goes a long way - coming from Golang and its verbose error handling, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt; for error propagation feels great.&lt;/p&gt;

&lt;h3 id=&quot;fighting-the-borrow-checker---and-calling-in-an-ally&quot;&gt;Fighting the Borrow Checker - and Calling in an Ally&lt;/h3&gt;
&lt;p&gt;A sentiment I’ve heard over the years is of developers ‘fighting the borrow checker’. ‘Fighting’ seems too strong a word for my experience. But maybe that’s because - one thing that I haven’t heard enough people mention enough - ChatGPT is pretty good at fighting back!&lt;/p&gt;

&lt;p&gt;On the occasions when I’ve been stuck, I’ve copy-pasted the offending code into ChatGPT 4, along with the error I’ve been getting, and asking for help. And every single time I’ve received thoughtful suggestions for how to navigate around or correctly achieve the desired outcome for cases totally specific to my situation. 
A specific example that came up recently whilst trying to return some probe results through the Prodzilla API. The values were nested in a hashmap, in a read write lock, in application state. I tried to access them like so:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.probe_results&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.cloned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;But got back the error &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;temporary value dropped while borrowed&lt;/code&gt;. Given the complexity of the multiple wrapping types, not getting an instant answer from Google, and that I was still learning Rust, I dropped the offending code into ChatGPT and it corrected it with an explanation right away:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.probe_results&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.cloned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I now know that in a situation like this we need to explicitly assign the variable so that the lock lives for the lifetime or scope of that variable - in this case for the function block - otherwise we’re creating a situation where the lock is closed before the result can be returned.&lt;/p&gt;

&lt;h3 id=&quot;fighting-the-borrow-checker-is-a-good-thing&quot;&gt;Fighting the Borrow Checker is a Good Thing&lt;/h3&gt;

&lt;p&gt;It’s kind of cool, looking at those two lines, I have a much better intrinsic mental sense (still not a perfect sense - definitely still learning!) of how long the memory lives, without allocating anything myself.&lt;/p&gt;

&lt;p&gt;Given all of this, I’m glad the borrow checker’s been fighting me. I’ve had to be more thoughtful about what memory should live where, and for how long, I’ve had AI help, and as you’ll see in the next section the performance benefits are real!&lt;/p&gt;

&lt;h2 id=&quot;the-outcome---prodzilla&quot;&gt;The Outcome - Prodzilla&lt;/h2&gt;
&lt;p&gt;After a couple of months spending time on Prodzilla after work, I’m proud to say that Prodzilla currently supports the following features:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Probing individual endpoints and Stories: chained requests to multiple endpoints, emulating real user flows&lt;/li&gt;
  &lt;li&gt;Verifying that response bodies, headers, and status codes meet expectations using operations such as Equals, Contains, etc.&lt;/li&gt;
  &lt;li&gt;Passing variables from one step of a Story to another, Github Actions-style, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${{steps.authenticate.response.body.token}}&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Automated notifications for probe or story failures via webhooks&lt;/li&gt;
  &lt;li&gt;Manually triggering a probe or story via a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/trigger&lt;/code&gt; endpoint&lt;/li&gt;
  &lt;li&gt;Retrieving a history of previous behavior for all probes and stories&lt;/li&gt;
  &lt;li&gt;OpenTelemetry integration - trace IDs for all probes&lt;/li&gt;
  &lt;li&gt;Configuring all of this via yaml - &lt;strong&gt;without writing code&lt;/strong&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;small-footprint-lightning-fast&quot;&gt;Small Footprint, Lightning Fast&lt;/h3&gt;
&lt;p&gt;Whilst running, Prodzilla consumes about &lt;strong&gt;9MB&lt;/strong&gt; of memory. Note that currently probe and story history is stored in memory rather than in a database, so this can inflate when calling sites with large response bodies. In the future I’ll introduce persistent storage.&lt;/p&gt;

&lt;p&gt;When testing with 10 multi-step probes being triggered every second (more than I expect anyone is reasonably going to be probing), memory barely moved from that 9MB mark, and at max consumed around &lt;strong&gt;1.5% of my CPU&lt;/strong&gt;, a crusty old i7-8550U @ 1.80GHz.&lt;/p&gt;

&lt;p&gt;The size of the production binary is &lt;strong&gt;7.8MB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As someone who has worked as a backend engineer for their whole career, across Golang, Kotlin, C# - these numbers are pretty crazy. An empty spring boot application - a point of reference as a very common backend framework - is going to run with somewhere between 100-200MB of RAM. To have a web server and a synthetic monitoring agent running under 10MB - this feels like magic, but also a step in the right direction.&lt;/p&gt;

&lt;p&gt;I’d like to spend some time benchmarking Prodzilla properly, and especially comparing it to some of the existing tools, such as Grafana’s synthetic monitoring agent - hopefully a story for another article.&lt;/p&gt;

&lt;h2 id=&quot;hosting&quot;&gt;Hosting&lt;/h2&gt;
&lt;p&gt;When building Prodzilla, I had a couple of hosting problems to overcome:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How can I host a Rust app cheaply for my own use?&lt;/li&gt;
  &lt;li&gt;How can my users cheaply host a Rust app that I’ve built?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the hardest parts of encouraging usage of open-source tools is the burden users have of hosting it themselves. To get a real backend service up and running, connected to a database, and exposed at some nice url - despite being the backbone of every production application ever - is not a streamlined process. When building and hosting any proof-of-concept or side project, these tasks are a huge time-sink.&lt;/p&gt;

&lt;h3 id=&quot;enter-shuttle&quot;&gt;Enter Shuttle&lt;/h3&gt;
&lt;p&gt;Trying to work out how to overcome this, somewhere along the way I found &lt;a href=&quot;https://www.shuttle.rs/&quot;&gt;Shuttle&lt;/a&gt;, which is an open-source platform that allows free hosting of Rust applications (using AWS behind the scenes). What surprised me about Shuttle was that without manually provisioning anything in AWS or GCP, I could deploy an application for free with just slight tweaks to my application code. I ported Prodzilla to deploy on Shuttle in about 5 minutes. &lt;a href=&quot;https://github.com/prodzilla/prodzilla/compare/main...shuttle&quot;&gt;Here’s the diff&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The core of the change is essentially adding an attribute and a return type to the main function:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;#[shuttle_runtime::main]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;shuttle_axum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShuttleAxum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve also started experimenting with integrating a database to store probe and story results in Prodzilla. Again, all the local setup is just gone, and with slight tweaks Prodzilla runs locally with a containerized database, or can be deployed to the cloud with a provisioned database:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;#[shuttle_runtime::main]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;#[shuttle_shared_db::Postgres]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PgPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;shuttle_axum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShuttleAxum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is kind of bizarre for me to acknowledge, but with Rust and Shuttle I could get an app with a database up and running at some real url, and into prod faster than in any other language. It feels like the future. This is what backend development should feel like. Products like Vercel have made frontend development and hosting considerably easier - but on the backend I feel like we’re used to kind of wrestling through cloud platforms, hence why Shuttle is such a nice surprise.&lt;/p&gt;

&lt;p&gt;I came into Prodzilla thinking that I’d get some awesome benefits from Rust, but would be slowed down by the language and hosting maturity. I was definitely wrong!&lt;/p&gt;

&lt;h2 id=&quot;vision-and-goals&quot;&gt;Vision and Goals&lt;/h2&gt;

&lt;p&gt;My ultimate goal with Prodzilla is to help fix production observability and testing, in the process helping everyone write more reliable software.&lt;/p&gt;

&lt;p&gt;I don’t think that observability and quality testing should be as divergent as they are, with different parts of the development lifecycle, different codebases, different methodologies. By allowing Prodzilla to easily run in CI/CD pipelines and against different environments it can help tackle that.&lt;/p&gt;

&lt;p&gt;I don’t think that system behavior documentation, both internal and customer-facing, should go out of date as quickly as it does. By leveraging Prodzilla’s history of observed behavior, building a feedback loop between documentation and observed behavior, with a bit of LLM magic, I think we can fix that.&lt;/p&gt;

&lt;p&gt;I think that we should test in production more, even for cases where it feels too hard. Creating test users alongside production data, supporting canary releasing, flagging test requests to avoid calling specific downstreams - these are all fairly opaque and difficult things at the moment that I think we can make easier.&lt;/p&gt;

&lt;p&gt;I know these are big goals - maybe too ambitious, but at least that’s the direction Prodzilla is heading in.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;All up, I’ve been working on a new synthetic monitoring tool, and I’m glad I decided to build it in Rust. I’ve found that between the language itself and tools like Shuttle it’s a joy to write really performant backend services very quickly!&lt;/p&gt;

&lt;p&gt;More than anything else I’m looking forward to feedback from everyone that tries out Prodzilla, and especially from anyone that would love to use it but needs &lt;em&gt;just that one more specific feature&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to get in touch at any of the below:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.prodzilla.io&quot;&gt;prodzilla.io&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://discord.gg/ud55NhraUm&quot;&gt;Prodzilla’s Discord&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://x.com/codingupastorm&quot;&gt;@codingupastorm on Twitter / X&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 21 Feb 2024 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2024/02/21/prodzilla-zero-to-prod-with-shuttle/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2024/02/21/prodzilla-zero-to-prod-with-shuttle/</guid>
      </item>
    
      <item>
        <title>Everyone's Talking About Shifting Left - Here's Why I'm Shifting Right</title>
        <description>&lt;p&gt;Every so often in software engineering, new methodologies and frameworks emerge with the promise of increasing the reliability and delivery velocity of software. These “Grand New Ways Of Doing Things” have a period of time during which they are applied universally, touted by consultants and Engineering Managers alike, to solve &lt;em&gt;all&lt;/em&gt; the current problems. Previous “Grand New Ways Of Doing Things” such as Agile, Test Driven Development, even Microservices, despite starting as cure-alls, have settled into the toolkit of sometimes-useful strategies, contingent upon context.&lt;/p&gt;

&lt;p&gt;The latest buzzword that’s probably injecting a few too many technical items on your product roadmaps is “Shifting Left,” a concept that champions the idea of integrating more testing, development, and planning stages earlier in the software development lifecycle. The principle is simple: the sooner you catch and fix a bug, the less it costs and the faster you can move. This approach encourages developers to run more tests locally, integrate earlier, and generally, speed up the feedback loop on the development process.&lt;/p&gt;

&lt;p&gt;However, despite its popularity, I remain skeptical about the effectiveness of Shifting Left, or at least the way that it’s generally applied. Here’s why:&lt;/p&gt;

&lt;h2 id=&quot;the-downsides-of-shifting-left&quot;&gt;The Downsides of Shifting Left&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Running services locally requires high dependence on mocks / fakes&lt;/strong&gt;. To run things locally or in early environments, teams often rely on mocks or fakes to stub out responses from downstream services. These require significant time to create and maintain, obviously don’t operate the same way as their real counterparts in production, and risk becoming outdated over time as the real service is updated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Production Paradox&lt;/strong&gt;. No matter how sophisticated the local or pre-production environments are, they never fully emulate the complexities of production. Here’s a list of some things that are likely to differ in production vs other environments:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;HTTP/ GRPC vs HTTPS / GRPCS, self-signed certs vs TLS, etc&lt;/li&gt;
  &lt;li&gt;Connections to vendors and third-parties&lt;/li&gt;
  &lt;li&gt;Access issues, networking and permission-wise - what the services and the engineers have access to&lt;/li&gt;
  &lt;li&gt;Number and availability of each service - everything pre-prod is usually scaled down for cost&lt;/li&gt;
  &lt;li&gt;The test data in pre-prod often looks vastly different to real use&lt;/li&gt;
  &lt;li&gt;The patterns of use in each environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This single gap is the leading cause of overconfidence in the stability and performance of software, and hence production incidents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev Efficiency&lt;/strong&gt;. It’s 2024. Software engineering is changing. The fastest delivering engineers on any team will at times have multiple pull requests open, relying on automated tests run somewhere in GitHub or GitLab land to check their work for them. Despite knowing how to do it in specific situations, I don’t believe great engineers regularly spin up a local environment, as it can be incredibly time-consuming, detracts from dev time, and this work can be rightfully offloaded to the cloud VM farm.&lt;/p&gt;

&lt;h2 id=&quot;embracing-the-fear-shifting-right&quot;&gt;Embracing the Fear: Shifting Right&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/iq-bell-curve.jpg&quot; alt=&quot;An IQ bell curve suggesting to test in production&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Shifting Right, on the other hand, is about embracing the once-taboo practice of testing in production. “Testing in Production” used to be synonymous with recklessness. Today, I see it as a sign of sophistication, and I see a lot of potential in this domain for enhancing software reliability and delivery speed.&lt;/p&gt;

&lt;h2 id=&quot;the-case-for-shifting-right&quot;&gt;The Case for Shifting Right&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Authentic Validation&lt;/strong&gt;. Testing in prod offers a level of assurance unmatched by any pre-prod environment. When you observe your software operating successfully in the real world, you know it’s genuinely ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shifting Right unifies testing strategy&lt;/strong&gt;. In the current standard development process, each of blackbox and end-to-end tests, synthetic monitoring, and observability occupies their own slice of a development cycle and has own codebase. Yet all of these things are extremely related! Convergence can not only simplify the testing process under one cohesive plan, but allows for less dev time spent on each individual step, and high levels of code reuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost Efficiency&lt;/strong&gt;: One thing engineering management everywhere is talking about more than shifting left is reducing cloud costs! Most dev teams are operating with 4-5 environments in various states of disrepair, but get almost all of their value from 1-2 of these (hint: one of these is prod!). Maintaining multiple dev or testing environments is a costly affair. By focusing on production, we can reduce unnecessary expenditure on cloud resources.&lt;/p&gt;

&lt;h2 id=&quot;introducing-prodzilla&quot;&gt;Introducing Prodzilla&lt;/h2&gt;

&lt;p&gt;It’s from this perspective that I’m developing &lt;a href=&quot;https://prodzilla.io&quot;&gt;Prodzilla&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Right now Prodzilla is an open-source, low-code, synthetic monitoring tool, with a focus on easily testing complex user flows not traditionally tested in prod. The intention is to grow it into a framework that provides everything you need to test in production, and surface the discovered behaviour in useful outputs such as internal or external docs and alerts.&lt;/p&gt;

&lt;p&gt;If you like the idea, please give us a star &lt;a href=&quot;https://github.com/prodzilla/prodzilla&quot;&gt;on our Github&lt;/a&gt;!&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;All this is to say, as with all things, the correct approach is likely balanced. If your engineers aren’t getting any feedback about the quality or behaviour of their code until the end of some pipeline, then yes, please shift left. But don’t fret just because your team isn’t running anything locally - consider this might actually be a good thing! Shifting Left on its own is not a silver bullet, and the losses associated with an over-reliance on simulated environments are significant.&lt;/p&gt;

&lt;p&gt;Shifting Right offers a pragmatic, reality-grounded approach that aligns testing with actual user experiences. I hope Prodzilla can be one part of this journey, aiming to make testing in production a feasible, efficient, and integral part of the software development lifecycle.&lt;/p&gt;
</description>
        <pubDate>Tue, 07 Nov 2023 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2023/11/07/why-im-shifting-left/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2023/11/07/why-im-shifting-left/</guid>
      </item>
    
      <item>
        <title>How I'm Getting Free Synthetic Monitoring</title>
        <description>&lt;p&gt;I’m using a couple of open-source and Rusty tools to get free synthetic monitoring for my side projects. It’s really easy - maybe it will help you!&lt;/p&gt;

&lt;h2 id=&quot;why-synthetic-monitoring&quot;&gt;Why Synthetic Monitoring?&lt;/h2&gt;

&lt;p&gt;Synthetic monitoring is a proactive approach to web application monitoring, whereby we fire real requests at real endpoints to simulate user interactions. It allows for consistent testing of website availability and behaviour, and is particularly useful for identifying and resolving issues before they impact real users!&lt;/p&gt;

&lt;h2 id=&quot;the-tools&quot;&gt;The Tools&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/prodzilla/prodzilla&quot;&gt;Prodzilla&lt;/a&gt; is a new open-source synthetic monitoring application built in Rust. At present it allows defining probes that will call defined endpoints on a defined schedule, and assert that the responses meet expectations. When they don’t, Prodzilla currently has the ability to alert by sending a webhook to a given URL. No need for any special setup to use it, so long as you have Rust installed. &lt;strong&gt;Full disclosure&lt;/strong&gt;: &lt;em&gt;I built it!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.shuttle.rs&quot;&gt;Shuttle&lt;/a&gt; is a great, quick, hosting service for Rust applications. Importantly it’s also currently free, and guarantees a forever free tier. Shuttle makes it extremely easy to deploy a live Rust application fast. For this tutorial you’ll need to create an account at &lt;a href=&quot;https://www.shuttle.rs&quot;&gt;shuttle.rs&lt;/a&gt; and then install the Shuttle CLI with:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo install cargo-shuttle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-process&quot;&gt;The Process&lt;/h2&gt;

&lt;h3 id=&quot;configuring-prodzilla&quot;&gt;Configuring Prodzilla&lt;/h3&gt;

&lt;p&gt;Prodzilla has &lt;a href=&quot;https://github.com/Prodzilla/prodzilla/tree/shuttle&quot;&gt;a specific branch ready to launch with Shuttle&lt;/a&gt;, so clone that. If you’re curious about the structural differences between this and a standard Rust application, the specific changes required to migrate are outlined in ‘&lt;a href=&quot;https://docs.shuttle.rs/migration/migrating-to-shuttle&quot;&gt;Migrating to Shuttle&lt;/a&gt;’.&lt;/p&gt;

&lt;p&gt;To get your local prodzilla ready to deploy, we’ll need to customise a couple of things.&lt;/p&gt;

&lt;p&gt;Firstly, you’ll want to customise your &lt;em&gt;prodzilla.yml&lt;/em&gt;. You likely want something like the below, substituting in the site you want to probe. This will probe a site is up and returning a HTTP 200 OK every 5 minutes (300 seconds), starting from 5 seconds after Prodzilla starts up.&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;probes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Your Probe&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://yourwebsite.com/endpoint&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;http_method&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GET&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;expectations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;StatusCode&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Equals&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;200&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;initial_delay&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;300&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The other fields are mostly self-explanatory, but you can also include expectations about &lt;em&gt;Body&lt;/em&gt;, and can also use the operations &lt;em&gt;Contains&lt;/em&gt; or &lt;em&gt;IsOneOf&lt;/em&gt; (using pipe separated values).&lt;/p&gt;

&lt;p&gt;If you need to add auth, Prodzilla currently supports auth using Bearer tokens in headers, though you would need a long-lived token with the current version of Prodzilla.&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;probes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Your Probe&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;Authorization&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Bearer &amp;lt;token&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you’d like some system to receive a signal when one of your probes fails, you can add a webhook receiver URL to your probe as well:&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;probes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Your Probe&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;alerts&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://alertme.site/webhook&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;deploying-to-shuttle&quot;&gt;Deploying to Shuttle&lt;/h3&gt;

&lt;p&gt;The last thing we need to do in code before deploying is to set the Shuttle project name, in &lt;em&gt;Shuttle.toml&lt;/em&gt;. Choose a unique name:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;name = &quot;my-prodzilla&quot;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And now we just need to send it! Which we can do by executing the following commands. Note that shuttle will complain if you haven’t committed in git, so do that or bypass it by adding the &lt;em&gt;–allow-dirty&lt;/em&gt; flag.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo shuttle project start
cargo shuttle project deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And voila! If you navigate to &lt;em&gt;https://{name}.shuttleapp.rs&lt;/em&gt; you should see a Roar! And if you navigate to &lt;em&gt;https://{name}.shuttleapp.rs/probe_results&lt;/em&gt; you should see a json output of the results of your probes, which are stored in memory.&lt;/p&gt;

&lt;h2 id=&quot;get-in-touch&quot;&gt;Get in Touch&lt;/h2&gt;

&lt;p&gt;I hope that’s been helpful - would love to hear any feedback. Happy roaring!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://x.com/codingupastorm&quot;&gt;X / Twitter: @codingupastorm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/jordandrews/&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://prodzilla.io&quot;&gt;prodzilla.io&lt;/a&gt;.&lt;/p&gt;

</description>
        <pubDate>Tue, 07 Nov 2023 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2023/11/07/prodzilla-and-shuttle/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2023/11/07/prodzilla-and-shuttle/</guid>
      </item>
    
      <item>
        <title>A Foray into Neuro-stuff</title>
        <description>&lt;p&gt;I haven’t posted in 3 years. I’m pursuing some private study / learning into Neuroscience generally, and trying to find some interesting, solvable problems I can commit to contributing to, bringing my previous experience in general software engineering.&lt;/p&gt;

&lt;p&gt;I’m deliberately avoiding academic research - something like pursuing a PhD. I’ll post about why one day.&lt;/p&gt;

&lt;p&gt;What I want to do is share what I’m learning and looking into with some cadence. I could note this privately, but I think there are some benefits to it being public.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I’m loosely committed to continue to work and post by talking about it publicly&lt;/li&gt;
  &lt;li&gt;Writing about things forces one to have clarity of thought, so I get a chance to refine my own thinking&lt;/li&gt;
  &lt;li&gt;Assuming I do “get somewhere” with this, it could provide a useful roadmap for myself or others on how I got here. (I’d love to elaborate also on what “get somewhere” means - again I’ll post why one day.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The format will evolve as I go.&lt;/p&gt;

&lt;h2 id=&quot;heres-what-im-thinking-about-now&quot;&gt;Here’s what I’m thinking about now&lt;/h2&gt;

&lt;p&gt;Current wider ideas:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;For the most part, academic code is poorly readable, not highly reusable, and slow.&lt;/li&gt;
  &lt;li&gt;There is starting to be a heap of data available online, which, so far as I can tell, noone is using cohesively. See &lt;a href=&quot;https://openneuro.org/&quot;&gt;OpenNeuro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;There are a heap of documented problems available online, usually in the form of PhD breifings. See &lt;a href=&quot;https://florey.edu.au/careers-and-study/studying-at-the-florey/&quot;&gt;The Florey Institute&lt;/a&gt; for an example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Specific Learnings:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It seems like the most available and useful format for gathering information from living brains is the MRI. An MRI can retrieve different data based on running MRI sequences.&lt;/li&gt;
  &lt;li&gt;Tractography is a specific imaging technique based on a set of particular MRI sequences, the DWI (Diffusion Weighted Image)&lt;/li&gt;
  &lt;li&gt;I think this is a good starting resource for tractography, which I got to by following a more recent article on tractography, which was part of a PhD brief: &lt;a href=&quot;https://www.cmu.edu/dietrich/psychology/cognitiveaxon/documents/DellAcqua_Catani_2013.pdf&quot;&gt;Hot topics in diffusion tractography&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 07 Nov 2023 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2023/11/07/foray-into-neuro/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2023/11/07/foray-into-neuro/</guid>
      </item>
    
      <item>
        <title>Executing Rust code from C#</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/cs-rs.png&quot; alt=&quot;C# and Rust logos&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Right at the front of “The Rust Book” there is &lt;a href=&quot;https://doc.rust-lang.org/1.5.0/book/rust-inside-other-languages.html&quot;&gt;a section about calling Rust code from other languages&lt;/a&gt;. The examples use Python, Ruby and Javascript and show how using Rust for expensive standalone processes can save time.&lt;/p&gt;

&lt;p&gt;I’ve spent a lot of time working with C# in my career, so naturally I was curious how much faster the example Rust code would be than the C# equivalent.&lt;/p&gt;

&lt;p&gt;The full repo is available &lt;a href=&quot;https://github.com/codingupastorm/rust-in-csharp&quot;&gt;here&lt;/a&gt; if you want to try it for yourself.&lt;/p&gt;

&lt;p&gt;Here’s the Rust code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pub extern fn process() {
    let handles: Vec&amp;lt;_&amp;gt; = (0..10).map(|_| {
        thread::spawn(|| {
            let mut x = 0;
            for _ in 0..5_000_000 {
                x += 1
            }
            x
        })
    }).collect();

    for h in handles {
        println!(&quot;Rust thread finished with count={}&quot;,
        h.join().map_err(|_| &quot;Could not join a thread!&quot;).unwrap());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code is doing something very trivial: it’s starting 10 threads, counting to 5,000,000 on each of them, and then announcing when it’s complete.&lt;/p&gt;

&lt;p&gt;Here is roughly the C# equivalent:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    private static void ProcessCSharp()
    {
        const int threadCount = 10;
        Task[] tasks = new Task[threadCount];

        for (int i = 0; i &amp;lt; threadCount; i++)
        {
            tasks[i] = Task.Factory.StartNew(() =&amp;gt;
            {
                int count = 0;
                for (int j = 0; j &amp;lt; 5_000_000; j++)
                {
                    count += 1;
                }
                Console.WriteLine(&quot;C# thread finished with count={0}&quot;, count);
            });
        }

        Task.WaitAll(tasks);
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ll see how these compare in terms of run-time soon.&lt;/p&gt;

&lt;h2 id=&quot;building-a-dll-from-a-rust-project&quot;&gt;Building a DLL From a Rust Project&lt;/h2&gt;

&lt;p&gt;To be able to call Rust methods from C#, we need to put it into a format that C# can understand. In this case we’re going to use DLL (Dynamic Linked Library) files.&lt;/p&gt;

&lt;p&gt;To generate a DLL from the Rust project, we have to firstly ensure that the external-facing methods are inside &lt;em&gt;lib.rs&lt;/em&gt; and given the visibility &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pub extern&lt;/code&gt;. They also need to be marked with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#[no_mangle]&lt;/code&gt; attribute, whch prevents Rust from internally messing with the API names during optimisation.&lt;/p&gt;

&lt;p&gt;Lastly, we need to add these lines to Cargo.toml before the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[dependencies]&lt;/code&gt; section:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[lib]
name=&quot;RustLibrary&quot;
crate-type = [&quot;dylib&quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These lines tell Rust and Cargo that we want a DLL named &lt;em&gt;RustLibrary.dll&lt;/em&gt; when we build the project.&lt;/p&gt;

&lt;p&gt;When all this is done, all we have to do is build our Rust project (with the Release flag because we want it to be as fast as possible):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo build --release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And voila! Our DLL, &lt;em&gt;target/release/RustLibrary.dll&lt;/em&gt; has been created for us!&lt;/p&gt;

&lt;h2 id=&quot;calling-a-dll-from-a-c-project&quot;&gt;Calling a DLL From A C# Project&lt;/h2&gt;

&lt;p&gt;Now that we have a DLL, we can interact with it by adding &lt;em&gt;RustLibrary.dll&lt;/em&gt; to a Visual Studio project, ensuring that it gets copied to the output folder on build, and importing the DLL inside our C# code.&lt;/p&gt;

&lt;p&gt;Here’s how that looks:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    [DllImport(&quot;RustLibrary.dll&quot;, EntryPoint = &quot;process&quot;)]
    private static extern void ProcessInRust();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is where the magic happens - if you now call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessInRust()&lt;/code&gt; anywhere in your C# project, what happens behind the scenes is your .NET process calls into the Rust code we created earlier!&lt;/p&gt;

&lt;h2 id=&quot;is-it-faster-yes&quot;&gt;Is it Faster? Yes.&lt;/h2&gt;

&lt;p&gt;Here’s the extremely basic code I wrote to test the speed of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessInRust()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessCSharp()&lt;/code&gt; methods above.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Stopwatch csharpStopwatch = new Stopwatch();
Stopwatch rustStopwatch = new Stopwatch();

csharpStopwatch.Start();
ProcessCSharp();
csharpStopwatch.Stop();

rustStopwatch.Start();
ProcessInRust();
rustStopwatch.Stop();

Console.WriteLine();
Console.WriteLine(&quot;Execution time in C#: &quot; + csharpStopwatch.Elapsed);
Console.WriteLine(&quot;Execution time in Rust: &quot; + rustStopwatch.Elapsed);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When I run this on my computer in the C# project:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dotnet run -- --release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the output:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
C# thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000
Rust thread finished with count=5000000

Execution time in C#: 00:00:00.0387920
Execution time in Rust: 00:00:00.0133602
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The results varied but this is about the closest C# got to Rust in my runs. According to this, Rust is around 3 times faster at summing to 5,000,000 on 10 threads. That’s not as big a difference as I was expecting, though I understand that calling into an external library itself is accounting for some of the Rust method’s execution time.&lt;/p&gt;

&lt;p&gt;I’m excited to try out some more complicated scenarios and see what the difference is like.&lt;/p&gt;

</description>
        <pubDate>Mon, 04 May 2020 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2020/05/04/executing-rust-from-csharp/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2020/05/04/executing-rust-from-csharp/</guid>
      </item>
    
      <item>
        <title>Testing as a Selfish Endeavour</title>
        <description>&lt;p&gt;At the start of my career I avoided writing tests wherever possible. I could start my application, and see that it worked for me. Why write tests for something I already know works? I get nothing out of it! This mindset is really okay for your own projects. Where you’re the boss, if you want to work like this and noone else is dependent on it - fine. No worries.&lt;/p&gt;

&lt;p&gt;I think about tests radically differently now though. Selfishly, I get a lot out of tests. They save me a lot of time, but they also help me &lt;strong&gt;save face&lt;/strong&gt;. That’s on top of all of the usability and financial benefits for the other developers on the project and the companies I work for.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-know-this-works&quot;&gt;How do I know this works?&lt;/h2&gt;

&lt;p&gt;Whenever you introduce new functionality to a repository, someone else is likely going to want to use it. And when they do, there is a chance it doesn’t work for them. Guaranteed. So many issues arise when running code on another computer. From different environments and system variables to missing packages, something will come up. If you push new code without tests demonstrating at least a success case, then it just looks like you committed broken code. That sucks! Especially because it might be a configuration issue on their end. If you committed your new code with a passing test case, you can point to it. If it didn’t work for someone else, maybe it’s a problem on their end. Tell them to go look at the test. What are they doing differently?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;By writing that test, you are automating away blame.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Moreover, if I’m a code reviewer for a repository, just looking at the code alone I have absolutely no idea if this thing does what it’s meant to. I would have to read some description of the expected behaviour, pull the code, run the application and then manually test it. At scale, when iteratively developing software, with a team of full-time developers, this is unfeasible. A test does all of these things for you. It describes the things that need to happen, runs the software, and then confirms that it did what was required. Be kind to your code reviewers, and decrease the chances of your pull request being rejected - write tests!&lt;/p&gt;

&lt;h2 id=&quot;vanquishing-bugs-forever&quot;&gt;Vanquishing bugs forever&lt;/h2&gt;

&lt;p&gt;A cool way to think about testing when fixing a bug is this:&lt;/p&gt;

&lt;p&gt;When you add a test to your automated test suite that checks for a specific bug, and then you fix that bug, &lt;strong&gt;you are vanquishing that bug from the face of the Earth. It will never appear again.&lt;/strong&gt; Noone else will be able to reintroduce that bug because your regression tests will recognise it &lt;strong&gt;forever.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;look-how-fast-this-is&quot;&gt;Look how fast this is&lt;/h2&gt;

&lt;p&gt;Profile before you start making optimisations to existing code. The amount of times I have assumed that a certain part of the code was slow, micro-optimised it like crazy and found that I shaved off almost nothing… is too many. Write tests first, know for certain what the bottleneck is, and then fix it. Save your own time.&lt;/p&gt;

&lt;p&gt;And the best part, the most self-boosting thing of all: There is absolutely nothing better than posting a screenshot of a test that used to run in 30 seconds and now runs in under 1 second thanks to your work. Staple that screenshot to the top of your pull request.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I think developers mostly consider testing to be something that is done for someone else. To meet contribution guidelines or appease reviewers. In reality, it serves the developer him/herself more than anyone. It’s a slightly narcissistic idea, but it definitely helps me write better code!&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Jan 2020 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2020/01/13/testing/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2020/01/13/testing/</guid>
      </item>
    
      <item>
        <title>The CREATE2 OpCode and DApp Onboarding in Ethereum</title>
        <description>&lt;p&gt;The Ethereum network’s next major upgrade is the &lt;a href=&quot;https://blog.ethereum.org/2019/01/11/ethereum-constantinople-upgrade-announcement/&quot;&gt;Constantinople upgrade&lt;/a&gt; (was meant to be January 16th but has since been delayed). The upgrade introduces several new features, one of which seems unexciting on the surface but enables a range of possibilities for scalability and user onboarding. This feature is the introduction of a new opcode for the Ethereum Virtual Machine: CREATE2. This article will briefly outline what CREATE2 does and how it could drastically improve the adoption cycle for decentralised applications.&lt;/p&gt;

&lt;h2 id=&quot;what-is-create2&quot;&gt;What is CREATE2?&lt;/h2&gt;

&lt;p&gt;The important thing about CREATE2 is it allows DApp (Decentralized Application) developers to generate contract addresses without having to actually deploy a contract. Previously there was no way of “reserving” a contract address without deploying it. We’ll discuss why this is a problem for adoption later.&lt;/p&gt;

&lt;p&gt;The actual CREATE2 opcode behaves virtually identically to the current CREATE opcode with 1 slight change. Both attempt to deploy some EVM bytecode as a new contract. However, whilst the contract address that a CREATE call deploys to is dependent solely on the sender and nonce, the new contract address for CREATE2 is dependent on extra input data.&lt;/p&gt;

&lt;p&gt;In simple terms, you can think of it as allowing developers a level of “control” over the new contract address generated.&lt;/p&gt;

&lt;h2 id=&quot;the-onboarding-process-before-create2&quot;&gt;The Onboarding Process Before CREATE2&lt;/h2&gt;

&lt;p&gt;Think of some DApp that we’re trying to build and to market to the general public. At some point in the process of users interacting with our DApp, we likely want to give them some on-chain reward; maybe ether, tokens, or some non-fungible token. To do this, of course, the users need their own address, despite this application being their first interaction with the Ethereum &lt;a href=&quot;https://hackernoon.com/tagged/blockchain&quot;&gt;blockchain&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are a couple of options here.&lt;/p&gt;

&lt;p&gt;We could maintain a list of private keys on some centralised server behind the scenes of the DApp. This would allow us to cheaply distribute new addresses to all of our users. However this is a significant &lt;a href=&quot;https://hackernoon.com/tagged/security&quot;&gt;security&lt;/a&gt; burden for us, and really takes the “D” out of “DApp”.&lt;/p&gt;

&lt;p&gt;Another option is to create a wallet-like contract for every new user. Initially, our DApp will have full rights to all of the operations on this contract. Users can still receive everything they need, and whenever they &lt;em&gt;do&lt;/em&gt; create their own Ethereum address, we can easily transfer full ownership over to them, removing the rights of our DApp. In theory, this works great. In practice, it’s very expensive. Contract deployments cost gas, and as the developers of this DApp we have to continually fund the creation of new contracts — even for cases where the users never come back. Sunk cost.&lt;/p&gt;

&lt;p&gt;If only we could know about these contract addresses without having to spend the gas to create them!&lt;/p&gt;

&lt;h2 id=&quot;enter-create2&quot;&gt;&lt;strong&gt;Enter CREATE2&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;With CREATE2 our DApps &lt;em&gt;can&lt;/em&gt; now know a contract’s address before it’s created. In the case above, we can easily generate wallet contract addresses for all of our users. Off-chain. For free.&lt;/p&gt;

&lt;p&gt;We can send all of the tokens and in-game items that we need to to this address, and when the user is ready to commit and claim their new property, we can require that they send a small amount of ether to the contract address. Which will allow our DApp to go and create the contract &lt;em&gt;for free&lt;/em&gt;, taking some of the funds to cover gas costs!&lt;/p&gt;

&lt;h2 id=&quot;concluding&quot;&gt;Concluding&lt;/h2&gt;

&lt;p&gt;This is just one possible brainstormed workflow, but hopefully gives you an idea of the kinds of things we can start doing when we are able to reserve contract addresses for currently unidentified users.&lt;/p&gt;

&lt;p&gt;Let me know if you have any thoughts, or if this high-level explanation can be improved in any way.&lt;/p&gt;

&lt;p&gt;Find me on Twitter: &lt;a href=&quot;https://twitter.com/codingupastorm&quot;&gt;https://twitter.com/codingupastorm&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 17 Jan 2019 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2019/01/17/create2/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2019/01/17/create2/</guid>
      </item>
    
      <item>
        <title>The Importance of Modularity in a Blockchain Platform</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/modularity.png&quot; alt=&quot;Project Ara: an idea for a modular smartphone.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Modularity refers to a system’s ability to be broken down into components which can be separated and recombined. The best software development tools are often highly modular, and allow the reuse of “assemblies” or “modules”. This principle is at the core of development frameworks like Java, C# and Go.&lt;/p&gt;

&lt;p&gt;Modularity promotes innovation because new ideas become trivial to implement. When creating a new web app, the majority of the code running is really inside of externally-developed packages; whether they be database connections, page rendering engines, input validators etc. As such, it’s extremely easy for developers to spin up a prototype of a new website idea.&lt;/p&gt;

&lt;h2 id=&quot;enter-crypto&quot;&gt;Enter: Crypto&lt;/h2&gt;

&lt;p&gt;However, if you were to go and look at the most prized crypto codebase of all, the &lt;a href=&quot;https://github.com/bitcoin/bitcoin&quot;&gt;Bitcoin Core&lt;/a&gt; repository, you’d notice that it’s extremely inflexible. Unmodular code is generally characterised by long files and classes, and individual implementations of classes often depend on other concrete implementations. For an example see &lt;a href=&quot;https://hackernoon.com/tagged/bitcoin&quot;&gt;Bitcoin&lt;/a&gt; Core’s &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/82ffd4d91832c275f791a17f697534cc677c89fd/src/validation.cpp&quot;&gt;validation.cpp&lt;/a&gt;. This isn’t just the case with Bitcoin Core. Most of the biggest &lt;a href=&quot;https://hackernoon.com/tagged/blockchain&quot;&gt;blockchain&lt;/a&gt; node repositories — another example is &lt;a href=&quot;https://github.com/ethereum/go-ethereum&quot;&gt;Go Ethereum&lt;/a&gt;- are absolutely not built with flexibility in mind.&lt;/p&gt;

&lt;p&gt;Now it’s important to note that in the case of Bitcoin, modularity isn’t a priority. If you believe you’re building the &lt;em&gt;singular&lt;/em&gt; “currency” of the future, why make it easier for others to build with your code? Bitcoin Core is highly integrated, but it has stood the test of time and it &lt;em&gt;works&lt;/em&gt;. This is not a criticism of Bitcoin Core’s codebase.&lt;/p&gt;

&lt;h2 id=&quot;experimenting-with-blockchains&quot;&gt;Experimenting with Blockchains&lt;/h2&gt;

&lt;p&gt;With blockchain being cited as the answer to everything, many projects are starting to experiment with different node implementations. Especially in the case of sensitive data and private chains, or cases where external data is core to a chain’s operation, projects are finding that a smart contract based approach does not allow them enough flexibility. Unfortunately until recently this has meant that in order to innovate, developers are pulling apart integrated nodes like Bitcoin’s, or starting new nodes from scratch.&lt;/p&gt;

&lt;p&gt;Both of these avenues are painful, time-consuming, and error-prone (insecure).&lt;/p&gt;

&lt;p&gt;This space is really going to thrive when a blockchain network with a completely new set of features can be spun up &lt;em&gt;clicks fingers&lt;/em&gt; &lt;em&gt;like that&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;stratis--a-modular-platform&quot;&gt;Stratis — A Modular Platform&lt;/h2&gt;

&lt;p&gt;The most exciting thing about Stratis for me is we’re thinking about building blockchains radically differently. Different consensus algorithms, smart contract executors, wallets, and two-way peg implementations are all features in the one codebase.&lt;/p&gt;

&lt;p&gt;Currently you can run — all from the one codebase:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;A Bitcoin (PoW) node&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A Stratis (PoS) node&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A Cirrus (PoA + smart contract) node.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moreover, because of how flexible the node is, I’m confident we could build out full node integrations for Bitcoin Cash, Gold, Private, Doge, Litecoin, etc. in *days *each. Down the road we could extend this to support even more chain types easily, after some foray into the account model and other features.&lt;/p&gt;

&lt;p&gt;When building a new website in .NET Core, you can preload a template and adjust the components to your needs rapidly, punching out a new prototype web app in under a day. We hope that with Stratis developers will be able to do the same but for their own blockchain networks.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;IFullNode node = new FullNodeBuilder()

    .UseNodeSettings(nodeSettings)

    .UseBlockStore()

    .UseMempool()

    .AddRPC()

    .AddSmartContracts()

    .UseCLRExecutor()

    .UseApi()

    .Build();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Isn’t it beautiful? Our &lt;a href=&quot;https://github.com/stratisproject/StratisBitcoinFullNode&quot;&gt;Full Node repo is here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;in-conclusion&quot;&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;Modularity == Innovation.&lt;/p&gt;

&lt;p&gt;I don’t think anyone is as far ahead as we are when it comes to a strong composable approach to building blockchain networks.&lt;/p&gt;

&lt;p&gt;To find out more follow us on Twitter: &lt;a href=&quot;https://twitter.com/stratisplatform&quot;&gt;https://twitter.com/stratisplatform&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or if you just want to wave: &lt;a href=&quot;https://twitter.com/codingupastorm&quot;&gt;https://twitter.com/codingupastorm&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 16 Jan 2019 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2019/01/16/modularity/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2019/01/16/modularity/</guid>
      </item>
    
      <item>
        <title>The Strangest Smart Contract Bug You Haven’t Heard About</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/bug.jpeg&quot; alt=&quot;A bug.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note: I have no &lt;a href=&quot;https://hackernoon.com/tagged/intention&quot;&gt;intention&lt;/a&gt; of discrediting the project or anyone involved with it. The beautiful part about crypto and smart contract development is all of the code is on display. I’m just commentating on a &lt;em&gt;monumental&lt;/em&gt; screwup and a very interesting situation.&lt;/p&gt;

&lt;p&gt;Legolas Exchange (LGO) &lt;a href=&quot;https://www.reddit.com/r/LegolasExchange/comments/7um3jc/hard_cap_reached_3500_bitcoin_raised_in_total/&quot;&gt;raised ~$30M USD&lt;/a&gt; early in 2018 and deployed an ERC-20 token on &lt;a href=&quot;https://hackernoon.com/tagged/ethereum&quot;&gt;Ethereum&lt;/a&gt;. The token has a peculiar feature built into the code that is supposed to reward hodlers (&lt;a href=&quot;https://knowyourmeme.com/memes/hodl&quot;&gt;sic&lt;/a&gt;). For every 6 month period in the first 2 years, all of the accounts that haven’t moved their funds yet should receive an additional 5% in tokens as a reward for their loyalty. The reward has the potential to be higher than 5% — increasing as others abandon their rewards.&lt;/p&gt;

&lt;p&gt;Sounds great right?&lt;/p&gt;

&lt;p&gt;Unfortunately the immutable contract was coded such that the extra 20% of tokens, that should have been used to pay out the bonuses, is virtually guaranteed to be lost.&lt;/p&gt;

&lt;p&gt;I say “virtually guaranteed” because there is a way to retrieve them — it just requires ungodly levels of cooperation. More on this soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Bug&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are several parts of the contract that I think should not have made it through any serious audit, such as the perverse use of percentages to assign token amounts.&lt;/p&gt;

&lt;p&gt;Nevertheless, the problematic bug that led to this article can be found on line 326 of the &lt;a href=&quot;https://etherscan.io/address/0x123ab195dd38b1b40510d467a6a359b201af056f#code&quot;&gt;contract source&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// calculate the bonus for one holded LGO
uint256 bonusByLgo = (BONUS_AMOUNT / 4)/unspentAmounts[_bonusDate];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m not going to go deep into this — you can easily check what I’m saying for yourself. All you need to know is that this variable, bonusByLgo is expecting to be assigned a percentage. Something like 0.05. If you’re a developer (from any background, not just smart contract development!) you know how absurd this is. A uint256 can only be assigned 0, 1, or any other whole integer.&lt;/p&gt;

&lt;p&gt;So when the bonus percentage to dish out is calculated, the user claiming is always going to receive a 0% reward due to natural rounding-down.&lt;/p&gt;

&lt;p&gt;Besides this mistake — the bigger mistake is this: &lt;em&gt;Any&lt;/em&gt; testing of the claimBonus method would have found this problem. $30 million US Dollars were put into a contract where the core feature was completely untested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How They “Resolved” It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To their credit, the LGO team started paying out the bonuses manually, from their own reserve, which was also 20% of tokens. You can see these transactions happening over a long period of time — if you want to do in-depth chain analysis you can find one LGO-owned address dispensing a round of bonuses &lt;a href=&quot;https://etherscan.io/token/0x123ab195dd38b1b40510d467a6a359b201af056f?a=0x1035a5dd4859a87cf25ed31b0df7436099f7d1c3&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Potentially holders of LGO will be reading this and have no idea something was wrong, but this mistake cost the company ~$7M USD at the worst, if we were to value the tokens at LGO’s highest historical market cap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Really Weird Way Out&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So as I mentioned when discussing the bug, the variable bonusByLgo will &lt;em&gt;almost&lt;/em&gt; always evaluate to 0. Except in one case. When (BONUS_AMOUNT/4) is bigger than unspentAmounts[_bonusDate] . When this happens, the remaining holders will receive one bonus token for every LGO token they hold — a 100% bonus!!&lt;/p&gt;

&lt;p&gt;What can trigger this condition? Only if 95% of the holders move their tokens. Only when 5% of the tokens are still eligible for bonuses, they would all receive a 100% bonus at each of the remaining bonus dates.&lt;/p&gt;

&lt;p&gt;The really crazy part is this! If the community came together and all decided to move their tokens — completely the opposite of what the contract intended — they could potentially deliver LGO back at least some of their tokens and &lt;em&gt;save LGO money&lt;/em&gt;. You could even imagine a situation where the LGO team or another rogue developer builds a smart contract that allows the bonus to be claimed and distributed amongst the remaining holders — though good luck getting the required &amp;gt;95% participation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Lesson&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Be skeptical of any token contracts with overly complex functionality. “Smart” smart contract developers should be staying away from any such gimmickry, and when it is absolutely needed, it should be tested and audited to extremes.&lt;/p&gt;

&lt;p&gt;For more on interesting aspects of smart contracts find me on Twitter: &lt;a href=&quot;https://twitter.com/codingupastorm&quot;&gt;https://twitter.com/codingupastorm&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Jan 2019 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2019/01/14/sc-bug/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2019/01/14/sc-bug/</guid>
      </item>
    
      <item>
        <title>The First Token Smart Contract Executing in Native C# / .NET on Stratis</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/stratis-sc.jpeg&quot; alt=&quot;A graphic about Stratis&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Hundreds of you have been messaging me that X other platform has smart contracts in C#. I can say with certainty that Stratis is the first to be executing C# natively. Other platforms (e.g. NEO) may be compiling C# syntax to custom machine code but we’re definitely the first to be executing actual .NET code on the Common Language Runtime, .NET’s virtual machine. (I should know, I previously built EthSharp which compiled C# for the EVM!)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over 12 months ago, slightly frustrated with the “young” state of solidity and &lt;a href=&quot;https://hackernoon.com/tagged/ethereum&quot;&gt;Ethereum&lt;/a&gt; smart contract development environments, I started craving bringing my favourite development environment (C# / .NET / Visual Studio) to &lt;a href=&quot;https://hackernoon.com/tagged/blockchain&quot;&gt;blockchain&lt;/a&gt; development. Over the course of a couple of months I made progress on a project called EthSharp(&lt;a href=&quot;https://github.com/EthSharp/ethsharp-compiler&quot;&gt;see it on github&lt;/a&gt;). It was starting to functionally generate EVM bytecode from C# syntax but I ultimately discontinued it because I felt that compiling to a non-native bytecode negates the possibility of leveraging an established framework’s ecosystem and may carry a range of security risks. &lt;em&gt;Note to self: Write an article about this!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The smart contracts team at Stratis has since been building something much more exciting, a blockchain with the ability to execute .NET code on-chain. Smart contract platforms so far have generally introduced or repackaged a custom virtual machine like the EVM, whilst we’ve gone for a very different approach :)&lt;/p&gt;

&lt;p&gt;The protocol isn’t in production yet — it’s scheduled to be live by the end of the year. You can find out more about &lt;a href=&quot;https://medium.com/@Stratisplatform/stratis-q4-development-roadmap-78d8080e4c39&quot;&gt;the stacked roadmap here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, what’s cool right now is that we have a first draft of a functional token contract (think ERC-20) written completely in C#, and executing on-chain. Thanks to &lt;a href=&quot;undefined&quot;&gt;Rowan de Haas&lt;/a&gt; for putting this one together. Find the most up-to-date source &lt;a href=&quot;https://github.com/stratisproject/StratisBitcoinFullNode/blob/7e0b60fe5292d68421367a5af0500fedbc6048a9/src/Stratis.SmartContracts.Token/StandardToken.cs&quot;&gt;in our node repository on github&lt;/a&gt;, or for now just marvel at this little preview:&lt;/p&gt;

&lt;iframe src=&quot;https://medium.com/media/915e2c27e18f6855143356d73712f522&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;We’re expecting to formalise the standard in the coming weeks, so yes it will have a catchy little name like “SRC-3” soon too.&lt;/p&gt;

&lt;p&gt;I’m hoping there is someone else out there as excited about this as I am. If I find time I’d love to go into the pros and cons of our smart contract execution approach.&lt;/p&gt;

&lt;p&gt;In the meantime, catch me on Twitter: &lt;a href=&quot;https://twitter.com/codingupastorm&quot;&gt;@codingupastorm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or join us on &lt;a href=&quot;https://discord.gg/cEu6AnW&quot;&gt;Discord&lt;/a&gt;! Find me in the #smart_contracts channel.&lt;/p&gt;
</description>
        <pubDate>Sat, 20 Oct 2018 00:00:00 +0000</pubDate>
        <link>https://codingupastorm.github.io/2018/10/20/token-sc/</link>
        <guid isPermaLink="true">https://codingupastorm.github.io/2018/10/20/token-sc/</guid>
      </item>
    
  </channel>
</rss>
