Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/0.39.3 #631

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
516 changes: 437 additions & 79 deletions Cargo.lock

Large diffs are not rendered by default.

61 changes: 32 additions & 29 deletions ic-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,57 @@ keywords = ["internet-computer", "agent", "icp", "dfinity"]
include = ["src", "Cargo.toml", "../LICENSE", "README.md"]

[dependencies]
async-trait.workspace = true
arc-swap = "1.7"
async-channel = "1.9"
async-lock = "3.3"
async-watch = "0.3"
backoff = "0.4.0"
cached = { version = "0.46", features = ["ahash"], default-features = false }
cached = { version = "0.52", features = ["ahash"], default-features = false }
candid = { workspace = true }
ed25519-consensus = { version = "2" }
der = "0.7"
ecdsa = "0.16"
ed25519-consensus = { workspace = true }
elliptic-curve = "0.13"
futures-util = { workspace = true }
hex = { workspace = true }
http = "0.2.6"
http-body = "0.4.5"
http = "1.0.0"
http-body = "1.0.0"
ic-certification = { workspace = true }
ic-transport-types = { workspace = true }
ic-verify-bls-signature = "0.1"
k256 = { version = "0.13.1", features = ["pem"] }
p256 = { version = "0.13.2", features = ["pem"] }
ic-verify-bls-signature = "0.5"
k256 = { workspace = true, features = ["pem"] }
p256 = { workspace = true, features = ["pem"] }
leb128 = { workspace = true }
pkcs8 = { version = "0.10.2", features = ["std"] }
sec1 = { version = "0.7.2", features = ["pem"] }
rand = "0.8.5"
rand = { workspace = true }
rangemap = "1.4"
ring = { workspace = true, features = ["std"] }
ring = { version = "0.17", optional = true }
serde = { workspace = true, features = ["derive"] }
serde_bytes = { workspace = true }
serde_cbor = { workspace = true }
serde_repr = { workspace = true }
sha2 = { workspace = true }
simple_asn1 = "0.6.1"
stop-token = "0.7"
thiserror = { workspace = true }
time = { workspace = true }
tower-service = "0.3"
tracing = { version = "0.1", optional = true }
url = "2.1.0"

[dependencies.hyper]
version = "0.14"
features = ["client", "http2", "http1"]
optional = true

[dependencies.reqwest]
version = "0.11.7"
workspace = true
default-features = false
features = ["blocking", "json", "rustls-tls-webpki-roots", "stream"]
optional = true

[dependencies.pem]
version = "2.0.1"
version = "3"
optional = true

[target.'cfg(not(target_family = "wasm"))'.dependencies]
hyper-rustls = { version = "0.24.1", features = [
"webpki-roots",
"http2",
], optional = true }
tokio = { version = "1.24.2", features = ["time"] }
rustls-webpki = "0.101.4"

[target.'cfg(target_family = "wasm")'.dependencies]
getrandom = { version = "0.2", features = ["js"], optional = true }
Expand All @@ -75,11 +75,12 @@ wasm-bindgen-futures = { version = "0.4", optional = true }
web-sys = { version = "0.3", features = ["Window"], optional = true }

[dev-dependencies]
serde_json = "1.0.79"
candid = { workspace = true, features = ["value"]}
serde_json.workspace = true
tracing-subscriber = "0.3"
tracing = "0.1"

[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
tokio = { version = "1.24.2", features = ["full"] }
tokio = { workspace = true, features = ["full"] }
mockito = "1.0.2"

[target.'cfg(target_family = "wasm")'.dev-dependencies]
Expand All @@ -93,9 +94,9 @@ web-sys = { version = "0.3", features = [
] }

[features]
default = ["pem", "reqwest"]
reqwest = ["dep:reqwest"]
hyper = ["dep:hyper", "dep:hyper-rustls"]
default = ["pem"]
pem = ["dep:pem"]
ring = ["dep:ring"]
ic_ref_tests = [
"default",
] # Used to separate integration tests for ic-ref which need a server running.
Expand All @@ -109,8 +110,10 @@ wasm-bindgen = [
"backoff/wasm-bindgen",
"cached/wasm",
]
_internal_dynamic-routing = []
tracing = ["dep:tracing"] # Does very little right now.

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"]
rustdoc-args = ["--cfg=docsrs"]
features = ["hyper"]
features = []
42 changes: 36 additions & 6 deletions ic-agent/src/agent/agent_config.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,61 @@
use reqwest::Client;
use url::Url;

use crate::{
agent::{NonceFactory, NonceGenerator, Transport},
agent::{NonceFactory, NonceGenerator},
identity::{anonymous::AnonymousIdentity, Identity},
};
use std::{sync::Arc, time::Duration};

use super::{route_provider::RouteProvider, HttpService};

/// A configuration for an agent.
#[non_exhaustive]
pub struct AgentConfig {
/// See [`with_nonce_factory`](super::AgentBuilder::with_nonce_factory).
pub nonce_factory: Arc<dyn NonceGenerator>,
/// See [`with_identity`](super::AgentBuilder::with_identity).
pub identity: Arc<dyn Identity>,
/// See [`with_ingress_expiry`](super::AgentBuilder::with_ingress_expiry).
pub ingress_expiry: Option<Duration>,
/// See [`with_transport`](super::AgentBuilder::with_transport).
pub transport: Option<Arc<dyn Transport>>,
pub ingress_expiry: Duration,
/// See [`with_http_client`](super::AgentBuilder::with_http_client).
pub client: Option<Client>,
/// See [`with_route_provider`](super::AgentBuilder::with_route_provider).
pub route_provider: Option<Arc<dyn RouteProvider>>,
/// See [`verify_query_signatures`](super::AgentBuilder::with_verify_query_signatures).
pub verify_query_signatures: bool,
/// See [`with_max_concurrent_requests`](super::AgentBuilder::with_max_concurrent_requests).
pub max_concurrent_requests: usize,
/// See [`with_max_response_body_size`](super::AgentBuilder::with_max_response_body_size).
pub max_response_body_size: Option<usize>,
/// See [`with_max_tcp_error_retries`](super::AgentBuilder::with_max_tcp_error_retries).
pub max_tcp_error_retries: usize,
/// See [`with_arc_http_middleware`](super::AgentBuilder::with_arc_http_middleware).
pub http_service: Option<Arc<dyn HttpService>>,
/// See [`with_max_polling_time`](super::AgentBuilder::with_max_polling_time).
pub max_polling_time: Duration,
/// See [`with_background_dynamic_routing`](super::AgentBuilder::with_background_dynamic_routing).
pub background_dynamic_routing: bool,
/// See [`with_url`](super::AgentBuilder::with_url).
pub url: Option<Url>,
}

impl Default for AgentConfig {
fn default() -> Self {
Self {
nonce_factory: Arc::new(NonceFactory::random()),
identity: Arc::new(AnonymousIdentity {}),
ingress_expiry: None,
transport: None,
ingress_expiry: Duration::from_secs(3 * 60),
client: None,
http_service: None,
verify_query_signatures: true,
max_concurrent_requests: 50,
route_provider: None,
max_response_body_size: None,
max_tcp_error_retries: 0,
max_polling_time: Duration::from_secs(60 * 5),
background_dynamic_routing: false,
url: None,
}
}
}
28 changes: 16 additions & 12 deletions ic-agent/src/agent/agent_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ pub enum AgentError {
#[error("Cannot parse Principal: {0}")]
PrincipalError(#[from] crate::export::PrincipalError),

/// The replica rejected the message.
#[error("The replica returned a replica error: reject code {:?}, reject message {}, error code {:?}", .0.reject_code, .0.reject_message, .0.error_code)]
ReplicaError(RejectResponse),
/// The subnet rejected the message.
#[error("The replica returned a rejection error: reject code {:?}, reject message {}, error code {:?}", .0.reject_code, .0.reject_message, .0.error_code)]
CertifiedReject(RejectResponse),

/// The replica rejected the message. This rejection cannot be verified as authentic.
#[error("The replica returned a rejection error: reject code {:?}, reject message {}, error code {:?}", .0.reject_code, .0.reject_message, .0.error_code)]
UncertifiedReject(RejectResponse),

/// The replica returned an HTTP error.
#[error("The replica returned an HTTP Error: {0}")]
Expand Down Expand Up @@ -94,15 +98,15 @@ pub enum AgentError {
#[error("The request status ({1}) at path {0:?} is invalid.")]
InvalidRequestStatus(Vec<Label>, String),

/// The certificate verification for a read_state call failed.
/// The certificate verification for a `read_state` call failed.
#[error("Certificate verification failed.")]
CertificateVerificationFailed(),

/// The signature verification for a query call failed.
#[error("Query signature verification failed.")]
QuerySignatureVerificationFailed,

/// The certificate contained a delegation that does not include the effective_canister_id in the canister_ranges field.
/// The certificate contained a delegation that does not include the `effective_canister_id` in the `canister_ranges` field.
#[error("Certificate is not authorized to respond to queries for this canister. While developing: Did you forget to set effective_canister_id?")]
CertificateNotAuthorized(),

Expand Down Expand Up @@ -171,17 +175,13 @@ pub enum AgentError {
#[error("The wallet canister must be upgraded: {0}")]
WalletUpgradeRequired(String),

/// The transport was not specified in the [`AgentBuilder`](super::AgentBuilder).
#[error("Missing replica transport in the Agent Builder.")]
MissingReplicaTransport(),

/// The response size exceeded the provided limit.
#[error("Response size exceeded limit.")]
ResponseSizeExceededLimit(),

/// An unknown error occurred during communication with the replica.
#[error("An error happened during communication with the replica: {0}")]
TransportError(Box<dyn std::error::Error + Send + Sync>),
TransportError(#[from] reqwest::Error),

/// There was a mismatch between the expected and actual CBOR data during inspection.
#[error("There is a mismatch between the CBOR encoded call and the arguments: field {field}, value in argument is {value_arg}, value in CBOR is {value_cbor}")]
Expand All @@ -201,13 +201,17 @@ pub enum AgentError {
/// Route provider failed to generate a url for some reason.
#[error("Route provider failed to generate url: {0}")]
RouteProviderError(String),

/// Invalid HTTP response.
#[error("Invalid HTTP response: {0}")]
InvalidHttpResponse(String),
}

impl PartialEq for AgentError {
fn eq(&self, other: &Self) -> bool {
// Verify the debug string is the same. Some of the subtypes of this error
// don't implement Eq or PartialEq, so we cannot rely on derive.
format!("{:?}", self) == format!("{:?}", other)
format!("{self:?}") == format!("{other:?}")
}
}

Expand Down Expand Up @@ -235,7 +239,7 @@ impl HttpErrorPayload {
f.write_fmt(format_args!(
"Http Error: status {}, content type {:?}, content: {}",
http::StatusCode::from_u16(self.status)
.map_or_else(|_| format!("{}", self.status), |code| format!("{}", code)),
.map_or_else(|_| format!("{}", self.status), |code| format!("{code}")),
self.content_type.clone().unwrap_or_default(),
String::from_utf8(self.content.clone()).unwrap_or_else(|_| format!(
"(unable to decode content as UTF-8: {:?})",
Expand Down
Loading
Loading