Skip to content

Add some support of reply hooks #535

@gshep

Description

@gshep

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions