Achieving Full Parallel Execution in Blockchain: A Neon EVM Technical Breakthrough

Achieving Full Parallel Execution in Blockchain: A Neon EVM Technical Breakthrough

Harness the transformative power of Solana’s parallel technology with Neon EVM to build faster, smarter, and more efficient blockchain applications.


Building with blockchain technology brings forth new paradigms and challenges for developers. As blockchain adoption grows, the demand for scalable and efficient transaction processing becomes paramount. Traditional networks, such as Ethereum, rely on sequential processing, where transactions are executed one after another. This method, while maintaining security and order, creates bottlenecks as demand increases, resulting in slower transaction speeds and elevated fees. These limitations become critical as blockchain usage expands, driven by the increasing volume of decentralized finance (DeFi) applications, blockchain gaming dApps, non-fungible tokens (NFTs), and complex smart contracts.


Solana, with its groundbreaking Sealevel parallel execution model, is designed to tackle the limitations of traditional sequential transaction processing. However, leveraging this innovation within the familiar Ethereum Virtual Machine (EVM) environment requires a unique approach, one that Neon EVM has ingeniously implemented.


Neon EVM brings the best of both worlds, harnessing the speed and efficiency of Solana's parallel processing while maintaining compatibility with Ethereum's robust ecosystem. This dual-complexity environment introduces new opportunities and challenges for developers, particularly optimizing transaction execution and ensuring data consistency. In this article, we take a deep dive into how Neon EVM addresses these challenges, specifically focusing on the execution of ERC-20 contracts like USDC, and the intricate mechanisms it employs to ensure efficient transaction execution. We also answer some tough questions on parallel processing.


Posing the tough questions


  1. Can the current blockchain infrastructure effectively support the shift from sequential to parallel processing without significant overhauls?
  2. How can we ensure the integrity and security of transactions when processed in parallel?
  3. What mechanisms are in place to prevent conflicts and maintain consistency across the blockchain network?
  4. How does Neon EVM specifically address the challenges posed by traditional sequential processing?
  5. How relevant is parallel processing when the Solana network is congested?


Ethereum's sequential transactions


Ethereum operates on a sequential transaction model, which is fundamental to its architecture. In this model, transactions are processed in a linear order, ensuring that each transaction is fully completed before the next one begins. This orderly execution ensures that the state of the blockchain is updated consistently, reducing the complexity involved in managing concurrent transactions. Sequential transaction processing guarantees deterministic outcomes, meaning that the result of executing a series of transactions is always predictable and consistent.


While the sequential transaction model of Ethereum provides robustness and simplicity, it also has limitations. One notable drawback is scalability. As the number of transactions increases, the time taken to process each transaction sequentially can become a bottleneck, leading to slower transaction throughput.


Let us consider a typical ERC-20 spending allowance mechanism. This would look something as follows:


Owner 1, Alice, would like to allow 10 USDC to be spent on one of the EVM protocol/smart contracts.


Optimistic lock Neon EVM

Simultaneously, Owner 2 - Bob, is trying to allow 500 USDC spending from his account.


Optimistic lock_Examplenation 4.png

These transactions in the Ethereum environment are executed sequentially (tx order is determined by the validator/miner of the block).


Solana's Sealevel parallel transaction execution


Solana introduces a revolutionary approach to blockchain technology with its Sealevel parallel smart contracts run-time. This innovation fundamentally changes how transactions are processed, offering advantages over traditional, sequential transaction models like those in Ethereum.


Solana's Sealevel enables parallel processing of smart contracts, allowing multiple transactions that interact with different accounts to be executed simultaneously. The approach leverages modern multi-core processors to handle multiple transactions simultaneously, akin to converting a single-lane road into a multi-lane expressway. By distributing transaction loads across multiple processing cores, parallel execution significantly reduces wait times and enhances network efficiency. This fundamental change not only mitigates delays and lowers transaction fees but also addresses the scalability constraints of traditional blockchain networks. For developers, this means that operations can be performed faster and more efficiently, opening the door to a new realm of decentralized applications and services.


Developers must explicitly provide a list of accounts to be blocked before executing Solana tx. This provides, for instance, the resolution of double-spending issues (and other types of race conditions). A more detailed description of Solana’s transaction design can be found here. It is important to note that Solana, by its design, uses a pessimistic locking approach.


*Double spending is an inconsistency where someone spends the same cryptocurrency twice or repeats the same transaction. Such inconsistencies are problematic and should be managed by appropriate measures.


Solana.PNG

Image source: Squads


Comparative overview of Parallel EVM solutions


The pursuit of parallel execution within EVM has led to several innovative approaches aimed at enhancing blockchain scalability and performance. These solutions seek to process independent transactions simultaneously, thereby increasing throughput. Notable implementations in the market other than Neon EVM include Polygon Parallel EVM, Monad, Sei V2, and BNB Chain’s parallel EVM; with only Neon EVM live on Solana mainnet while others are on various testnets or devnet stages. Each has its own set of pros and cons. Neon EVM stands apart as it is the only parallel EVM that utilizes L1 parallelization designed at the blockchain level on Solana, while others parallelize transaction processing by running several EVM instances. Additionally, Neon EVM being mainnet live for a year is market-tested, and this allows more experience in tackling the various market challenges for any live chain — from throughput to execution.


Polygon Parallel EVM implements a "minimal metadata approach" to identify conflicts upfront during block building. This strategy accelerates the validation process and reduces the frequency of re-executions by addressing conflicts early. However, in such a case, performance is highly reliant on the accuracy of the metadata. Monad utilizes static analysis to predict transaction dependencies and prevent conflicts before execution. This preemptive identification significantly reduces the likelihood of conflicts, thereby minimizing re-execution; but opens a new challenge in maintaining comprehensive and precise static analysis to ensure high performance and accuracy. Sei V2 enhances the developer experience by eliminating the need for manual state access specification and tracking conflicts in real time during execution. This approach simplifies the development process while achieving full parallel execution. Nonetheless, real-time conflict detection can still lead to re-execution, affecting overall performance.


In all these approaches, running separate EVM instances simultaneously has an overhead. State database optimization is then a challenge for all overhead EVM instances to achieve full parallel throughput. Neon EVM differs as it utilizes Solana's Sealevel processing to achieve parallel execution, so it does not require running separate EVM instances.


Neon EVM: Leveraging the strengths of Ethereum and Solana for next-gen dApps


Neon EVM, an Ethereum Virtual Machine built on Solana, stands at the forefront of innovation by leveraging Solana’s parallel execution capabilities. Live on Mainnet since July 2023, it empowers developers to build and deploy dApps seamlessly from EVM chains to Solana, all from their existing codebase. It leverages all the benefits of Solana, including parallel execution.


As the first and only parallelized EVM running on the Solana Mainnet and been battle-tested for a year by a host of dApps, Neon EVM presents a transformative approach to transaction execution. This puts Neon EVM uniquely positioned to fully realize parallel execution, addressing its potential and significant industry challenges.


Understanding the underlying Neon EVM architecture


Neon EVM architecture comprises two major components: Neon EVM smart contract and the Neon Proxy, which work in tandem to process transactions efficiently.


Neon EVM + Proxy.png


Neon Proxy serves as the intermediary between EVM transactions and Solana's network. It receives transactions according to Ethereum rules (N-txn) and wraps them into Solana-compatible transactions (S-txn). The Proxy ensures users can interact with Neon EVM using familiar tools and interfaces (Solidity, Vyper, Hardhat, Remix, Metamask, etc.), simplifying the transition for developers and users alike.


Key Functions of Neon Proxy:


  • Transaction splits and wraps: The Proxy wraps N-tx into S-tx, ensuring compatibility with Solana's network rules. This involves signing the transactions and preparing them for execution on Solana.
  • Iterative execution: For large EVM transactions, the Proxy splits them into smaller, manageable Solana transactions. These smaller transactions are executed iteratively and temporary result is stored in the Solana state after each iteration, ensuring the entire batch is processed as a unit.


The Proxy employs pessimistic locking as a concurrency control mechanism designed to manage access to resources in environments where data conflicts or inconsistencies are likely to occur due to simultaneous access by multiple users or processes. It operates on the principle of preemptively acquiring locks on resources, thereby ensuring exclusive access for the duration of a transaction or critical operation.


The Neon EVM Program (Solana smart contract) recognizes the transaction format from the received batch. Neon EVM extracts data from each transaction, therefore, it can retrieve all the original user information placed in the transaction.



Significant technical challenges arise primarily due to the differences between Ethereum’s and Solana’s transaction processing models. Here’s a detailed look at these challenges and the solutions employed:


Challenge 1: Executing large Ethereum transactions using small Solana transactions Neon EVM transactions, which are similar to Ethereum transactions, tend to be much larger in terms of computational units than Solana transactions (Solana transactions are small in comparison with Eth transactions and limited to just 1.4M Compute Units).


Solution: To manage this, Neon Proxy divides a large Ethereum transaction into smaller, iterative Solana transactions and executes them sequentially. Each iteration processes a portion of the overall task, and the intermediate states are stored in Solana state after each iteration. This method enables the seamless execution of large transactions within Solana's computational constraints.


Challenge 2: Concurrent execution of Ethereum transactions on Solana


Executing multiple Ethereum-like transactions in parallel on Solana requires a mechanism to prevent conflicts, such as double-spending. This is achieved by blocking accounts on the Solana level before iterative execution and releasing the lock at the end of the transaction. Essentially, this involves implementing pessimistic locking mechanism.


Solution: Neon Proxy implements a pessimistic locking mechanism. Before execution, it locks all relevant accounts involved in a transaction, ensuring no other transactions can access these accounts until the process is complete. This approach maintains data consistency and prevents conflicts. However, it also limits the potential for parallel execution, as accounts remain locked for the entire transaction.


Achieving iterative execution with pessimistic locking: A Neon EVM approach


To overcome the challenges, we developed the following approach to enable parallel execution on Neon EVM:


Pessimistic lock.png


In our above example, parallel execution on Neon EVM would appear, with Owner 1 (Alice) now wanting to allow spending 10 USDC on a protocol/smart contract. Every piece of their EVM data structure (mapping record, variable, array, etc.) is stored as a Solana account. Each piece used in the transaction is locked to solve the race condition. So, the first transaction locks the signer’s account and all data storage used by the USDC smart contract.


Important to note here is that with a pessimistic lock mechanism, locking the entire USDC data storage is vital to avoid deadlocks.


Pessimistic lock_Examplenation 1.png


Therefore, Transaction 1: Locks the signer’s account and all related USDC data storage. Transaction 2: Attempts to lock the same USDC data storage and waits for Transaction 1 to complete. All transactions competing for the same accounts are queued up, ensuring orderly execution.


Pessimistic lock_Examplenation 2.png


It is prudent to state that from a technical perspective, these challenges require innovative solutions to leverage Solana’s parallel processing capabilities while maintaining Ethereum’s transaction integrity. Neon EVM navigates these complexities, providing a robust platform for developers to build efficient and scalable dApps.


Well, if you got this far, then it's clear you’re eager to understand the deeper technical intricacies of parallel execution on the Solana environment and the benefits your dApps can leverage. So let’s dive into the ensuing challenges of parallel execution when the Solana network faces congestion and compute usage reaches all-time highs. Read on to explore these crucial aspects that reshape the future of EVM parallel technology.


Solana in 2024: Parallel execution challenges amid network congestion


In the early days of Solana, when network congestion was minimal and blocks were only 20-60% full of the maximum computational unit (CU) limit was reached, everything functioned smoothly. During this period, there was an abundance of computational resources available, leading to fewer iterations needed for each Neon EVM transaction and faster account lock releases. Performance tests on Neon EVM indicated that this architecture could handle up to 2000 Transactions Per Second (TPS) in synthetic tests and approximately 730 TPS on the Solana Mainnet.


Fast-forward to late 2023. After the Breakpoint 2023 event, the compute unit utilization per block on Solana dramatically increased to over 80%, and the activity on the ecosystem saw a massive upward trend (supported by memecoins, NFTs, DeFi, gaming, etc.). Meanwhile, due to a network layer issue on Solana, the failure rate of incoming transactions significantly increased to 80%.


Compute unit.PNG


This would imply the following multipliers:


  • Regular swaps usually require 1-50 iterative transactions, typically 1-5 on average.
  • Prior to any congestion, most of these transactions were executed within 1-2 Solana blocks, taking around 0.4 - 0.8 seconds.
  • After congestion, with only 20% of Compute Units available in the block, Neon EVM had to execute all iterations within 10-50+ blocks, resulting in a longer execution time.
  • If a transaction takes too long to execute, the execution conditions within the smart contract may change (like the exchange rate), causing the transaction to error out. By optimizing compute unit efficiency, we enabled Neon EVM to execute regular swaps within 1-2 Solana blocks, despite congestion and high CU utilization.


This increase also necessitated more iterative transactions and prolonged account lock durations. Due to the high failure rate, executing a single Neon EVM transaction split into multiple Solana transactions now required five times the original number of transactions. This extended account locking time led to longer transaction queues and a decline in TPS, which some users perceived as a performance issue with Neon EVM. Unlike typical Solana transactions that failed, Neon EVM transactions faced significant slowdowns, although with a much lower failure rate.


Neon EVM’s innovative response to Solana’s challenges


Initially, the pessimistic lock design above was effective. However, in the face of congestion, two fundamental problems with this design became evident:


  1. Long transaction execution time led to prolonged account blocking, causing the transaction queue to grow.
  2. Blocking many accounts and data structures also contributed to queue growth. Improving the granularity of account locking would also have led to deadlocks. To address these issues, we decided to switch to an optimistic lock design, as follows:


We transitioned the iterative execution process from a pessimistic to an optimistic model, updating it by locking accounts only in the final stage to save changes into the Solana state. This aims to ensure smoother transaction processing and reduce the likelihood of failed transactions. However, this design alone did not solve the problem of Solana block completion (~80%) and the need for numerous iterative transactions. The prolonged execution time of a Neon EVM transaction would have led to endless transaction repetition within the optimistic lock design too.


To effectively implement this change, we supplemented the following multi-pronged approach:


  • Optimize iterations: More efficiently distribute computational units among iterative transactions. This involved embedding Solana into the Neon Proxy to emulate each transaction on the Proxy side without querying remote Solana nodes.
  • Reduce overhead: Significantly decrease the time required to handle all iterations from the Proxy side. This adjustment required rewriting more than 90% of the Neon Proxy source code. Over the two years of Proxy development, better frameworks in Python emerged, enabling more efficient handling of asynchronous processes.
  • Increase atomicity of account locks: Reduce the number of blocked accounts by more precisely determining which parts of the data structures used in the EVM code will be changed.


For example, if the balance of one account is increased in two parallel transactions, blocking is unnecessary, as double spending is impossible in this case.


If you are a blockchain dApp builder and curious about these approaches, do stay tuned to Neon EVM website for some interesting explainers in our Neon Pulse tech series. More upcoming!


The result: Full parallel transaction execution achieved


With these innovative updates in place and live on Neon EVM mainnet, full parallel execution is a reality and the spending allowance would now look as follows:


Owner 1 (Alice) now wants to allow spending of 10 USDC on a protocol/smart contract deployed on Neon EVM.


Simultaneously, Owner 2 (Bob), is trying to allow 500 USDC spending from his account.

Here, the scenario looks as follows: Transaction 1: 1st transaction locks only the signer’s account and 1 record in allowed mapping - for Alice only. Transaction 2: 2nd transaction locks only its signer’s account and 1 different record in allowed mapping.


Both transactions are executed in parallel.


Optimistic lock_Examplenation 2.png


This comprehensive overhaul required extensive auditing and rigorous testing, including unit, load, and end-to-end tests.


How to manage parallel execution on Neon EVM mainnet: An example


Let us now put to practice and check parallel execution as shown above by Neon EVM. The sections below describe how parallel execution can be achieved for your dApps on Neon EVM environment.


  1. Make a dedicated folder for the test through the following command:


mkdir test-account-locking && cd "$_"


  1. Install needed libraries for the test:
     npm i ethers dotenv 
    Make a .env file that will hold the private key of the wallet needed for the test (ensure the wallet has at least 500 Devnet $NEON):
     PRIVATE_KEY_OWNER=XYZ 


  1. Generating 100 key-pairs:


Let’s create spam-keys folder, and it will generate inside of it 100 Ethereum public-private key pairs. For this create the following script files generate-keys.js with code

 
const { ethers } = require("ethers");
const fs = require('fs');

const spamKeysDir = __dirname + '/spam-keys/';
const logsPath = spamKeysDir + '.env';

const utils = {
    createLog: function(content) {
        if (fs.existsSync(logsPath)) {
            content = '\r\n' + content;
        }
        fs.writeFile(logsPath, content, function (err) {
            if (err) throw err;
        });
    }
};

if (!fs.existsSync(spamKeysDir)){
    fs.mkdirSync(spamKeysDir);
}

let accounts = [];
const ACCOUNTS_LEN = 100;
for (let i = 0; i < ACCOUNTS_LEN; ++i) {
    const account = ethers.Wallet.createRandom();
    accounts.push({address: account.address, privateKey: account.privateKey});
}

// save the accounts into .env file
utils.createLog('KEYS=' + JSON.stringify(accounts));
console.log('Generating keys done!'); 


And run it.


node generate-keys.js


  1. Top up 100 accounts with 1 NEON:


We are going to use command that will use the private key that you have attached inside .env file to airdrop 1 NEON to each one of the 100 wallets that we just generated with the previous command


Let’s create fill-in-keys.js with the code


const { ethers } = require("ethers");
require("dotenv").config();

const spamKeysDir = __dirname + '/spam-keys/';
const logsPath = spamKeysDir + '.env';

const DEVNET_RPC = 'https://devnet.neonevm.org';
const provider = new ethers.JsonRpcProvider(DEVNET_RPC);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY_OWNER, provider);

const accountKeys = require("dotenv").config({path: logsPath});
const accounts = JSON.parse(accountKeys.parsed.KEYS);
const ACCOUNTS_LEN = accounts.length;

async function init() {
    const nonce = await provider.getTransactionCount(signer.address); 
    console.log(nonce, 'nonce');

    // fill in accounts with test amounts
    async function executeTx(counter, nonceParam) {
        signer.sendTransaction({
            to: accounts[ACCOUNTS_LEN - counter].address,
            value: '2500000000000000000', // 2.5 NEONs
            nonce: nonceParam,
            gasPrice: '500000000000' // 500 Gwei
        }).then(function(res, err){
            console.log('TX HASH -', res.hash);

            counter-=1;
            nonceParam+=1;
            if (counter) {
                console.log('Transactions left to be executed -', counter);
                executeTx(counter, nonceParam);
            } else {
                console.log('NEON airdropping to accounts done!');
            }
        });
    }
    executeTx(ACCOUNTS_LEN, nonce);
}
init();


Execute:


node fill-in-keys.js


  1. The final thing to do is to prepare the broadcast command broadcast-raw-txs.js This command will load the 100 wallets from the spam-keys and use their keys to sign 100 raw transactions through eth_sendRawTransaction. The transactions are with same tx data to the very same contract - USDC approval, basically to mimic a “overload” of a single protocol. After this is done the script will batch all of the 100 raw transactions and submit them with 1 single POST request to the RPC.

const ethers = require("ethers");
require("dotenv").config({path: './spam-keys/.env'});

const DEVNET_RPC = 'https://devnet.neonevm.org';
const provider = new ethers.JsonRpcProvider(DEVNET_RPC);
const CHAIN_ID = 245022926;

let TxsBatchArr = [];
const accounts = JSON.parse(process.env.KEYS);
console.log(accounts, 'accounts');

const USDC = '0x512E48836Cd42F3eB6f50CEd9ffD81E0a7F15103';
const MORASWAP_ROUTER = '0x491FFC6eE42FEfB4Edab9BA7D5F3e639959E081B';
const USDC_APPROVE_ABI = [{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}];
const USDC_INTERFACE = new ethers.Interface(USDC_APPROVE_ABI);

let nonce;
async function init() {
    const signer = new ethers.Wallet(accounts[accounts.length - 1].privateKey, provider);
    nonce = await provider.getTransactionCount(signer.address);
    console.log(nonce, 'nonce'); 

    await signTransaction(provider, signer, TxsBatchArr, accounts.length);

    console.log(TxsBatchArr, 'TxsBatchArr');
    console.log(TxsBatchArr.length, 'TxsBatchArr.length');

    // send the batch of signed raw txs to the RPC
    const response = await requestToRpc(
        DEVNET_RPC,
        TxsBatchArr
    );
    console.log(response, 'response');
}
init();

// test USDC approval
async function signTransaction(provider, signer, signedTxs, counter) {
    let signedTx = await signer.signTransaction({
        from: signer.address,
        to: USDC,
        nonce: nonce,
        gasPrice: '500000000000', // 500 Galans
        gasLimit: '1500000', // 1 500 000 Gas limit
        value: '0',
        data: USDC_INTERFACE.encodeFunctionData("approve", [MORASWAP_ROUTER, 1]),
        type: 0,
        chainId: CHAIN_ID
    });
    signedTxs.push({"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":[signedTx],"id":(accounts.length + 1) - counter});

    counter-=1;
    if (counter > 0) {
        await signTransaction(provider, new ethers.Wallet(accounts[counter].privateKey, provider), signedTxs, counter); 
    }
}

async function requestToRpc(RPC, data) {
    const postRequest = await fetch(RPC, {
        method: 'POST',
        body: JSON.stringify(data),
        headers: { 'Content-Type': 'application/json' }
    });
    return await postRequest.json(); 
}


Execute:

node broadcast-raw-txs.js


  1. Now head to https://neonscan.org/blocks and you should be able to see multiple transactions should be batched together into same blocks. This proves that the contract account locking is now gone.


The future is Neon


As we deploy these performance enhancements and updates on our mainnet, we plan to test the system robustness and TPS figures in a live environment. We are also moving towards Neon Proxy decentralization and aim to eliminate the Proxy Operator’s whitelist.


As we prepare for the future, our plans for Mainnet deployment include implementing EIP-1559. This Ethereum Improvement Proposal can potentially impact transaction fees and user experience on Neon EVM. With Solana now emphasizing priority fees in 2024 after congestion challenges, this feature becomes important for dApps on Neon EVM.


By addressing these challenges head-on and innovating with solutions like optimistic locking and enhanced iteration management, Neon EVM is poised to harness the full potential of Solana’s parallel execution capabilities. This ensures that developers can build faster, smarter, and more efficient blockchain applications, paving the way for a new era of decentralized technology.


References


  1. Link to audit


  1. Neon EVM docs


  1. Mainnet TPS Leveraging parallel execution


  1. BNB research Parallel EVMs


  1. Coingecko What is Parallelization


  1. Breakpoint 2023 Neon EVM on Solana


This article is just the beginning. Welcome to Neon Pulse, our tech series dedicated to exploring all things impactful in the blockchain world, with a strong focus on Ethereum and Solana environments. Neon Pulse will provide deep dives into the technological advancements, performance optimizations, and innovative solutions driving the evolution of Neon EVM, bringing together the best of both worlds.


Join our community of pioneering developers and access exclusive content, performance updates, and in-depth analyses that will elevate your understanding and application of blockchain technology. Start building the future of decentralized applications with Neon EVM on Solana today!


For more information about Neon EVM and future updates, visit NeonEVM.org and connect with the community on Twitter or Discord.


*Disclaimer: The information contained on this webpage is not intended as and shall not be understood or construed as legal, tax, investment, financial, or other advice. Nothing contained in this constitutes a solicitation, recommendation, endorsement, or offer by Neon EVM or any third-party service provider to buy or sell any crypto-assets or other financial instruments. We recommend users do their own research, fully understand the nature of their purchase/actions and the risks involved and always seek independent financial advice if in doubt.

Yury Yurchenko
Yury YurchenkoChief Product Officer
Jun 16, 2024

Other articles