Skip to content

Commit 1a0d09f

Browse files
authored
Merge pull request #529 from opentensor/ban-unsafe-arithmetic-devnet
(Devnet Ready) Ban unsafe arithmetic operations
2 parents 703bdbd + 3c17efb commit 1a0d09f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+398
-228
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ members = [
88
resolver = "2"
99

1010
[workspace.lints.clippy]
11+
indexing-slicing = "deny"
12+
arithmetic-side-effects = "deny"
1113
type_complexity = "allow"
14+
unwrap-used = "deny"
1215

1316
[workspace.dependencies]
1417
cargo-husky = { version = "1", default-features = false }

node/src/chain_spec/finney.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::*;
55

66
pub fn finney_mainnet_config() -> Result<ChainSpec, String> {
77
let path: PathBuf = std::path::PathBuf::from("./snapshot.json");
8-
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;
8+
let wasm_binary = WASM_BINARY.ok_or("Development wasm not available".to_string())?;
99

1010
// We mmap the file into memory first, as this is *a lot* faster than using
1111
// `serde_json::from_reader`. See https://github.com/serde-rs/json/issues/160
@@ -53,7 +53,9 @@ pub fn finney_mainnet_config() -> Result<ChainSpec, String> {
5353
let key_account = sp_runtime::AccountId32::from(key);
5454

5555
processed_balances.push((key_account, *amount));
56-
balances_issuance += *amount;
56+
balances_issuance = balances_issuance
57+
.checked_add(*amount)
58+
.ok_or("Balances issuance overflowed".to_string())?;
5759
}
5860

5961
// Give front-ends necessary data to present to users

node/src/chain_spec/testnet.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub fn finney_testnet_config() -> Result<ChainSpec, String> {
2020
};
2121

2222
let old_state: ColdkeyHotkeys =
23-
json::from_slice(&bytes).map_err(|e| format!("Error parsing genesis file: {}", e))?;
23+
json::from_slice(&bytes).map_err(|e| format!("Error parsing genesis file: {e}"))?;
2424

2525
let mut processed_stakes: Vec<(
2626
sp_runtime::AccountId32,
@@ -53,7 +53,9 @@ pub fn finney_testnet_config() -> Result<ChainSpec, String> {
5353
let key_account = sp_runtime::AccountId32::from(key);
5454

5555
processed_balances.push((key_account, *amount));
56-
balances_issuance += *amount;
56+
balances_issuance = balances_issuance
57+
.checked_add(*amount)
58+
.ok_or("Balances issuance overflowed".to_string())?;
5759
}
5860

5961
// Give front-ends necessary data to present to users

pallets/admin-utils/src/benchmarking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Benchmarking setup
22
#![cfg(feature = "runtime-benchmarks")]
3+
#![allow(clippy::arithmetic_side_effects)]
34
use super::*;
45

56
#[allow(unused)]

pallets/admin-utils/tests/mock.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::arithmetic_side_effects, clippy::unwrap_used)]
2+
13
use frame_support::{
24
assert_ok, derive_impl, parameter_types,
35
traits::{Everything, Hooks},

pallets/collective/src/benchmarking.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// limitations under the License.
1717

1818
//! Staking pallet benchmarking.
19+
#![allow(clippy::arithmetic_side_effects, clippy::indexing_slicing)]
1920

2021
use super::*;
2122
use crate::Pallet as Collective;
@@ -70,7 +71,7 @@ benchmarks_instance_pallet! {
7071
// Proposals should be different so that different proposal hashes are generated
7172
let proposal: T::Proposal = SystemCall::<T>::remark { remark: id_to_remark_data(i, length) }.into();
7273
Collective::<T, I>::propose(
73-
SystemOrigin::Signed(old_members.last().unwrap().clone()).into(),
74+
SystemOrigin::Signed(old_members.last().expect("m is greater than 0; old_members must have at least 1 element; qed").clone()).into(),
7475
Box::new(proposal.clone()),
7576
MAX_BYTES,
7677
TryInto::<BlockNumberFor<T>>::try_into(3u64).ok().expect("convert u64 to block number.")

pallets/collective/src/lib.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use frame_support::{
5454
use scale_info::TypeInfo;
5555
use sp_io::storage;
5656
use sp_runtime::traits::Dispatchable;
57-
use sp_runtime::{traits::Hash, RuntimeDebug};
57+
use sp_runtime::{traits::Hash, RuntimeDebug, Saturating};
5858
use sp_std::{marker::PhantomData, prelude::*, result};
5959

6060
#[cfg(test)]
@@ -119,7 +119,7 @@ impl DefaultVote for MoreThanMajorityThenPrimeDefaultVote {
119119
_no_votes: MemberCount,
120120
len: MemberCount,
121121
) -> bool {
122-
let more_than_majority = yes_votes * 2 > len;
122+
let more_than_majority = yes_votes.saturating_mul(2) > len;
123123
more_than_majority || prime_vote.unwrap_or(false)
124124
}
125125
}
@@ -545,7 +545,9 @@ pub mod pallet {
545545
Error::<T, I>::DurationLowerThanConfiguredMotionDuration
546546
);
547547

548-
let threshold = (T::GetVotingMembers::get_count() / 2) + 1;
548+
let threshold = T::GetVotingMembers::get_count()
549+
.saturating_div(2)
550+
.saturating_add(1);
549551

550552
let members = Self::members();
551553
let (proposal_len, active_proposals) =
@@ -716,10 +718,15 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
716718
})?;
717719

718720
let index = Self::proposal_count();
719-
<ProposalCount<T, I>>::mutate(|i| *i += 1);
721+
<ProposalCount<T, I>>::try_mutate(|i| {
722+
*i = i
723+
.checked_add(1)
724+
.ok_or(Error::<T, I>::TooManyActiveProposals)?;
725+
Ok::<(), Error<T, I>>(())
726+
})?;
720727
<ProposalOf<T, I>>::insert(proposal_hash, proposal);
721728
let votes = {
722-
let end = frame_system::Pallet::<T>::block_number() + duration;
729+
let end = frame_system::Pallet::<T>::block_number().saturating_add(duration);
723730
Votes {
724731
index,
725732
threshold,
@@ -862,10 +869,10 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
862869
// default voting strategy.
863870
let default = T::DefaultVote::default_vote(prime_vote, yes_votes, no_votes, seats);
864871

865-
let abstentions = seats - (yes_votes + no_votes);
872+
let abstentions = seats.saturating_sub(yes_votes.saturating_add(no_votes));
866873
match default {
867-
true => yes_votes += abstentions,
868-
false => no_votes += abstentions,
874+
true => yes_votes = yes_votes.saturating_add(abstentions),
875+
false => no_votes = no_votes.saturating_add(abstentions),
869876
}
870877
let approved = yes_votes >= voting.threshold;
871878

@@ -981,7 +988,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
981988
Voting::<T, I>::remove(proposal_hash);
982989
let num_proposals = Proposals::<T, I>::mutate(|proposals| {
983990
proposals.retain(|h| h != &proposal_hash);
984-
proposals.len() + 1 // calculate weight based on original length
991+
proposals.len().saturating_add(1) // calculate weight based on original length
985992
});
986993
num_proposals as u32
987994
}
@@ -1154,7 +1161,7 @@ impl<
11541161
type Success = ();
11551162
fn try_origin(o: O) -> Result<Self::Success, O> {
11561163
o.into().and_then(|o| match o {
1157-
RawOrigin::Members(n, m) if n * D > N * m => Ok(()),
1164+
RawOrigin::Members(n, m) if n.saturating_mul(D) > N.saturating_mul(m) => Ok(()),
11581165
r => Err(O::from(r)),
11591166
})
11601167
}
@@ -1179,7 +1186,7 @@ impl<
11791186
type Success = ();
11801187
fn try_origin(o: O) -> Result<Self::Success, O> {
11811188
o.into().and_then(|o| match o {
1182-
RawOrigin::Members(n, m) if n * D >= N * m => Ok(()),
1189+
RawOrigin::Members(n, m) if n.saturating_mul(D) >= N.saturating_mul(m) => Ok(()),
11831190
r => Err(O::from(r)),
11841191
})
11851192
}

pallets/collective/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
1717

18-
#![allow(non_camel_case_types)]
18+
#![allow(non_camel_case_types, clippy::indexing_slicing, clippy::unwrap_used)]
1919

2020
use super::{Event as CollectiveEvent, *};
2121
use crate as pallet_collective;

pallets/commitments/src/benchmarking.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Benchmarking setup
22
#![cfg(feature = "runtime-benchmarks")]
3+
#![allow(clippy::arithmetic_side_effects)]
34
use super::*;
45

56
#[allow(unused)]
@@ -17,7 +18,11 @@ fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
1718
// This creates an `IdentityInfo` object with `num_fields` extra fields.
1819
// All data is pre-populated with some arbitrary bytes.
1920
fn create_identity_info<T: Config>(_num_fields: u32) -> CommitmentInfo<T::MaxFields> {
20-
let _data = Data::Raw(vec![0; 32].try_into().unwrap());
21+
let _data = Data::Raw(
22+
vec![0; 32]
23+
.try_into()
24+
.expect("vec length is less than 64; qed"),
25+
);
2126

2227
CommitmentInfo {
2328
fields: Default::default(),

pallets/commitments/src/lib.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use types::*;
1414
pub use weights::WeightInfo;
1515

1616
use frame_support::traits::Currency;
17-
use sp_runtime::traits::Zero;
17+
use sp_runtime::{traits::Zero, Saturating};
1818
use sp_std::boxed::Box;
1919

2020
type BalanceOf<T> =
@@ -138,12 +138,12 @@ pub mod pallet {
138138
let cur_block = <frame_system::Pallet<T>>::block_number();
139139
if let Some(last_commit) = <LastCommitment<T>>::get(netuid, &who) {
140140
ensure!(
141-
cur_block >= last_commit + T::RateLimit::get(),
141+
cur_block >= last_commit.saturating_add(T::RateLimit::get()),
142142
Error::<T>::CommitmentSetRateLimitExceeded
143143
);
144144
}
145145

146-
let fd = <BalanceOf<T>>::from(extra_fields) * T::FieldDeposit::get();
146+
let fd = <BalanceOf<T>>::from(extra_fields).saturating_mul(T::FieldDeposit::get());
147147
let mut id = match <CommitmentOf<T>>::get(netuid, &who) {
148148
Some(mut id) => {
149149
id.info = *info;
@@ -158,12 +158,13 @@ pub mod pallet {
158158
};
159159

160160
let old_deposit = id.deposit;
161-
id.deposit = T::InitialDeposit::get() + fd;
161+
id.deposit = T::InitialDeposit::get().saturating_add(fd);
162162
if id.deposit > old_deposit {
163-
T::Currency::reserve(&who, id.deposit - old_deposit)?;
163+
T::Currency::reserve(&who, id.deposit.saturating_sub(old_deposit))?;
164164
}
165165
if old_deposit > id.deposit {
166-
let err_amount = T::Currency::unreserve(&who, old_deposit - id.deposit);
166+
let err_amount =
167+
T::Currency::unreserve(&who, old_deposit.saturating_sub(id.deposit));
167168
debug_assert!(err_amount.is_zero());
168169
}
169170

0 commit comments

Comments
 (0)