Skip to content

Commit 694fe30

Browse files
committed
chore: add DecoderConfig when decoding candid in canister code
1 parent f9372c7 commit 694fe30

File tree

4 files changed

+34
-9
lines changed

4 files changed

+34
-9
lines changed

rs/nns/governance/canister/canister.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ic_nns_common::{
3131
};
3232
use ic_nns_constants::LEDGER_CANISTER_ID;
3333
use ic_nns_governance::{
34-
encode_metrics,
34+
decoder_config, encode_metrics,
3535
governance::{
3636
BitcoinNetwork, BitcoinSetConfigProposal, Environment, Governance, HeapGrowthPotential,
3737
TimeWarp,
@@ -964,7 +964,7 @@ fn get_effective_payload(mt: NnsFunction, payload: &[u8]) -> Cow<[u8]> {
964964
match mt {
965965
NnsFunction::BitcoinSetConfig => {
966966
// Decode the payload to get the network.
967-
let payload = Decode!(payload, BitcoinSetConfigProposal)
967+
let payload = Decode!([decoder_config()]; payload, BitcoinSetConfigProposal)
968968
.expect("payload must be a valid BitcoinSetConfigProposal.");
969969

970970
// Convert it to a call canister payload.

rs/nns/governance/src/governance.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
decoder_config,
23
governance::manage_neuron_request::{
34
execute_manage_neuron, simulate_manage_neuron, ManageNeuronRequest,
45
},
@@ -4688,7 +4689,7 @@ impl Governance {
46884689
update.payload.len(),
46894690
)
46904691
} else if update.nns_function == NnsFunction::IcpXdrConversionRate as i32 {
4691-
match Decode!(&update.payload, UpdateIcpXdrConversionRatePayload) {
4692+
match Decode!([decoder_config()]; &update.payload, UpdateIcpXdrConversionRatePayload) {
46924693
Ok(payload) => {
46934694
if payload.xdr_permyriad_per_icp
46944695
< self.heap_data
@@ -4711,7 +4712,7 @@ impl Governance {
47114712
),
47124713
}
47134714
} else if update.nns_function == NnsFunction::AssignNoid as i32 {
4714-
match Decode!(&update.payload, AddNodeOperatorPayload) {
4715+
match Decode!([decoder_config()]; &update.payload, AddNodeOperatorPayload) {
47154716
Ok(payload) => match payload.node_provider_principal_id {
47164717
Some(id) => {
47174718
let is_registered = self
@@ -4735,7 +4736,7 @@ impl Governance {
47354736
),
47364737
}
47374738
} else if update.nns_function == NnsFunction::AddOrRemoveDataCenters as i32 {
4738-
match Decode!(&update.payload, AddOrRemoveDataCentersProposalPayload) {
4739+
match Decode!([decoder_config()]; &update.payload, AddOrRemoveDataCentersProposalPayload) {
47394740
Ok(payload) => match payload.validate() {
47404741
Ok(_) => {
47414742
return Ok(());

rs/nns/governance/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ use crate::{
124124
governance::{Governance, TimeWarp},
125125
pb::v1::{governance::GovernanceCachedMetrics, ProposalStatus},
126126
};
127+
use candid::DecoderConfig;
127128
use mockall::automock;
128129
use std::{
129130
collections::{BTreeMap, HashMap},
@@ -160,6 +161,17 @@ mod reward;
160161
pub mod storage;
161162
mod subaccount_index;
162163

164+
/// Limit the amount of work for skipping unneeded data on the wire when parsing Candid.
165+
/// The value of 10_000 follows the Candid recommendation.
166+
const DEFAULT_SKIPPING_QUOTA: usize = 10_000;
167+
168+
pub fn decoder_config() -> DecoderConfig {
169+
let mut config = DecoderConfig::new();
170+
config.set_skipping_quota(DEFAULT_SKIPPING_QUOTA);
171+
config.set_full_error_message(false);
172+
config
173+
}
174+
163175
#[automock]
164176
trait Clock {
165177
fn now(&self) -> u64;

rs/rust_canisters/dfn_candid/src/lib.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
use candid::de::IDLDeserialize;
2-
use candid::CandidType;
32
pub use candid::{
4-
decode_args, encode_args, encode_one,
3+
decode_args_with_config, encode_args, encode_one,
54
utils::{ArgumentDecoder, ArgumentEncoder},
65
};
6+
use candid::{CandidType, DecoderConfig};
77
use on_wire::witness;
88
use on_wire::{FromWire, IntoWire, NewType};
99
use serde::de::DeserializeOwned;
1010

1111
pub struct Candid<T>(pub T);
1212

13+
/// Limit the amount of work for skipping unneeded data on the wire when parsing Candid.
14+
/// The value of 10_000 follows the Candid recommendation.
15+
const DEFAULT_SKIPPING_QUOTA: usize = 10_000;
16+
17+
fn decoder_config() -> DecoderConfig {
18+
let mut config = DecoderConfig::new();
19+
config.set_skipping_quota(DEFAULT_SKIPPING_QUOTA);
20+
config.set_full_error_message(false);
21+
config
22+
}
23+
1324
impl<T> NewType for Candid<T> {
1425
type Inner = T;
1526
fn from_inner(t: Self::Inner) -> Self {
@@ -28,7 +39,7 @@ impl<Tuple: ArgumentEncoder> IntoWire for Candid<Tuple> {
2839

2940
impl<Tuple: for<'a> ArgumentDecoder<'a>> FromWire for Candid<Tuple> {
3041
fn from_bytes(bytes: Vec<u8>) -> Result<Self, String> {
31-
let res = decode_args(&bytes).map_err(|e| e.to_string())?;
42+
let res = decode_args_with_config(&bytes, &decoder_config()).map_err(|e| e.to_string())?;
3243
Ok(Candid(res))
3344
}
3445
}
@@ -53,7 +64,8 @@ impl<T: CandidType> IntoWire for CandidOne<T> {
5364

5465
impl<A1: DeserializeOwned + CandidType> FromWire for CandidOne<A1> {
5566
fn from_bytes(bytes: Vec<u8>) -> Result<Self, String> {
56-
let mut de = IDLDeserialize::new(&bytes[..]).map_err(|e| e.to_string())?;
67+
let mut de = IDLDeserialize::new_with_config(&bytes[..], &decoder_config())
68+
.map_err(|e| e.to_string())?;
5769
let res = de.get_value().map_err(|e| e.to_string())?;
5870
Ok(CandidOne(res))
5971
}

0 commit comments

Comments
 (0)