Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
35359595 committed Apr 10, 2024
2 parents d2d8783 + e91a5e2 commit ee8e123
Show file tree
Hide file tree
Showing 38 changed files with 789 additions and 585 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,9 @@ before the PR can be merged. Here are the steps:
name = "solana-<PACKAGE_NAME>"
version = "0.0.1"
description = "<DESCRIPTION>"
authors = ["Solana Labs Maintainers <maintainers@solanalabs.com>"]
repository = "https://github.com/solana-labs/solana"
homepage = "https://solana.com/"
authors = ["Anza Maintainers <maintainers@anza.xyz>"]
repository = "https://github.com/anza-xyz/agave"
homepage = "https://anza.xyz"
documentation = "https://docs.rs/solana-<PACKAGE_NAME>"
license = "Apache-2.0"
edition = "2021"
Expand Down
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ resolver = "2"

[workspace.package]
version = "2.0.0"
authors = ["Solana Labs Maintainers <maintainers@solanalabs.com>"]
repository = "https://github.com/solana-labs/solana"
homepage = "https://solanalabs.com/"
authors = ["Anza Maintainers <maintainers@anza.xyz>"]
repository = "https://github.com/anza-xyz/agave"
homepage = "https://anza.xyz/"
license = "Apache-2.0"
edition = "2021"

Expand Down
2 changes: 1 addition & 1 deletion accounts-cluster-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ spl-token = { workspace = true, features = ["no-entrypoint"] }

[dev-dependencies]
solana-accounts-db = { workspace = true }
solana-core = { workspace = true }
solana-core = { workspace = true, features = ["dev-context-only-utils"] }
solana-local-cluster = { workspace = true }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
solana-test-validator = { workspace = true }
Expand Down
11 changes: 6 additions & 5 deletions accounts-db/src/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use {
crate::{
accounts_db::{
AccountsAddRootTiming, AccountsDb, LoadHint, LoadedAccount, ScanStorageResult,
VerifyAccountsHashAndLamportsConfig,
AccountsAddRootTiming, AccountsDb, LoadHint, LoadedAccount, ScanAccountStorageData,
ScanStorageResult, VerifyAccountsHashAndLamportsConfig,
},
accounts_index::{IndexKey, ScanConfig, ScanError, ScanResult, ZeroLamport},
ancestors::Ancestors,
Expand Down Expand Up @@ -201,21 +201,22 @@ impl Accounts {
/// returns only the latest/current version of B for this slot
pub fn scan_slot<F, B>(&self, slot: Slot, func: F) -> Vec<B>
where
F: Fn(LoadedAccount) -> Option<B> + Send + Sync,
F: Fn(&LoadedAccount) -> Option<B> + Send + Sync,
B: Sync + Send + Default + std::cmp::Eq,
{
let scan_result = self.accounts_db.scan_account_storage(
slot,
|loaded_account: LoadedAccount| {
|loaded_account: &LoadedAccount| {
// Cache only has one version per key, don't need to worry about versioning
func(loaded_account)
},
|accum: &DashMap<Pubkey, B>, loaded_account: LoadedAccount| {
|accum: &DashMap<Pubkey, B>, loaded_account: &LoadedAccount, _data| {
let loaded_account_pubkey = *loaded_account.pubkey();
if let Some(val) = func(loaded_account) {
accum.insert(loaded_account_pubkey, val);
}
},
ScanAccountStorageData::NoData,
);

match scan_result {
Expand Down
95 changes: 57 additions & 38 deletions accounts-db/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ use {
solana_nohash_hasher::{IntMap, IntSet},
solana_rayon_threadlimit::get_thread_count,
solana_sdk::{
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
account::{Account, AccountSharedData, ReadableAccount},
clock::{BankId, Epoch, Slot},
epoch_schedule::EpochSchedule,
genesis_config::{ClusterType, GenesisConfig},
Expand Down Expand Up @@ -170,6 +170,15 @@ enum ScanAccountStorageResult {
CacheFileNeedsToBeCreated((String, Range<Slot>)),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ScanAccountStorageData {
/// callback for accounts in storage will not include `data`
NoData,
/// return data (&[u8]) for each account.
/// This can be expensive to get and is not necessary for many scan operations.
DataRefForStorage,
}

#[derive(Default, Debug)]
/// hold alive accounts
/// alive means in the accounts index
Expand Down Expand Up @@ -919,7 +928,7 @@ impl<'a> LoadedAccount<'a> {
}
}

pub fn take_account(self) -> AccountSharedData {
pub fn take_account(&self) -> AccountSharedData {
match self {
LoadedAccount::Stored(stored_account_meta) => {
stored_account_meta.to_account_shared_data()
Expand All @@ -942,9 +951,7 @@ impl<'a> LoadedAccount<'a> {
pub fn data_len(&self) -> usize {
self.data().len()
}
}

impl<'a> ReadableAccount for LoadedAccount<'a> {
fn lamports(&self) -> u64 {
match self {
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.lamports(),
Expand All @@ -958,7 +965,7 @@ impl<'a> ReadableAccount for LoadedAccount<'a> {
LoadedAccount::Cached(cached_account) => cached_account.account.data(),
}
}
fn owner(&self) -> &Pubkey {
pub(crate) fn owner(&self) -> &Pubkey {
match self {
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.owner(),
LoadedAccount::Cached(cached_account) => cached_account.account.owner(),
Expand All @@ -976,19 +983,6 @@ impl<'a> ReadableAccount for LoadedAccount<'a> {
LoadedAccount::Cached(cached_account) => cached_account.account.rent_epoch(),
}
}
fn to_account_shared_data(&self) -> AccountSharedData {
match self {
LoadedAccount::Stored(_stored_account_meta) => AccountSharedData::create(
self.lamports(),
self.data().to_vec(),
*self.owner(),
self.executable(),
self.rent_epoch(),
),
// clone here to prevent data copy
LoadedAccount::Cached(cached_account) => cached_account.account.clone(),
}
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -2266,7 +2260,14 @@ impl<'a> AppendVecScan for ScanState<'a> {

let hash_is_missing = loaded_hash == AccountHash(Hash::default());
if self.config.check_hash || hash_is_missing {
let computed_hash = AccountsDb::hash_account(loaded_account, loaded_account.pubkey());
let computed_hash = AccountsDb::hash_account_data(
loaded_account.lamports(),
loaded_account.owner(),
loaded_account.executable(),
loaded_account.rent_epoch(),
loaded_account.data(),
loaded_account.pubkey(),
);
if hash_is_missing {
loaded_hash = computed_hash;
} else if self.config.check_hash && computed_hash != loaded_hash {
Expand Down Expand Up @@ -4844,11 +4845,12 @@ impl AccountsDb {
}

/// Scan a specific slot through all the account storage
pub fn scan_account_storage<R, B>(
pub(crate) fn scan_account_storage<R, B>(
&self,
slot: Slot,
cache_map_func: impl Fn(LoadedAccount) -> Option<R> + Sync,
storage_scan_func: impl Fn(&B, LoadedAccount) + Sync,
cache_map_func: impl Fn(&LoadedAccount) -> Option<R> + Sync,
storage_scan_func: impl Fn(&B, &LoadedAccount, Option<&[u8]>) + Sync,
scan_account_storage_data: ScanAccountStorageData,
) -> ScanStorageResult<R, B>
where
R: Send,
Expand All @@ -4862,7 +4864,7 @@ impl AccountsDb {
slot_cache
.par_iter()
.filter_map(|cached_account| {
cache_map_func(LoadedAccount::Cached(Cow::Borrowed(
cache_map_func(&LoadedAccount::Cached(Cow::Borrowed(
cached_account.value(),
)))
})
Expand All @@ -4873,7 +4875,7 @@ impl AccountsDb {
slot_cache
.iter()
.filter_map(|cached_account| {
cache_map_func(LoadedAccount::Cached(Cow::Borrowed(
cache_map_func(&LoadedAccount::Cached(Cow::Borrowed(
cached_account.value(),
)))
})
Expand All @@ -4898,10 +4900,13 @@ impl AccountsDb {
.storage
.get_slot_storage_entry_shrinking_in_progress_ok(slot)
{
storage
.accounts
.account_iter()
.for_each(|account| storage_scan_func(&retval, LoadedAccount::Stored(account)));
storage.accounts.account_iter().for_each(|account| {
let loaded_account = LoadedAccount::Stored(account);
let data = (scan_account_storage_data
== ScanAccountStorageData::DataRefForStorage)
.then_some(loaded_account.data());
storage_scan_func(&retval, &loaded_account, data)
});
}

ScanStorageResult::Stored(retval)
Expand Down Expand Up @@ -6625,7 +6630,14 @@ impl AccountsDb {
let balance = loaded_account.lamports();
let hash_is_missing = loaded_hash == AccountHash(Hash::default());
if config.check_hash || hash_is_missing {
let computed_hash = AccountsDb::hash_account(&loaded_account, loaded_account.pubkey());
let computed_hash = Self::hash_account_data(
loaded_account.lamports(),
loaded_account.owner(),
loaded_account.executable(),
loaded_account.rent_epoch(),
loaded_account.data(),
loaded_account.pubkey(),
);
if hash_is_missing {
loaded_hash = computed_hash;
}
Expand Down Expand Up @@ -7569,11 +7581,11 @@ impl AccountsDb {
let scan_result: ScanStorageResult<(Pubkey, AccountHash), DashMap<Pubkey, AccountHash>> =
self.scan_account_storage(
slot,
|loaded_account: LoadedAccount| {
|loaded_account: &LoadedAccount| {
// Cache only has one version per key, don't need to worry about versioning
Some((*loaded_account.pubkey(), loaded_account.loaded_hash()))
},
|accum: &DashMap<Pubkey, AccountHash>, loaded_account: LoadedAccount| {
|accum: &DashMap<Pubkey, AccountHash>, loaded_account: &LoadedAccount, _data| {
let mut loaded_hash = loaded_account.loaded_hash();
if loaded_hash == AccountHash(Hash::default()) {
loaded_hash = Self::hash_account_data(
Expand All @@ -7587,6 +7599,7 @@ impl AccountsDb {
}
accum.insert(*loaded_account.pubkey(), loaded_hash);
},
ScanAccountStorageData::NoData,
);
scan.stop();

Expand All @@ -7605,7 +7618,7 @@ impl AccountsDb {
ScanStorageResult<PubkeyHashAccount, DashMap<Pubkey, (AccountHash, AccountSharedData)>>;
let scan_result: ScanResult = self.scan_account_storage(
slot,
|loaded_account: LoadedAccount| {
|loaded_account: &LoadedAccount| {
// Cache only has one version per key, don't need to worry about versioning
Some(PubkeyHashAccount {
pubkey: *loaded_account.pubkey(),
Expand All @@ -7614,7 +7627,8 @@ impl AccountsDb {
})
},
|accum: &DashMap<Pubkey, (AccountHash, AccountSharedData)>,
loaded_account: LoadedAccount| {
loaded_account: &LoadedAccount,
_data| {
// Storage may have duplicates so only keep the latest version for each key
let mut loaded_hash = loaded_account.loaded_hash();
let key = *loaded_account.pubkey();
Expand All @@ -7624,6 +7638,7 @@ impl AccountsDb {
}
accum.insert(key, (loaded_hash, account));
},
ScanAccountStorageData::NoData,
);

match scan_result {
Expand Down Expand Up @@ -14186,9 +14201,10 @@ pub mod tests {
if let ScanStorageResult::Stored(slot_accounts) = accounts_db.scan_account_storage(
*slot as Slot,
|_| Some(0),
|slot_accounts: &DashSet<Pubkey>, loaded_account: LoadedAccount| {
|slot_accounts: &DashSet<Pubkey>, loaded_account: &LoadedAccount, _data| {
slot_accounts.insert(*loaded_account.pubkey());
},
ScanAccountStorageData::NoData,
) {
if *slot == alive_slot {
assert_eq!(slot_accounts.len(), keys.len());
Expand Down Expand Up @@ -14226,9 +14242,10 @@ pub mod tests {
if let ScanStorageResult::Stored(slot_account) = accounts_db.scan_account_storage(
*slot as Slot,
|_| Some(0),
|slot_account: &Arc<RwLock<Pubkey>>, loaded_account: LoadedAccount| {
|slot_account: &Arc<RwLock<Pubkey>>, loaded_account: &LoadedAccount, _data| {
*slot_account.write().unwrap() = *loaded_account.pubkey();
},
ScanAccountStorageData::NoData,
) {
assert_eq!(*slot_account.read().unwrap(), keys[*slot as usize]);
} else {
Expand Down Expand Up @@ -14291,7 +14308,7 @@ pub mod tests {
for slot in &slots {
let slot_accounts = accounts_db.scan_account_storage(
*slot as Slot,
|loaded_account: LoadedAccount| {
|loaded_account: &LoadedAccount| {
assert!(
!is_cache_at_limit,
"When cache is at limit, all roots should have been flushed to storage"
Expand All @@ -14301,14 +14318,15 @@ pub mod tests {
assert!(*slot > requested_flush_root);
Some(*loaded_account.pubkey())
},
|slot_accounts: &DashSet<Pubkey>, loaded_account: LoadedAccount| {
|slot_accounts: &DashSet<Pubkey>, loaded_account: &LoadedAccount, _data| {
slot_accounts.insert(*loaded_account.pubkey());
if !is_cache_at_limit {
// Only true when the limit hasn't been reached and there are still
// slots left in the cache
assert!(*slot <= requested_flush_root);
}
},
ScanAccountStorageData::NoData,
);

let slot_accounts = match slot_accounts {
Expand Down Expand Up @@ -14419,9 +14437,10 @@ pub mod tests {
.scan_account_storage(
*slot as Slot,
|_| Some(0),
|slot_account: &DashSet<Pubkey>, loaded_account: LoadedAccount| {
|slot_account: &DashSet<Pubkey>, loaded_account: &LoadedAccount, _data| {
slot_account.insert(*loaded_account.pubkey());
},
ScanAccountStorageData::NoData,
) {
slot_accounts.into_iter().collect::<HashSet<Pubkey>>()
} else {
Expand Down
1 change: 1 addition & 0 deletions bench-streamer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ fn main() -> Result<()> {
Duration::from_millis(1), // coalesce
true,
None,
false,
));
}

Expand Down
7 changes: 5 additions & 2 deletions bench-tps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ solana-clap-utils = { workspace = true }
solana-cli-config = { workspace = true }
solana-client = { workspace = true }
solana-connection-cache = { workspace = true }
solana-core = { workspace = true }
solana-core = { workspace = true, features = ["dev-context-only-utils"] }
solana-faucet = { workspace = true }
solana-genesis = { workspace = true }
solana-gossip = { workspace = true }
Expand All @@ -36,7 +36,7 @@ solana-rpc = { workspace = true }
solana-rpc-client = { workspace = true }
solana-rpc-client-api = { workspace = true }
solana-rpc-client-nonce-utils = { workspace = true }
solana-runtime = { workspace = true }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
solana-sdk = { workspace = true }
solana-streamer = { workspace = true }
solana-tpu-client = { workspace = true }
Expand All @@ -54,3 +54,6 @@ tempfile = { workspace = true }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[features]
dev-context-only-utils = []
Loading

0 comments on commit ee8e123

Please sign in to comment.