Skip to content

Commit

Permalink
feat: add call_with_verification and call_without_verification method…
Browse files Browse the repository at this point in the history
…s to QueryBuilder (#540)

* add methods

* changelog
  • Loading branch information
lwshang authored Mar 21, 2024
1 parent 7869e06 commit 8c39e26
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

* Added `QueryBuilder::call_with_verification()` and `QueryBuilder::call_without_verification()` which always/never verify query signatures
regardless the Agent level configuration from `AgentBuilder::with_verify_query_signatures`.

## [0.34.0] - 2024-03-18

* Changed `AgentError::ReplicaError` to `CertifiedReject` or `UncertifiedReject`. `CertifiedReject`s went through consensus, and `UncertifiedReject`s did not. If your code uses `ReplicaError`:
Expand Down
3 changes: 3 additions & 0 deletions ic-agent/src/agent/agent_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ async fn query() -> Result<(), AgentError> {
vec![],
None,
false,
None,
)
.await;

Expand All @@ -94,6 +95,7 @@ async fn query_error() -> Result<(), AgentError> {
vec![],
None,
false,
None,
)
.await;

Expand Down Expand Up @@ -135,6 +137,7 @@ async fn query_rejected() -> Result<(), AgentError> {
vec![],
None,
false,
None,
)
.await;

Expand Down
44 changes: 43 additions & 1 deletion ic-agent/src/agent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ impl Agent {

/// The simplest way to do a query call; sends a byte array and will return a byte vector.
/// The encoding is left as an exercise to the user.
#[allow(clippy::too_many_arguments)]
async fn query_raw(
&self,
canister_id: Principal,
Expand All @@ -431,6 +432,7 @@ impl Agent {
arg: Vec<u8>,
ingress_expiry_datetime: Option<u64>,
use_nonce: bool,
explicit_verify_query_signatures: Option<bool>,
) -> Result<Vec<u8>, AgentError> {
let content = self.query_content(
canister_id,
Expand All @@ -444,6 +446,7 @@ impl Agent {
effective_canister_id,
serialized_bytes,
content.to_request_id(),
explicit_verify_query_signatures,
)
.await
}
Expand All @@ -462,6 +465,7 @@ impl Agent {
effective_canister_id,
signed_query,
envelope.content.to_request_id(),
None,
)
.await
}
Expand All @@ -474,8 +478,9 @@ impl Agent {
effective_canister_id: Principal,
signed_query: Vec<u8>,
request_id: RequestId,
explicit_verify_query_signatures: Option<bool>,
) -> Result<Vec<u8>, AgentError> {
let response = if self.verify_query_signatures {
let response = if explicit_verify_query_signatures.unwrap_or(self.verify_query_signatures) {
let (response, mut subnet) = futures_util::try_join!(
self.query_endpoint::<QueryResponse>(effective_canister_id, signed_query),
self.get_subnet_by_canister(&effective_canister_id)
Expand Down Expand Up @@ -1554,6 +1559,43 @@ impl<'agent> QueryBuilder<'agent> {
self.arg,
self.ingress_expiry_datetime,
self.use_nonce,
None,
)
.await
}

/// Make a query call with signature verification. This will return a byte vector.
///
/// Compared with [call][Self::call], this method will **always** verify the signature of the query response
/// regardless the Agent level configuration from [AgentBuilder::with_verify_query_signatures].
pub async fn call_with_verification(self) -> Result<Vec<u8>, AgentError> {
self.agent
.query_raw(
self.canister_id,
self.effective_canister_id,
self.method_name,
self.arg,
self.ingress_expiry_datetime,
self.use_nonce,
Some(true),
)
.await
}

/// Make a query call without signature verification. This will return a byte vector.
///
/// Compared with [call][Self::call], this method will **never** verify the signature of the query response
/// regardless the Agent level configuration from [AgentBuilder::with_verify_query_signatures].
pub async fn call_without_verification(self) -> Result<Vec<u8>, AgentError> {
self.agent
.query_raw(
self.canister_id,
self.effective_canister_id,
self.method_name,
self.arg,
self.ingress_expiry_datetime,
self.use_nonce,
Some(false),
)
.await
}
Expand Down

0 comments on commit 8c39e26

Please sign in to comment.