forked from informalsystems/hermes
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generic query, channel query and reduce code (informalsystems#152)
* Added channel query and TryFromRaw trait * Implemented generic query for abci queries, converted connection query and channel query to use that and disabled client query for now. Removed unused code. * Fix for handling empty response value. * Moved query parameters into the command parameters with Into. (informalsystems#155) Co-authored-by: Adi Seredinschi <[email protected]>
- Loading branch information
1 parent
5752876
commit 9728e16
Showing
7 changed files
with
152 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,78 @@ | ||
use tendermint::abci; | ||
|
||
use crate::chain::Chain; | ||
use relayer_modules::error; | ||
use relayer_modules::query::IbcQuery; | ||
use relayer_modules::try_from_raw::TryFromRaw; | ||
use tendermint::abci::Path as TendermintPath; | ||
use tendermint::block; | ||
|
||
pub mod channel; | ||
pub mod client; | ||
pub mod connection; | ||
|
||
/// Perform an IBC `query` on the given `chain`, and return the corresponding IBC response. | ||
pub async fn ibc_query<C, Q>(chain: &C, query: Q) -> Result<Q::Response, error::Error> | ||
/// Query the ABCI application for information | ||
pub struct Request { | ||
/// Path to the data | ||
pub path: Option<TendermintPath>, | ||
|
||
/// Data to query | ||
pub data: String, | ||
|
||
/// Block height | ||
pub height: u64, | ||
|
||
/// Include proof in response | ||
pub prove: bool, | ||
} | ||
|
||
/// Whether or not this path requires proof verification. | ||
/// | ||
/// is_query_store_with_proofxpects a format like /<queryType>/<storeName>/<subpath>, | ||
/// where queryType must be "store" and subpath must be "key" to require a proof. | ||
fn is_query_store_with_proof(_path: &TendermintPath) -> bool { | ||
false | ||
} | ||
|
||
/// Perform a generic `abci_query` on the given `chain`, and return the corresponding deserialized response data. | ||
pub async fn query<C, T, O>(chain: &C, request: O) -> Result<T, error::Error> | ||
where | ||
C: Chain, | ||
Q: IbcQuery, | ||
C: Chain, // Chain configuration | ||
T: TryFromRaw, // Internal Struct type (expected response) | ||
O: Into<Request>, // Query Command configuration (opts) | ||
{ | ||
let abci_response = chain | ||
// RPC Request | ||
|
||
let request: Request = request.into(); | ||
let path = request.path.clone().unwrap(); // for the is_query_store_with_proof function | ||
|
||
// Use the Tendermint-rs RPC client to do the query - Todo: generalize further for other type of chains | ||
let response = chain | ||
.rpc_client() | ||
.abci_query( | ||
Some(query.path()), | ||
query.data(), | ||
Some(query.height().into()), | ||
query.prove(), | ||
request.path, | ||
request.data.to_string().into_bytes(), | ||
match request.height { | ||
0 => None, | ||
_ => Some(block::Height::from(request.height)), | ||
}, | ||
request.prove, | ||
) | ||
.await | ||
.map_err(|e| error::Kind::Rpc.context(e))?; | ||
|
||
if !abci_response.code.is_ok() { | ||
if !response.code.is_ok() { | ||
// Fail with response log | ||
return Err(error::Kind::Rpc | ||
.context(abci_response.log.to_string()) | ||
.into()); | ||
return Err(error::Kind::Rpc.context(response.log.to_string()).into()); | ||
} | ||
if response.value.is_empty() { | ||
// Fail due to empty response value (nothing to decode). | ||
return Err(error::Kind::EmptyResponseValue.into()); | ||
} | ||
|
||
// Verify response proof | ||
|
||
// Data that is not from trusted node or subspace query needs verification | ||
if is_query_store_with_proof(&query.path()) { | ||
if is_query_store_with_proof(&path) { | ||
todo!() // TODO: Verify proof | ||
} | ||
|
||
query.build_response(abci_response) | ||
} | ||
// Deserialize response data | ||
|
||
/// Whether or not this path requires proof verification. | ||
/// | ||
/// is_query_store_with_proofxpects a format like /<queryType>/<storeName>/<subpath>, | ||
/// where queryType must be "store" and subpath must be "key" to require a proof. | ||
fn is_query_store_with_proof(_path: &abci::Path) -> bool { | ||
false | ||
T::deserialize(response.value) | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.