Project name: Solang Solidity Compiler optimizations and error handling
Introduction: What is Hyperledger Solang?
Hyperledger Solang is a Solidity compiler for Solana and Substrate written in Rust that utilizes LLVM as the backend. It can be considered the first solid initiative towards making Solidity available for non-EVM chains, while maintaining compatibility with Ethereum’s Solidity compiler: Solc.
Chapter 1: Applying for the Hyperledger mentorship
I found out through a friend that Hyperledger Foundation hosts mentorships for open-source projects related to blockchain infrastructure, which has been my main interest since it covers a whole lot of different Computer Science topics (Distributed systems, cryptography, networking, etc.). As I scrolled through the presented projects, I found a Hyperledger Solang mentorship project addressing three issues:
The first issue intrigued me personally. I was working on a De-fi app, using Remix Solc compiler version 0.7.6 that didn’t have runtime overflow checking. The lack thereof was causing a function to misbehave and consumed me a few valuable days to dig into the issue I was facing. The debugging process was captivating and motivated me to go further in understanding how overflow checking works. Although the problem was fixed on later versions of Solc, I saw in the mentorship an opportunity to improve my knowledge about the topic.
I contacted Sean Young and Lucas Steuernagel, the mentors, and discussed some questions I had about the compiler. They were really helpful along the way.
Chapter 2: Getting warmed up
I was new to contributing to open source, didn’t have any experience with Rust and didn’t use Git quite often 🙂 I spent the first three weeks of my mentorship exploring the source code and deciding on what issue to start working on. Since it would give me a broader idea of the code base, I started with the array bounds optimization, whose goal was to decrease the number of instructions when checking if an array indexation is done within its length limits. More details about my work are available both in Solang’s documentation and in the pull request that addresses this.
In my first pull request, my mentors pointed out issues on how I was solving the task and raised many problems with my Rust programming style. I was clearly struggling with it. If you are learning Rust, do not take my approach of “learn by doing.” Please go to the Rust Book, read it, and try out the examples there. It will take some time in the beginning, but the examples will teach you the correct programming concepts. This is the only thing I regret not doing at the beginning of the mentorship.
After that PR was merged, I took some time to read Understanding Ownership and Smart Pointers chapters in the Rust book. That improved my code over the following PRs.
Chapter 3: Multiplication Overflow Detection
The issue at the core of this project was that there was no multiplication overflow detection for integers wider than 64 bits. There are some facts to consider before solving such a problem:
Given these two facts, Solang handled multiplication of larger bit widths by first rounding the value to the nearest 32 bits, then splitting the operands bits into chunks of 32 bits and performing long multiplication.
The multiplication of N bit values will result in at most 2N bit values. So overflow checking was done by assessing whether the uppermost N bits contain any set bits, and raising a runtime error if there are any. Signed multiplication overflow was done first by doing unsigned multiplication, then checking the result for an unexpected change in the sign.
Solang interfaces with LLVM using Inkwell crate. Basically, all of the above was written as Rust code that generates LLVM-IR with the desired logic.
Chapter 4: Improving Solang’s parser resilience.
Solang utilizes LALRPOP, a parser generator, for its parser. The problem was that once a parser or lexical error was found, the parser would throw an error and stop. If there are multiple errors in a Solidity file, the programmer will only see the first one.
I have utilized LALRPOP’s error recovery documentation to add new grammar rules to account for errors, in such a way that the parser returns multiple errors which makes coding easier.
Some messages for future mentees:
For the next six months, I will continue working on Hyperledger Solang through a Web3 Foundation grant with a focus on improving the Solang developer experience. Also, my team and I will continue our thesis project (a cross chain wallet), making sure it is production ready by the end of the next Spring semester. For the long term, I will continue working on blockchain infrastructure-related projects.