Quantcast
Channel: Active questions tagged rustc - Solana Stack Exchange
Viewing all articles
Browse latest Browse all 37

How do pass Context into multiple helper functions?

$
0
0

sorry if this is a more rusty question.

As the title suggests, how can I pass the context struct into multiple helper functions?

What I'd like to do is something like this:

impl<'info> BuyIn<'info> {    pub fn handler(ctx: Context<BuyIn>) -> Result<()> {        let tuple_vec = config!("ZERO_LEVEL","ZERO_MULTIPLIER","ONE_LEVEL","ONE_MULTIPLIER","TWO_LEVEL","TWO_MULTIPLIER","THREE_LEVEL","THREE_MULTIPLIER","FOUR_LEVEL","FOUR_MULTIPLIER"        );        msg!("{:#?}", tuple_vec);        for x in tuple_vec {            if x.0 == ctx.accounts.game.level {                let (amount, fee_amount) = calculate_transfers(x.1);                transfer_to_vault(&ctx, amount)?;                transfer_to_fee_collector(&ctx, fee_amount)?;                update_vault_state(&ctx, amount)?;                update_game_state(ctx)?;                break;            }        }        Ok(())    }}

And here is what my helpers look like:

pub fn calculate_transfers(multiplier: f32) -> (u64, u64) {    let amount = LAMPORTS_PER_SOL as f32 / multiplier;    let fee_amount = (amount * FEE_PERCENTAGE) as u64;    let amount = amount as u64 - fee_amount;    (amount, fee_amount)}pub fn transfer_to_fee_collector(    ctx: &Context<BuyIn>,    amount: u64,) -> Result<()> {    let cpi_context = CpiContext::new(        ctx.accounts.system_program.to_account_info(),         system_program::Transfer {            from: ctx.accounts.player.to_account_info(),            to: ctx.accounts.fee_collector.to_account_info(),        });    system_program::transfer(cpi_context, amount)?;    Ok(())}pub fn transfer_to_vault(    ctx: &Context<BuyIn>,    amount: u64,) -> Result<()> {    let cpi_context = CpiContext::new(        ctx.accounts.system_program.to_account_info(),         system_program::Transfer {            from: ctx.accounts.player.to_account_info(),            to: ctx.accounts.vault.to_account_info(),        });    system_program::transfer(cpi_context, amount)?;    Ok(())}pub fn update_game_state(ctx: Context<BuyIn>) -> Result<()> {    let player = &mut ctx.accounts.player;    let game = &mut ctx.accounts.game;    game.leaderboard.push(        Rank {            player: Some(player.key()),            weight: None,        }    );    Ok(())}pub fn update_vault_states(ctx: &Context<BuyIn>) -> Result<()> {    let vault = &mut ctx.accounts.vault;                   // error here    Ok(())}

And the error I recieve is the following:rustc: cannot borrow 'ctx.accounts.vault' as mutable, as it is behind a '&' reference 'ctx' is a '&' reference, so the data it refers to cannot be borrowed

Ive tried getting all the accounts before the for loop and then passing those as parameters to the helper functions, also changed parameters to include &mut type, but this results in an error in other functions. Specifically transfer_to_vault. I get a trait bound not satisfied when getting/passing in the account_info() into the Transfer struct.

Thanks!

edit: Trying another method but I'm unsure if it will work. Im unable to clone ctx, but I can pass &ctx to the helper functions and clone the relative accounts there into new variables.

My confusion with this is if I clone into new variable, will the subsequent logic/operations not actually be reflected on chain?

        for x in tuple_vec {            if x.0 == ctx.accounts.game.level {                let (amount, fee_amount) = calculate_transfers(x.1);                transfer_to_vault(&ctx, amount)?;                transfer_to_fee_collector(&ctx, fee_amount)?;                update_game_state(&ctx)?;                update_vault_state(&ctx, amount)?;                break;            }        }

And here are the new helpers:

pub fn calculate_transfers(multiplier: f32) -> (u64, u64) {    let amount = LAMPORTS_PER_SOL as f32 / multiplier;    let fee_amount = (amount * FEE_PERCENTAGE) as u64;    let amount = amount as u64 - fee_amount;    (amount, fee_amount)}pub fn transfer_to_vault(    ctx: &Context<BuyIn>,    amount: u64,) -> Result<()> {    let cpi_context = CpiContext::new(        ctx.accounts.system_program.to_account_info(),         system_program::Transfer {            from: ctx.accounts.player.to_account_info(),            to: ctx.accounts.vault.to_account_info(),        });    system_program::transfer(cpi_context, amount)?;    Ok(())}pub fn transfer_to_fee_collector(    ctx: &Context<BuyIn>,    amount: u64,) -> Result<()> {    let cpi_context = CpiContext::new(        ctx.accounts.system_program.to_account_info(),         system_program::Transfer {            from: ctx.accounts.player.to_account_info(),            to: ctx.accounts.fee_collector.to_account_info(),        });    system_program::transfer(cpi_context, amount)?;    Ok(())}pub fn update_game_state(    ctx: &Context<BuyIn>,) -> Result<()> {    let game = &mut ctx.accounts.game.clone();    game.leaderboard.push(        Rank {             player: Some(ctx.accounts.player.key()),             weight: None         }    );    Ok(())}pub fn update_vault_state(    ctx: &Context<BuyIn>,     amount: u64) -> Result<()> {    let mut vault = ctx.accounts.vault.clone();    vault.pot += amount;    Ok(())}

Viewing all articles
Browse latest Browse all 37

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>