Skip to content

Responses

Responses in the ISMP framework can be either one of a PostResponse or a GetResponse.

/// The response to a POST request
pub struct PostResponse {
    /// The POST request that triggered this response.
    pub post: Post,
    /// The response message.
    pub response: Vec<u8>,
    /// Unix timestamp at which this response expires in seconds.
    pub timeout_timestamp: u64,
}
 
/// The response to a GET request
pub struct GetResponse {
    /// The Get request that triggered this response.
    pub get: Get,
    /// Key-Values derived from the state proof
    pub values: BTreeMap<Vec<u8>, Option<Vec<u8>>>,
}
 
/// The ISMP response
pub enum Response {
    /// The response to a POST request
    Post(PostResponse),
    /// The response to a GET request
    Get(GetResponse),
}

PostResponse

A PostResponse can be seen as the result or return value of a PostRequest execution. IsmpModules may opt not to generate a PostResponse, and instead employ an optimistic model. In this model, the module state is altered before the request is dispatched, in such a way that it can be reverted if the request times out. This approach reduces considerable message round trip and verification expenses, providing a better user experience. However, when it's necessary to give the caller an execution result, the ISMP framework allows for a PostResponse. The PostResponse, much like a PostRequest can also time-out.

GetResponse

A GetResponse provides the requested storage values of a GetRequest, it contains a map of the requested key-value pairs. These values may be null, in which case they are represented as Option::None. The key-value pairs are derived from the state proof verification of the values at the given height. This verification is performed using the StateMachineClient of the destination StateMachine.

Handlers

The ISMP framework exposes a handler that allows relayers submit new responses, alongside the necessary state proofs required for verification so that they may be executed by IsmpModuless

handle_response

/// A request message holds a batch of responses to be dispatched from a source state machine
pub struct ResponseMessage {
    /// A set of either POST requests or responses to be handled
    pub datagram: RequestResponse,
    /// Membership batch proof for these req/res
    pub proof: Proof,
}
 
/// Validate the state machine, verify the response message and dispatch the message to the router
pub fn handle_response<H>(host: &H, msg: ResponseMessage) -> Result<(), Error>
where
    H: IsmpHost,
{
    // .. implementation details
}

The handle_response is used to notify onchain IsmpModules of new responses to be processed. A relayer will construct the ResponseMessage which holds a batch of new responses, and their relevant proofs. The handler will perform the following operations

  • Assert that the state machine's consensus client is not frozen
  • Assert that the configured challenge_period for the StateCommitment has elapsed
  • Assert that the responses have not been previously processed
  • Assert that the responses have not timed out
  • Assert that the proofs for the responses verify
  • Finally dispatch the responses to the relevant IsmpModule::on_response and store a receipt for each responses to prevent responses from being replayed.