Skip to content

feature(rpc): Adds rpc methods to enable/disable other cheatcodes#557

Open
0xzrf wants to merge 2 commits intosolana-foundation:mainfrom
0xzrf:cheatcode_enable_disable
Open

feature(rpc): Adds rpc methods to enable/disable other cheatcodes#557
0xzrf wants to merge 2 commits intosolana-foundation:mainfrom
0xzrf:cheatcode_enable_disable

Conversation

@0xzrf
Copy link
Contributor

@0xzrf 0xzrf commented Mar 5, 2026

Closes #543

Summary

This PR adds new rpc methods to the SurfnetCheatcodes trait to disable and enable different cheat codes

What Changed

  • Added disable_cheatcodes, enable_cheatcodes, lockout, disable_all_cheatcodes rpc methods
  • Added a CheatcodeConfig struct, CheatcodeFilter enum and RpcCheatcodes in surfpool-types crate. Here's the description for each:
/// main control handler
pub struct CheatcodeConfig {
    pub lockout: bool, // if true, allows disabling even the `surfnet_enableCheatcodes`/`surfnetdisableCheatcodes` methods
    pub filter: CheatcodeFilter,
}

pub enum CheatcodeFilter {
    #[default]
    All, // Disabled all the cheatcodes
    List(Vec<String>), // disables cheatcodes in a named list
}
// a list of all the cheatcodes rpc method names. Used to convert between rpc method name to enum value
pub enum RpcCheatcodes {
     CheatcodeRpcMethods.....
}
  • Added cheatcodes_config: Arc<Mutex<CheatcodeConfig>> to RunloopContext struct to allow cheatcode method filtering between RunloopContext and SurfpoolMiddleware
  • the surfnet_disableCheatcode and surfnet_enableCheatcode majorly just push to the CheatcodeFilter::List
  • Added code to filter out cheatcode rpc methods that are in the CheatcodeFilter::List variant(And rejects all the cheatcode rpc calls when CheatcodeFilter::All)
        if RpcCheatcodes::try_from(method_name.as_str()).is_ok()
            && let Some(meta_val) = meta.clone()
            && meta_val
                .cheatcode_config
                .lock()
                .unwrap() // this is okay since only on_request, disable_cheatcode and enable_cheatcode only use it, the rpc method being called after on_request
                .is_cheatcode_disabled(&method_name)
        {
            let error = Response::from(
                Error {
                    code: ErrorCode::InvalidRequest,
                    message: format!("Cheatsheet rpc method: {method_name} is currently disabled"),
                    data: None,
                },
                None,
            );
            warn!("Request rejected due to cheatsheet being disabled");

            return Either::Left(Box::pin(async move { Some(error) }));
        }
  • the lockout and disable_all_cheatcodes basically manipulate the state inside the CheatcodeConfig struct, while the CheatcodeConfig::is_cheatcode_disabled() handles whether to reject the request or not
  • Added tests for the workflow in crates/core/src/tests/ingration.rs:test_enable_and_disable_cheatcodes

Context

This PR is motivated by the issue #543 and (hopefully) adheres to mostly all the code expectation provided by @MicaiahReid , except the admin control(More then happy to add that too once I get some clarity on that part)

Copy link
Collaborator

@MicaiahReid MicaiahReid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome. The core internal logic is there, but I'd like to simplify the RPC interface a bit.

I'd like to keep all of the same functionality you've implemented, but only have a total of two new RPC methods:

  • surfnet_enableCheatcode
  • surfnet_disableCheatcode

When disabling a cheatcode, you can optionally provide { lockout: true } to allow disabling surfnet_enableCheatcode. For the enable/disable method, a list of methods can be provided, or just the string "all".

Here are some example requests.

Enable all cheatcodes (if `surfnet_enableCheatcode` is enabled) **Note**: if previously `surfnet_enableCheatcode` was disabled, this would return an error ```JSON { "jsonrpc": "2.0", "id": 1, "method": "surfnet_enableCheatcode", "params": [ "all" ] } ```
Disable all cheatcodes (except `surfnet_enableCheatcode`/`surfnet_disableCheatcode`, since no lockout option provided)
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_disableCheatcode",
  "params": [
    "all"
  ]
}
Disable the set account + set token account cheatcodes
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_disableCheatcode",
  "params": [
    ["surfnet_setAccount", "surfnet_setTokenAccount"]
  ]
}
Disable the set account + set token account cheatcodes
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_disableCheatcode",
  "params": [
    ["surfnet_setAccount", "surfnet_setTokenAccount"]
  ]
}
Disable `surfnet_enableCheatcode` If we didn't provide `{"lockout": true}` the method would return an error, saying to disable this cheatcode you need to provide the flag ```JSON { "jsonrpc": "2.0", "id": 1, "method": "surfnet_disbleCheatcode", "params": [ ["surfnet_enableCheatcode"], { "lockout": true } ] } ```

Hopefully those examples help clarify!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add cheatcode method to enable/disable other cheatcodes

2 participants