The oracle module provides the Provenance Blockchain with the capability to dynamically expose query endpoints through Interchain Queries (ICQ)
One challenge that the Provenance Blockchain faces is supporting each Provenance Blockchain Zone with a unique set of queries. It is not feasible to create an evolving set of queries for each chain. Furthermore, it is not desirable for other parties to request Provenance to build these endpoints for them and then upgrade. This module resolves these issues by enabling Provenance Blockchain zones to manage their own oracle.
Acknowledgements
We appreciate the substantial contributions made by Strangelove Ventures and Quasar Finance through their work on the Async ICQ Module and Interchain Query Demo. These resources were of paramount importance in informing the development of our oracle module.
AcknowledgementsConceptsOracleInterchain Queries (ICQ)Configuration RequirementsRelated ResourceStateOracleIBCMessagesMsgUpdateOracleRequestRequestResponseExpected FailuresMsgSendQueryOracleRequestRequestResponseExpected FailuresEventsEventOracleQuerySuccessEventOracleQueryErrorEventOracleQueryTimeoutQueriesOracleAddressQueryOracleAddressRequestQueryOracleAddressResponseOracleQueryOracleRequestQueryOracleResponseParamsSpecial Topics
Concepts
The Provenance Blockchain oracle module provides a minimal framework for interacting with oracle data through custom CosmWasm smart contracts and leverages Interchain Queries (ICQ) for cross-chain oracle functionality. The module operates as both an ICQ Controller and Host, enabling one Provenance blockchain to asynchronously query another blockchain's oracle through IBC channels, with results delivered via ACK messages and requiring proper channel configuration using the oracle and icqhost ports with specific parameters for successful cross-chain oracle operations.
Oracle
The Oracle is a custom built CosmWasm smart contract that the chain queries for data. Chain users can update the address with a proposal.
Interchain Queries (ICQ)
ICQ is heavily leveraged in order to allow one Provenance Blockchain to query another Provenance Blockchain's Oracle. This module acts as both the Controller and receiver of the Host in the ICQ realm.
When a user intends to query another chain, they initiate the process by submitting a query through a transaction on the ICQ Controller. This Controller delivers the query from the transaction to the ICQ Host module of the destination chain via IBC. Subsequently, the received query is routed by the ICQ Host to this module. Upon receipt, the module queries the Oracle using the provided input, and the resulting information is then transmitted back to the ICQ Controller in the form of an ACK message.
It should be noted that responses, which arrive in the form of the ACK, indicate that queries operate asynchronously. Consequently, these results will not be immediately accessible, requiring the user to wait for an emitted event on the response.
Configuration Requirements
For ICQ to function correctly, it is essential to establish an unordered channel connecting the two chains. This channel should be configured utilizing the oracle and icqhost ports on the ICQ Controller and ICQ Host correspondingly. The version should be designated as
icq-1
. Moreover, it is crucial to ensure that the HostEnabled
parameter is enabled with a value of true
, while the AllowQueries
parameter should encompass the path "/provenance.oracle.v1.Query/Oracle"
.Related Resource
- Async ICQ Module: cosmos/ibc-apps - Async ICQ Module
State
The Provenance Blockchain oracle module manages a minimal state collection that tracks the address of the Oracle CosmWasm smart contract and maintains IBC communication state for interchain queries. The state consists of the Oracle contract address that can be updated through governance proposals and the IBC port information used for communication between the oracle and icqhost modules, enabling the module to forward queries to the smart contract and relay responses while maintaining proper IBC channel connectivity for cross-chain oracle operations.
Oracle
The Oracle is a CosmWasm smart contract that the module forwards its queries to and relays responses from. Users can manipulate this state by submitting an update oracle proposal.
Storage Key:
0x01
Value:
[]byte{}
IBC
IBC communication exists between the oracle and icqhost modules. The oracle module tracks its channel's port in state.
Storage Key:
0x02
Value:
[]byte{}
Messages
The Provenance Blockchain oracle module provides two primary messages for managing oracle functionality and interchain queries: MsgUpdateOracleRequest for modifying the oracle contract address through governance proposals with authority validation, and MsgSendQueryOracleRequest for sending queries to other chains' oracles using Interchain Queries (ICQ) with proper channel and format validation. Both messages include comprehensive error handling for authority validation, address integrity checks, and channel connectivity requirements to ensure secure and reliable oracle operations across the blockchain network.
MsgUpdateOracleRequest
The oracle's address is modified by proposing the
MsgUpdateOracleRequest
message.Request
protobuf// Source: https://github.com/provenance-io/provenance/blob/65865991f93e2c1a7647e29be11f6527f49616e6/proto/provenance/oracle/v1/tx.proto#L37-L46 message MsgUpdateOracleRequest { option (cosmos.msg.v1.signer) = "authority"; // The address signing the message string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // The new oracle address string oracle = 2; }
Response
protobuf// Source: https://github.com/provenance-io/provenance/blob/65865991f93e2c1a7647e29be11f6527f49616e6/proto/provenance/oracle/v1/tx.proto#L48-L49 message MsgUpdateOracleResponse {}
Expected Failures
The message will fail under the following conditions:
- The authority does not match the gov module
- The new address does not pass basic integrity and format checks
MsgSendQueryOracleRequest
Sends a query to another chain's Oracle using ICQ.
Request
protobuf// Source: https://github.com/provenance-io/provenance/blob/65865991f93e2c1a7647e29be11f6527f49616e6/proto/provenance/oracle/v1/tx.proto#L21-L29 message MsgSendQueryOracleRequest { // The query data string query = 1; // The channel to send the query on string channel = 2; // The authority address string authority = 3; }
Response
protobuf// Source: https://github.com/provenance-io/provenance/blob/65865991f93e2c1a7647e29be11f6527f49616e6/proto/provenance/oracle/v1/tx.proto#L31-L35 message MsgSendQueryOracleResponse { // The sequence number for this query uint64 sequence = 1; }
Expected Failures
The message will fail under the following conditions:
- The authority does not pass basic integrity and format checks
- The query does not have the correct format
- The channel is invalid or does not pass basic integrity and format checks
Events
The Provenance Blockchain oracle module emits three distinct events to track the lifecycle and outcomes of Interchain Query (ICQ) operations: EventOracleQuerySuccess for successful responses containing oracle data, EventOracleQueryError for failed responses with error information, and EventOracleQueryTimeout for requests that exceed timeout limits. Each event includes channel and sequence ID information for tracking purposes, with successful events additionally providing the oracle query results and error events including detailed error messages from the responding module.
EventOracleQuerySuccess
This event is emitted when an ICQ response is received from an ACK and is successful.
Type | Attribute Key | Attribute Value |
OracleQuerySuccess | channel | Channel the ICQ request was sent on |
OracleQuerySuccess | sequence_id | Sequence ID of the ICQ request |
OracleQuerySuccess | result | Query data obtained from oracle |
EventOracleQueryError
This event is emitted when an ICQ response is received from an ACK and contains an error.
Type | Attribute Key | Attribute Value |
OracleQueryError | channel | Channel the ICQ request was sent on |
OracleQueryError | sequence_id | Sequence ID of the ICQ request |
OracleQueryError | error | Error received from the module |
EventOracleQueryTimeout
This event is emitted when an ICQ request results in a Timeout.
Type | Attribute Key | Attribute Value |
OracleQueryTimeout | channel | Channel the ICQ request was sent on |
OracleQueryTimeout | sequence_id | Sequence ID of the ICQ request |
Queries
The Provenance Blockchain oracle module provides a streamlined query service for interacting with oracle functionality through two primary endpoints: OracleAddress for retrieving the current oracle contract address, and Oracle for forwarding queries directly to the module's oracle smart contract. The query service enables users to discover oracle configuration and execute queries against the CosmWasm oracle contract with raw message data, receiving JSON responses that contain the oracle's computed results for the provided query parameters.
OracleAddress
Returns the address of the oracle.
HTTP Endpoint:
GET /provenance/oracle/v1/oracle_address
Request:
QueryOracleAddressRequest
Response: QueryOracleAddressResponse
QueryOracleAddressRequest
protobuf// Source: https://github.com/provenance-io/provenance // QueryOracleAddressRequest queries for the address of the oracle. message QueryOracleAddressRequest {}
QueryOracleAddressResponse
protobuf// Source: https://github.com/provenance-io/provenance // QueryOracleAddressResponse contains the address of the oracle. message QueryOracleAddressResponse { // The address of the oracle string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; }
Oracle
Forwards a query to the module's oracle.
HTTP Endpoint:
GET /provenance/oracle/v1/oracle
Request:
QueryOracleRequest
Response: QueryOracleResponse
QueryOracleRequest
protobuf// Source: https://github.com/provenance-io/provenance // QueryOracleRequest queries the module's oracle. message QueryOracleRequest { // Query contains the query data passed to the oracle. bytes query = 1 [(gogoproto.casttype) = "github.com/CosmWasm/wasmd/x/wasm/types.RawContractMessage"]; }
QueryOracleResponse
protobuf// Source: https://github.com/provenance-io/provenance // QueryOracleResponse contains the result of the query sent to the oracle. message QueryOracleResponse { // Data contains the json data returned from the oracle. bytes data = 1 [(gogoproto.casttype) = "github.com/CosmWasm/wasmd/x/wasm/types.RawContractMessage"]; }
protobuf// Example Query Service Definition // Source: https://github.com/provenance-io/provenance service Query { // OracleAddress returns the address of the oracle rpc OracleAddress(QueryOracleAddressRequest) returns (QueryOracleAddressResponse) { option (google.api.http).get = "/provenance/oracle/v1/oracle_address"; } // Oracle forwards a query to the module's oracle rpc Oracle(QueryOracleRequest) returns (QueryOracleResponse) { option (google.api.http).get = "/provenance/oracle/v1/oracle"; } }
Params
No param restrictions exist for the oracle module.