Hi, my name is Raul Jordan. I am a software engineer and one of the maintainers of the Ethereum blockchain protocol. I believe technology can help us build a less zero-sum world.
I like to write code in Go and Rust, and maintain a large open source project called Prysm. I currently work as a senior software engineer at Offchain Labs, the company behind the leading scalability solution for Ethereum, Arbitrum

Some of my blog's highlights are: Check out my Github or email me to get in touch

My Most Embarrassing Story as a Beginner Software Engineer

The beginner's curse of not knowing when to ask "why"

Image

Read more  ↩︎

Rust concepts I wish I learned earlier

Image

This past month, I have been enthralled by the Rust programming language given its unique edge for writing memory-safe, modern programs. Over the years, several languages have emerged as the most preferred by engineers to write resilient, backend software. The tides have shifted from Java/C++ into Go and Rust, which combine decades of programming language theory to build tools that are effective in our current age.

Rust’s numbers speak for themselves. As the number 1 most loved language in the famous stack overflow survey for seven years in a row, it has also recently been released as part of Linux kernel - a feat no language other than C has been able to accomplish. What’s exciting about the language, to me, is that it provides something truly new in the art of how software is built.

use std::thread;
use std::time::Duration;
use std::{collections::VecDeque, sync::Condvar, sync::Mutex};

fn main() {
    let queue = Mutex::new(VecDeque::new());

    thread::scope(|s| {
        let t = s.spawn(|| loop {
            let item = queue.lock().unwrap().pop_front();
            if let Some(item) = item {
                dbg!(item);
            } else {
                thread::park();
            }
        });

        for i in 0.. {
            queue.lock().unwrap().push_back(i);
            t.thread().unpark();
            thread::sleep(Duration::from_secs(1));
        }
    })
}
Read more  ↩︎

How to Set Up an Ethereum Proof-of-Stake Devnet in Minutes

Image

With Ethereum having finally transitioned to proof-of-stake, many people are wondering how to set up a local testing environment given so much has changed.

Read more  ↩︎

When Years of Work Finally Materialize

Back in late 2017, I was curious about a particular technology called Ethereum when I understood its incredible potential to change the world. I assembled a team of software engineers I met on the Internet that shared this vision and for 4 years, we have worked tirelessly to upgrade the system to one that is more economically and environmentally sustainable.

Read more  ↩︎

Using Interface Composition in Go As Guardrails

Image

Composition over inheritance

Go, as a programming language, favors simplicity. When writing abstractions in Go, interfaces are some of the most powerful tools available to developers, providing a whole suite of useful functionality for your applications and expressive packages.

Read more  ↩︎

When a Solution Is Right In Front of You

We had a crazy week debugging one of the trickiest issues we've seen in our software. This post showcases how we went down a rabbit hole of information only to conclude a resolution was far easier than we thought.

Read more  ↩︎

Reuse Expensive Computation With In-Progress Caches in Go

Caching is the go-to solution in applications to avoid repeating expensive computation and instead prefer some value that can be readily fetched in-memory. A simple caching strategy is to use a cache as a thin layer above database read access as follows:

package main

import "sync"

type Database struct {
	cache map[string][]byte
	lock  sync.RWMutex
}

func (db *Database) GetItem(key []byte) ([]byte, error) {
	db.lock.RLock()
	if value, ok := db.cache[string(key)]; ok {
		db.lock.RUnlock()
		return value
	}
	db.lock.RUnlock()
	return db.readFromDatabase(key)
}

func (db *Database) WriteItem(key, value []byte) error {
	if err := db.writeToDatabase(key, value); err != nil {
		return err
	}
	db.lock.Lock()
	db.cache[string(key)] = value
	db.lock.Unlock()
	return nil
}

This strategy works great for applications where you have requests to read access for a certain value repeatedly, preventing you from performing a potentially expensive db query and leveraging fast access in-memory. Caching is very helpful. For some problems, however, a cache is definitely not enough.

Read more  ↩︎