Skip to content

Commit

Permalink
chore: add DecoderConfig when decoding candid in BN code
Browse files Browse the repository at this point in the history
  • Loading branch information
mraszyk committed Mar 13, 2024
1 parent bb0ac2e commit 7625fb2
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 22 deletions.
Expand Up @@ -10,6 +10,7 @@ use mockall::automock;
use serde::Serialize;

use crate::{
decoder_config,
encode::{Decode, Encode},
verification::Verify,
};
Expand Down Expand Up @@ -102,7 +103,8 @@ impl GetCert for CanisterCertGetter {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(enc_pair) => Ok(Pair(
Expand Down Expand Up @@ -154,7 +156,8 @@ impl Upload for CanisterUploader {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(()) => Ok(()),
Expand Down Expand Up @@ -199,7 +202,8 @@ impl Export for CanisterExporter {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok((pkgs, iccert)) => Ok((
Expand Down
Expand Up @@ -20,7 +20,7 @@ use axum::{
routing::{delete, get, post, put},
Extension, Router, Server,
};
use candid::Principal;
use candid::{DecoderConfig, Principal};
use chacha20poly1305::{KeyInit, XChaCha20Poly1305};
use clap::Parser;
use futures::future::TryFutureExt;
Expand Down Expand Up @@ -82,6 +82,17 @@ const SERVICE_NAME: &str = "certificate-issuer";
pub(crate) static TASK_DELAY_SEC: AtomicU64 = AtomicU64::new(60);
pub(crate) static TASK_ERROR_DELAY_SEC: AtomicU64 = AtomicU64::new(10 * 60);

/// Limit the amount of work for skipping unneeded data on the wire when parsing Candid.
/// The value of 10_000 follows the Candid recommendation.
const DEFAULT_SKIPPING_QUOTA: usize = 10_000;

pub(crate) fn decoder_config() -> DecoderConfig {
let mut config = DecoderConfig::new();
config.set_skipping_quota(DEFAULT_SKIPPING_QUOTA);
config.set_full_error_message(false);
config
}

#[derive(Parser)]
#[command(name = SERVICE_NAME)]
struct Cli {
Expand Down
Expand Up @@ -8,6 +8,7 @@ use ic_agent::Agent;
use mockall::automock;
use serde::{Deserialize, Serialize};

use crate::decoder_config;
use crate::work::ProcessError;

pub type Id = String;
Expand Down Expand Up @@ -169,7 +170,8 @@ impl Get for CanisterGetter {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(reg) => Ok(reg.into()),
Expand Down Expand Up @@ -199,7 +201,8 @@ impl Create for CanisterCreator {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(id) => Ok(id),
Expand Down Expand Up @@ -232,7 +235,8 @@ impl Update for CanisterUpdater {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(()) => Ok(()),
Expand Down Expand Up @@ -262,7 +266,8 @@ impl Remove for CanisterRemover {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(()) => Ok(()),
Expand Down
Expand Up @@ -15,6 +15,7 @@ use crate::{
acme::{self, FinalizeError},
certificate::{self, GetCert, GetCertError, Pair},
check::Check,
decoder_config,
dns::{self, Resolve},
registration::{Id, Registration, State},
TASK_DELAY_SEC, TASK_ERROR_DELAY_SEC,
Expand Down Expand Up @@ -152,7 +153,8 @@ impl Queue for CanisterQueuer {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(()) => Ok(()),
Expand Down Expand Up @@ -182,7 +184,8 @@ impl Peek for CanisterPeeker {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(id) => Ok(id),
Expand Down Expand Up @@ -213,7 +216,8 @@ impl Dispense for CanisterDispenser {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(id) => Ok(id),
Expand All @@ -238,7 +242,8 @@ impl Dispense for CanisterDispenser {
.await
.context("failed to query canister")?;

let resp = Decode!(&resp, Response).context("failed to decode canister response")?;
let resp = Decode!([decoder_config()]; &resp, Response)
.context("failed to decode canister response")?;

match resp {
Response::Ok(reg) => Ok(reg.into()),
Expand Down
11 changes: 9 additions & 2 deletions rs/boundary_node/ic_balance_exporter/src/main.rs
Expand Up @@ -9,7 +9,7 @@ use std::{
use anyhow::{anyhow, Context, Error};
use async_trait::async_trait;
use axum::{handler::Handler, routing::get, Extension, Router};
use candid::{CandidType, Decode, Encode, Principal};
use candid::{CandidType, Decode, DecoderConfig, Encode, Principal};
use clap::Parser;
use dashmap::DashMap;
use futures::{future::TryFutureExt, stream::FuturesUnordered};
Expand Down Expand Up @@ -232,8 +232,15 @@ impl Scrape for Scraper {
.await
.context("failed to query canister")?;

// Limit the amount of work for skipping unneeded data on the wire when parsing Candid.
// The value of 10_000 follows the Candid recommendation.
const DEFAULT_SKIPPING_QUOTA: usize = 10_000;
let mut config = DecoderConfig::new();
config.set_skipping_quota(DEFAULT_SKIPPING_QUOTA);
config.set_full_error_message(false);

let Amount { amount } =
candid::Decode!(&result, Amount).context("failed to decode result")?;
candid::Decode!([config]; &result, Amount).context("failed to decode result")?;

Ok(amount)
}
Expand Down
12 changes: 12 additions & 0 deletions rs/boundary_node/ic_boundary/src/core.rs
Expand Up @@ -19,6 +19,7 @@ use axum::{
};
use axum_extra::middleware::option_layer;
use axum_server::{accept::DefaultAcceptor, Server};
use candid::DecoderConfig;
use futures::TryFutureExt;
use ic_interfaces_registry::ZERO_REGISTRY_VERSION;
use ic_registry_client::client::RegistryClientImpl;
Expand Down Expand Up @@ -75,6 +76,17 @@ const METRICS_CACHE_CAPACITY: usize = 15 * MB;

pub const MANAGEMENT_CANISTER_ID_PRINCIPAL: CanisterId = CanisterId::ic_00();

/// Limit the amount of work for skipping unneeded data on the wire when parsing Candid.
/// The value of 10_000 follows the Candid recommendation.
const DEFAULT_SKIPPING_QUOTA: usize = 10_000;

pub fn decoder_config() -> DecoderConfig {
let mut config = DecoderConfig::new();
config.set_skipping_quota(DEFAULT_SKIPPING_QUOTA);
config.set_full_error_message(false);
config
}

pub async fn main(cli: Cli) -> Result<(), Error> {
if cli.listen.http_timeout_connect > cli.health.check_timeout {
panic!("--check-timeout should be longer than --http-timeout-connect");
Expand Down
5 changes: 3 additions & 2 deletions rs/boundary_node/ic_boundary/src/management.rs
Expand Up @@ -13,7 +13,7 @@ use ratelimit::Ratelimiter;
use serde::Deserialize;

use crate::{
core::MANAGEMENT_CANISTER_ID_PRINCIPAL,
core::{decoder_config, MANAGEMENT_CANISTER_ID_PRINCIPAL},
routes::{ApiError, ErrorCause, RateLimitCause, RequestContext, RequestType},
};

Expand Down Expand Up @@ -88,7 +88,8 @@ struct BitcoinNetworkRecord {

fn extract_btc_network(ctx: &RequestContext) -> Result<BitcoinNetwork, Error> {
let arg = ctx.arg.as_ref().ok_or_else(|| anyhow!("missing arg"))?;
let r = Decode!(arg, BitcoinNetworkRecord).context("failed to decode arg")?;
let r =
Decode!([decoder_config()]; arg, BitcoinNetworkRecord).context("failed to decode arg")?;

Ok(r.network.into())
}
Expand Down
13 changes: 7 additions & 6 deletions rs/boundary_node/ic_boundary/src/routes.rs
Expand Up @@ -36,7 +36,7 @@ use url::Url;

use crate::{
cache::CacheStatus,
core::MAX_REQUEST_BODY_SIZE,
core::{decoder_config, MAX_REQUEST_BODY_SIZE},
http::{read_streaming_body, reqwest_error_infer, HttpClient},
persist::{RouteSubnet, Routes},
retry::RetryResult,
Expand Down Expand Up @@ -579,11 +579,12 @@ pub async fn preprocess_request(
let (arg, http_request) = match (&content.method_name, content.arg) {
(Some(method), Some(arg)) => {
if request_type == RequestType::Query && method == METHOD_HTTP {
let mut req: HttpRequest = Decode!(&arg.0, HttpRequest).map_err(|err| {
ErrorCause::UnableToParseHTTPArg(format!(
"unable to decode arg as HttpRequest: {err}"
))
})?;
let mut req: HttpRequest = Decode!([decoder_config()]; &arg.0, HttpRequest)
.map_err(|err| {
ErrorCause::UnableToParseHTTPArg(format!(
"unable to decode arg as HttpRequest: {err}"
))
})?;

// Remove specific headers
req.headers
Expand Down

0 comments on commit 7625fb2

Please sign in to comment.