Detailed explanation of how Interchain Queries work and why they’re designed this way
IAVL tree
) for reading operations using a specific path.interchainqueries
module’s state.
interchainqueries
module, finds the registered query and its parameters, and performs the abci_query
RPC. This call returns a set of key-value pairs along with proofs from the IAVL tree
.
interchainqueries
module. This operation is called KV Interchain Query result submission. The module verifies the result using the proofs, stores it on-chain, and notifies the owning smart contract about the new result.
interchainqueries
module’s state.
interchainqueries
module, finds the registered query and its parameters, and performs the tx_search
RPC. This call returns a list of transactions that match the filters and have been successfully processed on the remote chain.
interchainqueries
module. This operation is called TX Interchain Query result submission. The module verifies the result using the headers and passes the data to the owning smart contract.
interchainqueries
module. Acting as an intermediary between two blockchains, it is similar in concept to an IBC relayer. The main responsibilities of an Interchain Query relayer are:
interchainqueries
module’s state.
interchainqueries
module, which then forwards it to the relevant smart contracts.
query_deposit
module parameter.
In essence, query owners are expected to remove their queries once they are no longer needed. If a query is not used within the query_submit_timeout
period and the owner does not remove it, any network user is allowed to clean up the chain by removing the unused query. As a reward, the deposited assets are transferred to the user who performs the cleanup.
The deposit system serves multiple purposes:
query_submit_timeout
: A registered query property specifying the number of blocks that define the renewable query service period. This period starts when a query is registered and renews with each query update. The query_submit_timeout
value is set based on the module parameters at the time of query registration.
last_submitted_result_local_height
: A registered query property indicating the block height on the home chain when the query was last updated.
registered_at_height
: A registered query property indicating the block height on the home chain when the query was initially registered.
interchainqueries
module.
Since events are not part of the blockchain consensus and are not included in the transaction results (and thus not in TX Interchain Query result submissions), the interchainqueries
module cannot ensure that the submitted transactions match the filters specified in your query. While the module can confirm that the submitted data comes from a valid transaction, it cannot determine whether the transaction satisfies your specific filtering criteria.
To address this limitation, your contract’s SudoTXQueryResult
handler must include additional checks to verify that the submitted transactions meet the criteria defined in your query’s transaction filters. At a minimum, you should confirm that:
/cosmos.staking.v1beta1.MsgUndelegate
.delegator_address
matches the specific address, e.g., cosmos17s3uhcvrwrsp2ldjvxp8rseyc3ulpchdry87hp
.delegator_address
, any valid Undelegate transaction — regardless of the sender — could pass through, potentially compromising your application’s functionality.
Might be interesting:
interchainqueries
module requires KV proofs only during the submission process to verify that the submitted values match the provided proofs. Storing these proofs afterward would unnecessarily consume blockchain storage without serving any practical purpose. The KV results saved on-chain can be trusted because they are cryptographically verified during the submission step by the module.
The Proof
field is present but empty because the QueryResult type is used both for query result submission and for storing query results in the module’s state. This dual-purpose usage can cause confusion, but more specific types may be introduced in the future to address this issue.
interchainqueries
module directly sends the full TX results to the owning smart contracts during the TxQueryResult sudo
call. Once the sudo
call is successfully completed, the results are discarded, minimizing storage use.
The module stores only two things related to TX Interchain Queries:
sudo
entry point, which is only accessible to the chain.
interchainqueries
module relies on the contractmanager module to handle sudo
operations. The contractmanager
module enforces strict gas limits on sudo
callbacks, defined by its sudo_call_gas_limit
parameter, to prevent excessive gas usage.
To manage cases where computations exceed the allocated gas, the contractmanager
module recommends separating sudo
callbacks from heavy computations. One approach is to store the sudo
callback payload in the contract’s state during the sudo
call and then process it later in a separate external execute
call. This method ensures that the gas limit for sudo
calls is not exceeded, while still allowing complex logic to be executed when needed.
Might be interesting:
sudo
callback fails, the interchainqueries
module records the failure in the contractmanager module. This record includes all relevant information about the query and a redacted error message (reduced to the codespace and error code). A full error message is emitted as an event to provide more context about the failure. For details, see the message events emission section.
Failures due to out of gas
errors are also recorded.
Failed query result submissions can be retrieved from the contractmanager
module and resubmitted to the interchainqueries
module. For more information about reading and resubmitting failed operations, refer to the contractmanager documentation.
EndBlock
phase. When a removal message is processed, the TX Interchain Query is marked for removal. Subsequently, in each EndBlock
, a small batch of hashes is removed. The batch size is controlled by the tx_query_removal_limit
module parameter.
pruning
parameter: Configure this in the app.toml file to retain the required historical data for your queries.
indexer
parameter: Set this in the config.toml file to enable transaction indexing.