5 min read
Overview
Testing your on a local cluster is essential for rapid iterations and prototyping new Solana programs. However, the default configuration of your local cluster may not match the mainnet (or devnet) cluster's current feature set. This can lead to unexpected behavior when deploying your application to production.
In this guide, we will learn about Solana features, how to check the current feature set of a cluster, and how to configure your local cluster to match the mainnet cluster's feature set. Let's get started!
What You Will Do
- Learn about Solana features and how they might affect your application
- Check the current feature set of a Solana cluster
- Configure your local cluster to match the mainnet cluster's feature set
Prerequisites
- Solana CLI installed (version 1.18 or later)
- Experience with local Solana development (Guide: How to Set Up and Interact with a Local Solana Validator)
Understanding Solana Features
Solana is a rapidly evolving blockchain with new features and improvements being added regularly to respond to the needs of developers and users. Validators are equipped with various new capabilities through the introduction and activation of features through Feature Proposal and Gate Programs (see Resources for more information). These features can be activated in specific clusters, e.g., testnet, but not in others, such as mainnet, leading to variations in functionalities across different environments. When utilizing the default solana-test-validator
on a local setup, all features compatible with the locally installed Solana version are automatically activated. This automatic activation can lead to discrepancies in test results when applications are deployed to a different cluster. Understanding feature activations and their impact on application performance is crucial for proper testing.
For example, I recently tested an NFT program that relied on making a Cross-Program Invocation (CPI) to an inscription program by passing a very large (~3kb) data payload. The program failed on devnet despite working on the local cluster under identical conditions. I got this error: > Program returned error: "Instruction passed to inner instruction is too large (3284 > 1280)"
.
After some investigation, I discovered that my local cluster had a feature enabled that loosed CPI data payload size restrictions, while the devnet cluster did not. This can be a challenging issue to debug, so it's essential to understand how to check the feature set of a cluster and configure your local cluster to match the mainnet cluster's feature set.
Checking the Feature Set of a Cluster
To check the feature set of a cluster, you can use the solana feature status
command. This command allows you to query the current feature set of a cluster and check the status of individual features. Let's give it a shot on mainnet. In your terminal, enter:
solana feature status -um
This will fetch the status (active, inactive, or pending) for all features on mainnet (you could get devnet using -ud
, testnet using -ut
, or local cluster using -ul
).
You should see a list of features and their statuses:
Note that every feature has a unique public key. When proposed, each feature has:
- Feature: a unique public key that is used to identify the feature in the Solana codebase. You can see them all on GitHub here.
- Status: Active, Inactive, or Pending
- Activation Slot: The slot at which the feature was activated
- Description: A brief description of the feature
If you look closely, you can see the feature that caused my CPI data payload size issue: GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm: loosen cpi size restrictions
. At the time of this writing, the feature is disabled on mainnet and devnet but enabled on my local version of Solana. You can also see a reference to a GitHub Issue (26641) where we can learn more about the feature and its status. If you have a specific feature that you would like to query, you can add that feature's public key to your command like so:
solana feature status -um GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm
This should return the same table as before, but with only the feature you specified 🙌.
We can run the same command on our local cluster to see the differences. In a separate terminal, start your local cluster:
solana-test-validator
Then, run the solana feature status -ul
command in your original terminal. You should see a list of features and their statuses on your local cluster. Compare the features and statuses to those on mainnet to identify any discrepancies.
In my case, I can find the same feature is active on my local cluster:
This explains why my program worked on my local cluster but failed on devnet!
Note: the feature sets will change over time, so your results may vary, but the concept remains the same.
Now that we understand the issue, let's learn how to configure our local cluster to match the mainnet cluster's feature set. Go ahead and kill your local validator by pressing Ctrl + C
in the terminal where it is running, and proceed to the next section.
Configuring Your Local Cluster
The Solana CLI has a simple flag you can add to your solana-test-validator
command to configure your local cluster to disable a specific feature. The flag is --deactivate-feature
. You can use this flag to specify the feature set you would like to activate on your local cluster. So, in my case, I would run:
solana-test-validator --deactivate-feature GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm -r
Note: to use the--deactivate-feature
flag, we must use -r
flag as well to reset the local validator to genesis state. This will clear the ledger and restart the cluster with the new feature set.
Your local cluster should start as usual. You can now run the solana feature status GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm -ul
command to verify that the feature has been deactivated. You should see that the feature is now inactive on your local cluster:
GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm | inactive | NA | loosen cpi size restrictions #26641
That's it. In my example, I am now able to run my program on my local cluster and expect the same error as when I deploy it to devnet! ...now, I just need to fix the error 😅.
Anchor CLI
If you are building programs using Anchor, you are likely using anchor test
to start your local validator. At the time of this writing, to use the --deactivate-feature
flag with Anchor, you will need to start your local validator manually using the solana-test-validator
command as we did above. Then, just make sure you add the --skip-local-validator
flag to your anchor test
command. This will tell Anchor to use your manually started local validator instead of starting a new one.
A recent feature has been added (but not yet released as of v. 0.29) to Anchor that will allow you to include deactivate-feature
in your Anchor.toml
file. This will allow you to run anchor test
without needing to start your local validator manually. Keep an eye on the Anchor GitHub for updates on new releases.
Wrap up
Though a seemingly small detail, ensuring your local cluster performs the same as the mainnet cluster can save you a lot of time and headaches when deploying your application. By understanding Solana features and how to check and configure your local cluster's feature set, you can ensure that your application performs reliably across different clusters.
We would love to learn more about what you are building. Drop us a line on Discord or Twitter!