Understanding Contract Behaviour : Interupted and resumed

here is the contract update Interaction

https://dashboard.testnet.concordium.com/lookup/0541fd4a86d54ba7613e9321ec9f149fea39bf0770dce81eb7cdf784d0367db6

Code is


#[derive(Debug, Serialize, SchemaType, Clone, Copy)]
struct TransferPrize {
    winner: AccountAddress,
    match_id: u64,
}

#[receive(
    contract = "backgammon",
    name = "transfer_prize",
    parameter = "TransferPrize",
    enable_logger,
    mutable
)]
fn transfer_prize<S: HasStateApi>(
    ctx: &impl HasReceiveContext,
    host: &mut impl HasHost<State<S>, StateApiType = S>,
    logger: &mut impl HasLogger,
) -> ContractResult<()> {
    let admin = host.state().admin;
    let sender = ctx.sender();
    ensure!(
        sender.matches_account(&admin),
        BackgammonError::Unauthorized
    );
    let params: TransferPrize = ctx.parameter_cursor().get()?;
    // Get the contract owner, i.e. the account who initialized the contract.
    let winner = &params.winner;
    let match_id = &params.match_id;
    let prize_money = host.state().get_bet_amount(match_id);
    host.invoke_transfer(winner, 2 * prize_money)?;

    let (state, _builder) = host.state_and_builder();
    let mut instance = state.match_id.get_mut(match_id).unwrap();
    ensure_eq!(
        instance.status,
        Status::Ongoing,
        BackgammonError::Unauthorized
    );
    instance.winner = Winner::Player(*winner);
    instance.status = Status::Completed;

    logger.log(&BackgammonEvent::Winner(WinnerEvent {
        winner: *winner,
        amount: prize_money,
        id: *match_id,
    }))?;
    Ok(())
    // Result in a transfer of the whole balance to the contract owner.
}

What is causing interruption.

ownership of variable named “match_id” might be questionable .

Hi @blue,

The interrupts occur when you call either host.invoke_transfer or host.invoke_contract.
It means that the contract execution is paused/interrupted, then something else occurs, e.g. a transfer to an account or the invocation of another contract instance, and then the contract execution is resumed.

The interrupt/resume logs can be used as a sort of stack trace to figure out what occurred and also what might have gone wrong.
For example, if you have a chain of contract calls, i.e. contract A calls contract B, B calls both C and D, and it is the call to D that fails. Then you will be able to determine this from the interrupt/resume logs.

I hope that clarifies it.

Have a nice day
/ Kasper

1 Like