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

Add some support of reply hooks #535

Open
gshep opened this issue Sep 18, 2024 · 0 comments
Open

Add some support of reply hooks #535

gshep opened this issue Sep 18, 2024 · 0 comments

Comments

@gshep
Copy link
Member

gshep commented Sep 18, 2024

Problem to Solve

When developing programs with complex interactions, we have to take into account gas consumption. For example, our program A sends a request to another program B. In case of a successful response, A must save some record with the response data.

It is at this point in program A, during post-processing of message B, that the gas may be exhausted.

A common solution is to send a message with a gas deposit for the response and install a reply hook:

// ...
        gstd::msg::send_bytes_for_reply(vft_gateway_id, call_payload, 0, reply_deposit)
            .map_err(|_| Error::SendFailure)?
            .up_to(Some(reply_timeout))
            .map_err(|_| Error::ReplyTimeout)?
            .handle_reply(move || handle_reply(slot, transaction_index))
            .map_err(|_| Error::ReplyHook)?
            .await
            .map_err(|_| Error::ReplyFailure)?;

        let _ = self.notify_on(Event::Relayed {
            fungible_token,
            to: ActorId::from(event.to.0),
            amount,
        });

        Ok(())
    }

fn handle_reply(slot: u64, transaction_index: u64) {
    let reply_bytes = msg::load_bytes().expect("Unable to load bytes");
    let reply = vft_gateway::io::MintTokens::decode_reply(&reply_bytes)
        .expect("Unable to decode MintTokens reply");
    if let Err(e) = reply {
        panic!("Request to mint tokens failed: {e:?}");
    }

    let transactions = transactions_mut();
    if CAPACITY <= transactions.len() {
        transactions.pop_first();
    }

    transactions.insert((slot, transaction_index));
}

This reply hook can be benched later to determine minimal required gas for execution. The gas value then passed to the program's constructor.

The main disadvantage is that we don't have access to the sails service in the such reply hook. So cannot emit any event from it or have access to the program's state/storage, for example.

It would be nice to implement some support of that pattern on the sails side.

Possible Solution

research

Notes

No response

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