explicitly ignores struct fields which do not impact PartialEq impl (#24624)

Unless struct fields are explicitly ignored in PartialEq implementation,
there are no compile-time checks that if more fields are added to the
struct, PartialEq implementation is accordingly updated.
This commit is contained in:
behzad nouri 2022-04-24 14:33:42 +00:00 committed by GitHub
parent 8a062273de
commit be0bdd2261
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 34 deletions

View File

@ -155,7 +155,6 @@ use {
fmt, mem,
ops::{Deref, Div, RangeInclusive},
path::PathBuf,
ptr,
rc::Rc,
sync::{
atomic::{
@ -993,39 +992,101 @@ pub(crate) struct BankFieldsToSerialize<'a> {
// Can't derive PartialEq because RwLock doesn't implement PartialEq
impl PartialEq for Bank {
fn eq(&self, other: &Self) -> bool {
if ptr::eq(self, other) {
if std::ptr::eq(self, other) {
return true;
}
*self.blockhash_queue.read().unwrap() == *other.blockhash_queue.read().unwrap()
&& self.ancestors == other.ancestors
&& *self.hash.read().unwrap() == *other.hash.read().unwrap()
&& self.parent_hash == other.parent_hash
&& self.parent_slot == other.parent_slot
&& *self.hard_forks.read().unwrap() == *other.hard_forks.read().unwrap()
&& self.transaction_count.load(Relaxed) == other.transaction_count.load(Relaxed)
&& self.tick_height.load(Relaxed) == other.tick_height.load(Relaxed)
&& self.signature_count.load(Relaxed) == other.signature_count.load(Relaxed)
&& self.capitalization.load(Relaxed) == other.capitalization.load(Relaxed)
&& self.max_tick_height == other.max_tick_height
&& self.hashes_per_tick == other.hashes_per_tick
&& self.ticks_per_slot == other.ticks_per_slot
&& self.ns_per_slot == other.ns_per_slot
&& self.genesis_creation_time == other.genesis_creation_time
&& self.slots_per_year == other.slots_per_year
&& self.slot == other.slot
&& self.epoch == other.epoch
&& self.block_height == other.block_height
&& self.collector_id == other.collector_id
&& self.collector_fees.load(Relaxed) == other.collector_fees.load(Relaxed)
&& self.fee_calculator == other.fee_calculator
&& self.fee_rate_governor == other.fee_rate_governor
&& self.collected_rent.load(Relaxed) == other.collected_rent.load(Relaxed)
&& self.rent_collector == other.rent_collector
&& self.epoch_schedule == other.epoch_schedule
&& *self.inflation.read().unwrap() == *other.inflation.read().unwrap()
&& *self.stakes_cache.stakes() == *other.stakes_cache.stakes()
&& self.epoch_stakes == other.epoch_stakes
&& self.is_delta.load(Relaxed) == other.is_delta.load(Relaxed)
let Self {
rc: _,
src: _,
blockhash_queue,
ancestors,
hash,
parent_hash,
parent_slot,
hard_forks,
transaction_count,
transaction_error_count: _,
transaction_entries_count: _,
transactions_per_entry_max: _,
tick_height,
signature_count,
capitalization,
max_tick_height,
hashes_per_tick,
ticks_per_slot,
ns_per_slot,
genesis_creation_time,
slots_per_year,
slot,
bank_id: _,
epoch,
block_height,
collector_id,
collector_fees,
fee_calculator,
fee_rate_governor,
collected_rent,
rent_collector,
epoch_schedule,
inflation,
stakes_cache,
epoch_stakes,
is_delta,
// TODO: Confirm if all these fields are intentionally ignored!
builtin_programs: _,
compute_budget: _,
builtin_feature_transitions: _,
rewards: _,
cluster_type: _,
lazy_rent_collection: _,
rewards_pool_pubkeys: _,
cached_executors: _,
transaction_debug_keys: _,
transaction_log_collector_config: _,
transaction_log_collector: _,
feature_set: _,
drop_callback: _,
freeze_started: _,
vote_only_bank: _,
cost_tracker: _,
rewrites_skipped_this_slot: _,
sysvar_cache: _,
accounts_data_len: _,
fee_structure: _,
// Ignore new fields explicitly if they do not impact PartialEq.
// Adding ".." will remove compile-time checks that if a new field
// is added to the struct, this ParitalEq is accordingly updated.
} = self;
*blockhash_queue.read().unwrap() == *other.blockhash_queue.read().unwrap()
&& ancestors == &other.ancestors
&& *hash.read().unwrap() == *other.hash.read().unwrap()
&& parent_hash == &other.parent_hash
&& parent_slot == &other.parent_slot
&& *hard_forks.read().unwrap() == *other.hard_forks.read().unwrap()
&& transaction_count.load(Relaxed) == other.transaction_count.load(Relaxed)
&& tick_height.load(Relaxed) == other.tick_height.load(Relaxed)
&& signature_count.load(Relaxed) == other.signature_count.load(Relaxed)
&& capitalization.load(Relaxed) == other.capitalization.load(Relaxed)
&& max_tick_height == &other.max_tick_height
&& hashes_per_tick == &other.hashes_per_tick
&& ticks_per_slot == &other.ticks_per_slot
&& ns_per_slot == &other.ns_per_slot
&& genesis_creation_time == &other.genesis_creation_time
&& slots_per_year == &other.slots_per_year
&& slot == &other.slot
&& epoch == &other.epoch
&& block_height == &other.block_height
&& collector_id == &other.collector_id
&& collector_fees.load(Relaxed) == other.collector_fees.load(Relaxed)
&& fee_calculator == &other.fee_calculator
&& fee_rate_governor == &other.fee_rate_governor
&& collected_rent.load(Relaxed) == other.collected_rent.load(Relaxed)
&& rent_collector == &other.rent_collector
&& epoch_schedule == &other.epoch_schedule
&& *inflation.read().unwrap() == *other.inflation.read().unwrap()
&& *stakes_cache.stakes() == *other.stakes_cache.stakes()
&& epoch_stakes == &other.epoch_stakes
&& is_delta.load(Relaxed) == other.is_delta.load(Relaxed)
}
}

View File

@ -238,7 +238,12 @@ impl Default for VoteAccountInner {
impl PartialEq<VoteAccountInner> for VoteAccountInner {
fn eq(&self, other: &Self) -> bool {
self.account == other.account
let Self {
account,
vote_state: _,
vote_state_once: _,
} = self;
account == &other.account
}
}
@ -281,7 +286,12 @@ impl Clone for VoteAccounts {
impl PartialEq<VoteAccounts> for VoteAccounts {
fn eq(&self, other: &Self) -> bool {
self.vote_accounts == other.vote_accounts
let Self {
vote_accounts,
staked_nodes: _,
staked_nodes_once: _,
} = self;
vote_accounts == &other.vote_accounts
}
}