How I implemented Ethereum’s PBS using .NET Part 1

Introduction to PBS and .NET Core

.NET Core is an open-source, cross-platform framework developed by Microsoft for building modern applications. It enables the development of applications and services that run on Windows, Linux, ARM and macOS. As a modular and lightweight version of the .NET Framework, it's designed for high performance and supports multiple programming languages, including C#, F#, and Visual Basic. .NET Core's versatility and efficiency make it a popular choice for enterprise software development.

What is PBS

Present-day Ethereum validators create and broadcast blocks. They bundle together transactions that they have heard about through the gossip network and package them into a block that is sent out to peers on the Ethereum network. Proposer-builder separation (PBS) splits these tasks across multiple entities. External block builders become responsible for creating blocks and offering them to the block proposer in each slot. The block proposer cannot see the contents of the block, they simply choose the most profitable one, paying a fee to the block builder before sending the block to its peers. The PBS model currently used on the Ethereum network is an out-of-protocol PBS model and it divides the responsibilities of block production into four distinct roles:

  1. Block Searchers: Searchers look for the most profitable ways to build a block.

  2. Block Builders: Block builders are responsible for compiling and assembling blocks, either found through their own searches or through accepting external submissions from searchers. They gather transactions from the network, organize them (often based on transaction fees), and create a block. The objective for the block builder is to construct a block which will be as profitable as possible for them, while at the same time attempting to become the selected block by the relays, they're connected to, so their block is most likely to become proposed by the upcoming validator.

  3. Relays: After a block builder has built its block, they submit them to various relays. These relays then select the highest bidding one submitted to their relay for the upcoming block and delivers it to the upcoming block proposer who requests a block from the relay.

  4. Block Proposers: After a block is built, it is presented to a block proposer. The proposer's job is to select the most profitable block from the offerings of various builders. Importantly, proposers cannot view the contents of the blocks they're choosing, preventing any potential manipulation in transaction selection.

Using the existing PBS system, the aim was to create a marketplace of builders for the validators of the Ethereum network with increased competition and fairness for non-institutional-sized validators as they are less likely to build and operate these services.

Why PBS

In traditional blockchain models, validators or miners who create and propose blocks can have disproportionate power. They can decide which transactions to include or exclude, potentially leading to censorship or prioritization of their transactions. PBS mitigates this by separating the roles of building and proposing blocks, reducing the potential for any single participant to have undue influence over the network.

  • Separates Roles: PBS divides the tasks of creating blocks (builders) and adding them to the blockchain (proposers). This separation helps reduce the concentration of power and potential bias in block creation.

  • Improves Security: Since proposers cannot see the contents of the blocks they add, it's harder for bad actors to manipulate the blockchain for personal gain.

  • Increases Efficiency: Specialization in block building and proposing can lead to faster and more efficient processing of transactions.

Why .NET? The advantages and potential challenges

Since .NET Core was released in 2016 it has gained momentum due to the open-source perspective and multi-platform. Due to the long lifespan of .NET, there are plenty of frameworks and resources to help.

Advantages

Popularity

Based on the 2023 Stack Overflow developer survey, which received responses from over 60,000 developers globally, C# ranks 8th among 51 commonly used programming languages.

Cloud computing

Designed with cloud-computing in mind, .NET Core excels in creating efficient, scalable applications for cloud environments. Its compatibility with various cloud platforms ensures versatility and ease of deployment, making it a top choice for cloud-based development.

Ecosystem

The Microsoft ecosystem surrounding .NET Core is rich and diverse, offering developers a wide range of powerful tools and services. From Visual Studio’s comprehensive development environment to seamless integration with various Microsoft products, the ecosystem significantly enhances development efficiency.

Enterprise

According to Microsoft themselves over 95% of the “Fortune 500” companies use Microsoft Azure as cloud service.

Challenges

Encryption

My initial thoughts and concerns about this project were primarily surrounding some blockchain specific infrastructure such as the bleeding edge encryption technologies being used with libraries such as BLS, signatures and hashing, as well as the unique serialization. Writing my own implementations of these specific areas was something I wanted to avoid initially, if possible, until I had obtained a deeper understanding of how each of those areas operated and what potential pitfalls existed in each of them.

Integration

Builder API is an API for external builder nodes. This interface enables validators to delegate block building duties. The API consists of only four endpoints and the challenge is the understanding of the underlaying models which are quite large.

Testing

On top of doing unit testing, we also wanted to run tests on production data. To do so, we first had to obtain a valid execution payload header, and this was done by using a Testnet with relays available on it. In our case, we used Goerli, and we ended up with a hacky way of obtaining it where we monitored which validator would be producing a block and then made the query to all relays at the time that the validator was up for publishing a new block. After we had successfully retrieved a JSON with proper data in it, we could run tests on the JSON to ensure the payload was correct, that signatures matched, etc.

What I hoped to achieve with this implementation.

The main goal was to provide a wider choice of clients for the Ethereum eco-system by adding an additional programming language which in turn could attract developers from the .NET community.

Client diversity

Over 90% of all validators are running a single piece of MEV software on their hosts, and I believe there is a potential risk to the Ethereum network with this type of setup as while many validators use various consensus and execution layer clients, the validators also run this single type of software which could potentially cause a failure. As client diversity is improving for the consensus and execution layer, I believe the same improvements should be made for MEV software to further reduce potential risks of network failure. clientdiversity.org

Initial Project setup and configuration

The overall idea is to make an introduction and onboarding to web3 as seeming less as possible for a web2 developer. My approach is to use as many common tools as possible, in this case the project is built using Visual Studio 2022 Community edition and .NET 7.

The project structure is referred to a N-Layer application which comes in many shapes and forms but is essentially a separation of concern when it comes to structure an application in different layers.

Project solution
Project solution

PBS From a Developer’s Point of View

Examples, Packages, and Documentation, or the Lack Thereof.

The project structure of the application will likely be familiar to .NET programmers. The application features an API entry point, which in turn follows an application layer with associated domain models and a test project.

Thanks to a flowchart from mev-boost, we had an overview of what needed to be done. Briefly, it involved integrations with Proposals and Builders and verifying that the packages from them were accurate, which included, among other things, verifying signatures. This led to digging into existing packages and solutions for this purpose.

The packages we were looking for were related to hash verifications. We found a few potential solutions, but in each case, there was always something missing, like the package working only for certain parts, being deprecated, or not having been developed for a long time.

We continuously assessed potential risks with each package, for instance, whether it was reasonable to further develop it ourselves. Was it possible to extract the parts we needed from a larger project?

Conclusion

Ultimately, we settled on four separate packages from which we could extract what we needed and integrate them into our solution, elevating the code and implementing updates required by the latest hard forks which in some cases had not been implemented in the projects. Then, we lifted all the code to the latest version of .NET Core at the time of writing. It was a great feeling when we could compile and run through the entire process with real data from the Testnet, and all the tests passed.

After these tests were successful, we deployed 100 validators on Goerli, and successfully ran mev-sharp and had success in requesting, receiving and finally delivering blocks to the validator to be built!

Github repository:

Subscribe to Stefan Lindberg
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.