reduce replicode in accounts, fix cast to i64 (#5025)
This commit is contained in:
parent
41d0db078e
commit
8cad992170
|
@ -23,7 +23,6 @@ use std::collections::{HashMap, HashSet};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::remove_dir_all;
|
use std::fs::remove_dir_all;
|
||||||
use std::io::{BufReader, Read};
|
use std::io::{BufReader, Read};
|
||||||
use std::ops::Neg;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
@ -306,27 +305,47 @@ impl Accounts {
|
||||||
.filter(|(acc, _)| acc.lamports != 0)
|
.filter(|(acc, _)| acc.lamports != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_by_program(&self, fork: Fork, program_id: &Pubkey) -> Vec<(Pubkey, Account)> {
|
/// scans underlying accounts_db for this delta (fork) with a map function
|
||||||
let accumulator: Vec<Vec<(Pubkey, u64, Account)>> = self.accounts_db.scan_account_storage(
|
/// from StoredAccount to B
|
||||||
|
/// returns only the latest/current version of B for this fork
|
||||||
|
fn scan_fork<F, B>(&self, fork: Fork, func: F) -> Vec<B>
|
||||||
|
where
|
||||||
|
F: Fn(&StoredAccount) -> Option<B>,
|
||||||
|
F: Send + Sync,
|
||||||
|
B: Send + Default,
|
||||||
|
{
|
||||||
|
let accumulator: Vec<Vec<(Pubkey, u64, B)>> = self.accounts_db.scan_account_storage(
|
||||||
fork,
|
fork,
|
||||||
|stored_account: &StoredAccount,
|
|stored_account: &StoredAccount,
|
||||||
_id: AppendVecId,
|
_id: AppendVecId,
|
||||||
accum: &mut Vec<(Pubkey, u64, Account)>| {
|
accum: &mut Vec<(Pubkey, u64, B)>| {
|
||||||
if stored_account.balance.owner == *program_id {
|
if let Some(val) = func(stored_account) {
|
||||||
let val = (
|
accum.push((
|
||||||
stored_account.meta.pubkey,
|
stored_account.meta.pubkey,
|
||||||
stored_account.meta.write_version,
|
std::u64::MAX - stored_account.meta.write_version,
|
||||||
stored_account.clone_account(),
|
val,
|
||||||
);
|
));
|
||||||
accum.push(val)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let mut versions: Vec<(Pubkey, u64, Account)> =
|
|
||||||
accumulator.into_iter().flat_map(|x| x).collect();
|
let mut versions: Vec<(Pubkey, u64, B)> = accumulator.into_iter().flat_map(|x| x).collect();
|
||||||
versions.sort_by_key(|s| (s.0, (s.1 as i64).neg()));
|
versions.sort_by_key(|s| (s.0, s.1));
|
||||||
versions.dedup_by_key(|s| s.0);
|
versions.dedup_by_key(|s| s.0);
|
||||||
versions.into_iter().map(|s| (s.0, s.2)).collect()
|
versions
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_pubkey, _version, val)| val)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_by_program(&self, fork: Fork, program_id: &Pubkey) -> Vec<(Pubkey, Account)> {
|
||||||
|
self.scan_fork(fork, |stored_account| {
|
||||||
|
if stored_account.balance.owner == *program_id {
|
||||||
|
Some((stored_account.meta.pubkey, stored_account.clone_account()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Slow because lock is held for 1 operation instead of many
|
/// Slow because lock is held for 1 operation instead of many
|
||||||
|
@ -423,28 +442,19 @@ impl Accounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_internal_state(&self, fork_id: Fork) -> Option<Hash> {
|
pub fn hash_internal_state(&self, fork_id: Fork) -> Option<Hash> {
|
||||||
let accumulator: Vec<Vec<(Pubkey, u64, Hash)>> = self.accounts_db.scan_account_storage(
|
let account_hashes = self.scan_fork(fork_id, |stored_account| {
|
||||||
fork_id,
|
if !syscall::check_id(&stored_account.balance.owner) {
|
||||||
|stored_account: &StoredAccount,
|
Some(Self::hash_account(stored_account))
|
||||||
_id: AppendVecId,
|
} else {
|
||||||
accum: &mut Vec<(Pubkey, u64, Hash)>| {
|
None
|
||||||
if !syscall::check_id(&stored_account.balance.owner) {
|
}
|
||||||
accum.push((
|
});
|
||||||
stored_account.meta.pubkey,
|
|
||||||
stored_account.meta.write_version,
|
|
||||||
Self::hash_account(stored_account),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let mut account_hashes: Vec<_> = accumulator.into_iter().flat_map(|x| x).collect();
|
|
||||||
account_hashes.sort_by_key(|s| (s.0, (s.1 as i64).neg()));
|
|
||||||
account_hashes.dedup_by_key(|s| s.0);
|
|
||||||
if account_hashes.is_empty() {
|
if account_hashes.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let mut hasher = Hasher::default();
|
let mut hasher = Hasher::default();
|
||||||
for (_, _, hash) in account_hashes {
|
for hash in account_hashes {
|
||||||
hasher.hash(hash.as_ref());
|
hasher.hash(hash.as_ref());
|
||||||
}
|
}
|
||||||
Some(hasher.result())
|
Some(hasher.result())
|
||||||
|
|
Loading…
Reference in New Issue