Move accounts-db code to its own crate (#32766)
This commit is contained in:
parent
b97c451200
commit
f4287d70bb
|
@ -5151,9 +5151,9 @@ dependencies = [
|
||||||
"clap 2.33.3",
|
"clap 2.33.3",
|
||||||
"log",
|
"log",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-logger",
|
"solana-logger",
|
||||||
"solana-measure",
|
"solana-measure",
|
||||||
"solana-runtime",
|
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
]
|
]
|
||||||
|
@ -5167,6 +5167,7 @@ dependencies = [
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rayon",
|
"rayon",
|
||||||
"solana-account-decoder",
|
"solana-account-decoder",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-cli-config",
|
"solana-cli-config",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
|
@ -5187,6 +5188,84 @@ dependencies = [
|
||||||
"spl-token",
|
"spl-token",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solana-accounts-db"
|
||||||
|
version = "1.17.0"
|
||||||
|
dependencies = [
|
||||||
|
"arrayref",
|
||||||
|
"assert_matches",
|
||||||
|
"bincode",
|
||||||
|
"blake3",
|
||||||
|
"bv",
|
||||||
|
"bytemuck",
|
||||||
|
"byteorder",
|
||||||
|
"bzip2",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"dashmap 4.0.2",
|
||||||
|
"dir-diff",
|
||||||
|
"ed25519-dalek",
|
||||||
|
"flate2",
|
||||||
|
"fnv",
|
||||||
|
"fs-err",
|
||||||
|
"im",
|
||||||
|
"index_list",
|
||||||
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
|
"libsecp256k1",
|
||||||
|
"log",
|
||||||
|
"lru",
|
||||||
|
"lz4",
|
||||||
|
"memmap2",
|
||||||
|
"memoffset 0.9.0",
|
||||||
|
"modular-bitfield",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
|
"num_cpus",
|
||||||
|
"num_enum 0.6.1",
|
||||||
|
"once_cell",
|
||||||
|
"ouroboros",
|
||||||
|
"percentage",
|
||||||
|
"rand 0.7.3",
|
||||||
|
"rand_chacha 0.2.2",
|
||||||
|
"rayon",
|
||||||
|
"regex",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"siphasher",
|
||||||
|
"solana-accounts-db",
|
||||||
|
"solana-address-lookup-table-program",
|
||||||
|
"solana-bpf-loader-program",
|
||||||
|
"solana-bucket-map",
|
||||||
|
"solana-compute-budget-program",
|
||||||
|
"solana-config-program",
|
||||||
|
"solana-cost-model",
|
||||||
|
"solana-frozen-abi",
|
||||||
|
"solana-frozen-abi-macro",
|
||||||
|
"solana-loader-v4-program",
|
||||||
|
"solana-logger",
|
||||||
|
"solana-measure",
|
||||||
|
"solana-metrics",
|
||||||
|
"solana-perf",
|
||||||
|
"solana-program-runtime",
|
||||||
|
"solana-rayon-threadlimit",
|
||||||
|
"solana-sdk",
|
||||||
|
"solana-stake-program",
|
||||||
|
"solana-system-program",
|
||||||
|
"solana-vote-program",
|
||||||
|
"solana-zk-token-proof-program",
|
||||||
|
"solana-zk-token-sdk",
|
||||||
|
"static_assertions",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
|
"symlink",
|
||||||
|
"tar",
|
||||||
|
"tempfile",
|
||||||
|
"test-case",
|
||||||
|
"thiserror",
|
||||||
|
"zstd",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-address-lookup-table-program"
|
name = "solana-address-lookup-table-program"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
|
@ -5274,6 +5353,7 @@ dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-banks-interface",
|
"solana-banks-interface",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
"solana-runtime",
|
"solana-runtime",
|
||||||
|
@ -5715,6 +5795,7 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-address-lookup-table-program",
|
"solana-address-lookup-table-program",
|
||||||
"solana-bloom",
|
"solana-bloom",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
|
@ -5935,6 +6016,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml 0.9.25",
|
"serde_yaml 0.9.25",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-cli-config",
|
"solana-cli-config",
|
||||||
"solana-entry",
|
"solana-entry",
|
||||||
|
@ -5953,9 +6035,9 @@ name = "solana-genesis-utils"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-download-utils",
|
"solana-download-utils",
|
||||||
"solana-rpc-client",
|
"solana-rpc-client",
|
||||||
"solana-runtime",
|
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5981,6 +6063,7 @@ dependencies = [
|
||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-entry",
|
"solana-entry",
|
||||||
"solana-geyser-plugin-interface",
|
"solana-geyser-plugin-interface",
|
||||||
"solana-ledger",
|
"solana-ledger",
|
||||||
|
@ -6128,6 +6211,7 @@ dependencies = [
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"sha2 0.10.7",
|
"sha2 0.10.7",
|
||||||
"solana-account-decoder",
|
"solana-account-decoder",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-bpf-loader-program",
|
"solana-bpf-loader-program",
|
||||||
"solana-cost-model",
|
"solana-cost-model",
|
||||||
"solana-entry",
|
"solana-entry",
|
||||||
|
@ -6181,6 +6265,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"solana-account-decoder",
|
"solana-account-decoder",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-bpf-loader-program",
|
"solana-bpf-loader-program",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-cli-output",
|
"solana-cli-output",
|
||||||
|
@ -6233,6 +6318,7 @@ dependencies = [
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rayon",
|
"rayon",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
"solana-config-program",
|
"solana-config-program",
|
||||||
"solana-core",
|
"solana-core",
|
||||||
|
@ -6295,9 +6381,9 @@ version = "1.17.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.33.3",
|
"clap 2.33.3",
|
||||||
"log",
|
"log",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-logger",
|
"solana-logger",
|
||||||
"solana-measure",
|
"solana-measure",
|
||||||
"solana-runtime",
|
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
]
|
]
|
||||||
|
@ -6530,6 +6616,7 @@ dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-banks-client",
|
"solana-banks-client",
|
||||||
"solana-banks-interface",
|
"solana-banks-interface",
|
||||||
"solana-banks-server",
|
"solana-banks-server",
|
||||||
|
@ -6647,6 +6734,7 @@ dependencies = [
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"soketto",
|
"soketto",
|
||||||
"solana-account-decoder",
|
"solana-account-decoder",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-address-lookup-table-program",
|
"solana-address-lookup-table-program",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
"solana-entry",
|
"solana-entry",
|
||||||
|
@ -6817,6 +6905,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"siphasher",
|
"siphasher",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-address-lookup-table-program",
|
"solana-address-lookup-table-program",
|
||||||
"solana-bpf-loader-program",
|
"solana-bpf-loader-program",
|
||||||
"solana-bucket-map",
|
"solana-bucket-map",
|
||||||
|
@ -7019,8 +7108,8 @@ version = "1.17.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.33.3",
|
"clap 2.33.3",
|
||||||
"log",
|
"log",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-logger",
|
"solana-logger",
|
||||||
"solana-runtime",
|
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
]
|
]
|
||||||
|
@ -7080,6 +7169,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-cli-output",
|
"solana-cli-output",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
"solana-core",
|
"solana-core",
|
||||||
|
@ -7307,6 +7397,7 @@ dependencies = [
|
||||||
"serde_yaml 0.9.25",
|
"serde_yaml 0.9.25",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"solana-account-decoder",
|
"solana-account-decoder",
|
||||||
|
"solana-accounts-db",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-cli-config",
|
"solana-cli-config",
|
||||||
"solana-core",
|
"solana-core",
|
||||||
|
|
|
@ -3,6 +3,7 @@ members = [
|
||||||
"account-decoder",
|
"account-decoder",
|
||||||
"accounts-bench",
|
"accounts-bench",
|
||||||
"accounts-cluster-bench",
|
"accounts-cluster-bench",
|
||||||
|
"accounts-db",
|
||||||
"banking-bench",
|
"banking-bench",
|
||||||
"banks-client",
|
"banks-client",
|
||||||
"banks-interface",
|
"banks-interface",
|
||||||
|
@ -293,6 +294,7 @@ socket2 = "0.5.3"
|
||||||
soketto = "0.7"
|
soketto = "0.7"
|
||||||
solana_rbpf = "=0.6.0"
|
solana_rbpf = "=0.6.0"
|
||||||
solana-account-decoder = { path = "account-decoder", version = "=1.17.0" }
|
solana-account-decoder = { path = "account-decoder", version = "=1.17.0" }
|
||||||
|
solana-accounts-db = { path = "accounts-db", version = "=1.17.0" }
|
||||||
solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.0" }
|
solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.0" }
|
||||||
solana-banks-client = { path = "banks-client", version = "=1.17.0" }
|
solana-banks-client = { path = "banks-client", version = "=1.17.0" }
|
||||||
solana-banks-interface = { path = "banks-interface", version = "=1.17.0" }
|
solana-banks-interface = { path = "banks-interface", version = "=1.17.0" }
|
||||||
|
|
|
@ -12,9 +12,9 @@ edition = { workspace = true }
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-logger = { workspace = true }
|
solana-logger = { workspace = true }
|
||||||
solana-measure = { workspace = true }
|
solana-measure = { workspace = true }
|
||||||
solana-runtime = { workspace = true }
|
|
||||||
solana-sdk = { workspace = true }
|
solana-sdk = { workspace = true }
|
||||||
solana-version = { workspace = true }
|
solana-version = { workspace = true }
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,7 @@ extern crate log;
|
||||||
use {
|
use {
|
||||||
clap::{crate_description, crate_name, value_t, App, Arg},
|
clap::{crate_description, crate_name, value_t, App, Arg},
|
||||||
rayon::prelude::*,
|
rayon::prelude::*,
|
||||||
solana_measure::measure::Measure,
|
solana_accounts_db::{
|
||||||
solana_runtime::{
|
|
||||||
accounts::Accounts,
|
accounts::Accounts,
|
||||||
accounts_db::{
|
accounts_db::{
|
||||||
test_utils::{create_test_accounts, update_accounts_bench},
|
test_utils::{create_test_accounts, update_accounts_bench},
|
||||||
|
@ -16,6 +15,7 @@ use {
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
rent_collector::RentCollector,
|
rent_collector::RentCollector,
|
||||||
},
|
},
|
||||||
|
solana_measure::measure::Measure,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
genesis_config::ClusterType, pubkey::Pubkey, sysvar::epoch_schedule::EpochSchedule,
|
genesis_config::ClusterType, pubkey::Pubkey, sysvar::epoch_schedule::EpochSchedule,
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ log = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
solana-account-decoder = { workspace = true }
|
solana-account-decoder = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-clap-utils = { workspace = true }
|
solana-clap-utils = { workspace = true }
|
||||||
solana-cli-config = { workspace = true }
|
solana-cli-config = { workspace = true }
|
||||||
solana-client = { workspace = true }
|
solana-client = { workspace = true }
|
||||||
|
|
|
@ -4,6 +4,7 @@ use {
|
||||||
log::*,
|
log::*,
|
||||||
rand::{thread_rng, Rng},
|
rand::{thread_rng, Rng},
|
||||||
rayon::prelude::*,
|
rayon::prelude::*,
|
||||||
|
solana_accounts_db::inline_spl_token,
|
||||||
solana_clap_utils::{
|
solana_clap_utils::{
|
||||||
hidden_unless_forced, input_parsers::pubkey_of, input_validators::is_url_or_moniker,
|
hidden_unless_forced, input_parsers::pubkey_of, input_validators::is_url_or_moniker,
|
||||||
},
|
},
|
||||||
|
@ -11,7 +12,6 @@ use {
|
||||||
solana_client::transaction_executor::TransactionExecutor,
|
solana_client::transaction_executor::TransactionExecutor,
|
||||||
solana_gossip::gossip_service::discover,
|
solana_gossip::gossip_service::discover,
|
||||||
solana_rpc_client::rpc_client::RpcClient,
|
solana_rpc_client::rpc_client::RpcClient,
|
||||||
solana_runtime::inline_spl_token,
|
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
commitment_config::CommitmentConfig,
|
commitment_config::CommitmentConfig,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
|
@ -703,6 +703,7 @@ fn main() {
|
||||||
pub mod test {
|
pub mod test {
|
||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
|
solana_accounts_db::inline_spl_token,
|
||||||
solana_core::validator::ValidatorConfig,
|
solana_core::validator::ValidatorConfig,
|
||||||
solana_faucet::faucet::run_local_faucet,
|
solana_faucet::faucet::run_local_faucet,
|
||||||
solana_local_cluster::{
|
solana_local_cluster::{
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
[package]
|
||||||
|
name = "solana-accounts-db"
|
||||||
|
description = "Solana accounts db"
|
||||||
|
documentation = "https://docs.rs/solana-acounts-db"
|
||||||
|
version = { workspace = true }
|
||||||
|
authors = { workspace = true }
|
||||||
|
repository = { workspace = true }
|
||||||
|
homepage = { workspace = true }
|
||||||
|
license = { workspace = true }
|
||||||
|
edition = { workspace = true }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arrayref = { workspace = true }
|
||||||
|
bincode = { workspace = true }
|
||||||
|
blake3 = { workspace = true }
|
||||||
|
bv = { workspace = true, features = ["serde"] }
|
||||||
|
bytemuck = { workspace = true }
|
||||||
|
byteorder = { workspace = true }
|
||||||
|
bzip2 = { workspace = true }
|
||||||
|
crossbeam-channel = { workspace = true }
|
||||||
|
dashmap = { workspace = true, features = ["rayon", "raw-api"] }
|
||||||
|
dir-diff = { workspace = true }
|
||||||
|
flate2 = { workspace = true }
|
||||||
|
fnv = { workspace = true }
|
||||||
|
fs-err = { workspace = true }
|
||||||
|
im = { workspace = true, features = ["rayon", "serde"] }
|
||||||
|
index_list = { workspace = true }
|
||||||
|
itertools = { workspace = true }
|
||||||
|
lazy_static = { workspace = true }
|
||||||
|
log = { workspace = true }
|
||||||
|
lru = { workspace = true }
|
||||||
|
lz4 = { workspace = true }
|
||||||
|
memmap2 = { workspace = true }
|
||||||
|
modular-bitfield = { workspace = true }
|
||||||
|
num-derive = { workspace = true }
|
||||||
|
num-traits = { workspace = true }
|
||||||
|
num_cpus = { workspace = true }
|
||||||
|
num_enum = { workspace = true }
|
||||||
|
once_cell = { workspace = true }
|
||||||
|
ouroboros = { workspace = true }
|
||||||
|
percentage = { workspace = true }
|
||||||
|
rand = { workspace = true }
|
||||||
|
rayon = { workspace = true }
|
||||||
|
regex = { workspace = true }
|
||||||
|
serde = { workspace = true, features = ["rc"] }
|
||||||
|
serde_derive = { workspace = true }
|
||||||
|
siphasher = { workspace = true }
|
||||||
|
solana-address-lookup-table-program = { workspace = true }
|
||||||
|
solana-bpf-loader-program = { workspace = true }
|
||||||
|
solana-bucket-map = { workspace = true }
|
||||||
|
solana-compute-budget-program = { workspace = true }
|
||||||
|
solana-config-program = { workspace = true }
|
||||||
|
solana-cost-model = { workspace = true }
|
||||||
|
solana-frozen-abi = { workspace = true }
|
||||||
|
solana-frozen-abi-macro = { workspace = true }
|
||||||
|
solana-loader-v4-program = { workspace = true }
|
||||||
|
solana-measure = { workspace = true }
|
||||||
|
solana-metrics = { workspace = true }
|
||||||
|
solana-perf = { workspace = true }
|
||||||
|
solana-program-runtime = { workspace = true }
|
||||||
|
solana-rayon-threadlimit = { workspace = true }
|
||||||
|
solana-sdk = { workspace = true }
|
||||||
|
solana-stake-program = { workspace = true }
|
||||||
|
solana-system-program = { workspace = true }
|
||||||
|
solana-vote-program = { workspace = true }
|
||||||
|
solana-zk-token-proof-program = { workspace = true }
|
||||||
|
solana-zk-token-sdk = { workspace = true }
|
||||||
|
static_assertions = { workspace = true }
|
||||||
|
strum = { workspace = true, features = ["derive"] }
|
||||||
|
strum_macros = { workspace = true }
|
||||||
|
symlink = { workspace = true }
|
||||||
|
tar = { workspace = true }
|
||||||
|
tempfile = { workspace = true }
|
||||||
|
thiserror = { workspace = true }
|
||||||
|
zstd = { workspace = true }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["lib"]
|
||||||
|
name = "solana_accounts_db"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert_matches = { workspace = true }
|
||||||
|
ed25519-dalek = { workspace = true }
|
||||||
|
libsecp256k1 = { workspace = true }
|
||||||
|
memoffset = { workspace = true }
|
||||||
|
rand_chacha = { workspace = true }
|
||||||
|
# See order-crates-for-publishing.py for using this unusual `path = "."`
|
||||||
|
solana-accounts-db = { path = ".", features = ["dev-context-only-utils"] }
|
||||||
|
solana-logger = { workspace = true }
|
||||||
|
solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
|
||||||
|
static_assertions = { workspace = true }
|
||||||
|
test-case = { workspace = true }
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
rustc_version = { workspace = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
dev-context-only-utils = []
|
|
@ -0,0 +1,27 @@
|
||||||
|
extern crate rustc_version;
|
||||||
|
use rustc_version::{version_meta, Channel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Copied and adapted from
|
||||||
|
// https://github.com/Kimundi/rustc-version-rs/blob/1d692a965f4e48a8cb72e82cda953107c0d22f47/README.md#example
|
||||||
|
// Licensed under Apache-2.0 + MIT
|
||||||
|
match version_meta().unwrap().channel {
|
||||||
|
Channel::Stable => {
|
||||||
|
println!("cargo:rustc-cfg=RUSTC_WITHOUT_SPECIALIZATION");
|
||||||
|
}
|
||||||
|
Channel::Beta => {
|
||||||
|
println!("cargo:rustc-cfg=RUSTC_WITHOUT_SPECIALIZATION");
|
||||||
|
}
|
||||||
|
Channel::Nightly => {
|
||||||
|
println!("cargo:rustc-cfg=RUSTC_WITH_SPECIALIZATION");
|
||||||
|
}
|
||||||
|
Channel::Dev => {
|
||||||
|
println!("cargo:rustc-cfg=RUSTC_WITH_SPECIALIZATION");
|
||||||
|
// See https://github.com/solana-labs/solana/issues/11055
|
||||||
|
// We may be running the custom `rust-bpf-builder` toolchain,
|
||||||
|
// which currently needs `#![feature(proc_macro_hygiene)]` to
|
||||||
|
// be applied.
|
||||||
|
println!("cargo:rustc-cfg=RUSTC_NEEDS_PROC_MACRO_HYGIENE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum RentState {
|
pub enum RentState {
|
||||||
/// account.lamports == 0
|
/// account.lamports == 0
|
||||||
Uninitialized,
|
Uninitialized,
|
||||||
/// 0 < account.lamports < rent-exempt-minimum
|
/// 0 < account.lamports < rent-exempt-minimum
|
||||||
|
@ -23,7 +23,7 @@ pub(crate) enum RentState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RentState {
|
impl RentState {
|
||||||
pub(crate) fn from_account(account: &AccountSharedData, rent: &Rent) -> Self {
|
pub fn from_account(account: &AccountSharedData, rent: &Rent) -> Self {
|
||||||
if account.lamports() == 0 {
|
if account.lamports() == 0 {
|
||||||
Self::Uninitialized
|
Self::Uninitialized
|
||||||
} else if rent.is_exempt(account.lamports(), account.data().len()) {
|
} else if rent.is_exempt(account.lamports(), account.data().len()) {
|
||||||
|
@ -36,7 +36,7 @@ impl RentState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn transition_allowed_from(&self, pre_rent_state: &RentState) -> bool {
|
pub fn transition_allowed_from(&self, pre_rent_state: &RentState) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Uninitialized | Self::RentExempt => true,
|
Self::Uninitialized | Self::RentExempt => true,
|
||||||
Self::RentPaying {
|
Self::RentPaying {
|
||||||
|
@ -73,7 +73,7 @@ pub(crate) fn submit_rent_state_metrics(pre_rent_state: &RentState, post_rent_st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn check_rent_state(
|
pub fn check_rent_state(
|
||||||
pre_rent_state: Option<&RentState>,
|
pre_rent_state: Option<&RentState>,
|
||||||
post_rent_state: Option<&RentState>,
|
post_rent_state: Option<&RentState>,
|
||||||
transaction_context: &TransactionContext,
|
transaction_context: &TransactionContext,
|
|
@ -12,10 +12,10 @@ pub mod meta;
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AccountStorageReference {
|
pub struct AccountStorageReference {
|
||||||
/// the single storage for a given slot
|
/// the single storage for a given slot
|
||||||
pub(crate) storage: Arc<AccountStorageEntry>,
|
pub storage: Arc<AccountStorageEntry>,
|
||||||
/// id can be read from 'storage', but it is an atomic read.
|
/// id can be read from 'storage', but it is an atomic read.
|
||||||
/// id will never change while a storage is held, so we store it separately here for faster runtime lookup in 'get_account_storage_entry'
|
/// id will never change while a storage is held, so we store it separately here for faster runtime lookup in 'get_account_storage_entry'
|
||||||
pub(crate) id: AppendVecId,
|
pub id: AppendVecId,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type AccountStorageMap = DashMap<Slot, AccountStorageReference>;
|
pub type AccountStorageMap = DashMap<Slot, AccountStorageReference>;
|
||||||
|
@ -74,7 +74,7 @@ impl AccountStorage {
|
||||||
|
|
||||||
/// return the append vec for 'slot' if it exists
|
/// return the append vec for 'slot' if it exists
|
||||||
/// This is only ever called when shrink is not possibly running and there is a max of 1 append vec per slot.
|
/// This is only ever called when shrink is not possibly running and there is a max of 1 append vec per slot.
|
||||||
pub(crate) fn get_slot_storage_entry(&self, slot: Slot) -> Option<Arc<AccountStorageEntry>> {
|
pub fn get_slot_storage_entry(&self, slot: Slot) -> Option<Arc<AccountStorageEntry>> {
|
||||||
assert!(self.no_shrink_in_progress());
|
assert!(self.no_shrink_in_progress());
|
||||||
self.get_slot_storage_entry_shrinking_in_progress_ok(slot)
|
self.get_slot_storage_entry_shrinking_in_progress_ok(slot)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ impl AccountStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// initialize the storage map to 'all_storages'
|
/// initialize the storage map to 'all_storages'
|
||||||
pub(crate) fn initialize(&mut self, all_storages: AccountStorageMap) {
|
pub fn initialize(&mut self, all_storages: AccountStorageMap) {
|
||||||
assert!(self.map.is_empty());
|
assert!(self.map.is_empty());
|
||||||
assert!(self.no_shrink_in_progress());
|
assert!(self.no_shrink_in_progress());
|
||||||
self.map.extend(all_storages.into_iter())
|
self.map.extend(all_storages.into_iter())
|
||||||
|
@ -208,7 +208,7 @@ impl<'a> Iterator for AccountStorageIter<'a> {
|
||||||
/// exists while there is a shrink in progress
|
/// exists while there is a shrink in progress
|
||||||
/// keeps track of the 'new_store' being created and the 'old_store' being replaced.
|
/// keeps track of the 'new_store' being created and the 'old_store' being replaced.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ShrinkInProgress<'a> {
|
pub struct ShrinkInProgress<'a> {
|
||||||
storage: &'a AccountStorage,
|
storage: &'a AccountStorage,
|
||||||
/// old store which will be shrunk and replaced
|
/// old store which will be shrunk and replaced
|
||||||
old_store: Arc<AccountStorageEntry>,
|
old_store: Arc<AccountStorageEntry>,
|
||||||
|
@ -244,7 +244,7 @@ impl<'a> Drop for ShrinkInProgress<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ShrinkInProgress<'a> {
|
impl<'a> ShrinkInProgress<'a> {
|
||||||
pub(crate) fn new_storage(&self) -> &Arc<AccountStorageEntry> {
|
pub fn new_storage(&self) -> &Arc<AccountStorageEntry> {
|
||||||
&self.new_store
|
&self.new_store
|
||||||
}
|
}
|
||||||
pub(crate) fn old_storage(&self) -> &Arc<AccountStorageEntry> {
|
pub(crate) fn old_storage(&self) -> &Arc<AccountStorageEntry> {
|
|
@ -84,7 +84,7 @@ pub struct AccountLocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub(crate) enum RewardInterval {
|
pub enum RewardInterval {
|
||||||
/// the slot within the epoch is INSIDE the reward distribution interval
|
/// the slot within the epoch is INSIDE the reward distribution interval
|
||||||
InsideInterval,
|
InsideInterval,
|
||||||
/// the slot within the epoch is OUTSIDE the reward distribution interval
|
/// the slot within the epoch is OUTSIDE the reward distribution interval
|
||||||
|
@ -216,11 +216,11 @@ impl Accounts {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_empty(accounts_db: AccountsDb) -> Self {
|
pub fn new_empty(accounts_db: AccountsDb) -> Self {
|
||||||
Self::new(Arc::new(accounts_db))
|
Self::new(Arc::new(accounts_db))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(accounts_db: Arc<AccountsDb>) -> Self {
|
pub fn new(accounts_db: Arc<AccountsDb>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
accounts_db,
|
accounts_db,
|
||||||
account_locks: Mutex::new(AccountLocks::default()),
|
account_locks: Mutex::new(AccountLocks::default()),
|
||||||
|
@ -694,7 +694,7 @@ impl Accounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn load_accounts(
|
pub fn load_accounts(
|
||||||
&self,
|
&self,
|
||||||
ancestors: &Ancestors,
|
ancestors: &Ancestors,
|
||||||
txs: &[SanitizedTransaction],
|
txs: &[SanitizedTransaction],
|
||||||
|
@ -1306,7 +1306,7 @@ impl Accounts {
|
||||||
/// Store the accounts into the DB
|
/// Store the accounts into the DB
|
||||||
// allow(clippy) needed for various gating flags
|
// allow(clippy) needed for various gating flags
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn store_cached(
|
pub fn store_cached(
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
txs: &[SanitizedTransaction],
|
txs: &[SanitizedTransaction],
|
|
@ -28,12 +28,12 @@ use {
|
||||||
},
|
},
|
||||||
AccountStorage, AccountStorageStatus, ShrinkInProgress,
|
AccountStorage, AccountStorageStatus, ShrinkInProgress,
|
||||||
},
|
},
|
||||||
accounts_background_service::{DroppedSlotsSender, SendDroppedBankCallback},
|
|
||||||
accounts_cache::{AccountsCache, CachedAccount, SlotCache},
|
accounts_cache::{AccountsCache, CachedAccount, SlotCache},
|
||||||
accounts_file::{AccountsFile, AccountsFileError},
|
accounts_file::{AccountsFile, AccountsFileError},
|
||||||
accounts_hash::{
|
accounts_hash::{
|
||||||
AccountsDeltaHash, AccountsHash, AccountsHashEnum, AccountsHasher,
|
AccountsDeltaHash, AccountsHash, AccountsHashEnum, AccountsHasher,
|
||||||
CalcAccountsHashConfig, CalculateHashIntermediate, HashStats, IncrementalAccountsHash,
|
CalcAccountsHashConfig, CalculateHashIntermediate, HashStats, IncrementalAccountsHash,
|
||||||
|
SerdeAccountsDeltaHash, SerdeAccountsHash, SerdeIncrementalAccountsHash,
|
||||||
ZeroLamportAccounts,
|
ZeroLamportAccounts,
|
||||||
},
|
},
|
||||||
accounts_index::{
|
accounts_index::{
|
||||||
|
@ -62,8 +62,6 @@ use {
|
||||||
pubkey_bins::PubkeyBinCalculator24,
|
pubkey_bins::PubkeyBinCalculator24,
|
||||||
read_only_accounts_cache::ReadOnlyAccountsCache,
|
read_only_accounts_cache::ReadOnlyAccountsCache,
|
||||||
rent_collector::RentCollector,
|
rent_collector::RentCollector,
|
||||||
serde_snapshot::{SerdeAccountsDeltaHash, SerdeAccountsHash, SerdeIncrementalAccountsHash},
|
|
||||||
snapshot_utils::create_accounts_run_and_snapshot_dirs,
|
|
||||||
sorted_storages::SortedStorages,
|
sorted_storages::SortedStorages,
|
||||||
storable_accounts::StorableAccounts,
|
storable_accounts::StorableAccounts,
|
||||||
verify_accounts_hash_in_background::VerifyAccountsHashInBackground,
|
verify_accounts_hash_in_background::VerifyAccountsHashInBackground,
|
||||||
|
@ -394,7 +392,7 @@ enum LoadZeroLamports {
|
||||||
/// Note that this is non-deterministic if clean is running asynchronously.
|
/// Note that this is non-deterministic if clean is running asynchronously.
|
||||||
/// If a zero lamport account exists in the index, then Some is returned.
|
/// If a zero lamport account exists in the index, then Some is returned.
|
||||||
/// Once it is cleaned from the index, None is returned.
|
/// Once it is cleaned from the index, None is returned.
|
||||||
#[cfg(test)]
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
SomeWithZeroLamportAccountForTests,
|
SomeWithZeroLamportAccountForTests,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,7 +1019,7 @@ pub struct AccountStorageEntry {
|
||||||
pub(crate) slot: AtomicU64,
|
pub(crate) slot: AtomicU64,
|
||||||
|
|
||||||
/// storage holding the accounts
|
/// storage holding the accounts
|
||||||
pub(crate) accounts: AccountsFile,
|
pub accounts: AccountsFile,
|
||||||
|
|
||||||
/// Keeps track of the number of accounts stored in a specific AppendVec.
|
/// Keeps track of the number of accounts stored in a specific AppendVec.
|
||||||
/// This is periodically checked to reuse the stores that do not have
|
/// This is periodically checked to reuse the stores that do not have
|
||||||
|
@ -1057,7 +1055,7 @@ impl AccountStorageEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_existing(
|
pub fn new_existing(
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
id: AppendVecId,
|
id: AppendVecId,
|
||||||
accounts: AccountsFile,
|
accounts: AccountsFile,
|
||||||
|
@ -1211,6 +1209,76 @@ impl AccountStorageEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// To allow generating a bank snapshot directory with full state information, we need to
|
||||||
|
/// hardlink account appendvec files from the runtime operation directory to a snapshot
|
||||||
|
/// hardlink directory. This is to create the run/ and snapshot sub directories for an
|
||||||
|
/// account_path provided by the user. These two sub directories are on the same file
|
||||||
|
/// system partition to allow hard-linking.
|
||||||
|
pub fn create_accounts_run_and_snapshot_dirs(
|
||||||
|
account_dir: impl AsRef<Path>,
|
||||||
|
) -> std::io::Result<(PathBuf, PathBuf)> {
|
||||||
|
let run_path = account_dir.as_ref().join("run");
|
||||||
|
let snapshot_path = account_dir.as_ref().join("snapshot");
|
||||||
|
if (!run_path.is_dir()) || (!snapshot_path.is_dir()) {
|
||||||
|
// If the "run/" or "snapshot" sub directories do not exist, the directory may be from
|
||||||
|
// an older version for which the appendvec files are at this directory. Clean up
|
||||||
|
// them first.
|
||||||
|
// This will be done only once when transitioning from an old image without run directory
|
||||||
|
// to this new version using run and snapshot directories.
|
||||||
|
// The run/ content cleanup will be done at a later point. The snapshot/ content persists
|
||||||
|
// across the process boot, and will be purged by the account_background_service.
|
||||||
|
if fs_err::remove_dir_all(&account_dir).is_err() {
|
||||||
|
delete_contents_of_path(&account_dir);
|
||||||
|
}
|
||||||
|
fs_err::create_dir_all(&run_path)?;
|
||||||
|
fs_err::create_dir_all(&snapshot_path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((run_path, snapshot_path))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For all account_paths, create the run/ and snapshot/ sub directories.
|
||||||
|
/// If an account_path directory does not exist, create it.
|
||||||
|
/// It returns (account_run_paths, account_snapshot_paths) or error
|
||||||
|
pub fn create_all_accounts_run_and_snapshot_dirs(
|
||||||
|
account_paths: &[PathBuf],
|
||||||
|
) -> std::io::Result<(Vec<PathBuf>, Vec<PathBuf>)> {
|
||||||
|
let mut run_dirs = Vec::with_capacity(account_paths.len());
|
||||||
|
let mut snapshot_dirs = Vec::with_capacity(account_paths.len());
|
||||||
|
for account_path in account_paths {
|
||||||
|
// create the run/ and snapshot/ sub directories for each account_path
|
||||||
|
let (run_dir, snapshot_dir) = create_accounts_run_and_snapshot_dirs(account_path)?;
|
||||||
|
run_dirs.push(run_dir);
|
||||||
|
snapshot_dirs.push(snapshot_dir);
|
||||||
|
}
|
||||||
|
Ok((run_dirs, snapshot_dirs))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete the files and subdirectories in a directory.
|
||||||
|
/// This is useful if the process does not have permission
|
||||||
|
/// to delete the top level directory it might be able to
|
||||||
|
/// delete the contents of that directory.
|
||||||
|
pub fn delete_contents_of_path(path: impl AsRef<Path>) {
|
||||||
|
match fs_err::read_dir(path.as_ref()) {
|
||||||
|
Err(err) => {
|
||||||
|
warn!("Failed to delete contents: {err}")
|
||||||
|
}
|
||||||
|
Ok(dir_entries) => {
|
||||||
|
for entry in dir_entries.flatten() {
|
||||||
|
let sub_path = entry.path();
|
||||||
|
let result = if sub_path.is_dir() {
|
||||||
|
fs_err::remove_dir_all(&sub_path)
|
||||||
|
} else {
|
||||||
|
fs_err::remove_file(&sub_path)
|
||||||
|
};
|
||||||
|
if let Err(err) = result {
|
||||||
|
warn!("Failed to delete contents: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_temp_accounts_paths(count: u32) -> IoResult<(Vec<TempDir>, Vec<PathBuf>)> {
|
pub fn get_temp_accounts_paths(count: u32) -> IoResult<(Vec<TempDir>, Vec<PathBuf>)> {
|
||||||
let temp_dirs: IoResult<Vec<TempDir>> = (0..count).map(|_| TempDir::new()).collect();
|
let temp_dirs: IoResult<Vec<TempDir>> = (0..count).map(|_| TempDir::new()).collect();
|
||||||
let temp_dirs = temp_dirs?;
|
let temp_dirs = temp_dirs?;
|
||||||
|
@ -1371,7 +1439,7 @@ pub struct AccountsDb {
|
||||||
/// true iff we want to skip the initial hash calculation on startup
|
/// true iff we want to skip the initial hash calculation on startup
|
||||||
pub skip_initial_hash_calc: bool,
|
pub skip_initial_hash_calc: bool,
|
||||||
|
|
||||||
pub(crate) storage: AccountStorage,
|
pub storage: AccountStorage,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
/// from AccountsDbConfig
|
/// from AccountsDbConfig
|
||||||
|
@ -1392,10 +1460,10 @@ pub struct AccountsDb {
|
||||||
/// Set of shrinkable stores organized by map of slot to append_vec_id
|
/// Set of shrinkable stores organized by map of slot to append_vec_id
|
||||||
pub shrink_candidate_slots: Mutex<ShrinkCandidates>,
|
pub shrink_candidate_slots: Mutex<ShrinkCandidates>,
|
||||||
|
|
||||||
pub(crate) write_version: AtomicU64,
|
pub write_version: AtomicU64,
|
||||||
|
|
||||||
/// Set of storage paths to pick from
|
/// Set of storage paths to pick from
|
||||||
pub(crate) paths: Vec<PathBuf>,
|
pub paths: Vec<PathBuf>,
|
||||||
|
|
||||||
full_accounts_hash_cache_path: PathBuf,
|
full_accounts_hash_cache_path: PathBuf,
|
||||||
incremental_accounts_hash_cache_path: PathBuf,
|
incremental_accounts_hash_cache_path: PathBuf,
|
||||||
|
@ -1410,7 +1478,7 @@ pub struct AccountsDb {
|
||||||
|
|
||||||
/// Directory of paths this accounts_db needs to hold/remove
|
/// Directory of paths this accounts_db needs to hold/remove
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) temp_paths: Option<Vec<TempDir>>,
|
pub temp_paths: Option<Vec<TempDir>>,
|
||||||
|
|
||||||
/// Starting file size of appendvecs
|
/// Starting file size of appendvecs
|
||||||
file_size: u64,
|
file_size: u64,
|
||||||
|
@ -1433,7 +1501,7 @@ pub struct AccountsDb {
|
||||||
// Stats for purges called outside of clean_accounts()
|
// Stats for purges called outside of clean_accounts()
|
||||||
external_purge_slots_stats: PurgeStats,
|
external_purge_slots_stats: PurgeStats,
|
||||||
|
|
||||||
pub(crate) shrink_stats: ShrinkStats,
|
pub shrink_stats: ShrinkStats,
|
||||||
|
|
||||||
pub(crate) shrink_ancient_stats: ShrinkAncientStats,
|
pub(crate) shrink_ancient_stats: ShrinkAncientStats,
|
||||||
|
|
||||||
|
@ -1485,18 +1553,18 @@ pub struct AccountsDb {
|
||||||
/// number of slots remaining where filler accounts should be added
|
/// number of slots remaining where filler accounts should be added
|
||||||
pub filler_account_slots_remaining: AtomicU64,
|
pub filler_account_slots_remaining: AtomicU64,
|
||||||
|
|
||||||
pub(crate) verify_accounts_hash_in_bg: VerifyAccountsHashInBackground,
|
pub verify_accounts_hash_in_bg: VerifyAccountsHashInBackground,
|
||||||
|
|
||||||
/// Used to disable logging dead slots during removal.
|
/// Used to disable logging dead slots during removal.
|
||||||
/// allow disabling noisy log
|
/// allow disabling noisy log
|
||||||
pub(crate) log_dead_slots: AtomicBool,
|
pub log_dead_slots: AtomicBool,
|
||||||
|
|
||||||
/// debug feature to scan every append vec and verify refcounts are equal
|
/// debug feature to scan every append vec and verify refcounts are equal
|
||||||
exhaustively_verify_refcounts: bool,
|
exhaustively_verify_refcounts: bool,
|
||||||
|
|
||||||
/// this will live here until the feature for partitioned epoch rewards is activated.
|
/// this will live here until the feature for partitioned epoch rewards is activated.
|
||||||
/// At that point, this and other code can be deleted.
|
/// At that point, this and other code can be deleted.
|
||||||
pub(crate) partitioned_epoch_rewards_config: PartitionedEpochRewardsConfig,
|
pub partitioned_epoch_rewards_config: PartitionedEpochRewardsConfig,
|
||||||
|
|
||||||
/// the full accounts hash calculation as of a predetermined block height 'N'
|
/// the full accounts hash calculation as of a predetermined block height 'N'
|
||||||
/// to be included in the bank hash at a predetermined block height 'M'
|
/// to be included in the bank hash at a predetermined block height 'M'
|
||||||
|
@ -1534,7 +1602,7 @@ pub struct AccountsStats {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct PurgeStats {
|
pub struct PurgeStats {
|
||||||
last_report: AtomicInterval,
|
last_report: AtomicInterval,
|
||||||
safety_checks_elapsed: AtomicU64,
|
safety_checks_elapsed: AtomicU64,
|
||||||
remove_cache_elapsed: AtomicU64,
|
remove_cache_elapsed: AtomicU64,
|
||||||
|
@ -1949,7 +2017,7 @@ impl ShrinkStatsSub {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct ShrinkStats {
|
pub struct ShrinkStats {
|
||||||
last_report: AtomicInterval,
|
last_report: AtomicInterval,
|
||||||
num_slots_shrunk: AtomicUsize,
|
num_slots_shrunk: AtomicUsize,
|
||||||
storage_read_elapsed: AtomicU64,
|
storage_read_elapsed: AtomicU64,
|
||||||
|
@ -2233,7 +2301,7 @@ pub fn make_min_priority_thread_pool() -> ThreadPool {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(test, RUSTC_WITH_SPECIALIZATION))]
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
impl solana_frozen_abi::abi_example::AbiExample for AccountsDb {
|
impl solana_frozen_abi::abi_example::AbiExample for AccountsDb {
|
||||||
fn example() -> Self {
|
fn example() -> Self {
|
||||||
let accounts_db = AccountsDb::new_single_for_tests();
|
let accounts_db = AccountsDb::new_single_for_tests();
|
||||||
|
@ -2834,7 +2902,7 @@ impl AccountsDb {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn purge_keys_exact<'a, C: 'a>(
|
pub fn purge_keys_exact<'a, C: 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
pubkey_to_slot_set: impl Iterator<Item = &'a (Pubkey, C)>,
|
pubkey_to_slot_set: impl Iterator<Item = &'a (Pubkey, C)>,
|
||||||
) -> (Vec<(Slot, AccountInfo)>, PubkeysRemovedFromAccountsIndex)
|
) -> (Vec<(Slot, AccountInfo)>, PubkeysRemovedFromAccountsIndex)
|
||||||
|
@ -3805,7 +3873,7 @@ impl AccountsDb {
|
||||||
|
|
||||||
/// get all accounts in all the storages passed in
|
/// get all accounts in all the storages passed in
|
||||||
/// for duplicate pubkeys, the account with the highest write_value is returned
|
/// for duplicate pubkeys, the account with the highest write_value is returned
|
||||||
pub(crate) fn get_unique_accounts_from_storage<'a>(
|
pub fn get_unique_accounts_from_storage<'a>(
|
||||||
&self,
|
&self,
|
||||||
store: &'a Arc<AccountStorageEntry>,
|
store: &'a Arc<AccountStorageEntry>,
|
||||||
) -> GetUniqueAccountsResult<'a> {
|
) -> GetUniqueAccountsResult<'a> {
|
||||||
|
@ -4084,7 +4152,7 @@ impl AccountsDb {
|
||||||
/// Drop 'shrink_in_progress', which will cause the old store to be removed from the storage map.
|
/// Drop 'shrink_in_progress', which will cause the old store to be removed from the storage map.
|
||||||
/// For 'shrink_in_progress'.'old_storage' which is not retained, insert in 'dead_storages' and optionally 'dirty_stores'
|
/// For 'shrink_in_progress'.'old_storage' which is not retained, insert in 'dead_storages' and optionally 'dirty_stores'
|
||||||
/// This is the end of the life cycle of `shrink_in_progress`.
|
/// This is the end of the life cycle of `shrink_in_progress`.
|
||||||
pub(crate) fn mark_dirty_dead_stores(
|
pub fn mark_dirty_dead_stores(
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
add_dirty_stores: bool,
|
add_dirty_stores: bool,
|
||||||
|
@ -4112,7 +4180,7 @@ impl AccountsDb {
|
||||||
dead_storages
|
dead_storages
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn drop_or_recycle_stores(
|
pub fn drop_or_recycle_stores(
|
||||||
&self,
|
&self,
|
||||||
dead_storages: Vec<Arc<AccountStorageEntry>>,
|
dead_storages: Vec<Arc<AccountStorageEntry>>,
|
||||||
stats: &ShrinkStats,
|
stats: &ShrinkStats,
|
||||||
|
@ -4142,11 +4210,7 @@ impl AccountsDb {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return a store that can contain 'aligned_total' bytes
|
/// return a store that can contain 'aligned_total' bytes
|
||||||
pub(crate) fn get_store_for_shrink(
|
pub fn get_store_for_shrink(&self, slot: Slot, aligned_total: u64) -> ShrinkInProgress<'_> {
|
||||||
&self,
|
|
||||||
slot: Slot,
|
|
||||||
aligned_total: u64,
|
|
||||||
) -> ShrinkInProgress<'_> {
|
|
||||||
let shrunken_store = self
|
let shrunken_store = self
|
||||||
.try_recycle_store(slot, aligned_total, aligned_total + 1024)
|
.try_recycle_store(slot, aligned_total, aligned_total + 1024)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
|
@ -4316,20 +4380,6 @@ impl AccountsDb {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) fn sizes_of_accounts_in_storage_for_tests(&self, slot: Slot) -> Vec<usize> {
|
|
||||||
self.storage
|
|
||||||
.get_slot_storage_entry(slot)
|
|
||||||
.map(|storage| {
|
|
||||||
storage
|
|
||||||
.accounts
|
|
||||||
.account_iter()
|
|
||||||
.map(|account| account.stored_size())
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 'accounts' that exist in the current slot we are combining into a different ancient slot
|
/// 'accounts' that exist in the current slot we are combining into a different ancient slot
|
||||||
/// 'existing_ancient_pubkeys': pubkeys that exist currently in the ancient append vec slot
|
/// 'existing_ancient_pubkeys': pubkeys that exist currently in the ancient append vec slot
|
||||||
/// returns the pubkeys that are in 'accounts' that are already in 'existing_ancient_pubkeys'
|
/// returns the pubkeys that are in 'accounts' that are already in 'existing_ancient_pubkeys'
|
||||||
|
@ -4964,7 +5014,7 @@ impl AccountsDb {
|
||||||
/// Insert a default bank hash stats for `slot`
|
/// Insert a default bank hash stats for `slot`
|
||||||
///
|
///
|
||||||
/// This fn is called when creating a new bank from parent.
|
/// This fn is called when creating a new bank from parent.
|
||||||
pub(crate) fn insert_default_bank_hash_stats(&self, slot: Slot, parent_slot: Slot) {
|
pub fn insert_default_bank_hash_stats(&self, slot: Slot, parent_slot: Slot) {
|
||||||
let mut bank_hash_stats = self.bank_hash_stats.lock().unwrap();
|
let mut bank_hash_stats = self.bank_hash_stats.lock().unwrap();
|
||||||
if bank_hash_stats.get(&slot).is_some() {
|
if bank_hash_stats.get(&slot).is_some() {
|
||||||
error!("set_hash: already exists; multiple forks with shared slot {slot} as child (parent: {parent_slot})!?");
|
error!("set_hash: already exists; multiple forks with shared slot {slot} as child (parent: {parent_slot})!?");
|
||||||
|
@ -5613,7 +5663,7 @@ impl AccountsDb {
|
||||||
store
|
store
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn page_align(size: u64) -> u64 {
|
pub fn page_align(size: u64) -> u64 {
|
||||||
(size + (PAGE_SIZE - 1)) & !(PAGE_SIZE - 1)
|
(size + (PAGE_SIZE - 1)) & !(PAGE_SIZE - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5684,13 +5734,9 @@ impl AccountsDb {
|
||||||
self.storage.insert(slot, store)
|
self.storage.insert(slot, store)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_drop_bank_callback(
|
pub fn enable_bank_drop_callback(&self) {
|
||||||
&self,
|
|
||||||
pruned_banks_sender: DroppedSlotsSender,
|
|
||||||
) -> SendDroppedBankCallback {
|
|
||||||
self.is_bank_drop_callback_enabled
|
self.is_bank_drop_callback_enabled
|
||||||
.store(true, Ordering::Release);
|
.store(true, Ordering::Release);
|
||||||
SendDroppedBankCallback::new(pruned_banks_sender)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This should only be called after the `Bank::drop()` runs in bank.rs, See BANK_DROP_SAFETY
|
/// This should only be called after the `Bank::drop()` runs in bank.rs, See BANK_DROP_SAFETY
|
||||||
|
@ -5748,7 +5794,7 @@ impl AccountsDb {
|
||||||
|
|
||||||
/// Purges every slot in `removed_slots` from both the cache and storage. This includes
|
/// Purges every slot in `removed_slots` from both the cache and storage. This includes
|
||||||
/// entries in the accounts index, cache entries, and any backing storage entries.
|
/// entries in the accounts index, cache entries, and any backing storage entries.
|
||||||
pub(crate) fn purge_slots_from_cache_and_store<'a>(
|
pub fn purge_slots_from_cache_and_store<'a>(
|
||||||
&self,
|
&self,
|
||||||
removed_slots: impl Iterator<Item = &'a Slot> + Clone,
|
removed_slots: impl Iterator<Item = &'a Slot> + Clone,
|
||||||
purge_stats: &PurgeStats,
|
purge_stats: &PurgeStats,
|
||||||
|
@ -6248,8 +6294,9 @@ impl AccountsDb {
|
||||||
.fetch_add(recycle_stores_write_elapsed.as_us(), Ordering::Relaxed);
|
.fetch_add(recycle_stores_write_elapsed.as_us(), Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
pub(crate) fn flush_accounts_cache_slot_for_tests(&self, slot: Slot) {
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
pub fn flush_accounts_cache_slot_for_tests(&self, slot: Slot) {
|
||||||
self.flush_slot_cache(slot);
|
self.flush_slot_cache(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6567,7 +6614,7 @@ impl AccountsDb {
|
||||||
/// However, there is a clear path to be able to support this.
|
/// However, there is a clear path to be able to support this.
|
||||||
/// So, combine all accounts from 'slot_stores' into a new storage and return it.
|
/// So, combine all accounts from 'slot_stores' into a new storage and return it.
|
||||||
/// This runs prior to the storages being put in AccountsDb.storage
|
/// This runs prior to the storages being put in AccountsDb.storage
|
||||||
pub(crate) fn combine_multiple_slots_into_one_at_startup(
|
pub fn combine_multiple_slots_into_one_at_startup(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
id: AppendVecId,
|
id: AppendVecId,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
|
@ -7262,7 +7309,7 @@ impl AccountsDb {
|
||||||
stats.num_dirty_slots = num_dirty_slots;
|
stats.num_dirty_slots = num_dirty_slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn calculate_accounts_hash(
|
pub fn calculate_accounts_hash(
|
||||||
&self,
|
&self,
|
||||||
data_source: CalcAccountsHashDataSource,
|
data_source: CalcAccountsHashDataSource,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
|
@ -7781,10 +7828,7 @@ impl AccountsDb {
|
||||||
/// 1. pubkey, hash pairs for the slot
|
/// 1. pubkey, hash pairs for the slot
|
||||||
/// 2. us spent scanning
|
/// 2. us spent scanning
|
||||||
/// 3. Measure started when we began accumulating
|
/// 3. Measure started when we began accumulating
|
||||||
pub(crate) fn get_pubkey_hash_for_slot(
|
pub fn get_pubkey_hash_for_slot(&self, slot: Slot) -> (Vec<(Pubkey, Hash)>, u64, Measure) {
|
||||||
&self,
|
|
||||||
slot: Slot,
|
|
||||||
) -> (Vec<(Pubkey, Hash)>, u64, Measure) {
|
|
||||||
let mut scan = Measure::start("scan");
|
let mut scan = Measure::start("scan");
|
||||||
|
|
||||||
let scan_result: ScanStorageResult<(Pubkey, Hash), DashMap<Pubkey, Hash>> = self
|
let scan_result: ScanStorageResult<(Pubkey, Hash), DashMap<Pubkey, Hash>> = self
|
||||||
|
@ -7821,7 +7865,7 @@ impl AccountsDb {
|
||||||
///
|
///
|
||||||
/// As part of calculating the accounts delta hash, get a list of accounts modified this slot
|
/// As part of calculating the accounts delta hash, get a list of accounts modified this slot
|
||||||
/// (aka dirty pubkeys) and add them to `self.uncleaned_pubkeys` for future cleaning.
|
/// (aka dirty pubkeys) and add them to `self.uncleaned_pubkeys` for future cleaning.
|
||||||
pub(crate) fn calculate_accounts_delta_hash_internal(
|
pub fn calculate_accounts_delta_hash_internal(
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
ignore: Option<Pubkey>,
|
ignore: Option<Pubkey>,
|
||||||
|
@ -8569,7 +8613,7 @@ impl AccountsDb {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn store_accounts_frozen<'a, T: ReadableAccount + Sync + ZeroLamport + 'a>(
|
pub fn store_accounts_frozen<'a, T: ReadableAccount + Sync + ZeroLamport + 'a>(
|
||||||
&self,
|
&self,
|
||||||
accounts: impl StorableAccounts<'a, T>,
|
accounts: impl StorableAccounts<'a, T>,
|
||||||
hashes: Option<Vec<impl Borrow<Hash>>>,
|
hashes: Option<Vec<impl Borrow<Hash>>>,
|
||||||
|
@ -9381,7 +9425,7 @@ impl AccountsDb {
|
||||||
timings.storage_size_storages_us = storage_size_storages_time.as_us();
|
timings.storage_size_storages_us = storage_size_storages_time.as_us();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn print_accounts_stats(&self, label: &str) {
|
pub fn print_accounts_stats(&self, label: &str) {
|
||||||
self.print_index(label);
|
self.print_index(label);
|
||||||
self.print_count_and_status(label);
|
self.print_count_and_status(label);
|
||||||
info!("recycle_stores:");
|
info!("recycle_stores:");
|
||||||
|
@ -9474,10 +9518,6 @@ pub(crate) enum UpdateIndexThreadSelection {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl AccountsDb {
|
impl AccountsDb {
|
||||||
pub fn new(paths: Vec<PathBuf>, cluster_type: &ClusterType) -> Self {
|
|
||||||
Self::new_for_tests(paths, cluster_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_with_config_for_tests(
|
pub fn new_with_config_for_tests(
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
cluster_type: &ClusterType,
|
cluster_type: &ClusterType,
|
||||||
|
@ -9521,24 +9561,30 @@ impl AccountsDb {
|
||||||
let result = self.accounts_index.get(pubkey, Some(&ancestors), None);
|
let result = self.accounts_index.get(pubkey, Some(&ancestors), None);
|
||||||
result.map(|(list, index)| list.slot_list()[index].1.store_id())
|
result.map(|(list, index)| list.slot_list()[index].1.store_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alive_account_count_in_slot(&self, slot: Slot) -> usize {
|
|
||||||
self.storage
|
|
||||||
.get_slot_storage_entry(slot)
|
|
||||||
.map(|storage| storage.count())
|
|
||||||
.unwrap_or(0)
|
|
||||||
.saturating_add(
|
|
||||||
self.accounts_cache
|
|
||||||
.slot_cache(slot)
|
|
||||||
.map(|slot_cache| slot_cache.len())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
#[cfg(feature = "dev-context-only-utils")]
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
impl AccountsDb {
|
impl AccountsDb {
|
||||||
|
pub fn new(paths: Vec<PathBuf>, cluster_type: &ClusterType) -> Self {
|
||||||
|
Self::new_for_tests(paths, cluster_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_without_fixed_root(
|
||||||
|
&self,
|
||||||
|
ancestors: &Ancestors,
|
||||||
|
pubkey: &Pubkey,
|
||||||
|
) -> Option<(AccountSharedData, Slot)> {
|
||||||
|
self.do_load(
|
||||||
|
ancestors,
|
||||||
|
pubkey,
|
||||||
|
None,
|
||||||
|
LoadHint::Unspecified,
|
||||||
|
// callers of this expect zero lamport accounts that exist in the index to be returned as Some(empty)
|
||||||
|
LoadZeroLamports::SomeWithZeroLamportAccountForTests,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn accounts_delta_hashes(&self) -> &Mutex<HashMap<Slot, AccountsDeltaHash>> {
|
pub fn accounts_delta_hashes(&self) -> &Mutex<HashMap<Slot, AccountsDeltaHash>> {
|
||||||
&self.accounts_delta_hashes
|
&self.accounts_delta_hashes
|
||||||
}
|
}
|
||||||
|
@ -9558,6 +9604,182 @@ impl AccountsDb {
|
||||||
pub fn set_accounts_hash_for_tests(&self, slot: Slot, accounts_hash: AccountsHash) {
|
pub fn set_accounts_hash_for_tests(&self, slot: Slot, accounts_hash: AccountsHash) {
|
||||||
self.set_accounts_hash(slot, (accounts_hash, u64::default()));
|
self.set_accounts_hash(slot, (accounts_hash, u64::default()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assert_load_account(&self, slot: Slot, pubkey: Pubkey, expected_lamports: u64) {
|
||||||
|
let ancestors = vec![(slot, 0)].into_iter().collect();
|
||||||
|
let (account, slot) = self.load_without_fixed_root(&ancestors, &pubkey).unwrap();
|
||||||
|
assert_eq!((account.lamports(), slot), (expected_lamports, slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assert_not_load_account(&self, slot: Slot, pubkey: Pubkey) {
|
||||||
|
let ancestors = vec![(slot, 0)].into_iter().collect();
|
||||||
|
let load = self.load_without_fixed_root(&ancestors, &pubkey);
|
||||||
|
assert!(load.is_none(), "{load:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_accounts(&self, pubkeys: &[Pubkey], slot: Slot, num: usize, count: usize) {
|
||||||
|
let ancestors = vec![(slot, 0)].into_iter().collect();
|
||||||
|
for _ in 0..num {
|
||||||
|
let idx = thread_rng().gen_range(0, num);
|
||||||
|
let account = self.load_without_fixed_root(&ancestors, &pubkeys[idx]);
|
||||||
|
let account1 = Some((
|
||||||
|
AccountSharedData::new(
|
||||||
|
(idx + count) as u64,
|
||||||
|
0,
|
||||||
|
AccountSharedData::default().owner(),
|
||||||
|
),
|
||||||
|
slot,
|
||||||
|
));
|
||||||
|
assert_eq!(account, account1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// callers used to call store_uncached. But, this is not allowed anymore.
|
||||||
|
pub fn store_for_tests(&self, slot: Slot, accounts: &[(&Pubkey, &AccountSharedData)]) {
|
||||||
|
self.store(
|
||||||
|
(slot, accounts, INCLUDE_SLOT_IN_HASH_TESTS),
|
||||||
|
&StoreTo::Cache,
|
||||||
|
None,
|
||||||
|
StoreReclaims::Default,
|
||||||
|
UpdateIndexThreadSelection::PoolWithThreshold,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
|
pub fn modify_accounts(&self, pubkeys: &[Pubkey], slot: Slot, num: usize, count: usize) {
|
||||||
|
for idx in 0..num {
|
||||||
|
let account = AccountSharedData::new(
|
||||||
|
(idx + count) as u64,
|
||||||
|
0,
|
||||||
|
AccountSharedData::default().owner(),
|
||||||
|
);
|
||||||
|
self.store_for_tests(slot, &[(&pubkeys[idx], &account)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_storage(&self, slot: Slot, count: usize) {
|
||||||
|
assert!(self.storage.get_slot_storage_entry(slot).is_some());
|
||||||
|
let store = self.storage.get_slot_storage_entry(slot).unwrap();
|
||||||
|
let total_count = store.count();
|
||||||
|
assert_eq!(store.status(), AccountStorageStatus::Available);
|
||||||
|
assert_eq!(total_count, count);
|
||||||
|
let (expected_store_count, actual_store_count): (usize, usize) =
|
||||||
|
(store.approx_stored_count(), store.all_accounts().len());
|
||||||
|
assert_eq!(expected_store_count, actual_store_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_account(
|
||||||
|
&self,
|
||||||
|
pubkeys: &mut Vec<Pubkey>,
|
||||||
|
slot: Slot,
|
||||||
|
num: usize,
|
||||||
|
space: usize,
|
||||||
|
num_vote: usize,
|
||||||
|
) {
|
||||||
|
let ancestors = vec![(slot, 0)].into_iter().collect();
|
||||||
|
for t in 0..num {
|
||||||
|
let pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
let account =
|
||||||
|
AccountSharedData::new((t + 1) as u64, space, AccountSharedData::default().owner());
|
||||||
|
pubkeys.push(pubkey);
|
||||||
|
assert!(self.load_without_fixed_root(&ancestors, &pubkey).is_none());
|
||||||
|
self.store_for_tests(slot, &[(&pubkey, &account)]);
|
||||||
|
}
|
||||||
|
for t in 0..num_vote {
|
||||||
|
let pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
let account =
|
||||||
|
AccountSharedData::new((num + t + 1) as u64, space, &solana_vote_program::id());
|
||||||
|
pubkeys.push(pubkey);
|
||||||
|
let ancestors = vec![(slot, 0)].into_iter().collect();
|
||||||
|
assert!(self.load_without_fixed_root(&ancestors, &pubkey).is_none());
|
||||||
|
self.store_for_tests(slot, &[(&pubkey, &account)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sizes_of_accounts_in_storage_for_tests(&self, slot: Slot) -> Vec<usize> {
|
||||||
|
self.storage
|
||||||
|
.get_slot_storage_entry(slot)
|
||||||
|
.map(|storage| {
|
||||||
|
storage
|
||||||
|
.accounts
|
||||||
|
.account_iter()
|
||||||
|
.map(|account| account.stored_size())
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ref_count_for_pubkey(&self, pubkey: &Pubkey) -> RefCount {
|
||||||
|
self.accounts_index.ref_count_from_storage(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alive_account_count_in_slot(&self, slot: Slot) -> usize {
|
||||||
|
self.storage
|
||||||
|
.get_slot_storage_entry(slot)
|
||||||
|
.map(|storage| storage.count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.saturating_add(
|
||||||
|
self.accounts_cache
|
||||||
|
.slot_cache(slot)
|
||||||
|
.map(|slot_cache| slot_cache.len())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// useful to adapt tests written prior to introduction of the write cache
|
||||||
|
/// to use the write cache
|
||||||
|
pub fn add_root_and_flush_write_cache(&self, slot: Slot) {
|
||||||
|
self.add_root(slot);
|
||||||
|
self.flush_root_write_cache(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// useful to adapt tests written prior to introduction of the write cache
|
||||||
|
/// to use the write cache
|
||||||
|
pub fn flush_root_write_cache(&self, root: Slot) {
|
||||||
|
assert!(
|
||||||
|
self.accounts_index
|
||||||
|
.roots_tracker
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.alive_roots
|
||||||
|
.contains(&root),
|
||||||
|
"slot: {root}"
|
||||||
|
);
|
||||||
|
self.flush_accounts_cache(true, Some(root));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_account_count_in_append_vec(&self, slot: Slot) -> usize {
|
||||||
|
let store = self.storage.get_slot_storage_entry(slot);
|
||||||
|
if let Some(store) = store {
|
||||||
|
let count = store.all_accounts().len();
|
||||||
|
let stored_count = store.approx_stored_count();
|
||||||
|
assert_eq!(stored_count, count);
|
||||||
|
count
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
impl<'a> VerifyAccountsHashAndLamportsConfig<'a> {
|
||||||
|
pub fn new_for_test(
|
||||||
|
ancestors: &'a Ancestors,
|
||||||
|
epoch_schedule: &'a EpochSchedule,
|
||||||
|
rent_collector: &'a RentCollector,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
ancestors,
|
||||||
|
test_hash_calculation: true,
|
||||||
|
epoch_schedule,
|
||||||
|
rent_collector,
|
||||||
|
ignore_mismatch: false,
|
||||||
|
store_detailed_debug_info: false,
|
||||||
|
use_bg_thread_pool: false,
|
||||||
|
include_slot_in_hash: INCLUDE_SLOT_IN_HASH_TESTS,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of utility functions used for testing and benchmarking
|
/// A set of utility functions used for testing and benchmarking
|
||||||
|
@ -9649,7 +9871,7 @@ pub mod tests {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn linear_ancestors(end_slot: u64) -> Ancestors {
|
fn linear_ancestors(end_slot: u64) -> Ancestors {
|
||||||
let mut ancestors: Ancestors = vec![(0, 0)].into_iter().collect();
|
let mut ancestors: Ancestors = vec![(0, 0)].into_iter().collect();
|
||||||
for i in 1..end_slot {
|
for i in 1..end_slot {
|
||||||
ancestors.insert(i, (i - 1) as usize);
|
ancestors.insert(i, (i - 1) as usize);
|
||||||
|
@ -9688,21 +9910,6 @@ pub mod tests {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_without_fixed_root(
|
|
||||||
&self,
|
|
||||||
ancestors: &Ancestors,
|
|
||||||
pubkey: &Pubkey,
|
|
||||||
) -> Option<(AccountSharedData, Slot)> {
|
|
||||||
self.do_load(
|
|
||||||
ancestors,
|
|
||||||
pubkey,
|
|
||||||
None,
|
|
||||||
LoadHint::Unspecified,
|
|
||||||
// callers of this expect zero lamport accounts that exist in the index to be returned as Some(empty)
|
|
||||||
LoadZeroLamports::SomeWithZeroLamportAccountForTests,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_storage_for_slot(&self, slot: Slot) -> Option<Arc<AccountStorageEntry>> {
|
fn get_storage_for_slot(&self, slot: Slot) -> Option<Arc<AccountStorageEntry>> {
|
||||||
self.storage.get_slot_storage_entry(slot)
|
self.storage.get_slot_storage_entry(slot)
|
||||||
}
|
}
|
||||||
|
@ -9776,25 +9983,6 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VerifyAccountsHashAndLamportsConfig<'a> {
|
|
||||||
pub fn new_for_test(
|
|
||||||
ancestors: &'a Ancestors,
|
|
||||||
epoch_schedule: &'a EpochSchedule,
|
|
||||||
rent_collector: &'a RentCollector,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
ancestors,
|
|
||||||
test_hash_calculation: true,
|
|
||||||
epoch_schedule,
|
|
||||||
rent_collector,
|
|
||||||
ignore_mismatch: false,
|
|
||||||
store_detailed_debug_info: false,
|
|
||||||
use_bg_thread_pool: false,
|
|
||||||
include_slot_in_hash: INCLUDE_SLOT_IN_HASH_TESTS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_maybe_unref_accounts_already_in_ancient() {
|
fn test_maybe_unref_accounts_already_in_ancient() {
|
||||||
let db = AccountsDb::new_single_for_tests();
|
let db = AccountsDb::new_single_for_tests();
|
||||||
|
@ -11151,7 +11339,7 @@ pub mod tests {
|
||||||
let db = AccountsDb::new(Vec::new(), &ClusterType::Development);
|
let db = AccountsDb::new(Vec::new(), &ClusterType::Development);
|
||||||
|
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_account(&db, &mut pubkeys, 0, 100, 0, 0);
|
db.create_account(&mut pubkeys, 0, 100, 0, 0);
|
||||||
for _ in 1..100 {
|
for _ in 1..100 {
|
||||||
let idx = thread_rng().gen_range(0, 99);
|
let idx = thread_rng().gen_range(0, 99);
|
||||||
let ancestors = vec![(0, 0)].into_iter().collect();
|
let ancestors = vec![(0, 0)].into_iter().collect();
|
||||||
|
@ -11193,9 +11381,9 @@ pub mod tests {
|
||||||
let db = AccountsDb::new_single_for_tests();
|
let db = AccountsDb::new_single_for_tests();
|
||||||
|
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_account(&db, &mut pubkeys, 0, 2, DEFAULT_FILE_SIZE as usize / 3, 0);
|
db.create_account(&mut pubkeys, 0, 2, DEFAULT_FILE_SIZE as usize / 3, 0);
|
||||||
db.add_root_and_flush_write_cache(0);
|
db.add_root_and_flush_write_cache(0);
|
||||||
check_storage(&db, 0, 2);
|
db.check_storage(0, 2);
|
||||||
|
|
||||||
let pubkey = solana_sdk::pubkey::new_rand();
|
let pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let account = AccountSharedData::new(1, DEFAULT_FILE_SIZE as usize / 3, &pubkey);
|
let account = AccountSharedData::new(1, DEFAULT_FILE_SIZE as usize / 3, &pubkey);
|
||||||
|
@ -11272,7 +11460,7 @@ pub mod tests {
|
||||||
.accounts_index
|
.accounts_index
|
||||||
.get(&key, Some(&ancestors), None)
|
.get(&key, Some(&ancestors), None)
|
||||||
.is_some());
|
.is_some());
|
||||||
assert_load_account(&db, unrooted_slot, key, 1);
|
db.assert_load_account(unrooted_slot, key, 1);
|
||||||
|
|
||||||
// Purge the slot
|
// Purge the slot
|
||||||
db.remove_unrooted_slots(&[(unrooted_slot, unrooted_bank_id)]);
|
db.remove_unrooted_slots(&[(unrooted_slot, unrooted_bank_id)]);
|
||||||
|
@ -11289,7 +11477,7 @@ pub mod tests {
|
||||||
// Test we can store for the same slot again and get the right information
|
// Test we can store for the same slot again and get the right information
|
||||||
let account0 = AccountSharedData::new(2, 0, &key);
|
let account0 = AccountSharedData::new(2, 0, &key);
|
||||||
db.store_for_tests(unrooted_slot, &[(&key, &account0)]);
|
db.store_for_tests(unrooted_slot, &[(&key, &account0)]);
|
||||||
assert_load_account(&db, unrooted_slot, key, 2);
|
db.assert_load_account(unrooted_slot, key, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -11302,38 +11490,6 @@ pub mod tests {
|
||||||
run_test_remove_unrooted_slot(false);
|
run_test_remove_unrooted_slot(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_account(
|
|
||||||
accounts: &AccountsDb,
|
|
||||||
pubkeys: &mut Vec<Pubkey>,
|
|
||||||
slot: Slot,
|
|
||||||
num: usize,
|
|
||||||
space: usize,
|
|
||||||
num_vote: usize,
|
|
||||||
) {
|
|
||||||
let ancestors = vec![(slot, 0)].into_iter().collect();
|
|
||||||
for t in 0..num {
|
|
||||||
let pubkey = solana_sdk::pubkey::new_rand();
|
|
||||||
let account =
|
|
||||||
AccountSharedData::new((t + 1) as u64, space, AccountSharedData::default().owner());
|
|
||||||
pubkeys.push(pubkey);
|
|
||||||
assert!(accounts
|
|
||||||
.load_without_fixed_root(&ancestors, &pubkey)
|
|
||||||
.is_none());
|
|
||||||
accounts.store_for_tests(slot, &[(&pubkey, &account)]);
|
|
||||||
}
|
|
||||||
for t in 0..num_vote {
|
|
||||||
let pubkey = solana_sdk::pubkey::new_rand();
|
|
||||||
let account =
|
|
||||||
AccountSharedData::new((num + t + 1) as u64, space, &solana_vote_program::id());
|
|
||||||
pubkeys.push(pubkey);
|
|
||||||
let ancestors = vec![(slot, 0)].into_iter().collect();
|
|
||||||
assert!(accounts
|
|
||||||
.load_without_fixed_root(&ancestors, &pubkey)
|
|
||||||
.is_none());
|
|
||||||
accounts.store_for_tests(slot, &[(&pubkey, &account)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_accounts(accounts: &AccountsDb, pubkeys: &[Pubkey], slot: Slot, range: usize) {
|
fn update_accounts(accounts: &AccountsDb, pubkeys: &[Pubkey], slot: Slot, range: usize) {
|
||||||
for _ in 1..1000 {
|
for _ in 1..1000 {
|
||||||
let idx = thread_rng().gen_range(0, range);
|
let idx = thread_rng().gen_range(0, range);
|
||||||
|
@ -11359,64 +11515,12 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_storage(accounts: &AccountsDb, slot: Slot, count: usize) {
|
|
||||||
assert!(accounts.storage.get_slot_storage_entry(slot).is_some());
|
|
||||||
let store = accounts.storage.get_slot_storage_entry(slot).unwrap();
|
|
||||||
let total_count = store.count();
|
|
||||||
assert_eq!(store.status(), AccountStorageStatus::Available);
|
|
||||||
assert_eq!(total_count, count);
|
|
||||||
let (expected_store_count, actual_store_count): (usize, usize) =
|
|
||||||
(store.approx_stored_count(), store.all_accounts().len());
|
|
||||||
assert_eq!(expected_store_count, actual_store_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_accounts(
|
|
||||||
accounts: &AccountsDb,
|
|
||||||
pubkeys: &[Pubkey],
|
|
||||||
slot: Slot,
|
|
||||||
num: usize,
|
|
||||||
count: usize,
|
|
||||||
) {
|
|
||||||
let ancestors = vec![(slot, 0)].into_iter().collect();
|
|
||||||
for _ in 0..num {
|
|
||||||
let idx = thread_rng().gen_range(0, num);
|
|
||||||
let account = accounts.load_without_fixed_root(&ancestors, &pubkeys[idx]);
|
|
||||||
let account1 = Some((
|
|
||||||
AccountSharedData::new(
|
|
||||||
(idx + count) as u64,
|
|
||||||
0,
|
|
||||||
AccountSharedData::default().owner(),
|
|
||||||
),
|
|
||||||
slot,
|
|
||||||
));
|
|
||||||
assert_eq!(account, account1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::needless_range_loop)]
|
|
||||||
pub fn modify_accounts(
|
|
||||||
accounts: &AccountsDb,
|
|
||||||
pubkeys: &[Pubkey],
|
|
||||||
slot: Slot,
|
|
||||||
num: usize,
|
|
||||||
count: usize,
|
|
||||||
) {
|
|
||||||
for idx in 0..num {
|
|
||||||
let account = AccountSharedData::new(
|
|
||||||
(idx + count) as u64,
|
|
||||||
0,
|
|
||||||
AccountSharedData::default().owner(),
|
|
||||||
);
|
|
||||||
accounts.store_for_tests(slot, &[(&pubkeys[idx], &account)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_account_one() {
|
fn test_account_one() {
|
||||||
let (_accounts_dirs, paths) = get_temp_accounts_paths(1).unwrap();
|
let (_accounts_dirs, paths) = get_temp_accounts_paths(1).unwrap();
|
||||||
let db = AccountsDb::new(paths, &ClusterType::Development);
|
let db = AccountsDb::new(paths, &ClusterType::Development);
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_account(&db, &mut pubkeys, 0, 1, 0, 0);
|
db.create_account(&mut pubkeys, 0, 1, 0, 0);
|
||||||
let ancestors = vec![(0, 0)].into_iter().collect();
|
let ancestors = vec![(0, 0)].into_iter().collect();
|
||||||
let account = db.load_without_fixed_root(&ancestors, &pubkeys[0]).unwrap();
|
let account = db.load_without_fixed_root(&ancestors, &pubkeys[0]).unwrap();
|
||||||
let default_account = AccountSharedData::from(Account {
|
let default_account = AccountSharedData::from(Account {
|
||||||
|
@ -11431,18 +11535,18 @@ pub mod tests {
|
||||||
let (_accounts_dirs, paths) = get_temp_accounts_paths(2).unwrap();
|
let (_accounts_dirs, paths) = get_temp_accounts_paths(2).unwrap();
|
||||||
let db = AccountsDb::new(paths, &ClusterType::Development);
|
let db = AccountsDb::new(paths, &ClusterType::Development);
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_account(&db, &mut pubkeys, 0, 100, 0, 0);
|
db.create_account(&mut pubkeys, 0, 100, 0, 0);
|
||||||
check_accounts(&db, &pubkeys, 0, 100, 1);
|
db.check_accounts(&pubkeys, 0, 100, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_account_update() {
|
fn test_account_update() {
|
||||||
let accounts = AccountsDb::new_single_for_tests();
|
let accounts = AccountsDb::new_single_for_tests();
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_account(&accounts, &mut pubkeys, 0, 100, 0, 0);
|
accounts.create_account(&mut pubkeys, 0, 100, 0, 0);
|
||||||
update_accounts(&accounts, &pubkeys, 0, 99);
|
update_accounts(&accounts, &pubkeys, 0, 99);
|
||||||
accounts.add_root_and_flush_write_cache(0);
|
accounts.add_root_and_flush_write_cache(0);
|
||||||
check_storage(&accounts, 0, 100);
|
accounts.check_storage(0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -11613,24 +11717,6 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccountsDb {
|
|
||||||
pub fn all_account_count_in_append_vec(&self, slot: Slot) -> usize {
|
|
||||||
let store = self.storage.get_slot_storage_entry(slot);
|
|
||||||
if let Some(store) = store {
|
|
||||||
let count = store.all_accounts().len();
|
|
||||||
let stored_count = store.approx_stored_count();
|
|
||||||
assert_eq!(stored_count, count);
|
|
||||||
count
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ref_count_for_pubkey(&self, pubkey: &Pubkey) -> RefCount {
|
|
||||||
self.accounts_index.ref_count_from_storage(pubkey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_clean_zero_lamport_and_dead_slot() {
|
fn test_clean_zero_lamport_and_dead_slot() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
@ -12075,25 +12161,6 @@ pub mod tests {
|
||||||
assert_eq!(accounts.accounts_index.uncleaned_roots_len(), 0);
|
assert_eq!(accounts.accounts_index.uncleaned_roots_len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_load_account(
|
|
||||||
accounts: &AccountsDb,
|
|
||||||
slot: Slot,
|
|
||||||
pubkey: Pubkey,
|
|
||||||
expected_lamports: u64,
|
|
||||||
) {
|
|
||||||
let ancestors = vec![(slot, 0)].into_iter().collect();
|
|
||||||
let (account, slot) = accounts
|
|
||||||
.load_without_fixed_root(&ancestors, &pubkey)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!((account.lamports(), slot), (expected_lamports, slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_not_load_account(accounts: &AccountsDb, slot: Slot, pubkey: Pubkey) {
|
|
||||||
let ancestors = vec![(slot, 0)].into_iter().collect();
|
|
||||||
let load = accounts.load_without_fixed_root(&ancestors, &pubkey);
|
|
||||||
assert!(load.is_none(), "{load:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn assert_no_stores(accounts: &AccountsDb, slot: Slot) {
|
fn assert_no_stores(accounts: &AccountsDb, slot: Slot) {
|
||||||
let store = accounts.storage.get_slot_storage_entry(slot);
|
let store = accounts.storage.get_slot_storage_entry(slot);
|
||||||
assert!(store.is_none());
|
assert!(store.is_none());
|
||||||
|
@ -12148,7 +12215,7 @@ pub mod tests {
|
||||||
accounts.calculate_accounts_delta_hash(current_slot);
|
accounts.calculate_accounts_delta_hash(current_slot);
|
||||||
accounts.add_root_and_flush_write_cache(current_slot);
|
accounts.add_root_and_flush_write_cache(current_slot);
|
||||||
|
|
||||||
assert_load_account(&accounts, current_slot, pubkey, zero_lamport);
|
accounts.assert_load_account(current_slot, pubkey, zero_lamport);
|
||||||
|
|
||||||
current_slot += 1;
|
current_slot += 1;
|
||||||
accounts.calculate_accounts_delta_hash(current_slot);
|
accounts.calculate_accounts_delta_hash(current_slot);
|
||||||
|
@ -12177,9 +12244,9 @@ pub mod tests {
|
||||||
|
|
||||||
// storage for slot 1 had 2 accounts, now has 1 after pubkey 1
|
// storage for slot 1 had 2 accounts, now has 1 after pubkey 1
|
||||||
// was reclaimed
|
// was reclaimed
|
||||||
check_storage(&accounts, 1, 1);
|
accounts.check_storage(1, 1);
|
||||||
// storage for slot 2 had 1 accounts, now has 1
|
// storage for slot 2 had 1 accounts, now has 1
|
||||||
check_storage(&accounts, 2, 1);
|
accounts.check_storage(2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12208,7 +12275,7 @@ pub mod tests {
|
||||||
accounts.calculate_accounts_delta_hash(current_slot);
|
accounts.calculate_accounts_delta_hash(current_slot);
|
||||||
accounts.add_root_and_flush_write_cache(current_slot);
|
accounts.add_root_and_flush_write_cache(current_slot);
|
||||||
|
|
||||||
assert_load_account(&accounts, current_slot, pubkey, zero_lamport);
|
accounts.assert_load_account(current_slot, pubkey, zero_lamport);
|
||||||
|
|
||||||
// Otherwise slot 2 will not be removed
|
// Otherwise slot 2 will not be removed
|
||||||
current_slot += 1;
|
current_slot += 1;
|
||||||
|
@ -15970,39 +16037,6 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccountsDb {
|
impl AccountsDb {
|
||||||
/// useful to adapt tests written prior to introduction of the write cache
|
|
||||||
/// to use the write cache
|
|
||||||
pub fn add_root_and_flush_write_cache(&self, slot: Slot) {
|
|
||||||
self.add_root(slot);
|
|
||||||
self.flush_root_write_cache(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// useful to adapt tests written prior to introduction of the write cache
|
|
||||||
/// to use the write cache
|
|
||||||
pub(crate) fn flush_root_write_cache(&self, root: Slot) {
|
|
||||||
assert!(
|
|
||||||
self.accounts_index
|
|
||||||
.roots_tracker
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.alive_roots
|
|
||||||
.contains(&root),
|
|
||||||
"slot: {root}"
|
|
||||||
);
|
|
||||||
self.flush_accounts_cache(true, Some(root));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// callers used to call store_uncached. But, this is not allowed anymore.
|
|
||||||
pub fn store_for_tests(&self, slot: Slot, accounts: &[(&Pubkey, &AccountSharedData)]) {
|
|
||||||
self.store(
|
|
||||||
(slot, accounts, INCLUDE_SLOT_IN_HASH_TESTS),
|
|
||||||
&StoreTo::Cache,
|
|
||||||
None,
|
|
||||||
StoreReclaims::Default,
|
|
||||||
UpdateIndexThreadSelection::PoolWithThreshold,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// helper function to test unref_accounts or clean_dead_slots_from_accounts_index
|
/// helper function to test unref_accounts or clean_dead_slots_from_accounts_index
|
||||||
fn test_unref(
|
fn test_unref(
|
||||||
&self,
|
&self,
|
|
@ -1148,6 +1148,51 @@ pub struct IncrementalAccountsHash(pub Hash);
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub struct AccountsDeltaHash(pub Hash);
|
pub struct AccountsDeltaHash(pub Hash);
|
||||||
|
|
||||||
|
/// Snapshot serde-safe accounts delta hash
|
||||||
|
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq, AbiExample)]
|
||||||
|
pub struct SerdeAccountsDeltaHash(pub Hash);
|
||||||
|
|
||||||
|
impl From<SerdeAccountsDeltaHash> for AccountsDeltaHash {
|
||||||
|
fn from(accounts_delta_hash: SerdeAccountsDeltaHash) -> Self {
|
||||||
|
Self(accounts_delta_hash.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<AccountsDeltaHash> for SerdeAccountsDeltaHash {
|
||||||
|
fn from(accounts_delta_hash: AccountsDeltaHash) -> Self {
|
||||||
|
Self(accounts_delta_hash.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Snapshot serde-safe accounts hash
|
||||||
|
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq, AbiExample)]
|
||||||
|
pub struct SerdeAccountsHash(pub Hash);
|
||||||
|
|
||||||
|
impl From<SerdeAccountsHash> for AccountsHash {
|
||||||
|
fn from(accounts_hash: SerdeAccountsHash) -> Self {
|
||||||
|
Self(accounts_hash.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<AccountsHash> for SerdeAccountsHash {
|
||||||
|
fn from(accounts_hash: AccountsHash) -> Self {
|
||||||
|
Self(accounts_hash.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Snapshot serde-safe incremental accounts hash
|
||||||
|
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq, AbiExample)]
|
||||||
|
pub struct SerdeIncrementalAccountsHash(pub Hash);
|
||||||
|
|
||||||
|
impl From<SerdeIncrementalAccountsHash> for IncrementalAccountsHash {
|
||||||
|
fn from(incremental_accounts_hash: SerdeIncrementalAccountsHash) -> Self {
|
||||||
|
Self(incremental_accounts_hash.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<IncrementalAccountsHash> for SerdeIncrementalAccountsHash {
|
||||||
|
fn from(incremental_accounts_hash: IncrementalAccountsHash) -> Self {
|
||||||
|
Self(incremental_accounts_hash.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use {super::*, itertools::Itertools, std::str::FromStr, tempfile::tempdir};
|
use {super::*, itertools::Itertools, std::str::FromStr, tempfile::tempdir};
|
|
@ -449,7 +449,7 @@ pub struct RootsTracker {
|
||||||
/// Constructed during load from snapshots.
|
/// Constructed during load from snapshots.
|
||||||
/// Updated every time we add a new root or clean/shrink an append vec into irrelevancy.
|
/// Updated every time we add a new root or clean/shrink an append vec into irrelevancy.
|
||||||
/// Range is approximately the last N slots where N is # slots per epoch.
|
/// Range is approximately the last N slots where N is # slots per epoch.
|
||||||
pub(crate) alive_roots: RollingBitField,
|
pub alive_roots: RollingBitField,
|
||||||
uncleaned_roots: HashSet<Slot>,
|
uncleaned_roots: HashSet<Slot>,
|
||||||
previous_uncleaned_roots: HashSet<Slot>,
|
previous_uncleaned_roots: HashSet<Slot>,
|
||||||
}
|
}
|
||||||
|
@ -677,7 +677,7 @@ pub struct AccountsIndex<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> {
|
||||||
program_id_index: SecondaryIndex<DashMapSecondaryIndexEntry>,
|
program_id_index: SecondaryIndex<DashMapSecondaryIndexEntry>,
|
||||||
spl_token_mint_index: SecondaryIndex<DashMapSecondaryIndexEntry>,
|
spl_token_mint_index: SecondaryIndex<DashMapSecondaryIndexEntry>,
|
||||||
spl_token_owner_index: SecondaryIndex<RwLockSecondaryIndexEntry>,
|
spl_token_owner_index: SecondaryIndex<RwLockSecondaryIndexEntry>,
|
||||||
pub(crate) roots_tracker: RwLock<RootsTracker>,
|
pub roots_tracker: RwLock<RootsTracker>,
|
||||||
ongoing_scan_roots: RwLock<BTreeMap<Slot, u64>>,
|
ongoing_scan_roots: RwLock<BTreeMap<Slot, u64>>,
|
||||||
// Each scan has some latest slot `S` that is the tip of the fork the scan
|
// Each scan has some latest slot `S` that is the tip of the fork the scan
|
||||||
// is iterating over. The unique id of that slot `S` is recorded here (note we don't use
|
// is iterating over. The unique id of that slot `S` is recorded here (note we don't use
|
||||||
|
@ -1420,7 +1420,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> AccountsIndex<T, U> {
|
||||||
|
|
||||||
/// Get an account
|
/// Get an account
|
||||||
/// The latest account that appears in `ancestors` or `roots` is returned.
|
/// The latest account that appears in `ancestors` or `roots` is returned.
|
||||||
pub(crate) fn get(
|
pub fn get(
|
||||||
&self,
|
&self,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
ancestors: Option<&Ancestors>,
|
ancestors: Option<&Ancestors>,
|
||||||
|
@ -1996,7 +1996,8 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> AccountsIndex<T, U> {
|
||||||
self.roots_tracker.read().unwrap().uncleaned_roots.len()
|
self.roots_tracker.read().unwrap().uncleaned_roots.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
// filter any rooted entries and return them along with a bool that indicates
|
// filter any rooted entries and return them along with a bool that indicates
|
||||||
// if this account has no more entries. Note this does not update the secondary
|
// if this account has no more entries. Note this does not update the secondary
|
||||||
// indexes!
|
// indexes!
|
||||||
|
@ -2010,6 +2011,34 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> AccountsIndex<T, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
impl<T: IndexValue> AccountIndexGetResult<T> {
|
||||||
|
pub fn unwrap(self) -> (ReadAccountMapEntry<T>, usize) {
|
||||||
|
match self {
|
||||||
|
AccountIndexGetResult::Found(lock, size) => (lock, size),
|
||||||
|
_ => {
|
||||||
|
panic!("trying to unwrap AccountIndexGetResult with non-Success result");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_none(&self) -> bool {
|
||||||
|
!self.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_some(&self) -> bool {
|
||||||
|
matches!(self, AccountIndexGetResult::Found(_lock, _size))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map<V, F: FnOnce((ReadAccountMapEntry<T>, usize)) -> V>(self, f: F) -> Option<V> {
|
||||||
|
match self {
|
||||||
|
AccountIndexGetResult::Found(lock, size) => Some(f((lock, size))),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use {
|
use {
|
||||||
|
@ -2045,32 +2074,6 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: IndexValue> AccountIndexGetResult<T> {
|
|
||||||
pub fn unwrap(self) -> (ReadAccountMapEntry<T>, usize) {
|
|
||||||
match self {
|
|
||||||
AccountIndexGetResult::Found(lock, size) => (lock, size),
|
|
||||||
_ => {
|
|
||||||
panic!("trying to unwrap AccountIndexGetResult with non-Success result");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_none(&self) -> bool {
|
|
||||||
!self.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_some(&self) -> bool {
|
|
||||||
matches!(self, AccountIndexGetResult::Found(_lock, _size))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map<V, F: FnOnce((ReadAccountMapEntry<T>, usize)) -> V>(self, f: F) -> Option<V> {
|
|
||||||
match self {
|
|
||||||
AccountIndexGetResult::Found(lock, size) => Some(f((lock, size))),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_dashmap_secondary_index_state() -> (usize, usize, AccountSecondaryIndexes) {
|
fn create_dashmap_secondary_index_state() -> (usize, usize, AccountSecondaryIndexes) {
|
||||||
{
|
{
|
||||||
// Check that we're actually testing the correct variant
|
// Check that we're actually testing the correct variant
|
|
@ -14,9 +14,9 @@ use {
|
||||||
// Eager rent collection repeats in cyclic manner.
|
// Eager rent collection repeats in cyclic manner.
|
||||||
// Each cycle is composed of <partition_count> number of tiny pubkey subranges
|
// Each cycle is composed of <partition_count> number of tiny pubkey subranges
|
||||||
// to scan, which is always multiple of the number of slots in epoch.
|
// to scan, which is always multiple of the number of slots in epoch.
|
||||||
pub(crate) type PartitionIndex = u64;
|
pub type PartitionIndex = u64;
|
||||||
type PartitionsPerCycle = u64;
|
type PartitionsPerCycle = u64;
|
||||||
pub(crate) type Partition = (PartitionIndex, PartitionIndex, PartitionsPerCycle);
|
pub type Partition = (PartitionIndex, PartitionIndex, PartitionsPerCycle);
|
||||||
type RentCollectionCycleParams = (
|
type RentCollectionCycleParams = (
|
||||||
Epoch,
|
Epoch,
|
||||||
SlotCount,
|
SlotCount,
|
||||||
|
@ -43,7 +43,7 @@ fn partition_index_from_slot_index(
|
||||||
slot_index_in_epoch + epoch_index_in_cycle * slot_count_per_epoch
|
slot_index_in_epoch + epoch_index_in_cycle * slot_count_per_epoch
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_partition_from_slot_indexes(
|
pub fn get_partition_from_slot_indexes(
|
||||||
cycle_params: RentCollectionCycleParams,
|
cycle_params: RentCollectionCycleParams,
|
||||||
start_slot_index: SlotIndex,
|
start_slot_index: SlotIndex,
|
||||||
end_slot_index: SlotIndex,
|
end_slot_index: SlotIndex,
|
||||||
|
@ -100,8 +100,9 @@ pub(crate) fn get_partition_from_slot_indexes(
|
||||||
|
|
||||||
/// used only by filler accounts in debug path
|
/// used only by filler accounts in debug path
|
||||||
/// previous means slot - 1, not parent
|
/// previous means slot - 1, not parent
|
||||||
#[cfg(test)]
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
pub(crate) fn variable_cycle_partition_from_previous_slot(
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
pub fn variable_cycle_partition_from_previous_slot(
|
||||||
epoch_schedule: &EpochSchedule,
|
epoch_schedule: &EpochSchedule,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
) -> Partition {
|
) -> Partition {
|
||||||
|
@ -137,7 +138,7 @@ pub(crate) fn variable_cycle_partition_from_previous_slot(
|
||||||
/// 1. 'pubkey_range_from_partition'
|
/// 1. 'pubkey_range_from_partition'
|
||||||
/// 2. 'partition_from_pubkey'
|
/// 2. 'partition_from_pubkey'
|
||||||
/// 3. this function
|
/// 3. this function
|
||||||
pub(crate) fn get_partition_end_indexes(partition: &Partition) -> Vec<PartitionIndex> {
|
pub fn get_partition_end_indexes(partition: &Partition) -> Vec<PartitionIndex> {
|
||||||
if partition.0 == partition.1 && partition.0 == 0 {
|
if partition.0 == partition.1 && partition.0 == 0 {
|
||||||
// special case for start=end=0. ie. (0, 0, N). This returns [0]
|
// special case for start=end=0. ie. (0, 0, N). This returns [0]
|
||||||
vec![0]
|
vec![0]
|
||||||
|
@ -149,7 +150,7 @@ pub(crate) fn get_partition_end_indexes(partition: &Partition) -> Vec<PartitionI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn rent_single_epoch_collection_cycle_params(
|
pub fn rent_single_epoch_collection_cycle_params(
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
slot_count_per_epoch: SlotCount,
|
slot_count_per_epoch: SlotCount,
|
||||||
) -> RentCollectionCycleParams {
|
) -> RentCollectionCycleParams {
|
||||||
|
@ -163,7 +164,7 @@ pub(crate) fn rent_single_epoch_collection_cycle_params(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn rent_multi_epoch_collection_cycle_params(
|
pub fn rent_multi_epoch_collection_cycle_params(
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
slot_count_per_epoch: SlotCount,
|
slot_count_per_epoch: SlotCount,
|
||||||
first_normal_epoch: Epoch,
|
first_normal_epoch: Epoch,
|
||||||
|
@ -180,7 +181,7 @@ pub(crate) fn rent_multi_epoch_collection_cycle_params(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_partitions(
|
pub fn get_partitions(
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
parent_slot: Slot,
|
parent_slot: Slot,
|
||||||
slot_count_in_two_day: SlotCount,
|
slot_count_in_two_day: SlotCount,
|
||||||
|
@ -221,7 +222,7 @@ pub(crate) fn get_partitions(
|
||||||
// start_index..=end_index. But it has some exceptional cases, including
|
// start_index..=end_index. But it has some exceptional cases, including
|
||||||
// this important and valid one:
|
// this important and valid one:
|
||||||
// 0..=0: the first partition in the new epoch when crossing epochs
|
// 0..=0: the first partition in the new epoch when crossing epochs
|
||||||
pub(crate) fn pubkey_range_from_partition(
|
pub fn pubkey_range_from_partition(
|
||||||
(start_index, end_index, partition_count): Partition,
|
(start_index, end_index, partition_count): Partition,
|
||||||
) -> RangeInclusive<Pubkey> {
|
) -> RangeInclusive<Pubkey> {
|
||||||
assert!(start_index <= end_index);
|
assert!(start_index <= end_index);
|
||||||
|
@ -336,14 +337,14 @@ pub(crate) fn pubkey_range_from_partition(
|
||||||
start_pubkey_final..=end_pubkey_final
|
start_pubkey_final..=end_pubkey_final
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn prefix_from_pubkey(pubkey: &Pubkey) -> u64 {
|
pub fn prefix_from_pubkey(pubkey: &Pubkey) -> u64 {
|
||||||
const PREFIX_SIZE: usize = mem::size_of::<u64>();
|
const PREFIX_SIZE: usize = mem::size_of::<u64>();
|
||||||
u64::from_be_bytes(pubkey.as_ref()[0..PREFIX_SIZE].try_into().unwrap())
|
u64::from_be_bytes(pubkey.as_ref()[0..PREFIX_SIZE].try_into().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the inverse of pubkey_range_from_partition.
|
/// This is the inverse of pubkey_range_from_partition.
|
||||||
/// return the lowest end_index which would contain this pubkey
|
/// return the lowest end_index which would contain this pubkey
|
||||||
pub(crate) fn partition_from_pubkey(
|
pub fn partition_from_pubkey(
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
partition_count: PartitionsPerCycle,
|
partition_count: PartitionsPerCycle,
|
||||||
) -> PartitionIndex {
|
) -> PartitionIndex {
|
|
@ -89,6 +89,36 @@ impl Ancestors {
|
||||||
self.ancestors.max_exclusive().saturating_sub(1)
|
self.ancestors.max_exclusive().saturating_sub(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
impl std::iter::FromIterator<(Slot, usize)> for Ancestors {
|
||||||
|
fn from_iter<I>(iter: I) -> Self
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = (Slot, usize)>,
|
||||||
|
{
|
||||||
|
let mut data = Vec::new();
|
||||||
|
for i in iter {
|
||||||
|
data.push(i);
|
||||||
|
}
|
||||||
|
Ancestors::from(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
impl From<Vec<(Slot, usize)>> for Ancestors {
|
||||||
|
fn from(source: Vec<(Slot, usize)>) -> Ancestors {
|
||||||
|
Ancestors::from(source.into_iter().map(|(slot, _)| slot).collect::<Vec<_>>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
impl Ancestors {
|
||||||
|
pub fn insert(&mut self, slot: Slot, _size: usize) {
|
||||||
|
self.ancestors.insert(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use {
|
use {
|
||||||
|
@ -96,30 +126,6 @@ pub mod tests {
|
||||||
std::collections::HashSet,
|
std::collections::HashSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl std::iter::FromIterator<(Slot, usize)> for Ancestors {
|
|
||||||
fn from_iter<I>(iter: I) -> Self
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = (Slot, usize)>,
|
|
||||||
{
|
|
||||||
let mut data = Vec::new();
|
|
||||||
for i in iter {
|
|
||||||
data.push(i);
|
|
||||||
}
|
|
||||||
Ancestors::from(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<(Slot, usize)>> for Ancestors {
|
|
||||||
fn from(source: Vec<(Slot, usize)>) -> Ancestors {
|
|
||||||
Ancestors::from(source.into_iter().map(|(slot, _)| slot).collect::<Vec<_>>())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Ancestors {
|
|
||||||
pub fn insert(&mut self, slot: Slot, _size: usize) {
|
|
||||||
self.ancestors.insert(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ancestors_permutations() {
|
fn test_ancestors_permutations() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
|
@ -16,7 +16,7 @@ struct HashAge {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Low memory overhead, so can be cloned for every checkpoint
|
/// Low memory overhead, so can be cloned for every checkpoint
|
||||||
#[frozen_abi(digest = "J66ssCYGtWdQu5oyJxFKFeZY86nUjThBdBeXQYuRPDvE")]
|
#[frozen_abi(digest = "8upYCMG37Awf4FGQ5kKtZARHP1QfD2GMpQCPnwCCsxhu")]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, AbiExample)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, AbiExample)]
|
||||||
pub struct BlockhashQueue {
|
pub struct BlockhashQueue {
|
||||||
/// index of last hash to be registered
|
/// index of last hash to be registered
|
||||||
|
@ -124,7 +124,7 @@ impl BlockhashQueue {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_max_age(&self) -> usize {
|
pub fn get_max_age(&self) -> usize {
|
||||||
self.max_age
|
self.max_age
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -133,7 +133,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> BucketMapHolder<T, U>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return when the bg threads have reached an 'idle' state
|
/// return when the bg threads have reached an 'idle' state
|
||||||
pub(crate) fn wait_for_idle(&self) {
|
pub fn wait_for_idle(&self) {
|
||||||
assert!(self.get_startup());
|
assert!(self.get_startup());
|
||||||
if self.disk.is_none() {
|
if self.disk.is_none() {
|
||||||
return;
|
return;
|
|
@ -23,7 +23,7 @@ pub struct Header {
|
||||||
count: usize,
|
count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct CacheHashDataFile {
|
pub struct CacheHashDataFile {
|
||||||
cell_size: u64,
|
cell_size: u64,
|
||||||
mmap: MmapMut,
|
mmap: MmapMut,
|
||||||
capacity: u64,
|
capacity: u64,
|
||||||
|
@ -31,13 +31,13 @@ pub(crate) struct CacheHashDataFile {
|
||||||
|
|
||||||
impl CacheHashDataFile {
|
impl CacheHashDataFile {
|
||||||
/// return a slice of a reference to all the cache hash data from the mmapped file
|
/// return a slice of a reference to all the cache hash data from the mmapped file
|
||||||
pub(crate) fn get_cache_hash_data(&self) -> &[EntryType] {
|
pub fn get_cache_hash_data(&self) -> &[EntryType] {
|
||||||
self.get_slice(0)
|
self.get_slice(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
/// Populate 'accumulator' from entire contents of the cache file.
|
/// Populate 'accumulator' from entire contents of the cache file.
|
||||||
pub(crate) fn load_all(
|
pub fn load_all(
|
||||||
&self,
|
&self,
|
||||||
accumulator: &mut SavedType,
|
accumulator: &mut SavedType,
|
||||||
start_bin_index: usize,
|
start_bin_index: usize,
|
||||||
|
@ -196,7 +196,7 @@ impl CacheHashData {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
/// load from 'file_name' into 'accumulator'
|
/// load from 'file_name' into 'accumulator'
|
||||||
pub(crate) fn load(
|
pub fn load(
|
||||||
&self,
|
&self,
|
||||||
file_name: impl AsRef<Path>,
|
file_name: impl AsRef<Path>,
|
||||||
accumulator: &mut SavedType,
|
accumulator: &mut SavedType,
|
||||||
|
@ -213,7 +213,7 @@ impl CacheHashData {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// map 'file_name' into memory
|
/// map 'file_name' into memory
|
||||||
pub(crate) fn load_map(
|
pub fn load_map(
|
||||||
&self,
|
&self,
|
||||||
file_name: impl AsRef<Path>,
|
file_name: impl AsRef<Path>,
|
||||||
) -> Result<CacheHashDataFile, std::io::Error> {
|
) -> Result<CacheHashDataFile, std::io::Error> {
|
|
@ -94,7 +94,7 @@ pub struct InMemAccountsIndex<T: IndexValue, U: DiskIndexValue + From<T> + Into<
|
||||||
bucket: Option<Arc<BucketApi<(Slot, U)>>>,
|
bucket: Option<Arc<BucketApi<(Slot, U)>>>,
|
||||||
|
|
||||||
// pubkey ranges that this bin must hold in the cache while the range is present in this vec
|
// pubkey ranges that this bin must hold in the cache while the range is present in this vec
|
||||||
pub(crate) cache_ranges_held: CacheRangesHeld,
|
pub cache_ranges_held: CacheRangesHeld,
|
||||||
// incremented each time stop_evictions is changed
|
// incremented each time stop_evictions is changed
|
||||||
stop_evictions_changes: AtomicU64,
|
stop_evictions_changes: AtomicU64,
|
||||||
// true while ranges are being manipulated. Used to keep an async flush from removing things while a range is being held.
|
// true while ranges are being manipulated. Used to keep an async flush from removing things while a range is being held.
|
||||||
|
@ -322,7 +322,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
|
||||||
|
|
||||||
/// lookup 'pubkey' in index (in_mem or disk).
|
/// lookup 'pubkey' in index (in_mem or disk).
|
||||||
/// call 'callback' whether found or not
|
/// call 'callback' whether found or not
|
||||||
pub(crate) fn get_internal<RT>(
|
pub fn get_internal<RT>(
|
||||||
&self,
|
&self,
|
||||||
pubkey: &K,
|
pubkey: &K,
|
||||||
// return true if item should be added to in_mem cache
|
// return true if item should be added to in_mem cache
|
||||||
|
@ -545,7 +545,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
|
||||||
/// the new item.
|
/// the new item.
|
||||||
/// if 'other_slot' is some, then also remove any entries in the slot list that are at 'other_slot'
|
/// if 'other_slot' is some, then also remove any entries in the slot list that are at 'other_slot'
|
||||||
/// return resulting len of slot list
|
/// return resulting len of slot list
|
||||||
pub(crate) fn lock_and_update_slot_list(
|
pub fn lock_and_update_slot_list(
|
||||||
current: &AccountMapEntryInner<T>,
|
current: &AccountMapEntryInner<T>,
|
||||||
new_value: (Slot, T),
|
new_value: (Slot, T),
|
||||||
other_slot: Option<Slot>,
|
other_slot: Option<Slot>,
|
||||||
|
@ -920,7 +920,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
|
||||||
self.stop_evictions_changes.load(Ordering::Acquire)
|
self.stop_evictions_changes.load(Ordering::Acquire)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn flush(&self, can_advance_age: bool) {
|
pub fn flush(&self, can_advance_age: bool) {
|
||||||
if let Some(flush_guard) = FlushGuard::lock(&self.flushing_active) {
|
if let Some(flush_guard) = FlushGuard::lock(&self.flushing_active) {
|
||||||
self.flush_internal(&flush_guard, can_advance_age)
|
self.flush_internal(&flush_guard, can_advance_age)
|
||||||
}
|
}
|
||||||
|
@ -1089,7 +1089,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
|
||||||
/// duplicate pubkeys have a slot list with len > 1
|
/// duplicate pubkeys have a slot list with len > 1
|
||||||
/// These were collected for this bin when we did batch inserts in the bg flush threads.
|
/// These were collected for this bin when we did batch inserts in the bg flush threads.
|
||||||
/// Insert these into the in-mem index, then return the duplicate (Slot, Pubkey)
|
/// Insert these into the in-mem index, then return the duplicate (Slot, Pubkey)
|
||||||
pub(crate) fn populate_and_retrieve_duplicate_keys_from_startup(&self) -> Vec<(Slot, Pubkey)> {
|
pub fn populate_and_retrieve_duplicate_keys_from_startup(&self) -> Vec<(Slot, Pubkey)> {
|
||||||
// in order to return accurate and complete duplicates, we must have nothing left remaining to insert
|
// in order to return accurate and complete duplicates, we must have nothing left remaining to insert
|
||||||
assert!(self.startup_info.insert.lock().unwrap().is_empty());
|
assert!(self.startup_info.insert.lock().unwrap().is_empty());
|
||||||
|
|
|
@ -3,7 +3,7 @@ use solana_sdk::pubkey::{Pubkey, PUBKEY_BYTES};
|
||||||
|
|
||||||
solana_sdk::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
solana_sdk::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
||||||
|
|
||||||
pub(crate) mod program_v3_4_0 {
|
pub mod program_v3_4_0 {
|
||||||
solana_sdk::declare_id!("NToK4t5AQzxPNpUA84DkxgfXaVDbDQQjpHKCqsbY46B");
|
solana_sdk::declare_id!("NToK4t5AQzxPNpUA84DkxgfXaVDbDQQjpHKCqsbY46B");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ pub const SPL_TOKEN_ACCOUNT_MINT_OFFSET: usize = 0;
|
||||||
pub const SPL_TOKEN_ACCOUNT_OWNER_OFFSET: usize = 32;
|
pub const SPL_TOKEN_ACCOUNT_OWNER_OFFSET: usize = 32;
|
||||||
const SPL_TOKEN_ACCOUNT_LENGTH: usize = 165;
|
const SPL_TOKEN_ACCOUNT_LENGTH: usize = 165;
|
||||||
|
|
||||||
pub(crate) trait GenericTokenAccount {
|
pub trait GenericTokenAccount {
|
||||||
fn valid_account_data(account_data: &[u8]) -> bool;
|
fn valid_account_data(account_data: &[u8]) -> bool;
|
||||||
|
|
||||||
// Call after account length has already been verified
|
// Call after account length has already been verified
|
|
@ -0,0 +1,59 @@
|
||||||
|
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(min_specialization))]
|
||||||
|
#![allow(clippy::integer_arithmetic)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
pub mod account_info;
|
||||||
|
pub mod account_overrides;
|
||||||
|
pub mod account_rent_state;
|
||||||
|
pub mod account_storage;
|
||||||
|
pub mod accounts;
|
||||||
|
pub mod accounts_cache;
|
||||||
|
pub mod accounts_db;
|
||||||
|
pub mod accounts_file;
|
||||||
|
pub mod accounts_hash;
|
||||||
|
pub mod accounts_index;
|
||||||
|
pub mod accounts_index_storage;
|
||||||
|
pub mod accounts_partition;
|
||||||
|
pub mod accounts_update_notifier_interface;
|
||||||
|
pub mod active_stats;
|
||||||
|
pub mod ancestors;
|
||||||
|
pub mod ancient_append_vecs;
|
||||||
|
pub mod append_vec;
|
||||||
|
pub mod blockhash_queue;
|
||||||
|
pub mod bucket_map_holder;
|
||||||
|
pub mod bucket_map_holder_stats;
|
||||||
|
pub mod cache_hash_data;
|
||||||
|
pub mod cache_hash_data_stats;
|
||||||
|
pub mod contains;
|
||||||
|
pub mod epoch_accounts_hash;
|
||||||
|
pub mod hardened_unpack;
|
||||||
|
pub mod in_mem_accounts_index;
|
||||||
|
pub mod inline_spl_token;
|
||||||
|
pub mod inline_spl_token_2022;
|
||||||
|
pub mod nonce_info;
|
||||||
|
pub mod partitioned_rewards;
|
||||||
|
mod pubkey_bins;
|
||||||
|
mod read_only_accounts_cache;
|
||||||
|
pub mod rent_collector;
|
||||||
|
pub mod rent_debits;
|
||||||
|
mod rolling_bit_field;
|
||||||
|
pub mod secondary_index;
|
||||||
|
pub mod shared_buffer_reader;
|
||||||
|
pub mod sorted_storages;
|
||||||
|
pub mod stake_rewards;
|
||||||
|
pub mod storable_accounts;
|
||||||
|
pub mod tiered_storage;
|
||||||
|
pub mod transaction_error_metrics;
|
||||||
|
pub mod transaction_results;
|
||||||
|
mod verify_accounts_hash_in_background;
|
||||||
|
pub mod waitable_condvar;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_metrics;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_frozen_abi_macro;
|
|
@ -6,22 +6,22 @@ use solana_sdk::clock::Slot;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Configuration options for partitioned epoch rewards.
|
/// Configuration options for partitioned epoch rewards.
|
||||||
/// This struct allows various forms of testing, especially prior to feature activation.
|
/// This struct allows various forms of testing, especially prior to feature activation.
|
||||||
pub(crate) struct PartitionedEpochRewardsConfig {
|
pub struct PartitionedEpochRewardsConfig {
|
||||||
/// Number of blocks for reward calculation and storing vote accounts.
|
/// Number of blocks for reward calculation and storing vote accounts.
|
||||||
/// Distributing rewards to stake accounts begins AFTER this many blocks.
|
/// Distributing rewards to stake accounts begins AFTER this many blocks.
|
||||||
/// Normally, this will be 1.
|
/// Normally, this will be 1.
|
||||||
/// if force_one_slot_partitioned_rewards, this will be 0 (ie. we take 0 blocks just for reward calculation)
|
/// if force_one_slot_partitioned_rewards, this will be 0 (ie. we take 0 blocks just for reward calculation)
|
||||||
pub(crate) reward_calculation_num_blocks: Slot,
|
pub reward_calculation_num_blocks: Slot,
|
||||||
/// number of stake accounts to store in one block during partitioned reward interval
|
/// number of stake accounts to store in one block during partitioned reward interval
|
||||||
/// normally, this is a number tuned for reasonable performance, such as 4096 accounts/block
|
/// normally, this is a number tuned for reasonable performance, such as 4096 accounts/block
|
||||||
/// if force_one_slot_partitioned_rewards, this will usually be u64::MAX so that all stake accounts are written in the first block
|
/// if force_one_slot_partitioned_rewards, this will usually be u64::MAX so that all stake accounts are written in the first block
|
||||||
pub(crate) stake_account_stores_per_block: Slot,
|
pub stake_account_stores_per_block: Slot,
|
||||||
/// if true, end of epoch bank rewards will force using partitioned rewards distribution.
|
/// if true, end of epoch bank rewards will force using partitioned rewards distribution.
|
||||||
/// see `set_test_enable_partitioned_rewards`
|
/// see `set_test_enable_partitioned_rewards`
|
||||||
pub(crate) test_enable_partitioned_rewards: bool,
|
pub test_enable_partitioned_rewards: bool,
|
||||||
/// if true, end of epoch non-partitioned bank rewards will test the partitioned rewards distribution vote and stake accounts
|
/// if true, end of epoch non-partitioned bank rewards will test the partitioned rewards distribution vote and stake accounts
|
||||||
/// This has a significant performance impact on the first slot in each new epoch.
|
/// This has a significant performance impact on the first slot in each new epoch.
|
||||||
pub(crate) test_compare_partitioned_epoch_rewards: bool,
|
pub test_compare_partitioned_epoch_rewards: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PartitionedEpochRewardsConfig {
|
impl Default for PartitionedEpochRewardsConfig {
|
||||||
|
@ -55,7 +55,7 @@ pub enum TestPartitionedEpochRewards {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl PartitionedEpochRewardsConfig {
|
impl PartitionedEpochRewardsConfig {
|
||||||
pub(crate) fn new(test: TestPartitionedEpochRewards) -> Self {
|
pub fn new(test: TestPartitionedEpochRewards) -> Self {
|
||||||
match test {
|
match test {
|
||||||
TestPartitionedEpochRewards::None => Self::default(),
|
TestPartitionedEpochRewards::None => Self::default(),
|
||||||
TestPartitionedEpochRewards::CompareResults => {
|
TestPartitionedEpochRewards::CompareResults => {
|
|
@ -27,7 +27,7 @@ struct ReadOnlyAccountCacheEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ReadOnlyAccountsCache {
|
pub struct ReadOnlyAccountsCache {
|
||||||
cache: DashMap<ReadOnlyCacheKey, ReadOnlyAccountCacheEntry>,
|
cache: DashMap<ReadOnlyCacheKey, ReadOnlyAccountCacheEntry>,
|
||||||
// When an item is first entered into the cache, it is added to the end of
|
// When an item is first entered into the cache, it is added to the end of
|
||||||
// the queue. Also each time an entry is looked up from the cache it is
|
// the queue. Also each time an entry is looked up from the cache it is
|
||||||
|
@ -44,7 +44,7 @@ pub(crate) struct ReadOnlyAccountsCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadOnlyAccountsCache {
|
impl ReadOnlyAccountsCache {
|
||||||
pub(crate) fn new(max_data_size: usize) -> Self {
|
pub fn new(max_data_size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
max_data_size,
|
max_data_size,
|
||||||
cache: DashMap::default(),
|
cache: DashMap::default(),
|
||||||
|
@ -102,7 +102,7 @@ impl ReadOnlyAccountsCache {
|
||||||
CACHE_ENTRY_SIZE + account.data().len()
|
CACHE_ENTRY_SIZE + account.data().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn store(&self, pubkey: Pubkey, slot: Slot, account: AccountSharedData) {
|
pub fn store(&self, pubkey: Pubkey, slot: Slot, account: AccountSharedData) {
|
||||||
let key = (pubkey, slot);
|
let key = (pubkey, slot);
|
||||||
let account_size = self.account_size(&account);
|
let account_size = self.account_size(&account);
|
||||||
self.data_size.fetch_add(account_size, Ordering::Relaxed);
|
self.data_size.fetch_add(account_size, Ordering::Relaxed);
|
||||||
|
@ -138,7 +138,7 @@ impl ReadOnlyAccountsCache {
|
||||||
self.evicts.fetch_add(num_evicts, Ordering::Relaxed);
|
self.evicts.fetch_add(num_evicts, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove(&self, pubkey: Pubkey, slot: Slot) -> Option<AccountSharedData> {
|
pub fn remove(&self, pubkey: Pubkey, slot: Slot) -> Option<AccountSharedData> {
|
||||||
let (_, entry) = self.cache.remove(&(pubkey, slot))?;
|
let (_, entry) = self.cache.remove(&(pubkey, slot))?;
|
||||||
// self.queue should be modified only after removing the entry from the
|
// self.queue should be modified only after removing the entry from the
|
||||||
// cache, so that this is still safe if another thread writes to the
|
// cache, so that this is still safe if another thread writes to the
|
||||||
|
@ -149,11 +149,11 @@ impl ReadOnlyAccountsCache {
|
||||||
Some(entry.account)
|
Some(entry.account)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn cache_len(&self) -> usize {
|
pub fn cache_len(&self) -> usize {
|
||||||
self.cache.len()
|
self.cache.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn data_size(&self) -> usize {
|
pub fn data_size(&self) -> usize {
|
||||||
self.data_size.load(Ordering::Relaxed)
|
self.data_size.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ enum RentResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RentCollector {
|
impl RentCollector {
|
||||||
pub(crate) fn new(
|
pub fn new(
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
epoch_schedule: EpochSchedule,
|
epoch_schedule: EpochSchedule,
|
||||||
slots_per_year: f64,
|
slots_per_year: f64,
|
||||||
|
@ -63,7 +63,7 @@ impl RentCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clone_with_epoch(&self, epoch: Epoch) -> Self {
|
pub fn clone_with_epoch(&self, epoch: Epoch) -> Self {
|
||||||
Self {
|
Self {
|
||||||
epoch,
|
epoch,
|
||||||
..self.clone()
|
..self.clone()
|
||||||
|
@ -71,18 +71,14 @@ impl RentCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// true if it is easy to determine this account should consider having rent collected from it
|
/// true if it is easy to determine this account should consider having rent collected from it
|
||||||
pub(crate) fn should_collect_rent(
|
pub fn should_collect_rent(&self, address: &Pubkey, account: &impl ReadableAccount) -> bool {
|
||||||
&self,
|
|
||||||
address: &Pubkey,
|
|
||||||
account: &impl ReadableAccount,
|
|
||||||
) -> bool {
|
|
||||||
!(account.executable() // executable accounts must be rent-exempt balance
|
!(account.executable() // executable accounts must be rent-exempt balance
|
||||||
|| *address == incinerator::id())
|
|| *address == incinerator::id())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// given an account that 'should_collect_rent'
|
/// given an account that 'should_collect_rent'
|
||||||
/// returns (amount rent due, is_exempt_from_rent)
|
/// returns (amount rent due, is_exempt_from_rent)
|
||||||
pub(crate) fn get_rent_due(&self, account: &impl ReadableAccount) -> RentDue {
|
pub fn get_rent_due(&self, account: &impl ReadableAccount) -> RentDue {
|
||||||
if self
|
if self
|
||||||
.rent
|
.rent
|
||||||
.is_exempt(account.lamports(), account.data().len())
|
.is_exempt(account.lamports(), account.data().len())
|
||||||
|
@ -111,7 +107,7 @@ impl RentCollector {
|
||||||
// This is NOT thread safe at some level. If we try to collect from the same account in
|
// This is NOT thread safe at some level. If we try to collect from the same account in
|
||||||
// parallel, we may collect twice.
|
// parallel, we may collect twice.
|
||||||
#[must_use = "add to Bank::collected_rent"]
|
#[must_use = "add to Bank::collected_rent"]
|
||||||
pub(crate) fn collect_from_existing_account(
|
pub fn collect_from_existing_account(
|
||||||
&self,
|
&self,
|
||||||
address: &Pubkey,
|
address: &Pubkey,
|
||||||
account: &mut AccountSharedData,
|
account: &mut AccountSharedData,
|
||||||
|
@ -188,11 +184,11 @@ impl RentCollector {
|
||||||
|
|
||||||
/// Information computed during rent collection
|
/// Information computed during rent collection
|
||||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
|
||||||
pub(crate) struct CollectedInfo {
|
pub struct CollectedInfo {
|
||||||
/// Amount of rent collected from account
|
/// Amount of rent collected from account
|
||||||
pub(crate) rent_amount: u64,
|
pub rent_amount: u64,
|
||||||
/// Size of data reclaimed from account (happens when account's lamports go to zero)
|
/// Size of data reclaimed from account (happens when account's lamports go to zero)
|
||||||
pub(crate) account_data_len_reclaimed: u64,
|
pub account_data_len_reclaimed: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Add for CollectedInfo {
|
impl std::ops::Add for CollectedInfo {
|
|
@ -1,11 +1,11 @@
|
||||||
use {
|
use {
|
||||||
crate::bank::RewardInfo,
|
crate::stake_rewards::RewardInfo,
|
||||||
solana_sdk::{pubkey::Pubkey, reward_type::RewardType},
|
solana_sdk::{pubkey::Pubkey, reward_type::RewardType},
|
||||||
std::collections::HashMap,
|
std::collections::HashMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) struct RentDebit {
|
pub struct RentDebit {
|
||||||
rent_collected: u64,
|
rent_collected: u64,
|
||||||
post_balance: u64,
|
post_balance: u64,
|
||||||
}
|
}
|
||||||
|
@ -27,18 +27,24 @@ impl RentDebit {
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
pub struct RentDebits(HashMap<Pubkey, RentDebit>);
|
pub struct RentDebits(HashMap<Pubkey, RentDebit>);
|
||||||
impl RentDebits {
|
impl RentDebits {
|
||||||
pub(crate) fn get_account_rent_debit(&self, address: &Pubkey) -> u64 {
|
pub fn get_account_rent_debit(&self, address: &Pubkey) -> u64 {
|
||||||
self.0
|
self.0
|
||||||
.get(address)
|
.get(address)
|
||||||
.map(|r| r.rent_collected)
|
.map(|r| r.rent_collected)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
pub(crate) fn len(&self) -> usize {
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, address: &Pubkey, rent_collected: u64, post_balance: u64) {
|
pub fn insert(&mut self, address: &Pubkey, rent_collected: u64, post_balance: u64) {
|
||||||
if rent_collected != 0 {
|
if rent_collected != 0 {
|
||||||
self.0.insert(
|
self.0.insert(
|
|
@ -0,0 +1,115 @@
|
||||||
|
//! Code for stake and vote rewards
|
||||||
|
|
||||||
|
use {
|
||||||
|
crate::{accounts_db::IncludeSlotInHash, storable_accounts::StorableAccounts},
|
||||||
|
solana_sdk::{
|
||||||
|
account::AccountSharedData, clock::Slot, pubkey::Pubkey, reward_type::RewardType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, AbiExample, Clone, Copy)]
|
||||||
|
pub struct RewardInfo {
|
||||||
|
pub reward_type: RewardType,
|
||||||
|
/// Reward amount
|
||||||
|
pub lamports: i64,
|
||||||
|
/// Account balance in lamports after `lamports` was applied
|
||||||
|
pub post_balance: u64,
|
||||||
|
/// Vote account commission when the reward was credited, only present for voting and staking rewards
|
||||||
|
pub commission: Option<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(AbiExample, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
|
pub struct StakeReward {
|
||||||
|
pub stake_pubkey: Pubkey,
|
||||||
|
pub stake_reward_info: RewardInfo,
|
||||||
|
pub stake_account: AccountSharedData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StakeReward {
|
||||||
|
pub fn get_stake_reward(&self) -> i64 {
|
||||||
|
self.stake_reward_info.lamports
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// allow [StakeReward] to be passed to `StoreAccounts` directly without copies or vec construction
|
||||||
|
impl<'a> StorableAccounts<'a, AccountSharedData> for (Slot, &'a [StakeReward], IncludeSlotInHash) {
|
||||||
|
fn pubkey(&self, index: usize) -> &Pubkey {
|
||||||
|
&self.1[index].stake_pubkey
|
||||||
|
}
|
||||||
|
fn account(&self, index: usize) -> &AccountSharedData {
|
||||||
|
&self.1[index].stake_account
|
||||||
|
}
|
||||||
|
fn slot(&self, _index: usize) -> Slot {
|
||||||
|
// per-index slot is not unique per slot when per-account slot is not included in the source data
|
||||||
|
self.target_slot()
|
||||||
|
}
|
||||||
|
fn target_slot(&self) -> Slot {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.1.len()
|
||||||
|
}
|
||||||
|
fn include_slot_in_hash(&self) -> IncludeSlotInHash {
|
||||||
|
self.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
use {
|
||||||
|
rand::Rng,
|
||||||
|
solana_sdk::{
|
||||||
|
account::WritableAccount,
|
||||||
|
rent::Rent,
|
||||||
|
signature::{Keypair, Signer},
|
||||||
|
},
|
||||||
|
solana_stake_program::stake_state,
|
||||||
|
solana_vote_program::vote_state,
|
||||||
|
};
|
||||||
|
|
||||||
|
// These functions/fields are only usable from a dev context (i.e. tests and benches)
|
||||||
|
#[cfg(feature = "dev-context-only-utils")]
|
||||||
|
impl StakeReward {
|
||||||
|
pub fn new_random() -> Self {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let rent = Rent::free();
|
||||||
|
|
||||||
|
let validator_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
let validator_stake_lamports = 20;
|
||||||
|
let validator_staking_keypair = Keypair::new();
|
||||||
|
let validator_voting_keypair = Keypair::new();
|
||||||
|
|
||||||
|
let validator_vote_account = vote_state::create_account(
|
||||||
|
&validator_voting_keypair.pubkey(),
|
||||||
|
&validator_pubkey,
|
||||||
|
10,
|
||||||
|
validator_stake_lamports,
|
||||||
|
);
|
||||||
|
|
||||||
|
let validator_stake_account = stake_state::create_account(
|
||||||
|
&validator_staking_keypair.pubkey(),
|
||||||
|
&validator_voting_keypair.pubkey(),
|
||||||
|
&validator_vote_account,
|
||||||
|
&rent,
|
||||||
|
validator_stake_lamports,
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
stake_pubkey: Pubkey::new_unique(),
|
||||||
|
stake_reward_info: RewardInfo {
|
||||||
|
reward_type: RewardType::Staking,
|
||||||
|
lamports: rng.gen_range(1, 200),
|
||||||
|
post_balance: 0, /* unused atm */
|
||||||
|
commission: None, /* unused atm */
|
||||||
|
},
|
||||||
|
|
||||||
|
stake_account: validator_stake_account,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn credit(&mut self, amount: u64) {
|
||||||
|
self.stake_reward_info.lamports = amount as i64;
|
||||||
|
self.stake_reward_info.post_balance += amount;
|
||||||
|
self.stake_account.checked_add_lamports(amount).unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -203,7 +203,7 @@ pub struct StorableAccountsBySlot<'a> {
|
||||||
impl<'a> StorableAccountsBySlot<'a> {
|
impl<'a> StorableAccountsBySlot<'a> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
/// each element of slots_and_accounts is (source slot, accounts moving FROM source slot)
|
/// each element of slots_and_accounts is (source slot, accounts moving FROM source slot)
|
||||||
pub(crate) fn new(
|
pub fn new(
|
||||||
target_slot: Slot,
|
target_slot: Slot,
|
||||||
slots_and_accounts: &'a [(Slot, &'a [&'a StoredAccountMeta<'a>])],
|
slots_and_accounts: &'a [(Slot, &'a [&'a StoredAccountMeta<'a>])],
|
||||||
include_slot_in_hash: IncludeSlotInHash,
|
include_slot_in_hash: IncludeSlotInHash,
|
|
@ -16,16 +16,16 @@ use {
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct TieredReadableAccount<'accounts_file, M: TieredAccountMeta> {
|
pub struct TieredReadableAccount<'accounts_file, M: TieredAccountMeta> {
|
||||||
/// TieredAccountMeta
|
/// TieredAccountMeta
|
||||||
pub(crate) meta: &'accounts_file M,
|
pub meta: &'accounts_file M,
|
||||||
/// The address of the account
|
/// The address of the account
|
||||||
pub(crate) address: &'accounts_file Pubkey,
|
pub address: &'accounts_file Pubkey,
|
||||||
/// The address of the account owner
|
/// The address of the account owner
|
||||||
pub(crate) owner: &'accounts_file Pubkey,
|
pub owner: &'accounts_file Pubkey,
|
||||||
/// The index for accessing the account inside its belonging AccountsFile
|
/// The index for accessing the account inside its belonging AccountsFile
|
||||||
pub(crate) index: usize,
|
pub index: usize,
|
||||||
/// The account block that contains this account. Note that this account
|
/// The account block that contains this account. Note that this account
|
||||||
/// block may be shared with other accounts.
|
/// block may be shared with other accounts.
|
||||||
pub(crate) account_block: &'accounts_file [u8],
|
pub account_block: &'accounts_file [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'accounts_file, M: TieredAccountMeta> TieredReadableAccount<'accounts_file, M> {
|
impl<'accounts_file, M: TieredAccountMeta> TieredReadableAccount<'accounts_file, M> {
|
|
@ -12,9 +12,9 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct VerifyAccountsHashInBackground {
|
pub struct VerifyAccountsHashInBackground {
|
||||||
/// true when verification has completed or never had to run in background
|
/// true when verification has completed or never had to run in background
|
||||||
pub(crate) verified: Arc<AtomicBool>,
|
pub verified: Arc<AtomicBool>,
|
||||||
/// enable waiting for verification to become complete
|
/// enable waiting for verification to become complete
|
||||||
complete: Arc<WaitableCondvar>,
|
complete: Arc<WaitableCondvar>,
|
||||||
/// thread doing verification
|
/// thread doing verification
|
||||||
|
@ -39,14 +39,14 @@ impl Default for VerifyAccountsHashInBackground {
|
||||||
|
|
||||||
impl VerifyAccountsHashInBackground {
|
impl VerifyAccountsHashInBackground {
|
||||||
/// start the bg thread to do the verification
|
/// start the bg thread to do the verification
|
||||||
pub(crate) fn start(&self, start: impl FnOnce() -> JoinHandle<bool>) {
|
pub fn start(&self, start: impl FnOnce() -> JoinHandle<bool>) {
|
||||||
// note that we're not verified before
|
// note that we're not verified before
|
||||||
self.verified.store(false, Ordering::Release);
|
self.verified.store(false, Ordering::Release);
|
||||||
*self.thread.lock().unwrap() = Some(start());
|
*self.thread.lock().unwrap() = Some(start());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// notify that the bg process has completed
|
/// notify that the bg process has completed
|
||||||
pub(crate) fn background_finished(&self) {
|
pub fn background_finished(&self) {
|
||||||
self.complete.notify_all();
|
self.complete.notify_all();
|
||||||
self.background_completed.store(true, Ordering::Release);
|
self.background_completed.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ impl VerifyAccountsHashInBackground {
|
||||||
/// notify that verification was completed successfully
|
/// notify that verification was completed successfully
|
||||||
/// This can occur because it completed in the background
|
/// This can occur because it completed in the background
|
||||||
/// or if the verification was run in the foreground.
|
/// or if the verification was run in the foreground.
|
||||||
pub(crate) fn verification_complete(&self) {
|
pub fn verification_complete(&self) {
|
||||||
self.verified.store(true, Ordering::Release);
|
self.verified.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ impl VerifyAccountsHashInBackground {
|
||||||
/// return true if bg hash verification is complete
|
/// return true if bg hash verification is complete
|
||||||
/// return false if bg hash verification has not completed yet
|
/// return false if bg hash verification has not completed yet
|
||||||
/// if hash verification failed, a panic will occur
|
/// if hash verification failed, a panic will occur
|
||||||
pub(crate) fn check_complete(&self) -> bool {
|
pub fn check_complete(&self) -> bool {
|
||||||
if self.verified.load(Ordering::Acquire) {
|
if self.verified.load(Ordering::Acquire) {
|
||||||
// already completed
|
// already completed
|
||||||
return true;
|
return true;
|
||||||
|
@ -95,7 +95,7 @@ impl VerifyAccountsHashInBackground {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub mod tests {
|
||||||
use {super::*, std::thread::Builder};
|
use {super::*, std::thread::Builder};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
|
@ -13,6 +13,7 @@ edition = { workspace = true }
|
||||||
bincode = { workspace = true }
|
bincode = { workspace = true }
|
||||||
crossbeam-channel = { workspace = true }
|
crossbeam-channel = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-banks-interface = { workspace = true }
|
solana-banks-interface = { workspace = true }
|
||||||
solana-client = { workspace = true }
|
solana-client = { workspace = true }
|
||||||
solana-runtime = { workspace = true }
|
solana-runtime = { workspace = true }
|
||||||
|
|
|
@ -2,6 +2,7 @@ use {
|
||||||
bincode::{deserialize, serialize},
|
bincode::{deserialize, serialize},
|
||||||
crossbeam_channel::{unbounded, Receiver, Sender},
|
crossbeam_channel::{unbounded, Receiver, Sender},
|
||||||
futures::{future, prelude::stream::StreamExt},
|
futures::{future, prelude::stream::StreamExt},
|
||||||
|
solana_accounts_db::transaction_results::TransactionExecutionResult,
|
||||||
solana_banks_interface::{
|
solana_banks_interface::{
|
||||||
Banks, BanksRequest, BanksResponse, BanksTransactionResultWithMetadata,
|
Banks, BanksRequest, BanksResponse, BanksTransactionResultWithMetadata,
|
||||||
BanksTransactionResultWithSimulation, TransactionConfirmationStatus, TransactionMetadata,
|
BanksTransactionResultWithSimulation, TransactionConfirmationStatus, TransactionMetadata,
|
||||||
|
@ -12,7 +13,6 @@ use {
|
||||||
bank::{Bank, TransactionSimulationResult},
|
bank::{Bank, TransactionSimulationResult},
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
commitment::BlockCommitmentCache,
|
commitment::BlockCommitmentCache,
|
||||||
transaction_results::TransactionExecutionResult,
|
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
|
|
|
@ -37,6 +37,7 @@ rayon = { workspace = true }
|
||||||
rolling-file = { workspace = true }
|
rolling-file = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_derive = { workspace = true }
|
serde_derive = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-address-lookup-table-program = { workspace = true }
|
solana-address-lookup-table-program = { workspace = true }
|
||||||
solana-bloom = { workspace = true }
|
solana-bloom = { workspace = true }
|
||||||
solana-client = { workspace = true }
|
solana-client = { workspace = true }
|
||||||
|
|
|
@ -5,14 +5,17 @@
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crossbeam_channel::{Receiver, Sender},
|
crossbeam_channel::{Receiver, Sender},
|
||||||
solana_gossip::cluster_info::{ClusterInfo, MAX_ACCOUNTS_HASHES},
|
solana_accounts_db::{
|
||||||
solana_measure::measure_us,
|
|
||||||
solana_runtime::{
|
|
||||||
accounts_db::CalcAccountsHashFlavor,
|
accounts_db::CalcAccountsHashFlavor,
|
||||||
accounts_hash::{
|
accounts_hash::{
|
||||||
AccountsHash, AccountsHashEnum, CalcAccountsHashConfig, HashStats,
|
AccountsHash, AccountsHashEnum, CalcAccountsHashConfig, HashStats,
|
||||||
IncrementalAccountsHash,
|
IncrementalAccountsHash,
|
||||||
},
|
},
|
||||||
|
sorted_storages::SortedStorages,
|
||||||
|
},
|
||||||
|
solana_gossip::cluster_info::{ClusterInfo, MAX_ACCOUNTS_HASHES},
|
||||||
|
solana_measure::measure_us,
|
||||||
|
solana_runtime::{
|
||||||
serde_snapshot::BankIncrementalSnapshotPersistence,
|
serde_snapshot::BankIncrementalSnapshotPersistence,
|
||||||
snapshot_config::SnapshotConfig,
|
snapshot_config::SnapshotConfig,
|
||||||
snapshot_package::{
|
snapshot_package::{
|
||||||
|
@ -20,7 +23,6 @@ use {
|
||||||
SnapshotType,
|
SnapshotType,
|
||||||
},
|
},
|
||||||
snapshot_utils,
|
snapshot_utils,
|
||||||
sorted_storages::SortedStorages,
|
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, DEFAULT_MS_PER_SLOT},
|
clock::{Slot, DEFAULT_MS_PER_SLOT},
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
use {
|
use {
|
||||||
super::leader_slot_timing_metrics::LeaderExecuteAndCommitTimings,
|
super::leader_slot_timing_metrics::LeaderExecuteAndCommitTimings,
|
||||||
itertools::Itertools,
|
itertools::Itertools,
|
||||||
|
solana_accounts_db::{
|
||||||
|
accounts::TransactionLoadResult,
|
||||||
|
transaction_results::{TransactionExecutionResult, TransactionResults},
|
||||||
|
},
|
||||||
solana_ledger::{
|
solana_ledger::{
|
||||||
blockstore_processor::TransactionStatusSender, token_balances::collect_token_balances,
|
blockstore_processor::TransactionStatusSender, token_balances::collect_token_balances,
|
||||||
},
|
},
|
||||||
solana_measure::measure_us,
|
solana_measure::measure_us,
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
accounts::TransactionLoadResult,
|
|
||||||
bank::{Bank, CommitTransactionCounts, TransactionBalancesSet},
|
bank::{Bank, CommitTransactionCounts, TransactionBalancesSet},
|
||||||
bank_utils,
|
bank_utils,
|
||||||
prioritization_fee_cache::PrioritizationFeeCache,
|
prioritization_fee_cache::PrioritizationFeeCache,
|
||||||
transaction_batch::TransactionBatch,
|
transaction_batch::TransactionBatch,
|
||||||
transaction_results::{TransactionExecutionResult, TransactionResults},
|
|
||||||
vote_sender_types::ReplayVoteSender,
|
vote_sender_types::ReplayVoteSender,
|
||||||
},
|
},
|
||||||
solana_sdk::{pubkey::Pubkey, saturating_add_assign},
|
solana_sdk::{pubkey::Pubkey, saturating_add_assign},
|
||||||
|
|
|
@ -9,6 +9,10 @@ use {
|
||||||
BankingStageStats,
|
BankingStageStats,
|
||||||
},
|
},
|
||||||
itertools::Itertools,
|
itertools::Itertools,
|
||||||
|
solana_accounts_db::{
|
||||||
|
transaction_error_metrics::TransactionErrorMetrics,
|
||||||
|
transaction_results::TransactionCheckResult,
|
||||||
|
},
|
||||||
solana_ledger::token_balances::collect_token_balances,
|
solana_ledger::token_balances::collect_token_balances,
|
||||||
solana_measure::{measure::Measure, measure_us},
|
solana_measure::{measure::Measure, measure_us},
|
||||||
solana_poh::poh_recorder::{
|
solana_poh::poh_recorder::{
|
||||||
|
@ -19,8 +23,6 @@ use {
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::{Bank, LoadAndExecuteTransactionsOutput},
|
bank::{Bank, LoadAndExecuteTransactionsOutput},
|
||||||
transaction_batch::TransactionBatch,
|
transaction_batch::TransactionBatch,
|
||||||
transaction_error_metrics::TransactionErrorMetrics,
|
|
||||||
transaction_results::TransactionCheckResult,
|
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, MAX_PROCESSING_AGE},
|
clock::{Slot, FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, MAX_PROCESSING_AGE},
|
||||||
|
|
|
@ -3,8 +3,8 @@ use {
|
||||||
leader_slot_timing_metrics::{LeaderExecuteAndCommitTimings, LeaderSlotTimingMetrics},
|
leader_slot_timing_metrics::{LeaderExecuteAndCommitTimings, LeaderSlotTimingMetrics},
|
||||||
unprocessed_transaction_storage::InsertPacketBatchSummary,
|
unprocessed_transaction_storage::InsertPacketBatchSummary,
|
||||||
},
|
},
|
||||||
|
solana_accounts_db::transaction_error_metrics::*,
|
||||||
solana_poh::poh_recorder::BankStart,
|
solana_poh::poh_recorder::BankStart,
|
||||||
solana_runtime::transaction_error_metrics::*,
|
|
||||||
solana_sdk::{clock::Slot, saturating_add_assign},
|
solana_sdk::{clock::Slot, saturating_add_assign},
|
||||||
std::time::Instant,
|
std::time::Instant,
|
||||||
};
|
};
|
||||||
|
|
|
@ -978,11 +978,12 @@ mod test {
|
||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
itertools::Itertools,
|
itertools::Itertools,
|
||||||
|
solana_accounts_db::contains::Contains,
|
||||||
solana_ledger::{
|
solana_ledger::{
|
||||||
blockstore::{make_chaining_slot_entries, Blockstore},
|
blockstore::{make_chaining_slot_entries, Blockstore},
|
||||||
get_tmp_ledger_path,
|
get_tmp_ledger_path,
|
||||||
},
|
},
|
||||||
solana_runtime::{bank::Bank, bank_utils, contains::Contains},
|
solana_runtime::{bank::Bank, bank_utils},
|
||||||
solana_sdk::hash::Hash,
|
solana_sdk::hash::Hash,
|
||||||
trees::tr,
|
trees::tr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crossbeam_channel::{Receiver, RecvTimeoutError, Sender},
|
crossbeam_channel::{Receiver, RecvTimeoutError, Sender},
|
||||||
|
solana_accounts_db::stake_rewards::RewardInfo,
|
||||||
solana_ledger::blockstore::Blockstore,
|
solana_ledger::blockstore::Blockstore,
|
||||||
solana_runtime::bank::RewardInfo,
|
|
||||||
solana_sdk::{clock::Slot, pubkey::Pubkey},
|
solana_sdk::{clock::Slot, pubkey::Pubkey},
|
||||||
solana_transaction_status::Reward,
|
solana_transaction_status::Reward,
|
||||||
std::{
|
std::{
|
||||||
|
|
|
@ -31,6 +31,12 @@ use {
|
||||||
crossbeam_channel::{bounded, unbounded, Receiver},
|
crossbeam_channel::{bounded, unbounded, Receiver},
|
||||||
lazy_static::lazy_static,
|
lazy_static::lazy_static,
|
||||||
quinn::Endpoint,
|
quinn::Endpoint,
|
||||||
|
solana_accounts_db::{
|
||||||
|
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
|
||||||
|
accounts_index::AccountSecondaryIndexes,
|
||||||
|
accounts_update_notifier_interface::AccountsUpdateNotifier,
|
||||||
|
hardened_unpack::{open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
|
||||||
|
},
|
||||||
solana_client::connection_cache::{ConnectionCache, Protocol},
|
solana_client::connection_cache::{ConnectionCache, Protocol},
|
||||||
solana_entry::poh::compute_hash_time_ns,
|
solana_entry::poh::compute_hash_time_ns,
|
||||||
solana_geyser_plugin_manager::{
|
solana_geyser_plugin_manager::{
|
||||||
|
@ -83,13 +89,9 @@ use {
|
||||||
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService, DroppedSlotsReceiver,
|
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService, DroppedSlotsReceiver,
|
||||||
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
||||||
},
|
},
|
||||||
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
|
|
||||||
accounts_index::AccountSecondaryIndexes,
|
|
||||||
accounts_update_notifier_interface::AccountsUpdateNotifier,
|
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
commitment::BlockCommitmentCache,
|
commitment::BlockCommitmentCache,
|
||||||
hardened_unpack::{open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
|
|
||||||
prioritization_fee_cache::PrioritizationFeeCache,
|
prioritization_fee_cache::PrioritizationFeeCache,
|
||||||
runtime_config::RuntimeConfig,
|
runtime_config::RuntimeConfig,
|
||||||
snapshot_archive_info::SnapshotArchiveInfoGetter,
|
snapshot_archive_info::SnapshotArchiveInfoGetter,
|
||||||
|
@ -1917,7 +1919,7 @@ fn maybe_warp_slot(
|
||||||
&root_bank,
|
&root_bank,
|
||||||
&Pubkey::default(),
|
&Pubkey::default(),
|
||||||
warp_slot,
|
warp_slot,
|
||||||
solana_runtime::accounts_db::CalcAccountsHashDataSource::Storages,
|
solana_accounts_db::accounts_db::CalcAccountsHashDataSource::Storages,
|
||||||
));
|
));
|
||||||
bank_forks.set_root(
|
bank_forks.set_root(
|
||||||
warp_slot,
|
warp_slot,
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
use {
|
use {
|
||||||
crate::snapshot_utils::create_tmp_accounts_dir_for_tests,
|
crate::snapshot_utils::create_tmp_accounts_dir_for_tests,
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::{
|
||||||
|
accounts_db::{
|
||||||
|
AccountShrinkThreshold, CalcAccountsHashDataSource, INCLUDE_SLOT_IN_HASH_TESTS,
|
||||||
|
},
|
||||||
|
accounts_hash::CalcAccountsHashConfig,
|
||||||
|
accounts_index::AccountSecondaryIndexes,
|
||||||
|
epoch_accounts_hash::EpochAccountsHash,
|
||||||
|
},
|
||||||
solana_core::{
|
solana_core::{
|
||||||
accounts_hash_verifier::AccountsHashVerifier,
|
accounts_hash_verifier::AccountsHashVerifier,
|
||||||
snapshot_packager_service::SnapshotPackagerService,
|
snapshot_packager_service::SnapshotPackagerService,
|
||||||
|
@ -11,14 +19,8 @@ use {
|
||||||
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService, DroppedSlotsReceiver,
|
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService, DroppedSlotsReceiver,
|
||||||
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
||||||
},
|
},
|
||||||
accounts_db::{
|
|
||||||
AccountShrinkThreshold, CalcAccountsHashDataSource, INCLUDE_SLOT_IN_HASH_TESTS,
|
|
||||||
},
|
|
||||||
accounts_hash::CalcAccountsHashConfig,
|
|
||||||
accounts_index::AccountSecondaryIndexes,
|
|
||||||
bank::{epoch_accounts_hash_utils, Bank, BankTestConfig},
|
bank::{epoch_accounts_hash_utils, Bank, BankTestConfig},
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
epoch_accounts_hash::EpochAccountsHash,
|
|
||||||
genesis_utils::{self, GenesisConfigInfo},
|
genesis_utils::{self, GenesisConfigInfo},
|
||||||
runtime_config::RuntimeConfig,
|
runtime_config::RuntimeConfig,
|
||||||
snapshot_archive_info::SnapshotArchiveInfoGetter,
|
snapshot_archive_info::SnapshotArchiveInfoGetter,
|
||||||
|
|
|
@ -6,6 +6,12 @@ use {
|
||||||
fs_extra::dir::CopyOptions,
|
fs_extra::dir::CopyOptions,
|
||||||
itertools::Itertools,
|
itertools::Itertools,
|
||||||
log::{info, trace},
|
log::{info, trace},
|
||||||
|
solana_accounts_db::{
|
||||||
|
accounts_db::{self, CalcAccountsHashDataSource, ACCOUNTS_DB_CONFIG_FOR_TESTING},
|
||||||
|
accounts_hash::AccountsHash,
|
||||||
|
accounts_index::AccountSecondaryIndexes,
|
||||||
|
epoch_accounts_hash::EpochAccountsHash,
|
||||||
|
},
|
||||||
solana_core::{
|
solana_core::{
|
||||||
accounts_hash_verifier::AccountsHashVerifier,
|
accounts_hash_verifier::AccountsHashVerifier,
|
||||||
snapshot_packager_service::SnapshotPackagerService,
|
snapshot_packager_service::SnapshotPackagerService,
|
||||||
|
@ -14,14 +20,10 @@ use {
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
accounts_background_service::{
|
accounts_background_service::{
|
||||||
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService,
|
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService,
|
||||||
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
PrunedBanksRequestHandler, SendDroppedBankCallback, SnapshotRequestHandler,
|
||||||
},
|
},
|
||||||
accounts_db::{self, CalcAccountsHashDataSource, ACCOUNTS_DB_CONFIG_FOR_TESTING},
|
|
||||||
accounts_hash::AccountsHash,
|
|
||||||
accounts_index::AccountSecondaryIndexes,
|
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
epoch_accounts_hash::EpochAccountsHash,
|
|
||||||
genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo},
|
genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo},
|
||||||
runtime_config::RuntimeConfig,
|
runtime_config::RuntimeConfig,
|
||||||
snapshot_archive_info::FullSnapshotArchiveInfo,
|
snapshot_archive_info::FullSnapshotArchiveInfo,
|
||||||
|
@ -958,14 +960,15 @@ fn test_snapshots_with_background_services(
|
||||||
let (snapshot_package_sender, snapshot_package_receiver) = unbounded();
|
let (snapshot_package_sender, snapshot_package_receiver) = unbounded();
|
||||||
|
|
||||||
let bank_forks = Arc::new(RwLock::new(snapshot_test_config.bank_forks));
|
let bank_forks = Arc::new(RwLock::new(snapshot_test_config.bank_forks));
|
||||||
let callback = bank_forks
|
bank_forks
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.root_bank()
|
.root_bank()
|
||||||
.rc
|
.rc
|
||||||
.accounts
|
.accounts
|
||||||
.accounts_db
|
.accounts_db
|
||||||
.create_drop_bank_callback(pruned_banks_sender);
|
.enable_bank_drop_callback();
|
||||||
|
let callback = SendDroppedBankCallback::new(pruned_banks_sender);
|
||||||
for bank in bank_forks.read().unwrap().banks().values() {
|
for bank in bank_forks.read().unwrap().banks().values() {
|
||||||
bank.set_callback(Some(Box::new(callback.clone())));
|
bank.set_callback(Some(Box::new(callback.clone())));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ edition = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-download-utils = { workspace = true }
|
solana-download-utils = { workspace = true }
|
||||||
solana-rpc-client = { workspace = true }
|
solana-rpc-client = { workspace = true }
|
||||||
solana-runtime = { workspace = true }
|
|
||||||
solana-sdk = { workspace = true }
|
solana-sdk = { workspace = true }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use {
|
use {
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::hardened_unpack::unpack_genesis_archive,
|
||||||
solana_download_utils::download_genesis_if_missing,
|
solana_download_utils::download_genesis_if_missing,
|
||||||
solana_rpc_client::rpc_client::RpcClient,
|
solana_rpc_client::rpc_client::RpcClient,
|
||||||
solana_runtime::hardened_unpack::unpack_genesis_archive,
|
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE},
|
genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE},
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
|
|
|
@ -17,6 +17,7 @@ itertools = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
serde_yaml = { workspace = true }
|
serde_yaml = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-clap-utils = { workspace = true }
|
solana-clap-utils = { workspace = true }
|
||||||
solana-cli-config = { workspace = true }
|
solana-cli-config = { workspace = true }
|
||||||
solana-entry = { workspace = true }
|
solana-entry = { workspace = true }
|
||||||
|
|
|
@ -5,6 +5,7 @@ use {
|
||||||
base64::{prelude::BASE64_STANDARD, Engine},
|
base64::{prelude::BASE64_STANDARD, Engine},
|
||||||
clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg, ArgMatches},
|
clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg, ArgMatches},
|
||||||
itertools::Itertools,
|
itertools::Itertools,
|
||||||
|
solana_accounts_db::hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
||||||
solana_clap_utils::{
|
solana_clap_utils::{
|
||||||
input_parsers::{
|
input_parsers::{
|
||||||
cluster_type_of, pubkey_of, pubkeys_of, unix_timestamp_from_rfc3339_datetime,
|
cluster_type_of, pubkey_of, pubkeys_of, unix_timestamp_from_rfc3339_datetime,
|
||||||
|
@ -16,7 +17,6 @@ use {
|
||||||
solana_entry::poh::compute_hashes_per_tick,
|
solana_entry::poh::compute_hashes_per_tick,
|
||||||
solana_genesis::{genesis_accounts::add_genesis_accounts, Base64Account},
|
solana_genesis::{genesis_accounts::add_genesis_accounts, Base64Account},
|
||||||
solana_ledger::{blockstore::create_new_ledger, blockstore_options::LedgerColumnOptions},
|
solana_ledger::{blockstore::create_new_ledger, blockstore_options::LedgerColumnOptions},
|
||||||
solana_runtime::hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
|
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
|
||||||
bpf_loader_upgradeable::UpgradeableLoaderState,
|
bpf_loader_upgradeable::UpgradeableLoaderState,
|
||||||
|
|
|
@ -19,6 +19,7 @@ jsonrpc-server-utils = { workspace = true }
|
||||||
libloading = { workspace = true }
|
libloading = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-entry = { workspace = true }
|
solana-entry = { workspace = true }
|
||||||
solana-geyser-plugin-interface = { workspace = true }
|
solana-geyser-plugin-interface = { workspace = true }
|
||||||
solana-ledger = { workspace = true }
|
solana-ledger = { workspace = true }
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
use {
|
use {
|
||||||
crate::geyser_plugin_manager::GeyserPluginManager,
|
crate::geyser_plugin_manager::GeyserPluginManager,
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::{
|
||||||
|
account_storage::meta::StoredAccountMeta,
|
||||||
|
accounts_update_notifier_interface::AccountsUpdateNotifierInterface,
|
||||||
|
},
|
||||||
solana_geyser_plugin_interface::geyser_plugin_interface::{
|
solana_geyser_plugin_interface::geyser_plugin_interface::{
|
||||||
ReplicaAccountInfoV3, ReplicaAccountInfoVersions,
|
ReplicaAccountInfoV3, ReplicaAccountInfoVersions,
|
||||||
},
|
},
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_metrics::*,
|
solana_metrics::*,
|
||||||
solana_runtime::{
|
|
||||||
account_storage::meta::StoredAccountMeta,
|
|
||||||
accounts_update_notifier_interface::AccountsUpdateNotifierInterface,
|
|
||||||
},
|
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{AccountSharedData, ReadableAccount},
|
account::{AccountSharedData, ReadableAccount},
|
||||||
clock::Slot,
|
clock::Slot,
|
||||||
|
|
|
@ -4,12 +4,12 @@ use {
|
||||||
geyser_plugin_manager::GeyserPluginManager,
|
geyser_plugin_manager::GeyserPluginManager,
|
||||||
},
|
},
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::stake_rewards::RewardInfo,
|
||||||
solana_geyser_plugin_interface::geyser_plugin_interface::{
|
solana_geyser_plugin_interface::geyser_plugin_interface::{
|
||||||
ReplicaBlockInfoV2, ReplicaBlockInfoVersions,
|
ReplicaBlockInfoV2, ReplicaBlockInfoVersions,
|
||||||
},
|
},
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_metrics::*,
|
solana_metrics::*,
|
||||||
solana_runtime::bank::RewardInfo,
|
|
||||||
solana_sdk::{clock::UnixTimestamp, pubkey::Pubkey},
|
solana_sdk::{clock::UnixTimestamp, pubkey::Pubkey},
|
||||||
solana_transaction_status::{Reward, Rewards},
|
solana_transaction_status::{Reward, Rewards},
|
||||||
std::sync::{Arc, RwLock},
|
std::sync::{Arc, RwLock},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use {
|
use {
|
||||||
solana_runtime::bank::RewardInfo,
|
solana_accounts_db::stake_rewards::RewardInfo,
|
||||||
solana_sdk::{clock::UnixTimestamp, pubkey::Pubkey},
|
solana_sdk::{clock::UnixTimestamp, pubkey::Pubkey},
|
||||||
std::sync::{Arc, RwLock},
|
std::sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,12 @@ use {
|
||||||
},
|
},
|
||||||
crossbeam_channel::Receiver,
|
crossbeam_channel::Receiver,
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::accounts_update_notifier_interface::AccountsUpdateNotifier,
|
||||||
solana_ledger::entry_notifier_interface::EntryNotifierLock,
|
solana_ledger::entry_notifier_interface::EntryNotifierLock,
|
||||||
solana_rpc::{
|
solana_rpc::{
|
||||||
optimistically_confirmed_bank_tracker::SlotNotification,
|
optimistically_confirmed_bank_tracker::SlotNotification,
|
||||||
transaction_notifier_interface::TransactionNotifierLock,
|
transaction_notifier_interface::TransactionNotifierLock,
|
||||||
},
|
},
|
||||||
solana_runtime::accounts_update_notifier_interface::AccountsUpdateNotifier,
|
|
||||||
std::{
|
std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{
|
sync::{
|
||||||
|
|
|
@ -25,6 +25,7 @@ regex = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
solana-account-decoder = { workspace = true }
|
solana-account-decoder = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-bpf-loader-program = { workspace = true }
|
solana-bpf-loader-program = { workspace = true }
|
||||||
solana-clap-utils = { workspace = true }
|
solana-clap-utils = { workspace = true }
|
||||||
solana-cli-output = { workspace = true }
|
solana-cli-output = { workspace = true }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
clap::{value_t, values_t_or_exit, ArgMatches},
|
clap::{value_t, values_t_or_exit, ArgMatches},
|
||||||
solana_runtime::{
|
solana_accounts_db::{
|
||||||
accounts_db::{AccountsDb, AccountsDbConfig, FillerAccountsConfig},
|
accounts_db::{AccountsDb, AccountsDbConfig, FillerAccountsConfig},
|
||||||
accounts_index::{AccountsIndexConfig, IndexLimitMb},
|
accounts_index::{AccountsIndexConfig, IndexLimitMb},
|
||||||
partitioned_rewards::TestPartitionedEpochRewards,
|
partitioned_rewards::TestPartitionedEpochRewards,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use {
|
||||||
clap::{value_t, value_t_or_exit, values_t_or_exit, ArgMatches},
|
clap::{value_t, value_t_or_exit, values_t_or_exit, ArgMatches},
|
||||||
crossbeam_channel::unbounded,
|
crossbeam_channel::unbounded,
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::hardened_unpack::open_genesis_config,
|
||||||
solana_core::{
|
solana_core::{
|
||||||
accounts_hash_verifier::AccountsHashVerifier, validator::BlockVerificationMethod,
|
accounts_hash_verifier::AccountsHashVerifier, validator::BlockVerificationMethod,
|
||||||
},
|
},
|
||||||
|
@ -26,7 +27,6 @@ use {
|
||||||
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
PrunedBanksRequestHandler, SnapshotRequestHandler,
|
||||||
},
|
},
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
hardened_unpack::open_genesis_config,
|
|
||||||
snapshot_config::SnapshotConfig,
|
snapshot_config::SnapshotConfig,
|
||||||
snapshot_hash::StartingSnapshotHashes,
|
snapshot_hash::StartingSnapshotHashes,
|
||||||
snapshot_utils::{
|
snapshot_utils::{
|
||||||
|
|
|
@ -16,6 +16,10 @@ use {
|
||||||
},
|
},
|
||||||
serde_json::json,
|
serde_json::json,
|
||||||
solana_account_decoder::{UiAccount, UiAccountData, UiAccountEncoding},
|
solana_account_decoder::{UiAccount, UiAccountData, UiAccountEncoding},
|
||||||
|
solana_accounts_db::{
|
||||||
|
accounts::Accounts, accounts_db::CalcAccountsHashDataSource, accounts_index::ScanConfig,
|
||||||
|
hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
||||||
|
},
|
||||||
solana_clap_utils::{
|
solana_clap_utils::{
|
||||||
hidden_unless_forced,
|
hidden_unless_forced,
|
||||||
input_parsers::{cluster_type_of, pubkey_of, pubkeys_of},
|
input_parsers::{cluster_type_of, pubkey_of, pubkeys_of},
|
||||||
|
@ -46,12 +50,8 @@ use {
|
||||||
},
|
},
|
||||||
solana_measure::{measure, measure::Measure},
|
solana_measure::{measure, measure::Measure},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
accounts::Accounts,
|
|
||||||
accounts_db::CalcAccountsHashDataSource,
|
|
||||||
accounts_index::ScanConfig,
|
|
||||||
bank::{Bank, RewardCalculationEvent, TotalAccountsStats},
|
bank::{Bank, RewardCalculationEvent, TotalAccountsStats},
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
|
||||||
runtime_config::RuntimeConfig,
|
runtime_config::RuntimeConfig,
|
||||||
snapshot_archive_info::SnapshotArchiveInfoGetter,
|
snapshot_archive_info::SnapshotArchiveInfoGetter,
|
||||||
snapshot_bank_utils,
|
snapshot_bank_utils,
|
||||||
|
@ -2292,7 +2292,7 @@ fn main() {
|
||||||
create_new_ledger(
|
create_new_ledger(
|
||||||
&output_directory,
|
&output_directory,
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
solana_runtime::hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
solana_accounts_db::hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
||||||
LedgerColumnOptions::default(),
|
LedgerColumnOptions::default(),
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
|
|
|
@ -37,6 +37,7 @@ serde = { workspace = true }
|
||||||
serde_bytes = { workspace = true }
|
serde_bytes = { workspace = true }
|
||||||
sha2 = { workspace = true }
|
sha2 = { workspace = true }
|
||||||
solana-account-decoder = { workspace = true }
|
solana-account-decoder = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-bpf-loader-program = { workspace = true }
|
solana-bpf-loader-program = { workspace = true }
|
||||||
solana-cost-model = { workspace = true }
|
solana-cost-model = { workspace = true }
|
||||||
solana-entry = { workspace = true }
|
solana-entry = { workspace = true }
|
||||||
|
|
|
@ -10,9 +10,9 @@ use {
|
||||||
use_snapshot_archives_at_startup::{self, UseSnapshotArchivesAtStartup},
|
use_snapshot_archives_at_startup::{self, UseSnapshotArchivesAtStartup},
|
||||||
},
|
},
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::accounts_update_notifier_interface::AccountsUpdateNotifier,
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
accounts_background_service::AbsRequestSender,
|
accounts_background_service::AbsRequestSender,
|
||||||
accounts_update_notifier_interface::AccountsUpdateNotifier,
|
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
snapshot_archive_info::{
|
snapshot_archive_info::{
|
||||||
FullSnapshotArchiveInfo, IncrementalSnapshotArchiveInfo, SnapshotArchiveInfoGetter,
|
FullSnapshotArchiveInfo, IncrementalSnapshotArchiveInfo, SnapshotArchiveInfoGetter,
|
||||||
|
|
|
@ -32,6 +32,9 @@ use {
|
||||||
ThreadPool,
|
ThreadPool,
|
||||||
},
|
},
|
||||||
rocksdb::{DBRawIterator, LiveFile},
|
rocksdb::{DBRawIterator, LiveFile},
|
||||||
|
solana_accounts_db::hardened_unpack::{
|
||||||
|
unpack_genesis_archive, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
|
||||||
|
},
|
||||||
solana_entry::entry::{create_ticks, Entry},
|
solana_entry::entry::{create_ticks, Entry},
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_metrics::{
|
solana_metrics::{
|
||||||
|
@ -39,10 +42,7 @@ use {
|
||||||
poh_timing_point::{send_poh_timing_point, PohTimingSender, SlotPohTimingInfo},
|
poh_timing_point::{send_poh_timing_point, PohTimingSender, SlotPohTimingInfo},
|
||||||
},
|
},
|
||||||
solana_rayon_threadlimit::get_max_thread_count,
|
solana_rayon_threadlimit::get_max_thread_count,
|
||||||
solana_runtime::{
|
solana_runtime::bank::Bank,
|
||||||
bank::Bank,
|
|
||||||
hardened_unpack::{unpack_genesis_archive, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
|
|
||||||
},
|
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, UnixTimestamp, DEFAULT_TICKS_PER_SECOND},
|
clock::{Slot, UnixTimestamp, DEFAULT_TICKS_PER_SECOND},
|
||||||
genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE, DEFAULT_GENESIS_FILE},
|
genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE, DEFAULT_GENESIS_FILE},
|
||||||
|
|
|
@ -26,7 +26,7 @@ use {
|
||||||
WriteBatch as RWriteBatch, DB,
|
WriteBatch as RWriteBatch, DB,
|
||||||
},
|
},
|
||||||
serde::{de::DeserializeOwned, Serialize},
|
serde::{de::DeserializeOwned, Serialize},
|
||||||
solana_runtime::hardened_unpack::UnpackError,
|
solana_accounts_db::hardened_unpack::UnpackError,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, UnixTimestamp},
|
clock::{Slot, UnixTimestamp},
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
|
|
|
@ -16,6 +16,16 @@ use {
|
||||||
rand::{seq::SliceRandom, thread_rng},
|
rand::{seq::SliceRandom, thread_rng},
|
||||||
rayon::{prelude::*, ThreadPool},
|
rayon::{prelude::*, ThreadPool},
|
||||||
scopeguard::defer,
|
scopeguard::defer,
|
||||||
|
solana_accounts_db::{
|
||||||
|
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
|
||||||
|
accounts_index::AccountSecondaryIndexes,
|
||||||
|
accounts_update_notifier_interface::AccountsUpdateNotifier,
|
||||||
|
epoch_accounts_hash::EpochAccountsHash,
|
||||||
|
rent_debits::RentDebits,
|
||||||
|
transaction_results::{
|
||||||
|
TransactionExecutionDetails, TransactionExecutionResult, TransactionResults,
|
||||||
|
},
|
||||||
|
},
|
||||||
solana_cost_model::cost_model::CostModel,
|
solana_cost_model::cost_model::CostModel,
|
||||||
solana_entry::entry::{
|
solana_entry::entry::{
|
||||||
self, create_ticks, Entry, EntrySlice, EntryType, EntryVerificationStatus, VerifyRecyclers,
|
self, create_ticks, Entry, EntrySlice, EntryType, EntryVerificationStatus, VerifyRecyclers,
|
||||||
|
@ -26,21 +36,13 @@ use {
|
||||||
solana_rayon_threadlimit::{get_max_thread_count, get_thread_count},
|
solana_rayon_threadlimit::{get_max_thread_count, get_thread_count},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
accounts_background_service::{AbsRequestSender, SnapshotRequestType},
|
accounts_background_service::{AbsRequestSender, SnapshotRequestType},
|
||||||
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
|
|
||||||
accounts_index::AccountSecondaryIndexes,
|
|
||||||
accounts_update_notifier_interface::AccountsUpdateNotifier,
|
|
||||||
bank::{Bank, TransactionBalancesSet},
|
bank::{Bank, TransactionBalancesSet},
|
||||||
bank_forks::BankForks,
|
bank_forks::BankForks,
|
||||||
bank_utils,
|
bank_utils,
|
||||||
commitment::VOTE_THRESHOLD_SIZE,
|
commitment::VOTE_THRESHOLD_SIZE,
|
||||||
epoch_accounts_hash::EpochAccountsHash,
|
|
||||||
prioritization_fee_cache::PrioritizationFeeCache,
|
prioritization_fee_cache::PrioritizationFeeCache,
|
||||||
rent_debits::RentDebits,
|
|
||||||
runtime_config::RuntimeConfig,
|
runtime_config::RuntimeConfig,
|
||||||
transaction_batch::TransactionBatch,
|
transaction_batch::TransactionBatch,
|
||||||
transaction_results::{
|
|
||||||
TransactionExecutionDetails, TransactionExecutionResult, TransactionResults,
|
|
||||||
},
|
|
||||||
vote_account::VoteAccountsHashMap,
|
vote_account::VoteAccountsHashMap,
|
||||||
vote_sender_types::ReplayVoteSender,
|
vote_sender_types::ReplayVoteSender,
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,6 +15,7 @@ itertools = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
|
solana-accounts-db = { workspace = true }
|
||||||
solana-client = { workspace = true }
|
solana-client = { workspace = true }
|
||||||
solana-config-program = { workspace = true }
|
solana-config-program = { workspace = true }
|
||||||
solana-core = { workspace = true }
|
solana-core = { workspace = true }
|
||||||
|
|
|
@ -6,6 +6,7 @@ use {
|
||||||
},
|
},
|
||||||
itertools::izip,
|
itertools::izip,
|
||||||
log::*,
|
log::*,
|
||||||
|
solana_accounts_db::accounts_db::create_accounts_run_and_snapshot_dirs,
|
||||||
solana_client::{connection_cache::ConnectionCache, thin_client::ThinClient},
|
solana_client::{connection_cache::ConnectionCache, thin_client::ThinClient},
|
||||||
solana_core::{
|
solana_core::{
|
||||||
consensus::tower_storage::FileTowerStorage,
|
consensus::tower_storage::FileTowerStorage,
|
||||||
|
@ -23,7 +24,6 @@ use {
|
||||||
ValidatorVoteKeypairs,
|
ValidatorVoteKeypairs,
|
||||||
},
|
},
|
||||||
snapshot_config::SnapshotConfig,
|
snapshot_config::SnapshotConfig,
|
||||||
snapshot_utils::create_accounts_run_and_snapshot_dirs,
|
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{Account, AccountSharedData},
|
account::{Account, AccountSharedData},
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue