Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev: enhance extensibility #43

Open
EvolveArt opened this issue Mar 9, 2024 · 0 comments
Open

dev: enhance extensibility #43

EvolveArt opened this issue Mar 9, 2024 · 0 comments

Comments

@EvolveArt
Copy link
Collaborator

Current Behavior

If we want to add benchmarks for a new contract and/or a new benchmarking function it's not clear where we should add it.
The codebases violates the SRP in many places.

Expected Behavior

GatlingShooterSetup should only be responsible for doing the setup for one contract. deploy_erc20 should be replaced by deploy_contract.

Here is an example for an ERC20Shooter, from this example it's very clear how one would add an ERC721Shooter or any other shooter for another contract.

trait Shooter {
    fn setup(&self);
    fn shoot(&self, config: GatlingConfig);
    async fn execute(&self, user: &mut GooseUser) -> TransactionResult;
    fn get_calldata(&self) -> Vec<FieldElement>;
}

struct ERC20Shooter {
    contract_name: String,
    contract_address: String,
    num_runs: u64,
}

impl Shooter for ERC20Shooter {
    fn setup(&self) {
        log::info!("{}", format!("Setting up {0} shooter", self.contract_name));
    }

    fn shoot(&self, config: GatlingConfig) {
        log::info!("{}", format!("Shooting {0}", self.contract_name));
    }

    async fn execute(&self, user: &mut GooseUser) -> TransactionResult {
        log::info!("{}", format!("Executing {0}", self.contract_name));
        Ok(())
    }

    fn get_calldata(&self) -> Vec<FieldElement> {
        let (amount_low, amount_high) = (felt!("1"), felt!("0"));
        vec![VOID_ADDRESS, amount_low, amount_high]
    }
}

With such a design we can simplify the whole codebase and get rid of all specific functions for erc20/erc721.
Most of the code for erc20 transfers and erc721 being fairly similar we can abstract the excution logic under the Shooter trait and let the client implement its own logic.

This is a very simple spec, as the refactor progresses we can refine it to our needs. Probably we will want to have all the core similar logic under another trait GooseExecutor that would be able to operate on any object that implements the Shooter trait.

pub async fn run_goose<T: Shooter>(shooter: T) -> color_eyre::Result<()> {
    // ..
    let transaction: TransactionFunction = Arc::new(move |user| Box::pin(shooter.execute(user)));
    // ..

    Ok(())
}
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

No branches or pull requests

1 participant