Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ mod tests {
.get(&deserialized_bank.slot())
.unwrap()
.clone();
bank.compare_bank(&deserialized_bank);
assert!(*bank == deserialized_bank);

let slot_snapshot_paths = snapshot_utils::get_snapshot_paths(&snapshot_path);

Expand Down
4 changes: 2 additions & 2 deletions explorer/wasm/src/stake_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub type Epoch = u64;

#[wasm_bindgen]
#[repr(transparent)]
#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Debug, Deserialize, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Pubkey([u8; 32]);

#[wasm_bindgen]
Expand Down Expand Up @@ -164,7 +164,7 @@ impl Stake {
}

#[wasm_bindgen]
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
#[derive(Serialize, Debug, Deserialize, PartialEq, Clone, Copy)]
pub struct Delegation {
/// to whom the stake is delegated
voter_pubkey: Pubkey,
Expand Down
92 changes: 46 additions & 46 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ pub(crate) struct BankFieldsToDeserialize {
// This is separated from BankFieldsToDeserialize to avoid cloning by using refs.
// So, sync fields with BankFieldsToDeserialize!
// all members are made public to remain Bank private and to make versioned serializer workable on this
#[derive(Debug)]
pub(crate) struct BankFieldsToSerialize<'a> {
pub(crate) blockhash_queue: &'a RwLock<BlockhashQueue>,
pub(crate) ancestors: &'a Ancestors,
Expand Down Expand Up @@ -477,6 +478,46 @@ pub(crate) struct BankFieldsToSerialize<'a> {
pub(crate) is_delta: bool,
}

// Can't derive PartialEq because RwLock doesn't implement PartialEq
impl PartialEq for Bank {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, why can't we just derive PartialEq? A comment might be desirable to explain the limitation.

@carllin carllin Oct 8, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hehe so the issue was RwLock doesn't implement PartialEq, and we can't implement it for RwLock because it doesn't belong to this crate, added comment!

fn eq(&self, other: &Self) -> bool {
if 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.unused == other.unused
&& 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.read().unwrap() == *other.stakes.read().unwrap()
&& self.epoch_stakes == other.epoch_stakes
&& self.is_delta.load(Relaxed) == other.is_delta.load(Relaxed)

@ryoqun ryoqun Oct 8, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how we can maintain this for the addition of newer fields... This problem exists from compare_bank.

}
}

#[derive(Debug, PartialEq, Serialize, Deserialize, AbiExample, Default, Clone, Copy)]
pub struct RewardInfo {
pub lamports: i64, // Reward amount
Expand Down Expand Up @@ -878,7 +919,11 @@ impl Bank {
);
assert_eq!(bank.epoch_schedule, genesis_config.epoch_schedule);
assert_eq!(bank.epoch, bank.epoch_schedule.get_epoch(bank.slot));

bank.fee_rate_governor.lamports_per_signature = bank.fee_calculator.lamports_per_signature;
assert_eq!(
bank.fee_rate_governor.create_fee_calculator(),
bank.fee_calculator
);
bank
}

Expand Down Expand Up @@ -3590,51 +3635,6 @@ impl Bank {
}
}

pub fn compare_bank(&self, dbank: &Bank) {
if ptr::eq(self, dbank) {
return;
}
Comment on lines -3594 to -3596

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should be kept to deadlock free? #10466

Yeah, we should have added an comment...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah good catch, thanks!

assert_eq!(self.slot, dbank.slot);
assert_eq!(self.collector_id, dbank.collector_id);
assert_eq!(self.epoch_schedule, dbank.epoch_schedule);
assert_eq!(self.hashes_per_tick, dbank.hashes_per_tick);
assert_eq!(self.ticks_per_slot, dbank.ticks_per_slot);
assert_eq!(self.parent_hash, dbank.parent_hash);
assert_eq!(
self.tick_height.load(Relaxed),
dbank.tick_height.load(Relaxed)
);
assert_eq!(self.is_delta.load(Relaxed), dbank.is_delta.load(Relaxed));

{
let bh = self.hash.read().unwrap();
let dbh = dbank.hash.read().unwrap();
assert_eq!(*bh, *dbh);
}

{
let st = self.stakes.read().unwrap();
let dst = dbank.stakes.read().unwrap();
assert_eq!(*st, *dst);
}

{
let bhq = self.blockhash_queue.read().unwrap();
let dbhq = dbank.blockhash_queue.read().unwrap();
assert_eq!(*bhq, *dbhq);
}

{
let sc = self.src.status_cache.read().unwrap();
let dsc = dbank.src.status_cache.read().unwrap();
assert_eq!(*sc, *dsc);
}
assert_eq!(
self.rc.accounts.bank_hash_at(self.slot),
dbank.rc.accounts.bank_hash_at(dbank.slot)
);
}

pub fn clean_accounts(&self, skip_last: bool) {
let max_clean_slot = if skip_last {
// Don't clean the slot we're snapshotting because it may have zero-lamport
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/blockhash_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct HashAge {

/// Low memory overhead, so can be cloned for every checkpoint
#[frozen_abi(digest = "EwaoLA34VN18E95GvjmkeStUpWqTeBd7FGpd7mppLmEw")]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, AbiExample)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, AbiExample)]
pub struct BlockhashQueue {
/// updated whenever an hash is registered
hash_height: u64,
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/epoch_stakes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use std::{collections::HashMap, sync::Arc};
pub type NodeIdToVoteAccounts = HashMap<Pubkey, NodeVoteAccounts>;
pub type EpochAuthorizedVoters = HashMap<Pubkey, Pubkey>;

#[derive(Clone, Serialize, Debug, Deserialize, Default, PartialEq, AbiExample)]
#[derive(Clone, Serialize, Debug, Deserialize, Default, PartialEq, Eq, AbiExample)]
pub struct NodeVoteAccounts {
pub vote_accounts: Vec<Pubkey>,
pub total_stake: u64,
}

#[derive(Clone, Serialize, Deserialize, AbiExample)]
#[derive(Clone, Debug, Serialize, Deserialize, AbiExample, PartialEq)]
pub struct EpochStakes {
stakes: Arc<Stakes>,
total_stake: u64,
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/serde_snapshot/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ fn test_bank_serialize_style(serde_style: SerdeStyle) {
assert_eq!(dbank.get_balance(&key1.pubkey()), 0);
assert_eq!(dbank.get_balance(&key2.pubkey()), 10);
assert_eq!(dbank.get_balance(&key3.pubkey()), 0);
bank2.compare_bank(&dbank);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

(I wonder why this was like this not defining ==.)..

assert!(bank2 == dbank);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nits: how about assert_eq!?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue I ran into with assert_eq! was that it requires Bank implement Debug, which means all the program stack CowCachedExecutors -> Executor -> InvokeContext have to all implement Debug , and I didn't want to plumb all of that through 😩

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carllin FYI, I've took the initiative here after stressed with not being able to freely dbg!() bunch of bank fields: https://github.com/solana-labs/solana/pull/13017/files#diff-b5dead0a38e5f63447595bbeda1428d3aa851d33954343bb1bc38b4b00add5fdR159

}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/fee_calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub struct FeeRateGovernor {
// The current cost of a signature This amount may increase/decrease over time based on
// cluster processing load.
#[serde(skip)]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is where gating would be necessary. Alternatively we just set this value on deserialize to bank.fee_calculator.lamports_per_signature

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryoqun after talking with @t-nelson, it seems removing the skip here directly also breaks RPC, seems like the path of least resistance is to just manually assign this field for now. Thoughts?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the path of least resistance is to just manually assign this field for now. Thoughts?

@carllin yeah, I think this solution is good.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, when did this bug started to occur? Since beginning? ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm yeah I would guess since it was first checked in xD

lamports_per_signature: u64,
pub lamports_per_signature: u64,

// The target cost of a signature when the cluster is operating around target_signatures_per_slot
// signatures
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/hard_forks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use byteorder::{ByteOrder, LittleEndian};
use solana_sdk::clock::Slot;

#[derive(Default, Clone, Deserialize, Serialize, AbiExample)]
#[derive(Default, Clone, Debug, Deserialize, Serialize, AbiExample, PartialEq, Eq)]
pub struct HardForks {
hard_forks: Vec<(Slot, usize)>,
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/stake_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ use std::ops::Deref;

pub const MAX_ENTRIES: usize = 512; // it should never take as many as 512 epochs to warm up or cool down

#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone, AbiExample)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, Clone, AbiExample)]
pub struct StakeHistoryEntry {
pub effective: u64, // effective stake at this epoch
pub activating: u64, // sum of portion of stakes not fully warmed up
pub deactivating: u64, // requested to be cooled down, not fully deactivated yet
}

#[repr(C)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone, AbiExample)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, Clone, AbiExample)]
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);

impl StakeHistory {
Expand Down