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:
parent
cae8f61952
commit
e3e8179f2d
|
@ -111,7 +111,7 @@ impl ExecuteTimings {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BankStatusCache = StatusCache<Result<()>>;
|
type BankStatusCache = StatusCache<Result<()>>;
|
||||||
#[frozen_abi(digest = "3ZaEt781qwhfQSE4DZPBHhng2S6MuimchRjkR9ZWzDFs")]
|
#[frozen_abi(digest = "EcB9J7sm37t1R47vLcvGuNeiRciB4Efq1EDWDWL6Bp5h")]
|
||||||
pub type BankSlotDelta = SlotDelta<Result<()>>;
|
pub type BankSlotDelta = SlotDelta<Result<()>>;
|
||||||
type TransactionAccountRefCells = Vec<Rc<RefCell<Account>>>;
|
type TransactionAccountRefCells = Vec<Rc<RefCell<Account>>>;
|
||||||
type TransactionAccountDepRefCells = Vec<(Pubkey, RefCell<Account>)>;
|
type TransactionAccountDepRefCells = Vec<(Pubkey, RefCell<Account>)>;
|
||||||
|
|
|
@ -198,6 +198,9 @@ pub enum InstructionError {
|
||||||
|
|
||||||
#[error("Invalid account owner")]
|
#[error("Invalid account owner")]
|
||||||
InvalidAccountOwner,
|
InvalidAccountOwner,
|
||||||
|
|
||||||
|
#[error("Program arithmetic overflowed")]
|
||||||
|
ArithmeticOverflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
|
|
@ -218,7 +218,10 @@ impl GenesisConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ns_per_slot(&self) -> u128 {
|
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 {
|
pub fn slots_per_year(&self) -> f64 {
|
||||||
|
|
|
@ -18,7 +18,7 @@ impl HardForks {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|(slot, _)| *slot == new_slot)
|
.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 {
|
} else {
|
||||||
self.hard_forks.push((new_slot, 1));
|
self.hard_forks.push((new_slot, 1));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(specialization))]
|
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(specialization))]
|
||||||
#![cfg_attr(RUSTC_NEEDS_PROC_MACRO_HYGIENE, feature(proc_macro_hygiene))]
|
#![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
|
// Allows macro expansion of `use ::solana_sdk::*` to work within this crate
|
||||||
extern crate self as solana_sdk;
|
extern crate self as solana_sdk;
|
||||||
|
|
|
@ -153,8 +153,14 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
||||||
return Err(InstructionError::MissingRequiredSignature);
|
return Err(InstructionError::MissingRequiredSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.try_account_ref_mut()?.lamports -= lamports;
|
let nonce_balance = self.try_account_ref_mut()?.lamports;
|
||||||
to.try_account_ref_mut()?.lamports += 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::integer_arithmetic)]
|
||||||
use crate::clock::DEFAULT_TICKS_PER_SECOND;
|
use crate::clock::DEFAULT_TICKS_PER_SECOND;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
|
|
@ -292,11 +292,11 @@ impl Default for MockInvokeContext {
|
||||||
}
|
}
|
||||||
impl InvokeContext for MockInvokeContext {
|
impl InvokeContext for MockInvokeContext {
|
||||||
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
|
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
|
||||||
self.invoke_depth += 1;
|
self.invoke_depth = self.invoke_depth.saturating_add(1);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn pop(&mut self) {
|
fn pop(&mut self) {
|
||||||
self.invoke_depth -= 1;
|
self.invoke_depth = self.invoke_depth.saturating_sub(1);
|
||||||
}
|
}
|
||||||
fn invoke_depth(&self) -> usize {
|
fn invoke_depth(&self) -> usize {
|
||||||
self.invoke_depth
|
self.invoke_depth
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::integer_arithmetic)]
|
||||||
#![cfg(feature = "full")]
|
#![cfg(feature = "full")]
|
||||||
|
|
||||||
use crate::instruction::Instruction;
|
use crate::instruction::Instruction;
|
||||||
|
|
|
@ -15,6 +15,8 @@ pub fn version_from_hash(hash: &Hash) -> u16 {
|
||||||
.for_each(|(accum, seed)| *accum ^= *seed)
|
.for_each(|(accum, seed)| *accum ^= *seed)
|
||||||
});
|
});
|
||||||
// convert accum into a u16
|
// 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;
|
let version = ((accum[0] as u16) << 8) | accum[1] as u16;
|
||||||
|
|
||||||
// ensure version is never zero, to avoid looking like an uninitialized version
|
// ensure version is never zero, to avoid looking like an uninitialized version
|
||||||
|
|
|
@ -40,29 +40,29 @@ where
|
||||||
V: Borrow<(Slot, UnixTimestamp)>,
|
V: Borrow<(Slot, UnixTimestamp)>,
|
||||||
{
|
{
|
||||||
let mut stake_per_timestamp: BTreeMap<UnixTimestamp, u128> = BTreeMap::new();
|
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 {
|
for (vote_pubkey, slot_timestamp) in unique_timestamps {
|
||||||
let (timestamp_slot, timestamp) = slot_timestamp.borrow();
|
let (timestamp_slot, timestamp) = slot_timestamp.borrow();
|
||||||
let offset = slot.saturating_sub(*timestamp_slot) as u32 * slot_duration;
|
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
|
let stake = stakes
|
||||||
.get(vote_pubkey.borrow())
|
.get(vote_pubkey.borrow())
|
||||||
.map(|(stake, _account)| stake)
|
.map(|(stake, _account)| stake)
|
||||||
.unwrap_or(&0);
|
.unwrap_or(&0);
|
||||||
stake_per_timestamp
|
stake_per_timestamp
|
||||||
.entry(estimate)
|
.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);
|
.or_insert(*stake as u128);
|
||||||
total_stake += *stake as u128;
|
total_stake = total_stake.saturating_add(*stake as u128);
|
||||||
}
|
}
|
||||||
if total_stake == 0 {
|
if total_stake == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut stake_accumulator = 0;
|
let mut stake_accumulator: u128 = 0;
|
||||||
let mut estimate = 0;
|
let mut estimate = 0;
|
||||||
// Populate `estimate` with stake-weighted median timestamp
|
// Populate `estimate` with stake-weighted median timestamp
|
||||||
for (timestamp, stake) in stake_per_timestamp.into_iter() {
|
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 {
|
if stake_accumulator > total_stake / 2 {
|
||||||
estimate = timestamp;
|
estimate = timestamp;
|
||||||
break;
|
break;
|
||||||
|
@ -84,15 +84,16 @@ where
|
||||||
// estimate offset since the start of the epoch is higher than
|
// estimate offset since the start of the epoch is higher than
|
||||||
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW`
|
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW`
|
||||||
estimate = epoch_start_timestamp
|
estimate = epoch_start_timestamp
|
||||||
+ poh_estimate_offset.as_secs() as i64
|
.saturating_add(poh_estimate_offset.as_secs() as i64)
|
||||||
+ max_allowable_drift_slow.as_secs() as i64;
|
.saturating_add(max_allowable_drift_slow.as_secs() as i64);
|
||||||
} else if estimate_offset < poh_estimate_offset
|
} else if estimate_offset < poh_estimate_offset
|
||||||
&& poh_estimate_offset - estimate_offset > max_allowable_drift_fast
|
&& poh_estimate_offset - estimate_offset > max_allowable_drift_fast
|
||||||
{
|
{
|
||||||
// estimate offset since the start of the epoch is lower than
|
// estimate offset since the start of the epoch is lower than
|
||||||
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST`
|
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST`
|
||||||
estimate = epoch_start_timestamp + poh_estimate_offset.as_secs() as i64
|
estimate = epoch_start_timestamp
|
||||||
- max_allowable_drift_fast.as_secs() as i64;
|
.saturating_add(poh_estimate_offset.as_secs() as i64)
|
||||||
|
.saturating_sub(max_allowable_drift_fast.as_secs() as i64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(estimate)
|
Some(estimate)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::integer_arithmetic)]
|
||||||
//! The `timing` module provides std::time utility functions.
|
//! The `timing` module provides std::time utility functions.
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
|
|
@ -117,4 +117,5 @@ pub enum InstructionErrorType {
|
||||||
BorshIoError = 44,
|
BorshIoError = 44,
|
||||||
AccountNotRentExempt = 45,
|
AccountNotRentExempt = 45,
|
||||||
InvalidAccountOwner = 46,
|
InvalidAccountOwner = 46,
|
||||||
|
ArithmeticOverflow = 47,
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,6 +509,7 @@ impl TryFrom<tx_by_addr::TransactionError> for TransactionError {
|
||||||
44 => InstructionError::BorshIoError(String::new()),
|
44 => InstructionError::BorshIoError(String::new()),
|
||||||
45 => InstructionError::AccountNotRentExempt,
|
45 => InstructionError::AccountNotRentExempt,
|
||||||
46 => InstructionError::InvalidAccountOwner,
|
46 => InstructionError::InvalidAccountOwner,
|
||||||
|
47 => InstructionError::ArithmeticOverflow,
|
||||||
_ => return Err("Invalid InstructionError"),
|
_ => return Err("Invalid InstructionError"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -735,6 +736,9 @@ impl From<TransactionError> for tx_by_addr::TransactionError {
|
||||||
InstructionError::InvalidAccountOwner => {
|
InstructionError::InvalidAccountOwner => {
|
||||||
tx_by_addr::InstructionErrorType::InvalidAccountOwner
|
tx_by_addr::InstructionErrorType::InvalidAccountOwner
|
||||||
}
|
}
|
||||||
|
InstructionError::ArithmeticOverflow => {
|
||||||
|
tx_by_addr::InstructionErrorType::ArithmeticOverflow
|
||||||
|
}
|
||||||
} as i32,
|
} as i32,
|
||||||
custom: match instruction_error {
|
custom: match instruction_error {
|
||||||
InstructionError::Custom(custom) => {
|
InstructionError::Custom(custom) => {
|
||||||
|
|
|
@ -96,6 +96,7 @@ enum InstructionErrorType {
|
||||||
BORSH_IO_ERROR = 44;
|
BORSH_IO_ERROR = 44;
|
||||||
ACCOUNT_NOT_RENT_EXEMPT = 45;
|
ACCOUNT_NOT_RENT_EXEMPT = 45;
|
||||||
INVALID_ACCOUNT_OWNER = 46;
|
INVALID_ACCOUNT_OWNER = 46;
|
||||||
|
ARITHMETIC_OVERFLOW = 47;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UnixTimestamp {
|
message UnixTimestamp {
|
||||||
|
|
Loading…
Reference in New Issue