-
Notifications
You must be signed in to change notification settings - Fork 5
Description
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