The Interchain Queries (ICQ) module leverages the existing relayer infrastructure, with some custom changes, to enable two connected chains to query data from eachothers' state. The module only needs to be imported by the chain that wishes to perform queries. The relayer is expected to parse queries from the requesting chain, perform them on the chain indicated in the query, and pass the result back to the requesting chain. This document will describe the Cosmos SDK module aspect of Interchain Queries. For the relayer aspect, refer to the Relayer document.
PeriodicICQ
: describes a periodic data request and serves as a template for instances of such periodic queries. The periodic includes all details about what data is required and which chain it should be queried from. It also specifies how often the query should take place (i.e. the period length) and timeout parameters.PendingICQInstance
: an instance of a periodic query that can be seen as a pending query. An instance is created at every period, as specified by the periodic, and this instance is deleted once a result is submitted or it timesout. These query instances are picked up by the custom relayer and fulfilled according to the details in the request.PendingICQRequest
: This is the message that will be retrieved by the relayer. The data is a combination of thePendingICQInstance
andPeriodicICQ
to have the full message available to the relayer without storing duplicate data in the blockchain.PeriodicLastDataPointId
: stores thelast_result_id
of the last result submitted by the relayer in response to a specific periodic query. There is onePeriodicLastDataPointId
perPeriodicICQ
and its stored under theperiodic_id
as astring
and doesn't have it's ownmessage
type. Thelast_result_id
points toDataPoint
uniqueId
which stores the last result.DataPoint
: Stores a result of a servicedPendingICQInstance
.ICQTimeouts
: this is created perPeriodicICQ
we increment the amount of timeouts that occur for that periodic query as well as the last source chain height that the timeout occured at. If the BeginBlock notices that the timeout height was reached it will expire aPendingICQInstance
s. If the relayer submits a late result, this is completely ignored.
List of PeriodicICQ
, each with:
- Id (
uint64
): basic unique identifier - Path (
string
): query path, e.g./store/bank/key
- TimeoutHeightPadding (
uint64
): timeout height will be current height plus this value - TargetHeight (
uint64
):The height of the chain we are querying, this is usually set to0
to always query the heighest height of the target chain. - ClientId (
string
): IBC client Id of the target chain e.g07-tendermint-0
- Creator (
string
): string identifying the creator of this query (not necessarily an address), e.g. a module's name - ChainId (
string
): chain ID of the data source where data should be queried from, this is purely for viewing purposes and not used anywhere - QueryParameters (
[]byte
): query parameters, e.g.append(banktypes.CreateAccountBalancesPrefix(add1), []byte("stake")...)
- BlockRepeat (
uint64
): the period length, e.g. 10 blocks - LastHeightExecuted (
uint64
): the last local height at which this interchain query was invoked - MaxResults (
uint64
): the total number of concurrent results thisPeriodicICQ
should store. The results will be overwritten once exceeded. E.G30
meaning the31st
result will overwrite the1st
result.
List of PendingICQInstance
, each based on an PeriodicICQ
instance:
- Id (
uint64
): basic unique identifier - TimeoutHeight (
uint64
): height at which a result for this query will be considered invalid, calculated by adding periodic's timeout height padding to the current height - TargetHeight (
uint64
): from periodic - PeriodicId (
uint64
): ID of periodic
List of PendingICQRequest
, each based on an PeriodicICQ
and PendingICQInstance
:
- Id (
uint64
): basic unique identifier - Path (
uint64
): from periodic - TimeoutHeight (
uint64
): height at which a result for this query will be considered invalid, calculated by adding periodic's timeout height padding to the current height - TargetHeight (
uint64
): from periodic - ClientId (
uint64
): from periodic - Creator (
uint64
): from periodic - QueryParameters (
uint64
): from periodic - PeriodicId (
uint64
): ID of periodic
List of PeriodicLastDataPointId
, each based on an PeriodicICQ
instance, only stored as a string not struct:
- LastResultId (
string
): matches the ID of the last datapoint stored under the periodic query id
List of DataPoint
, each based on an PendingICQInstance
and populated by MsgSubmitICQResult
tx:
- Id (
string
): basic unique identifier - LocalHeight (
uint64
): local height at which result was recorded, i.e. upon MsgSubmitICQResult handling - TargetHeight (
uint64
): the height at which the result was retrieved from the target chain - Data (
[]byte
): encoded query result from MsgSubmitICQResult - PrevDataPointId: (
string
): id of the previous datapoint linking them all together
List of ICQTimeouts
, each based on an PeriodicICQ
instance:
- PeriodicId (
uint64
): identifier which points to the periodic query - Timeouts (
uint64
): number of times pending query instances timed out for the periodic query - LastTimeoutHeight (
uint64
): last local height that a periodic query has timedout
For all the above values, a count is also stored.
MsgSubmitICQResult
: used by relayer to submit an interchain query result. If the result arrives too late (i.e. timeout) it is ignored. PeriodicLastDataPointId
is updated as well as DataPoint
is created or updated depending on if the max results limit is reached.
- QueryId (
uint64
): matches the ID of query that this result is for - Result (
[]byte
): encoded query result - Height (
ibc.core.client.v1.Height
): the height at which the result was retrieved from the target chain - FromAddress (
string
): relayer that submitted this result, i.e. the one that signed this message - Proof (
*crypto.ProofOps
): data validity proof - PeriodicId (
uint64
): ID of periodic that this result corresponds to
n/a
ProcessBeginBlockPendingQueries
: iterates over allPendingICQInstance
s and if the timeout height has been exceeded, the particular instance is timed-out. This means that aICQTimeouts
instance is updated and the originalPendingICQInstance
is deleted.
ExecutePeriodicQueries
: iterates over allPeriodicICQ
s and createsPendingICQInstance
s if enough blocks have elapsed since the last time the query was invoked. This is the case when the sum of LastHeightExecuted (e.g. 1,000,000) and BlockRepeat (e.g. 5) is equal to the current block height (e.g. 1,000,005).
No special dependencies
n/a
- Programmatic relayer incentivisation/subsidisation