Sdk: start to appease clippy's integer arithmetic check (#15736)

* Move to module-level clippy allowance

* Fix stake_weighted_timestamp math

* Fix genesis_config

* Fix shred_version

* Fix hard_forks

* Fix process_instruction

* Add ArithmeticOverflow ix error

* Fix nonce_keyed_account

* Update BankSlotDelta frozen abi due to new ix error
This commit is contained in:
Tyera Eulberg 2021-03-08 18:37:57 -07:00 committed by GitHub
parent cae8f61952
commit e3e8179f2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 41 additions and 18 deletions

View File

@ -111,7 +111,7 @@ impl ExecuteTimings {
}
type BankStatusCache = StatusCache<Result<()>>;
#[frozen_abi(digest = "3ZaEt781qwhfQSE4DZPBHhng2S6MuimchRjkR9ZWzDFs")]
#[frozen_abi(digest = "EcB9J7sm37t1R47vLcvGuNeiRciB4Efq1EDWDWL6Bp5h")]
pub type BankSlotDelta = SlotDelta<Result<()>>;
type TransactionAccountRefCells = Vec<Rc<RefCell<Account>>>;
type TransactionAccountDepRefCells = Vec<(Pubkey, RefCell<Account>)>;

View File

@ -198,6 +198,9 @@ pub enum InstructionError {
#[error("Invalid account owner")]
InvalidAccountOwner,
#[error("Program arithmetic overflowed")]
ArithmeticOverflow,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]

View File

@ -218,7 +218,10 @@ impl GenesisConfig {
}
pub fn ns_per_slot(&self) -> u128 {
self.poh_config.target_tick_duration.as_nanos() * self.ticks_per_slot() as u128
self.poh_config
.target_tick_duration
.as_nanos()
.saturating_mul(self.ticks_per_slot() as u128)
}
pub fn slots_per_year(&self) -> f64 {

View File

@ -18,7 +18,7 @@ impl HardForks {
.iter()
.position(|(slot, _)| *slot == new_slot)
{
self.hard_forks[i] = (new_slot, self.hard_forks[i].1 + 1);
self.hard_forks[i] = (new_slot, self.hard_forks[i].1.saturating_add(1));
} else {
self.hard_forks.push((new_slot, 1));
}

View File

@ -1,6 +1,5 @@
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(specialization))]
#![cfg_attr(RUSTC_NEEDS_PROC_MACRO_HYGIENE, feature(proc_macro_hygiene))]
#![allow(clippy::integer_arithmetic)]
// Allows macro expansion of `use ::solana_sdk::*` to work within this crate
extern crate self as solana_sdk;

View File

@ -153,8 +153,14 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
return Err(InstructionError::MissingRequiredSignature);
}
self.try_account_ref_mut()?.lamports -= lamports;
to.try_account_ref_mut()?.lamports += lamports;
let nonce_balance = self.try_account_ref_mut()?.lamports;
self.try_account_ref_mut()?.lamports = nonce_balance
.checked_sub(lamports)
.ok_or(InstructionError::ArithmeticOverflow)?;
let to_balance = to.try_account_ref_mut()?.lamports;
to.try_account_ref_mut()?.lamports = to_balance
.checked_add(lamports)
.ok_or(InstructionError::ArithmeticOverflow)?;
Ok(())
}

View File

@ -1,3 +1,4 @@
#![allow(clippy::integer_arithmetic)]
use crate::clock::DEFAULT_TICKS_PER_SECOND;
use std::time::Duration;

View File

@ -292,11 +292,11 @@ impl Default for MockInvokeContext {
}
impl InvokeContext for MockInvokeContext {
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
self.invoke_depth += 1;
self.invoke_depth = self.invoke_depth.saturating_add(1);
Ok(())
}
fn pop(&mut self) {
self.invoke_depth -= 1;
self.invoke_depth = self.invoke_depth.saturating_sub(1);
}
fn invoke_depth(&self) -> usize {
self.invoke_depth

View File

@ -1,3 +1,4 @@
#![allow(clippy::integer_arithmetic)]
#![cfg(feature = "full")]
use crate::instruction::Instruction;

View File

@ -15,6 +15,8 @@ pub fn version_from_hash(hash: &Hash) -> u16 {
.for_each(|(accum, seed)| *accum ^= *seed)
});
// convert accum into a u16
// Because accum[0] is a u8, 8bit left shift of the u16 can never overflow
#[allow(clippy::integer_arithmetic)]
let version = ((accum[0] as u16) << 8) | accum[1] as u16;
// ensure version is never zero, to avoid looking like an uninitialized version

View File

@ -40,29 +40,29 @@ where
V: Borrow<(Slot, UnixTimestamp)>,
{
let mut stake_per_timestamp: BTreeMap<UnixTimestamp, u128> = BTreeMap::new();
let mut total_stake = 0;
let mut total_stake: u128 = 0;
for (vote_pubkey, slot_timestamp) in unique_timestamps {
let (timestamp_slot, timestamp) = slot_timestamp.borrow();
let offset = slot.saturating_sub(*timestamp_slot) as u32 * slot_duration;
let estimate = timestamp + offset.as_secs() as i64;
let estimate = timestamp.saturating_add(offset.as_secs() as i64);
let stake = stakes
.get(vote_pubkey.borrow())
.map(|(stake, _account)| stake)
.unwrap_or(&0);
stake_per_timestamp
.entry(estimate)
.and_modify(|stake_sum| *stake_sum += *stake as u128)
.and_modify(|stake_sum| *stake_sum = stake_sum.saturating_add(*stake as u128))
.or_insert(*stake as u128);
total_stake += *stake as u128;
total_stake = total_stake.saturating_add(*stake as u128);
}
if total_stake == 0 {
return None;
}
let mut stake_accumulator = 0;
let mut stake_accumulator: u128 = 0;
let mut estimate = 0;
// Populate `estimate` with stake-weighted median timestamp
for (timestamp, stake) in stake_per_timestamp.into_iter() {
stake_accumulator += stake;
stake_accumulator = stake_accumulator.saturating_add(stake);
if stake_accumulator > total_stake / 2 {
estimate = timestamp;
break;
@ -84,15 +84,16 @@ where
// estimate offset since the start of the epoch is higher than
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW`
estimate = epoch_start_timestamp
+ poh_estimate_offset.as_secs() as i64
+ max_allowable_drift_slow.as_secs() as i64;
.saturating_add(poh_estimate_offset.as_secs() as i64)
.saturating_add(max_allowable_drift_slow.as_secs() as i64);
} else if estimate_offset < poh_estimate_offset
&& poh_estimate_offset - estimate_offset > max_allowable_drift_fast
{
// estimate offset since the start of the epoch is lower than
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST`
estimate = epoch_start_timestamp + poh_estimate_offset.as_secs() as i64
- max_allowable_drift_fast.as_secs() as i64;
estimate = epoch_start_timestamp
.saturating_add(poh_estimate_offset.as_secs() as i64)
.saturating_sub(max_allowable_drift_fast.as_secs() as i64);
}
}
Some(estimate)

View File

@ -1,3 +1,4 @@
#![allow(clippy::integer_arithmetic)]
//! The `timing` module provides std::time utility functions.
use std::time::{Duration, SystemTime, UNIX_EPOCH};

View File

@ -117,4 +117,5 @@ pub enum InstructionErrorType {
BorshIoError = 44,
AccountNotRentExempt = 45,
InvalidAccountOwner = 46,
ArithmeticOverflow = 47,
}

View File

@ -509,6 +509,7 @@ impl TryFrom<tx_by_addr::TransactionError> for TransactionError {
44 => InstructionError::BorshIoError(String::new()),
45 => InstructionError::AccountNotRentExempt,
46 => InstructionError::InvalidAccountOwner,
47 => InstructionError::ArithmeticOverflow,
_ => return Err("Invalid InstructionError"),
};
@ -735,6 +736,9 @@ impl From<TransactionError> for tx_by_addr::TransactionError {
InstructionError::InvalidAccountOwner => {
tx_by_addr::InstructionErrorType::InvalidAccountOwner
}
InstructionError::ArithmeticOverflow => {
tx_by_addr::InstructionErrorType::ArithmeticOverflow
}
} as i32,
custom: match instruction_error {
InstructionError::Custom(custom) => {

View File

@ -96,6 +96,7 @@ enum InstructionErrorType {
BORSH_IO_ERROR = 44;
ACCOUNT_NOT_RENT_EXEMPT = 45;
INVALID_ACCOUNT_OWNER = 46;
ARITHMETIC_OVERFLOW = 47;
}
message UnixTimestamp {