foundry icon indicating copy to clipboard operation
foundry copied to clipboard

Feature request: chaos-anvil

Open prestwich opened this issue 3 years ago • 4 comments

Component

Anvil

Describe the feature you would like

Description

Add chaos modes to anvil to better simulate real network conditions.

Motivation

RPC issues are common causes of bugs in foundry, script execution, and off-chain actors. Because mainnet nodes are consistently less reliable than testnet nodes and simulation nodes, it is difficult to test resilience to RPC issues in an application before production deployment

To support stress testing libs, applications, etc, we should add chaos features to anvil, to simulate faulty or weird behavior of mainnet RPC nodes

Details

A --chaos flag for anvil that takes the following instructions each of which enables a specific feature:

  • tx - getTransaction may not fail return a known transaction
  • send - txns broadcast do not always confirm immediately. They may confirm after a delay (which should not block RPC), or not at all.
  • getLog - events are sometimes randomly deleted from eth_getLogs request responses
  • streamLog - events are sometimes randomly dropped from log streams

Example invocation anvil --chaos tx,send,getLog

Bonus points if we can configure frequency at which each of these events occur :)

Additional context

No response

prestwich avatar Nov 29 '22 14:11 prestwich

@mattsse this would be really sick. fault injection effectively. it's possible we could add this feature cleanly by implementing it as a wrapper around our current anvil axum api? that would be minimally invasive while letting us Config everything that the user sees.

I wonder if a generalized version of this is a proxy queueimplementation that sits in front of any node?

gakonst avatar Nov 29 '22 14:11 gakonst

ye, we could easily intercept this here:

https://github.com/foundry-rs/foundry/blob/07dccfd6ebac583ccd63bb818bf27e29b2a4005f/anvil/src/eth/api.rs#L138

with something like:

fn intercept(&self, req: EthRequest) -> Result<EthRequest, ResponseResult>;

mattsse avatar Nov 29 '22 15:11 mattsse

If there is still interest in this feature, I stubbed out a super basic outline for how this might work. You can see it at my fork here - https://github.com/0xcacti/foundry/tree/0xcacti/chaos/crates/anvil

Basically, you add a config flag --chaos to the cli. You can pass in --chaos tx,send for some default rate of fault injection. Or you can configure probabilities with --chaos tx:0.005, ... and tx will inject faults 0.5% of the time.

If I am not totally off base here, I would need guidance on determining exactly which api methods we want to intercept and exactly how we want the failures to occur. Of course, no concerns if I am not going down the right path and we want to scrap this.

I also wrote out an example for how we might intercept logs It's pretty verbose and I am sure there is a better way to do it, but it's a start. (Again, this might not even be the right behavior we want)

    /// Returns logs matching given filter object.
    ///
    /// Handler for ETH RPC call: `eth_getLogs`
    pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
        node_info!("eth_getLogs");
        let logs = self.backend.logs(filter).await;
        if let Some(chaos_config) = &self.chaos_config {
            if let Some(failure_rate) = chaos_config.get_log {
                if rand::random::<f64>() < failure_rate {
                    if let Ok(logs) = logs {
                        return Ok(self.intercept_logs(logs, failure_rate))
                    }
                }
            }
        }
        logs
    }

    fn intercept_logs(&self, logs: Vec<Log>, failure_rate: f64) -> Vec<Log> {
        logs.into_iter().filter(|_| rand::random::<f64>() > failure_rate).collect()
    }

Also would love stylistic guidance if you want me to go forward with implementing this.

Modified Files:

  • api.rs : adding chaos_config to EthApi and adding intercept example code for log

https://github.com/0xcacti/foundry/blob/9eda31b95fce4b66f92c3f122adfa6c432fe9a37/crates/anvil/src/eth/api.rs#L1125

  • lib.rs : adding chaos config handling to spawn(mut config: NodeConfig)

https://github.com/0xcacti/foundry/blob/9eda31b95fce4b66f92c3f122adfa6c432fe9a37/crates/anvil/src/lib.rs#L93

  • config.rs : adding chaos_config to NodeConfig

https://github.com/0xcacti/foundry/blob/9eda31b95fce4b66f92c3f122adfa6c432fe9a37/crates/anvil/src/config.rs#L163

  • cmd.rs : add --chaos to the cli

https://github.com/0xcacti/foundry/blob/9eda31b95fce4b66f92c3f122adfa6c432fe9a37/crates/anvil/src/cmd.rs#L80

Added File: chaos.rs https://github.com/0xcacti/foundry/blob/0xcacti/chaos/crates/anvil/src/eth/chaos.rs

0xcacti avatar Sep 20 '23 05:09 0xcacti

I'm curious if this would be interesting for Reth too (or it already has simulators for this). If a general solution can be found this could be very useful for our users through Reth-Anvil.

zerosnacks avatar Jun 12 '25 14:06 zerosnacks