deps: replace lru with schnellru (#1217)

* deps: replace lru with schnellru

* bring the peace to the galaxy
This commit is contained in:
ordian
2023-08-28 19:04:11 +02:00
committed by GitHub
parent 7125f65fe6
commit c168a77e26
32 changed files with 207 additions and 241 deletions
Generated
+12 -15
View File
@@ -3332,7 +3332,6 @@ dependencies = [
"cumulus-primitives-parachain-inherent", "cumulus-primitives-parachain-inherent",
"cumulus-relay-chain-interface", "cumulus-relay-chain-interface",
"futures", "futures",
"lru 0.10.1",
"parity-scale-codec", "parity-scale-codec",
"polkadot-node-primitives", "polkadot-node-primitives",
"polkadot-node-subsystem", "polkadot-node-subsystem",
@@ -3344,6 +3343,7 @@ dependencies = [
"sc-consensus-babe", "sc-consensus-babe",
"sc-consensus-slots", "sc-consensus-slots",
"sc-telemetry", "sc-telemetry",
"schnellru",
"sp-api", "sp-api",
"sp-application-crypto", "sp-application-crypto",
"sp-block-builder", "sp-block-builder",
@@ -3822,7 +3822,6 @@ dependencies = [
"cumulus-relay-chain-interface", "cumulus-relay-chain-interface",
"cumulus-relay-chain-rpc-interface", "cumulus-relay-chain-rpc-interface",
"futures", "futures",
"lru 0.11.0",
"polkadot-availability-recovery", "polkadot-availability-recovery",
"polkadot-collator-protocol", "polkadot-collator-protocol",
"polkadot-core-primitives", "polkadot-core-primitives",
@@ -3839,6 +3838,7 @@ dependencies = [
"sc-service", "sc-service",
"sc-tracing", "sc-tracing",
"sc-utils", "sc-utils",
"schnellru",
"sp-api", "sp-api",
"sp-consensus", "sp-consensus",
"sp-consensus-babe", "sp-consensus-babe",
@@ -3857,7 +3857,6 @@ dependencies = [
"futures", "futures",
"futures-timer", "futures-timer",
"jsonrpsee", "jsonrpsee",
"lru 0.11.0",
"parity-scale-codec", "parity-scale-codec",
"pin-project", "pin-project",
"polkadot-overseer", "polkadot-overseer",
@@ -3865,6 +3864,7 @@ dependencies = [
"sc-client-api", "sc-client-api",
"sc-rpc-api", "sc-rpc-api",
"sc-service", "sc-service",
"schnellru",
"serde", "serde",
"serde_json", "serde_json",
"smoldot", "smoldot",
@@ -7765,9 +7765,6 @@ name = "lru"
version = "0.11.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5"
dependencies = [
"hashbrown 0.14.0",
]
[[package]] [[package]]
name = "lru-cache" name = "lru-cache"
@@ -11696,7 +11693,6 @@ dependencies = [
"fatality", "fatality",
"futures", "futures",
"futures-timer", "futures-timer",
"lru 0.11.0",
"parity-scale-codec", "parity-scale-codec",
"polkadot-erasure-coding", "polkadot-erasure-coding",
"polkadot-node-network-protocol", "polkadot-node-network-protocol",
@@ -11708,6 +11704,7 @@ dependencies = [
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"rand 0.8.5", "rand 0.8.5",
"sc-network", "sc-network",
"schnellru",
"sp-core", "sp-core",
"sp-keyring", "sp-keyring",
"sp-keystore", "sp-keystore",
@@ -11726,7 +11723,6 @@ dependencies = [
"futures", "futures",
"futures-timer", "futures-timer",
"log", "log",
"lru 0.11.0",
"parity-scale-codec", "parity-scale-codec",
"polkadot-erasure-coding", "polkadot-erasure-coding",
"polkadot-node-network-protocol", "polkadot-node-network-protocol",
@@ -11738,6 +11734,7 @@ dependencies = [
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"rand 0.8.5", "rand 0.8.5",
"sc-network", "sc-network",
"schnellru",
"sp-application-crypto", "sp-application-crypto",
"sp-core", "sp-core",
"sp-keyring", "sp-keyring",
@@ -11827,7 +11824,6 @@ dependencies = [
"futures-timer", "futures-timer",
"indexmap 1.9.3", "indexmap 1.9.3",
"lazy_static", "lazy_static",
"lru 0.11.0",
"parity-scale-codec", "parity-scale-codec",
"polkadot-erasure-coding", "polkadot-erasure-coding",
"polkadot-node-network-protocol", "polkadot-node-network-protocol",
@@ -11839,6 +11835,7 @@ dependencies = [
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"sc-keystore", "sc-keystore",
"sc-network", "sc-network",
"schnellru",
"sp-application-crypto", "sp-application-crypto",
"sp-keyring", "sp-keyring",
"sp-keystore", "sp-keystore",
@@ -11951,7 +11948,6 @@ dependencies = [
"futures-timer", "futures-timer",
"kvdb", "kvdb",
"kvdb-memorydb", "kvdb-memorydb",
"lru 0.11.0",
"merlin 2.0.1", "merlin 2.0.1",
"parity-scale-codec", "parity-scale-codec",
"parking_lot 0.12.1", "parking_lot 0.12.1",
@@ -11965,6 +11961,7 @@ dependencies = [
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"rand_core 0.5.1", "rand_core 0.5.1",
"sc-keystore", "sc-keystore",
"schnellru",
"schnorrkel 0.9.1", "schnorrkel 0.9.1",
"sp-application-crypto", "sp-application-crypto",
"sp-consensus", "sp-consensus",
@@ -12125,7 +12122,6 @@ dependencies = [
"futures-timer", "futures-timer",
"kvdb", "kvdb",
"kvdb-memorydb", "kvdb-memorydb",
"lru 0.11.0",
"parity-scale-codec", "parity-scale-codec",
"polkadot-node-primitives", "polkadot-node-primitives",
"polkadot-node-subsystem", "polkadot-node-subsystem",
@@ -12134,6 +12130,7 @@ dependencies = [
"polkadot-primitives", "polkadot-primitives",
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"sc-keystore", "sc-keystore",
"schnellru",
"sp-application-crypto", "sp-application-crypto",
"sp-core", "sp-core",
"sp-keyring", "sp-keyring",
@@ -12333,7 +12330,6 @@ version = "1.0.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"futures", "futures",
"lru 0.11.0",
"polkadot-node-metrics", "polkadot-node-metrics",
"polkadot-node-primitives", "polkadot-node-primitives",
"polkadot-node-subsystem", "polkadot-node-subsystem",
@@ -12341,6 +12337,7 @@ dependencies = [
"polkadot-node-subsystem-types", "polkadot-node-subsystem-types",
"polkadot-primitives", "polkadot-primitives",
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"schnellru",
"sp-api", "sp-api",
"sp-consensus-babe", "sp-consensus-babe",
"sp-core", "sp-core",
@@ -12504,7 +12501,6 @@ dependencies = [
"kvdb-shared-tests", "kvdb-shared-tests",
"lazy_static", "lazy_static",
"log", "log",
"lru 0.11.0",
"parity-db", "parity-db",
"parity-scale-codec", "parity-scale-codec",
"parking_lot 0.11.2", "parking_lot 0.11.2",
@@ -12520,6 +12516,7 @@ dependencies = [
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"prioritized-metered-channel", "prioritized-metered-channel",
"rand 0.8.5", "rand 0.8.5",
"schnellru",
"sp-application-crypto", "sp-application-crypto",
"sp-core", "sp-core",
"sp-keystore", "sp-keystore",
@@ -12537,7 +12534,6 @@ dependencies = [
"femme", "femme",
"futures", "futures",
"futures-timer", "futures-timer",
"lru 0.11.0",
"orchestra", "orchestra",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"polkadot-node-metrics", "polkadot-node-metrics",
@@ -12548,6 +12544,7 @@ dependencies = [
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"prioritized-metered-channel", "prioritized-metered-channel",
"sc-client-api", "sc-client-api",
"schnellru",
"sp-api", "sp-api",
"sp-core", "sp-core",
"tikv-jemalloc-ctl", "tikv-jemalloc-ctl",
@@ -12992,7 +12989,6 @@ dependencies = [
"kvdb", "kvdb",
"kvdb-rocksdb", "kvdb-rocksdb",
"log", "log",
"lru 0.11.0",
"mmr-gadget", "mmr-gadget",
"pallet-babe", "pallet-babe",
"pallet-im-online", "pallet-im-online",
@@ -13066,6 +13062,7 @@ dependencies = [
"sc-telemetry", "sc-telemetry",
"sc-transaction-pool", "sc-transaction-pool",
"sc-transaction-pool-api", "sc-transaction-pool-api",
"schnellru",
"serde", "serde",
"serde_json", "serde_json",
"serial_test", "serial_test",
+1 -1
View File
@@ -10,7 +10,7 @@ async-trait = "0.1.73"
codec = { package = "parity-scale-codec", version = "3.0.0", features = [ "derive" ] } codec = { package = "parity-scale-codec", version = "3.0.0", features = [ "derive" ] }
futures = "0.3.28" futures = "0.3.28"
tracing = "0.1.37" tracing = "0.1.37"
lru = "0.10.0" schnellru = "0.2.1"
# Substrate # Substrate
sc-client-api = { path = "../../../../substrate/client/api" } sc-client-api = { path = "../../../../substrate/client/api" }
@@ -21,7 +21,7 @@
/// should be thrown out and which ones should be kept. /// should be thrown out and which ones should be kept.
use codec::Codec; use codec::Codec;
use cumulus_client_consensus_common::ParachainBlockImportMarker; use cumulus_client_consensus_common::ParachainBlockImportMarker;
use lru::LruCache; use schnellru::{ByLength, LruMap};
use sc_consensus::{ use sc_consensus::{
import_queue::{BasicQueue, Verifier as VerifierT}, import_queue::{BasicQueue, Verifier as VerifierT},
@@ -36,27 +36,28 @@ use sp_consensus_aura::{AuraApi, Slot, SlotDuration};
use sp_core::crypto::Pair; use sp_core::crypto::Pair;
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider}; use sp_inherents::{CreateInherentDataProviders, InherentDataProvider};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
use std::{fmt::Debug, num::NonZeroUsize, sync::Arc}; use std::{fmt::Debug, sync::Arc};
const LRU_WINDOW: usize = 256; const LRU_WINDOW: u32 = 256;
const EQUIVOCATION_LIMIT: usize = 16; const EQUIVOCATION_LIMIT: usize = 16;
struct NaiveEquivocationDefender { struct NaiveEquivocationDefender {
cache: LruCache<u64, usize>, cache: LruMap<u64, usize>,
} }
impl Default for NaiveEquivocationDefender { impl Default for NaiveEquivocationDefender {
fn default() -> Self { fn default() -> Self {
NaiveEquivocationDefender { NaiveEquivocationDefender { cache: LruMap::new(ByLength::new(LRU_WINDOW)) }
cache: LruCache::new(NonZeroUsize::new(LRU_WINDOW).expect("window > 0; qed")),
}
} }
} }
impl NaiveEquivocationDefender { impl NaiveEquivocationDefender {
// return `true` if equivocation is beyond the limit. // return `true` if equivocation is beyond the limit.
fn insert_and_check(&mut self, slot: Slot) -> bool { fn insert_and_check(&mut self, slot: Slot) -> bool {
let val = self.cache.get_or_insert_mut(*slot, || 0); let val = self
.cache
.get_or_insert(*slot, || 0)
.expect("insertion with ByLength limiter always succeeds; qed");
if *val == EQUIVOCATION_LIMIT { if *val == EQUIVOCATION_LIMIT {
true true
} else { } else {
@@ -36,7 +36,7 @@ cumulus-relay-chain-rpc-interface = { path = "../relay-chain-rpc-interface" }
cumulus-primitives-core = { path = "../../primitives/core" } cumulus-primitives-core = { path = "../../primitives/core" }
array-bytes = "6.1" array-bytes = "6.1"
lru = "0.11.0" schnellru = "0.2.1"
tracing = "0.1.37" tracing = "0.1.37"
async-trait = "0.1.73" async-trait = "0.1.73"
futures = "0.3.28" futures = "0.3.28"
@@ -15,7 +15,7 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use futures::{select, StreamExt}; use futures::{select, StreamExt};
use lru::LruCache; use schnellru::{ByLength, LruMap};
use std::sync::Arc; use std::sync::Arc;
use polkadot_availability_recovery::AvailabilityRecoverySubsystem; use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
@@ -157,7 +157,7 @@ fn build_overseer(
.span_per_active_leaf(Default::default()) .span_per_active_leaf(Default::default())
.active_leaves(Default::default()) .active_leaves(Default::default())
.supports_parachains(runtime_client) .supports_parachains(runtime_client)
.known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE)) .known_leaves(LruMap::new(ByLength::new(KNOWN_LEAVES_CACHE_SIZE)))
.metrics(Metrics::register(registry)?) .metrics(Metrics::register(registry)?)
.spawner(spawner); .spawner(spawner);
@@ -34,7 +34,7 @@ async-trait = "0.1.73"
url = "2.4.0" url = "2.4.0"
serde_json = "1.0.105" serde_json = "1.0.105"
serde = "1.0.183" serde = "1.0.183"
lru = "0.11.0" schnellru = "0.2.1"
smoldot = { version = "0.11.0", default_features = false, features = ["std"]} smoldot = { version = "0.11.0", default_features = false, features = ["std"]}
smoldot-light = { version = "0.9.0", default_features = false, features = ["std"] } smoldot-light = { version = "0.9.0", default_features = false, features = ["std"] }
either = "1.8.1" either = "1.8.1"
@@ -31,10 +31,10 @@ use jsonrpsee::{
}, },
ws_client::WsClientBuilder, ws_client::WsClientBuilder,
}; };
use lru::LruCache;
use sc_rpc_api::chain::ChainApiClient; use sc_rpc_api::chain::ChainApiClient;
use schnellru::{ByLength, LruMap};
use sp_runtime::generic::SignedBlock; use sp_runtime::generic::SignedBlock;
use std::{num::NonZeroUsize, sync::Arc}; use std::sync::Arc;
use tokio::sync::mpsc::{ use tokio::sync::mpsc::{
channel as tokio_channel, Receiver as TokioReceiver, Sender as TokioSender, channel as tokio_channel, Receiver as TokioReceiver, Sender as TokioSender,
}; };
@@ -307,8 +307,7 @@ impl ReconnectingWebsocketWorker {
return return
}; };
let mut imported_blocks_cache = let mut imported_blocks_cache = LruMap::new(ByLength::new(40));
LruCache::new(NonZeroUsize::new(40).expect("40 is nonzero; qed."));
let mut should_reconnect = ConnectionStatus::Connected; let mut should_reconnect = ConnectionStatus::Connected;
let mut last_seen_finalized_num: RelayNumber = 0; let mut last_seen_finalized_num: RelayNumber = 0;
loop { loop {
@@ -365,7 +364,7 @@ impl ReconnectingWebsocketWorker {
match import_event { match import_event {
Some(Ok(header)) => { Some(Ok(header)) => {
let hash = header.hash(); let hash = header.hash();
if imported_blocks_cache.contains(&hash) { if imported_blocks_cache.peek(&hash).is_some() {
tracing::debug!( tracing::debug!(
target: LOG_TARGET, target: LOG_TARGET,
number = header.number, number = header.number,
@@ -374,7 +373,7 @@ impl ReconnectingWebsocketWorker {
); );
continue; continue;
} }
imported_blocks_cache.put(hash, ()); imported_blocks_cache.insert(hash, ());
distribute_header(header, &mut self.imported_header_listeners); distribute_header(header, &mut self.imported_header_listeners);
}, },
None => { None => {
@@ -11,7 +11,7 @@ futures-timer = "3.0.2"
parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] }
gum = { package = "tracing-gum", path = "../../gum" } gum = { package = "tracing-gum", path = "../../gum" }
bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] }
lru = "0.11.0" schnellru = "0.2.1"
merlin = "2.0" merlin = "2.0"
schnorrkel = "0.9.1" schnorrkel = "0.9.1"
kvdb = "0.13.0" kvdb = "0.13.0"
@@ -643,7 +643,7 @@ pub(crate) mod tests {
blank_state(), blank_state(),
RuntimeInfo::new_with_config(RuntimeInfoConfig { RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: DISPUTE_WINDOW.into(), session_cache_lru_size: DISPUTE_WINDOW.get(),
}), }),
) )
} }
@@ -755,7 +755,7 @@ pub(crate) mod tests {
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: DISPUTE_WINDOW.into(), session_cache_lru_size: DISPUTE_WINDOW.get(),
}); });
let header = header.clone(); let header = header.clone();
@@ -878,7 +878,7 @@ pub(crate) mod tests {
let test_fut = { let test_fut = {
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: DISPUTE_WINDOW.into(), session_cache_lru_size: DISPUTE_WINDOW.get(),
}); });
let header = header.clone(); let header = header.clone();
@@ -994,7 +994,7 @@ pub(crate) mod tests {
let test_fut = { let test_fut = {
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: DISPUTE_WINDOW.into(), session_cache_lru_size: DISPUTE_WINDOW.get(),
}); });
let header = header.clone(); let header = header.clone();
@@ -1092,7 +1092,7 @@ pub(crate) mod tests {
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: DISPUTE_WINDOW.into(), session_cache_lru_size: DISPUTE_WINDOW.get(),
}); });
let header = header.clone(); let header = header.clone();
+9 -10
View File
@@ -69,11 +69,12 @@ use std::{
collections::{ collections::{
btree_map::Entry as BTMEntry, hash_map::Entry as HMEntry, BTreeMap, HashMap, HashSet, btree_map::Entry as BTMEntry, hash_map::Entry as HMEntry, BTreeMap, HashMap, HashSet,
}, },
num::NonZeroUsize,
sync::Arc, sync::Arc,
time::Duration, time::Duration,
}; };
use schnellru::{ByLength, LruMap};
use approval_checking::RequiredTranches; use approval_checking::RequiredTranches;
use criteria::{AssignmentCriteria, RealAssignmentCriteria}; use criteria::{AssignmentCriteria, RealAssignmentCriteria};
use persisted_entries::{ApprovalEntry, BlockEntry, CandidateEntry}; use persisted_entries::{ApprovalEntry, BlockEntry, CandidateEntry};
@@ -102,10 +103,7 @@ const APPROVAL_CHECKING_TIMEOUT: Duration = Duration::from_secs(120);
/// Value rather arbitrarily: Should not be hit in practice, it exists to more easily diagnose dead /// Value rather arbitrarily: Should not be hit in practice, it exists to more easily diagnose dead
/// lock issues for example. /// lock issues for example.
const WAIT_FOR_SIGS_TIMEOUT: Duration = Duration::from_millis(500); const WAIT_FOR_SIGS_TIMEOUT: Duration = Duration::from_millis(500);
const APPROVAL_CACHE_SIZE: NonZeroUsize = match NonZeroUsize::new(1024) { const APPROVAL_CACHE_SIZE: u32 = 1024;
Some(cap) => cap,
None => panic!("Approval cache size must be non-zero."),
};
const TICK_TOO_FAR_IN_FUTURE: Tick = 20; // 10 seconds. const TICK_TOO_FAR_IN_FUTURE: Tick = 20; // 10 seconds.
const APPROVAL_DELAY: Tick = 2; const APPROVAL_DELAY: Tick = 2;
@@ -627,7 +625,7 @@ impl CurrentlyCheckingSet {
pub async fn next( pub async fn next(
&mut self, &mut self,
approvals_cache: &mut lru::LruCache<CandidateHash, ApprovalOutcome>, approvals_cache: &mut LruMap<CandidateHash, ApprovalOutcome>,
) -> (HashSet<Hash>, ApprovalState) { ) -> (HashSet<Hash>, ApprovalState) {
if !self.currently_checking.is_empty() { if !self.currently_checking.is_empty() {
if let Some(approval_state) = self.currently_checking.next().await { if let Some(approval_state) = self.currently_checking.next().await {
@@ -635,7 +633,8 @@ impl CurrentlyCheckingSet {
.candidate_hash_map .candidate_hash_map
.remove(&approval_state.candidate_hash) .remove(&approval_state.candidate_hash)
.unwrap_or_default(); .unwrap_or_default();
approvals_cache.put(approval_state.candidate_hash, approval_state.approval_outcome); approvals_cache
.insert(approval_state.candidate_hash, approval_state.approval_outcome);
return (out, approval_state) return (out, approval_state)
} }
} }
@@ -782,11 +781,11 @@ where
// `None` on start-up. Gets initialized/updated on leaf update // `None` on start-up. Gets initialized/updated on leaf update
let mut session_info_provider = RuntimeInfo::new_with_config(RuntimeInfoConfig { let mut session_info_provider = RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: DISPUTE_WINDOW.into(), session_cache_lru_size: DISPUTE_WINDOW.get(),
}); });
let mut wakeups = Wakeups::default(); let mut wakeups = Wakeups::default();
let mut currently_checking_set = CurrentlyCheckingSet::default(); let mut currently_checking_set = CurrentlyCheckingSet::default();
let mut approvals_cache = lru::LruCache::new(APPROVAL_CACHE_SIZE); let mut approvals_cache = LruMap::new(ByLength::new(APPROVAL_CACHE_SIZE));
let mut last_finalized_height: Option<BlockNumber> = { let mut last_finalized_height: Option<BlockNumber> = {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
@@ -922,7 +921,7 @@ async fn handle_actions<Context>(
metrics: &Metrics, metrics: &Metrics,
wakeups: &mut Wakeups, wakeups: &mut Wakeups,
currently_checking_set: &mut CurrentlyCheckingSet, currently_checking_set: &mut CurrentlyCheckingSet,
approvals_cache: &mut lru::LruCache<CandidateHash, ApprovalOutcome>, approvals_cache: &mut LruMap<CandidateHash, ApprovalOutcome>,
mode: &mut Mode, mode: &mut Mode,
actions: Vec<Action>, actions: Vec<Action>,
) -> SubsystemResult<bool> { ) -> SubsystemResult<bool> {
@@ -11,7 +11,7 @@ gum = { package = "tracing-gum", path = "../../gum" }
parity-scale-codec = "3.6.1" parity-scale-codec = "3.6.1"
kvdb = "0.13.0" kvdb = "0.13.0"
thiserror = "1.0.31" thiserror = "1.0.31"
lru = "0.11.0" schnellru = "0.2.1"
fatality = "0.0.6" fatality = "0.0.6"
polkadot-primitives = { path = "../../../primitives" } polkadot-primitives = { path = "../../../primitives" }
@@ -25,7 +25,7 @@
//! When importing a dispute vote from another node, this will trigger dispute participation to //! When importing a dispute vote from another node, this will trigger dispute participation to
//! recover and validate the block. //! recover and validate the block.
use std::{num::NonZeroUsize, sync::Arc}; use std::sync::Arc;
use futures::FutureExt; use futures::FutureExt;
@@ -222,8 +222,7 @@ impl DisputeCoordinatorSubsystem {
// keep all sessions for a dispute window // keep all sessions for a dispute window
let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig {
keystore: None, keystore: None,
session_cache_lru_size: NonZeroUsize::new(DISPUTE_WINDOW.get() as usize) session_cache_lru_size: DISPUTE_WINDOW.get(),
.expect("DISPUTE_WINDOW can't be 0; qed."),
}); });
let mut overlay_db = OverlayedBackend::new(&mut backend); let mut overlay_db = OverlayedBackend::new(&mut backend);
let ( let (
@@ -14,13 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::{ use std::collections::{BTreeMap, HashSet};
collections::{BTreeMap, HashSet},
num::NonZeroUsize,
};
use futures::channel::oneshot; use futures::channel::oneshot;
use lru::LruCache; use schnellru::{ByLength, LruMap};
use polkadot_node_primitives::{DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION, MAX_FINALITY_LAG}; use polkadot_node_primitives::{DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION, MAX_FINALITY_LAG};
use polkadot_node_subsystem::{ use polkadot_node_subsystem::{
@@ -52,10 +49,7 @@ mod candidates;
/// `last_observed_blocks` LRU. This means, this value should the very least be as large as the /// `last_observed_blocks` LRU. This means, this value should the very least be as large as the
/// number of expected forks for keeping chain scraping efficient. Making the LRU much larger than /// number of expected forks for keeping chain scraping efficient. Making the LRU much larger than
/// that has very limited use. /// that has very limited use.
const LRU_OBSERVED_BLOCKS_CAPACITY: NonZeroUsize = match NonZeroUsize::new(20) { const LRU_OBSERVED_BLOCKS_CAPACITY: u32 = 20;
Some(cap) => cap,
None => panic!("Observed blocks cache size must be non-zero"),
};
/// `ScrapedUpdates` /// `ScrapedUpdates`
/// ///
@@ -173,7 +167,7 @@ pub struct ChainScraper {
/// ///
/// We assume that ancestors of cached blocks are already processed, i.e. we have saved /// We assume that ancestors of cached blocks are already processed, i.e. we have saved
/// corresponding included candidates. /// corresponding included candidates.
last_observed_blocks: LruCache<Hash, ()>, last_observed_blocks: LruMap<Hash, ()>,
/// Maps included candidate hashes to one or more relay block heights and hashes. /// Maps included candidate hashes to one or more relay block heights and hashes.
/// These correspond to all the relay blocks which marked a candidate as included, /// These correspond to all the relay blocks which marked a candidate as included,
/// and are needed to apply reversions in case a dispute is concluded against the /// and are needed to apply reversions in case a dispute is concluded against the
@@ -202,7 +196,7 @@ impl ChainScraper {
let mut s = Self { let mut s = Self {
included_candidates: candidates::ScrapedCandidates::new(), included_candidates: candidates::ScrapedCandidates::new(),
backed_candidates: candidates::ScrapedCandidates::new(), backed_candidates: candidates::ScrapedCandidates::new(),
last_observed_blocks: LruCache::new(LRU_OBSERVED_BLOCKS_CAPACITY), last_observed_blocks: LruMap::new(ByLength::new(LRU_OBSERVED_BLOCKS_CAPACITY)),
inclusions: Inclusions::new(), inclusions: Inclusions::new(),
}; };
let update = let update =
@@ -288,7 +282,7 @@ impl ChainScraper {
}, },
} }
self.last_observed_blocks.put(activated.hash, ()); self.last_observed_blocks.insert(activated.hash, ());
Ok(scraped_updates) Ok(scraped_updates)
} }
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies] [dependencies]
futures = "0.3.21" futures = "0.3.21"
gum = { package = "tracing-gum", path = "../../gum" } gum = { package = "tracing-gum", path = "../../gum" }
lru = "0.11.0" schnellru = "0.2.1"
sp-consensus-babe = { path = "../../../../substrate/primitives/consensus/babe" } sp-consensus-babe = { path = "../../../../substrate/primitives/consensus/babe" }
+107 -110
View File
@@ -14,9 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::{collections::btree_map::BTreeMap, num::NonZeroUsize}; use std::collections::btree_map::BTreeMap;
use lru::LruCache; use schnellru::{ByLength, LruMap};
use sp_consensus_babe::Epoch; use sp_consensus_babe::Epoch;
use polkadot_primitives::{ use polkadot_primitives::{
@@ -32,77 +32,74 @@ use polkadot_primitives::{
/// much if finality stalls (we only query state for unfinalized blocks + maybe latest finalized). /// much if finality stalls (we only query state for unfinalized blocks + maybe latest finalized).
/// In any case, a cache is an optimization. We should avoid a situation where having a large cache /// In any case, a cache is an optimization. We should avoid a situation where having a large cache
/// leads to OOM or puts pressure on other important stuff like PVF execution/preparation. /// leads to OOM or puts pressure on other important stuff like PVF execution/preparation.
const DEFAULT_CACHE_CAP: NonZeroUsize = match NonZeroUsize::new(128) { const DEFAULT_CACHE_CAP: u32 = 128;
Some(cap) => cap,
None => panic!("lru capacity must be non-zero"),
};
pub(crate) struct RequestResultCache { pub(crate) struct RequestResultCache {
authorities: LruCache<Hash, Vec<AuthorityDiscoveryId>>, authorities: LruMap<Hash, Vec<AuthorityDiscoveryId>>,
validators: LruCache<Hash, Vec<ValidatorId>>, validators: LruMap<Hash, Vec<ValidatorId>>,
validator_groups: LruCache<Hash, (Vec<Vec<ValidatorIndex>>, GroupRotationInfo)>, validator_groups: LruMap<Hash, (Vec<Vec<ValidatorIndex>>, GroupRotationInfo)>,
availability_cores: LruCache<Hash, Vec<CoreState>>, availability_cores: LruMap<Hash, Vec<CoreState>>,
persisted_validation_data: persisted_validation_data:
LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option<PersistedValidationData>>, LruMap<(Hash, ParaId, OccupiedCoreAssumption), Option<PersistedValidationData>>,
assumed_validation_data: assumed_validation_data:
LruCache<(ParaId, Hash), Option<(PersistedValidationData, ValidationCodeHash)>>, LruMap<(ParaId, Hash), Option<(PersistedValidationData, ValidationCodeHash)>>,
check_validation_outputs: LruCache<(Hash, ParaId, CandidateCommitments), bool>, check_validation_outputs: LruMap<(Hash, ParaId, CandidateCommitments), bool>,
session_index_for_child: LruCache<Hash, SessionIndex>, session_index_for_child: LruMap<Hash, SessionIndex>,
validation_code: LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCode>>, validation_code: LruMap<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCode>>,
validation_code_by_hash: LruCache<ValidationCodeHash, Option<ValidationCode>>, validation_code_by_hash: LruMap<ValidationCodeHash, Option<ValidationCode>>,
candidate_pending_availability: LruCache<(Hash, ParaId), Option<CommittedCandidateReceipt>>, candidate_pending_availability: LruMap<(Hash, ParaId), Option<CommittedCandidateReceipt>>,
candidate_events: LruCache<Hash, Vec<CandidateEvent>>, candidate_events: LruMap<Hash, Vec<CandidateEvent>>,
session_executor_params: LruCache<SessionIndex, Option<ExecutorParams>>, session_executor_params: LruMap<SessionIndex, Option<ExecutorParams>>,
session_info: LruCache<SessionIndex, SessionInfo>, session_info: LruMap<SessionIndex, SessionInfo>,
dmq_contents: LruCache<(Hash, ParaId), Vec<InboundDownwardMessage<BlockNumber>>>, dmq_contents: LruMap<(Hash, ParaId), Vec<InboundDownwardMessage<BlockNumber>>>,
inbound_hrmp_channels_contents: inbound_hrmp_channels_contents:
LruCache<(Hash, ParaId), BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>>, LruMap<(Hash, ParaId), BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>>,
current_babe_epoch: LruCache<Hash, Epoch>, current_babe_epoch: LruMap<Hash, Epoch>,
on_chain_votes: LruCache<Hash, Option<ScrapedOnChainVotes>>, on_chain_votes: LruMap<Hash, Option<ScrapedOnChainVotes>>,
pvfs_require_precheck: LruCache<Hash, Vec<ValidationCodeHash>>, pvfs_require_precheck: LruMap<Hash, Vec<ValidationCodeHash>>,
validation_code_hash: validation_code_hash:
LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCodeHash>>, LruMap<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCodeHash>>,
version: LruCache<Hash, u32>, version: LruMap<Hash, u32>,
disputes: LruCache<Hash, Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>, disputes: LruMap<Hash, Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>,
unapplied_slashes: unapplied_slashes:
LruCache<Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>>, LruMap<Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>>,
key_ownership_proof: key_ownership_proof:
LruCache<(Hash, ValidatorId), Option<vstaging::slashing::OpaqueKeyOwnershipProof>>, LruMap<(Hash, ValidatorId), Option<vstaging::slashing::OpaqueKeyOwnershipProof>>,
staging_para_backing_state: LruCache<(Hash, ParaId), Option<vstaging::BackingState>>, staging_para_backing_state: LruMap<(Hash, ParaId), Option<vstaging::BackingState>>,
staging_async_backing_params: LruCache<Hash, vstaging::AsyncBackingParams>, staging_async_backing_params: LruMap<Hash, vstaging::AsyncBackingParams>,
} }
impl Default for RequestResultCache { impl Default for RequestResultCache {
fn default() -> Self { fn default() -> Self {
Self { Self {
authorities: LruCache::new(DEFAULT_CACHE_CAP), authorities: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
validators: LruCache::new(DEFAULT_CACHE_CAP), validators: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
validator_groups: LruCache::new(DEFAULT_CACHE_CAP), validator_groups: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
availability_cores: LruCache::new(DEFAULT_CACHE_CAP), availability_cores: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
persisted_validation_data: LruCache::new(DEFAULT_CACHE_CAP), persisted_validation_data: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
assumed_validation_data: LruCache::new(DEFAULT_CACHE_CAP), assumed_validation_data: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
check_validation_outputs: LruCache::new(DEFAULT_CACHE_CAP), check_validation_outputs: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
session_index_for_child: LruCache::new(DEFAULT_CACHE_CAP), session_index_for_child: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
validation_code: LruCache::new(DEFAULT_CACHE_CAP), validation_code: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
validation_code_by_hash: LruCache::new(DEFAULT_CACHE_CAP), validation_code_by_hash: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
candidate_pending_availability: LruCache::new(DEFAULT_CACHE_CAP), candidate_pending_availability: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
candidate_events: LruCache::new(DEFAULT_CACHE_CAP), candidate_events: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
session_executor_params: LruCache::new(DEFAULT_CACHE_CAP), session_executor_params: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
session_info: LruCache::new(DEFAULT_CACHE_CAP), session_info: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
dmq_contents: LruCache::new(DEFAULT_CACHE_CAP), dmq_contents: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
inbound_hrmp_channels_contents: LruCache::new(DEFAULT_CACHE_CAP), inbound_hrmp_channels_contents: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
current_babe_epoch: LruCache::new(DEFAULT_CACHE_CAP), current_babe_epoch: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
on_chain_votes: LruCache::new(DEFAULT_CACHE_CAP), on_chain_votes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
pvfs_require_precheck: LruCache::new(DEFAULT_CACHE_CAP), pvfs_require_precheck: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
validation_code_hash: LruCache::new(DEFAULT_CACHE_CAP), validation_code_hash: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
version: LruCache::new(DEFAULT_CACHE_CAP), version: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
disputes: LruCache::new(DEFAULT_CACHE_CAP), disputes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
unapplied_slashes: LruCache::new(DEFAULT_CACHE_CAP), unapplied_slashes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
key_ownership_proof: LruCache::new(DEFAULT_CACHE_CAP), key_ownership_proof: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
staging_para_backing_state: LruCache::new(DEFAULT_CACHE_CAP), staging_para_backing_state: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
staging_async_backing_params: LruCache::new(DEFAULT_CACHE_CAP), staging_async_backing_params: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
} }
} }
} }
@@ -112,7 +109,7 @@ impl RequestResultCache {
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
) -> Option<&Vec<AuthorityDiscoveryId>> { ) -> Option<&Vec<AuthorityDiscoveryId>> {
self.authorities.get(relay_parent) self.authorities.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_authorities( pub(crate) fn cache_authorities(
@@ -120,22 +117,22 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
authorities: Vec<AuthorityDiscoveryId>, authorities: Vec<AuthorityDiscoveryId>,
) { ) {
self.authorities.put(relay_parent, authorities); self.authorities.insert(relay_parent, authorities);
} }
pub(crate) fn validators(&mut self, relay_parent: &Hash) -> Option<&Vec<ValidatorId>> { pub(crate) fn validators(&mut self, relay_parent: &Hash) -> Option<&Vec<ValidatorId>> {
self.validators.get(relay_parent) self.validators.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_validators(&mut self, relay_parent: Hash, validators: Vec<ValidatorId>) { pub(crate) fn cache_validators(&mut self, relay_parent: Hash, validators: Vec<ValidatorId>) {
self.validators.put(relay_parent, validators); self.validators.insert(relay_parent, validators);
} }
pub(crate) fn validator_groups( pub(crate) fn validator_groups(
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
) -> Option<&(Vec<Vec<ValidatorIndex>>, GroupRotationInfo)> { ) -> Option<&(Vec<Vec<ValidatorIndex>>, GroupRotationInfo)> {
self.validator_groups.get(relay_parent) self.validator_groups.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_validator_groups( pub(crate) fn cache_validator_groups(
@@ -143,22 +140,22 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
groups: (Vec<Vec<ValidatorIndex>>, GroupRotationInfo), groups: (Vec<Vec<ValidatorIndex>>, GroupRotationInfo),
) { ) {
self.validator_groups.put(relay_parent, groups); self.validator_groups.insert(relay_parent, groups);
} }
pub(crate) fn availability_cores(&mut self, relay_parent: &Hash) -> Option<&Vec<CoreState>> { pub(crate) fn availability_cores(&mut self, relay_parent: &Hash) -> Option<&Vec<CoreState>> {
self.availability_cores.get(relay_parent) self.availability_cores.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_availability_cores(&mut self, relay_parent: Hash, cores: Vec<CoreState>) { pub(crate) fn cache_availability_cores(&mut self, relay_parent: Hash, cores: Vec<CoreState>) {
self.availability_cores.put(relay_parent, cores); self.availability_cores.insert(relay_parent, cores);
} }
pub(crate) fn persisted_validation_data( pub(crate) fn persisted_validation_data(
&mut self, &mut self,
key: (Hash, ParaId, OccupiedCoreAssumption), key: (Hash, ParaId, OccupiedCoreAssumption),
) -> Option<&Option<PersistedValidationData>> { ) -> Option<&Option<PersistedValidationData>> {
self.persisted_validation_data.get(&key) self.persisted_validation_data.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_persisted_validation_data( pub(crate) fn cache_persisted_validation_data(
@@ -166,14 +163,14 @@ impl RequestResultCache {
key: (Hash, ParaId, OccupiedCoreAssumption), key: (Hash, ParaId, OccupiedCoreAssumption),
data: Option<PersistedValidationData>, data: Option<PersistedValidationData>,
) { ) {
self.persisted_validation_data.put(key, data); self.persisted_validation_data.insert(key, data);
} }
pub(crate) fn assumed_validation_data( pub(crate) fn assumed_validation_data(
&mut self, &mut self,
key: (Hash, ParaId, Hash), key: (Hash, ParaId, Hash),
) -> Option<&Option<(PersistedValidationData, ValidationCodeHash)>> { ) -> Option<&Option<(PersistedValidationData, ValidationCodeHash)>> {
self.assumed_validation_data.get(&(key.1, key.2)) self.assumed_validation_data.get(&(key.1, key.2)).map(|v| &*v)
} }
pub(crate) fn cache_assumed_validation_data( pub(crate) fn cache_assumed_validation_data(
@@ -181,14 +178,14 @@ impl RequestResultCache {
key: (ParaId, Hash), key: (ParaId, Hash),
data: Option<(PersistedValidationData, ValidationCodeHash)>, data: Option<(PersistedValidationData, ValidationCodeHash)>,
) { ) {
self.assumed_validation_data.put(key, data); self.assumed_validation_data.insert(key, data);
} }
pub(crate) fn check_validation_outputs( pub(crate) fn check_validation_outputs(
&mut self, &mut self,
key: (Hash, ParaId, CandidateCommitments), key: (Hash, ParaId, CandidateCommitments),
) -> Option<&bool> { ) -> Option<&bool> {
self.check_validation_outputs.get(&key) self.check_validation_outputs.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_check_validation_outputs( pub(crate) fn cache_check_validation_outputs(
@@ -196,11 +193,11 @@ impl RequestResultCache {
key: (Hash, ParaId, CandidateCommitments), key: (Hash, ParaId, CandidateCommitments),
value: bool, value: bool,
) { ) {
self.check_validation_outputs.put(key, value); self.check_validation_outputs.insert(key, value);
} }
pub(crate) fn session_index_for_child(&mut self, relay_parent: &Hash) -> Option<&SessionIndex> { pub(crate) fn session_index_for_child(&mut self, relay_parent: &Hash) -> Option<&SessionIndex> {
self.session_index_for_child.get(relay_parent) self.session_index_for_child.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_session_index_for_child( pub(crate) fn cache_session_index_for_child(
@@ -208,14 +205,14 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
index: SessionIndex, index: SessionIndex,
) { ) {
self.session_index_for_child.put(relay_parent, index); self.session_index_for_child.insert(relay_parent, index);
} }
pub(crate) fn validation_code( pub(crate) fn validation_code(
&mut self, &mut self,
key: (Hash, ParaId, OccupiedCoreAssumption), key: (Hash, ParaId, OccupiedCoreAssumption),
) -> Option<&Option<ValidationCode>> { ) -> Option<&Option<ValidationCode>> {
self.validation_code.get(&key) self.validation_code.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_validation_code( pub(crate) fn cache_validation_code(
@@ -223,7 +220,7 @@ impl RequestResultCache {
key: (Hash, ParaId, OccupiedCoreAssumption), key: (Hash, ParaId, OccupiedCoreAssumption),
value: Option<ValidationCode>, value: Option<ValidationCode>,
) { ) {
self.validation_code.put(key, value); self.validation_code.insert(key, value);
} }
// the actual key is `ValidationCodeHash` (`Hash` is ignored), // the actual key is `ValidationCodeHash` (`Hash` is ignored),
@@ -232,7 +229,7 @@ impl RequestResultCache {
&mut self, &mut self,
key: (Hash, ValidationCodeHash), key: (Hash, ValidationCodeHash),
) -> Option<&Option<ValidationCode>> { ) -> Option<&Option<ValidationCode>> {
self.validation_code_by_hash.get(&key.1) self.validation_code_by_hash.get(&key.1).map(|v| &*v)
} }
pub(crate) fn cache_validation_code_by_hash( pub(crate) fn cache_validation_code_by_hash(
@@ -240,14 +237,14 @@ impl RequestResultCache {
key: ValidationCodeHash, key: ValidationCodeHash,
value: Option<ValidationCode>, value: Option<ValidationCode>,
) { ) {
self.validation_code_by_hash.put(key, value); self.validation_code_by_hash.insert(key, value);
} }
pub(crate) fn candidate_pending_availability( pub(crate) fn candidate_pending_availability(
&mut self, &mut self,
key: (Hash, ParaId), key: (Hash, ParaId),
) -> Option<&Option<CommittedCandidateReceipt>> { ) -> Option<&Option<CommittedCandidateReceipt>> {
self.candidate_pending_availability.get(&key) self.candidate_pending_availability.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_candidate_pending_availability( pub(crate) fn cache_candidate_pending_availability(
@@ -255,11 +252,11 @@ impl RequestResultCache {
key: (Hash, ParaId), key: (Hash, ParaId),
value: Option<CommittedCandidateReceipt>, value: Option<CommittedCandidateReceipt>,
) { ) {
self.candidate_pending_availability.put(key, value); self.candidate_pending_availability.insert(key, value);
} }
pub(crate) fn candidate_events(&mut self, relay_parent: &Hash) -> Option<&Vec<CandidateEvent>> { pub(crate) fn candidate_events(&mut self, relay_parent: &Hash) -> Option<&Vec<CandidateEvent>> {
self.candidate_events.get(relay_parent) self.candidate_events.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_candidate_events( pub(crate) fn cache_candidate_events(
@@ -267,22 +264,22 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
events: Vec<CandidateEvent>, events: Vec<CandidateEvent>,
) { ) {
self.candidate_events.put(relay_parent, events); self.candidate_events.insert(relay_parent, events);
} }
pub(crate) fn session_info(&mut self, key: SessionIndex) -> Option<&SessionInfo> { pub(crate) fn session_info(&mut self, key: SessionIndex) -> Option<&SessionInfo> {
self.session_info.get(&key) self.session_info.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_session_info(&mut self, key: SessionIndex, value: SessionInfo) { pub(crate) fn cache_session_info(&mut self, key: SessionIndex, value: SessionInfo) {
self.session_info.put(key, value); self.session_info.insert(key, value);
} }
pub(crate) fn session_executor_params( pub(crate) fn session_executor_params(
&mut self, &mut self,
session_index: SessionIndex, session_index: SessionIndex,
) -> Option<&Option<ExecutorParams>> { ) -> Option<&Option<ExecutorParams>> {
self.session_executor_params.get(&session_index) self.session_executor_params.get(&session_index).map(|v| &*v)
} }
pub(crate) fn cache_session_executor_params( pub(crate) fn cache_session_executor_params(
@@ -290,14 +287,14 @@ impl RequestResultCache {
session_index: SessionIndex, session_index: SessionIndex,
value: Option<ExecutorParams>, value: Option<ExecutorParams>,
) { ) {
self.session_executor_params.put(session_index, value); self.session_executor_params.insert(session_index, value);
} }
pub(crate) fn dmq_contents( pub(crate) fn dmq_contents(
&mut self, &mut self,
key: (Hash, ParaId), key: (Hash, ParaId),
) -> Option<&Vec<InboundDownwardMessage<BlockNumber>>> { ) -> Option<&Vec<InboundDownwardMessage<BlockNumber>>> {
self.dmq_contents.get(&key) self.dmq_contents.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_dmq_contents( pub(crate) fn cache_dmq_contents(
@@ -305,14 +302,14 @@ impl RequestResultCache {
key: (Hash, ParaId), key: (Hash, ParaId),
value: Vec<InboundDownwardMessage<BlockNumber>>, value: Vec<InboundDownwardMessage<BlockNumber>>,
) { ) {
self.dmq_contents.put(key, value); self.dmq_contents.insert(key, value);
} }
pub(crate) fn inbound_hrmp_channels_contents( pub(crate) fn inbound_hrmp_channels_contents(
&mut self, &mut self,
key: (Hash, ParaId), key: (Hash, ParaId),
) -> Option<&BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>> { ) -> Option<&BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>> {
self.inbound_hrmp_channels_contents.get(&key) self.inbound_hrmp_channels_contents.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_inbound_hrmp_channel_contents( pub(crate) fn cache_inbound_hrmp_channel_contents(
@@ -320,22 +317,22 @@ impl RequestResultCache {
key: (Hash, ParaId), key: (Hash, ParaId),
value: BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>, value: BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>,
) { ) {
self.inbound_hrmp_channels_contents.put(key, value); self.inbound_hrmp_channels_contents.insert(key, value);
} }
pub(crate) fn current_babe_epoch(&mut self, relay_parent: &Hash) -> Option<&Epoch> { pub(crate) fn current_babe_epoch(&mut self, relay_parent: &Hash) -> Option<&Epoch> {
self.current_babe_epoch.get(relay_parent) self.current_babe_epoch.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_current_babe_epoch(&mut self, relay_parent: Hash, epoch: Epoch) { pub(crate) fn cache_current_babe_epoch(&mut self, relay_parent: Hash, epoch: Epoch) {
self.current_babe_epoch.put(relay_parent, epoch); self.current_babe_epoch.insert(relay_parent, epoch);
} }
pub(crate) fn on_chain_votes( pub(crate) fn on_chain_votes(
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
) -> Option<&Option<ScrapedOnChainVotes>> { ) -> Option<&Option<ScrapedOnChainVotes>> {
self.on_chain_votes.get(relay_parent) self.on_chain_votes.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_on_chain_votes( pub(crate) fn cache_on_chain_votes(
@@ -343,14 +340,14 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
scraped: Option<ScrapedOnChainVotes>, scraped: Option<ScrapedOnChainVotes>,
) { ) {
self.on_chain_votes.put(relay_parent, scraped); self.on_chain_votes.insert(relay_parent, scraped);
} }
pub(crate) fn pvfs_require_precheck( pub(crate) fn pvfs_require_precheck(
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
) -> Option<&Vec<ValidationCodeHash>> { ) -> Option<&Vec<ValidationCodeHash>> {
self.pvfs_require_precheck.get(relay_parent) self.pvfs_require_precheck.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_pvfs_require_precheck( pub(crate) fn cache_pvfs_require_precheck(
@@ -358,14 +355,14 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
pvfs: Vec<ValidationCodeHash>, pvfs: Vec<ValidationCodeHash>,
) { ) {
self.pvfs_require_precheck.put(relay_parent, pvfs); self.pvfs_require_precheck.insert(relay_parent, pvfs);
} }
pub(crate) fn validation_code_hash( pub(crate) fn validation_code_hash(
&mut self, &mut self,
key: (Hash, ParaId, OccupiedCoreAssumption), key: (Hash, ParaId, OccupiedCoreAssumption),
) -> Option<&Option<ValidationCodeHash>> { ) -> Option<&Option<ValidationCodeHash>> {
self.validation_code_hash.get(&key) self.validation_code_hash.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_validation_code_hash( pub(crate) fn cache_validation_code_hash(
@@ -373,22 +370,22 @@ impl RequestResultCache {
key: (Hash, ParaId, OccupiedCoreAssumption), key: (Hash, ParaId, OccupiedCoreAssumption),
value: Option<ValidationCodeHash>, value: Option<ValidationCodeHash>,
) { ) {
self.validation_code_hash.put(key, value); self.validation_code_hash.insert(key, value);
} }
pub(crate) fn version(&mut self, relay_parent: &Hash) -> Option<&u32> { pub(crate) fn version(&mut self, relay_parent: &Hash) -> Option<&u32> {
self.version.get(relay_parent) self.version.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_version(&mut self, key: Hash, value: u32) { pub(crate) fn cache_version(&mut self, key: Hash, value: u32) {
self.version.put(key, value); self.version.insert(key, value);
} }
pub(crate) fn disputes( pub(crate) fn disputes(
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
) -> Option<&Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>> { ) -> Option<&Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>> {
self.disputes.get(relay_parent) self.disputes.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_disputes( pub(crate) fn cache_disputes(
@@ -396,14 +393,14 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
value: Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, value: Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>,
) { ) {
self.disputes.put(relay_parent, value); self.disputes.insert(relay_parent, value);
} }
pub(crate) fn unapplied_slashes( pub(crate) fn unapplied_slashes(
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
) -> Option<&Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>> { ) -> Option<&Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>> {
self.unapplied_slashes.get(relay_parent) self.unapplied_slashes.get(relay_parent).map(|v| &*v)
} }
pub(crate) fn cache_unapplied_slashes( pub(crate) fn cache_unapplied_slashes(
@@ -411,14 +408,14 @@ impl RequestResultCache {
relay_parent: Hash, relay_parent: Hash,
value: Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>, value: Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>,
) { ) {
self.unapplied_slashes.put(relay_parent, value); self.unapplied_slashes.insert(relay_parent, value);
} }
pub(crate) fn key_ownership_proof( pub(crate) fn key_ownership_proof(
&mut self, &mut self,
key: (Hash, ValidatorId), key: (Hash, ValidatorId),
) -> Option<&Option<vstaging::slashing::OpaqueKeyOwnershipProof>> { ) -> Option<&Option<vstaging::slashing::OpaqueKeyOwnershipProof>> {
self.key_ownership_proof.get(&key) self.key_ownership_proof.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_key_ownership_proof( pub(crate) fn cache_key_ownership_proof(
@@ -426,7 +423,7 @@ impl RequestResultCache {
key: (Hash, ValidatorId), key: (Hash, ValidatorId),
value: Option<vstaging::slashing::OpaqueKeyOwnershipProof>, value: Option<vstaging::slashing::OpaqueKeyOwnershipProof>,
) { ) {
self.key_ownership_proof.put(key, value); self.key_ownership_proof.insert(key, value);
} }
// This request is never cached, hence always returns `None`. // This request is never cached, hence always returns `None`.
@@ -441,7 +438,7 @@ impl RequestResultCache {
&mut self, &mut self,
key: (Hash, ParaId), key: (Hash, ParaId),
) -> Option<&Option<vstaging::BackingState>> { ) -> Option<&Option<vstaging::BackingState>> {
self.staging_para_backing_state.get(&key) self.staging_para_backing_state.get(&key).map(|v| &*v)
} }
pub(crate) fn cache_staging_para_backing_state( pub(crate) fn cache_staging_para_backing_state(
@@ -449,14 +446,14 @@ impl RequestResultCache {
key: (Hash, ParaId), key: (Hash, ParaId),
value: Option<vstaging::BackingState>, value: Option<vstaging::BackingState>,
) { ) {
self.staging_para_backing_state.put(key, value); self.staging_para_backing_state.insert(key, value);
} }
pub(crate) fn staging_async_backing_params( pub(crate) fn staging_async_backing_params(
&mut self, &mut self,
key: &Hash, key: &Hash,
) -> Option<&vstaging::AsyncBackingParams> { ) -> Option<&vstaging::AsyncBackingParams> {
self.staging_async_backing_params.get(key) self.staging_async_backing_params.get(key).map(|v| &*v)
} }
pub(crate) fn cache_staging_async_backing_params( pub(crate) fn cache_staging_async_backing_params(
@@ -464,7 +461,7 @@ impl RequestResultCache {
key: Hash, key: Hash,
value: vstaging::AsyncBackingParams, value: vstaging::AsyncBackingParams,
) { ) {
self.staging_async_backing_params.put(key, value); self.staging_async_backing_params.insert(key, value);
} }
} }
@@ -20,7 +20,7 @@ sp-keystore = { path = "../../../../substrate/primitives/keystore" }
thiserror = "1.0.31" thiserror = "1.0.31"
rand = "0.8.5" rand = "0.8.5"
derive_more = "0.99.17" derive_more = "0.99.17"
lru = "0.11.0" schnellru = "0.2.1"
fatality = "0.0.6" fatality = "0.0.6"
[dev-dependencies] [dev-dependencies]
@@ -14,10 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::{collections::HashSet, num::NonZeroUsize}; use std::collections::HashSet;
use lru::LruCache;
use rand::{seq::SliceRandom, thread_rng}; use rand::{seq::SliceRandom, thread_rng};
use schnellru::{ByLength, LruMap};
use polkadot_node_subsystem::overseer; use polkadot_node_subsystem::overseer;
use polkadot_node_subsystem_util::runtime::RuntimeInfo; use polkadot_node_subsystem_util::runtime::RuntimeInfo;
@@ -37,7 +37,7 @@ pub struct SessionCache {
/// Note: Performance of fetching is really secondary here, but we need to ensure we are going /// Note: Performance of fetching is really secondary here, but we need to ensure we are going
/// to get any existing cache entry, before fetching new information, as we should not mess up /// to get any existing cache entry, before fetching new information, as we should not mess up
/// the order of validators in `SessionInfo::validator_groups`. /// the order of validators in `SessionInfo::validator_groups`.
session_info_cache: LruCache<SessionIndex, SessionInfo>, session_info_cache: LruMap<SessionIndex, SessionInfo>,
} }
/// Localized session information, tailored for the needs of availability distribution. /// Localized session information, tailored for the needs of availability distribution.
@@ -83,7 +83,7 @@ impl SessionCache {
pub fn new() -> Self { pub fn new() -> Self {
SessionCache { SessionCache {
// We need to cache the current and the last session the most: // We need to cache the current and the last session the most:
session_info_cache: LruCache::new(NonZeroUsize::new(2).unwrap()), session_info_cache: LruMap::new(ByLength::new(2)),
} }
} }
@@ -115,7 +115,7 @@ impl SessionCache {
gum::trace!(target: LOG_TARGET, session_index, "Calling `with_info`"); gum::trace!(target: LOG_TARGET, session_index, "Calling `with_info`");
let r = with_info(&info); let r = with_info(&info);
gum::trace!(target: LOG_TARGET, session_index, "Storing session info in lru!"); gum::trace!(target: LOG_TARGET, session_index, "Storing session info in lru!");
self.session_info_cache.put(session_index, info); self.session_info_cache.insert(session_index, info);
Ok(Some(r)) Ok(Some(r))
} else { } else {
Ok(None) Ok(None)
@@ -142,7 +142,7 @@ impl SessionCache {
/// will be put at the beginning of the group. /// will be put at the beginning of the group.
pub fn report_bad(&mut self, report: BadValidators) -> Result<()> { pub fn report_bad(&mut self, report: BadValidators) -> Result<()> {
let available_sessions = self.session_info_cache.iter().map(|(k, _)| *k).collect(); let available_sessions = self.session_info_cache.iter().map(|(k, _)| *k).collect();
let session = self.session_info_cache.get_mut(&report.session_index).ok_or( let session = self.session_info_cache.get(&report.session_index).ok_or(
Error::NoSuchCachedSession { Error::NoSuchCachedSession {
available_sessions, available_sessions,
missing_session: report.session_index, missing_session: report.session_index,
@@ -7,7 +7,7 @@ license.workspace = true
[dependencies] [dependencies]
futures = "0.3.21" futures = "0.3.21"
lru = "0.11.0" schnellru = "0.2.1"
rand = "0.8.5" rand = "0.8.5"
fatality = "0.0.6" fatality = "0.0.6"
thiserror = "1.0.31" thiserror = "1.0.31"
@@ -35,8 +35,8 @@ use futures::{
stream::{FuturesUnordered, StreamExt}, stream::{FuturesUnordered, StreamExt},
task::{Context, Poll}, task::{Context, Poll},
}; };
use lru::LruCache;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use schnellru::{ByLength, LruMap};
use fatality::Nested; use fatality::Nested;
use polkadot_erasure_coding::{ use polkadot_erasure_coding::{
@@ -82,10 +82,7 @@ const LOG_TARGET: &str = "parachain::availability-recovery";
const N_PARALLEL: usize = 50; const N_PARALLEL: usize = 50;
// Size of the LRU cache where we keep recovered data. // Size of the LRU cache where we keep recovered data.
const LRU_SIZE: NonZeroUsize = match NonZeroUsize::new(16) { const LRU_SIZE: u32 = 16;
Some(cap) => cap,
None => panic!("Availability-recovery cache size must be non-zero."),
};
const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Peer sent unparsable request"); const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Peer sent unparsable request");
@@ -927,7 +924,7 @@ struct State {
live_block: (BlockNumber, Hash), live_block: (BlockNumber, Hash),
/// An LRU cache of recently recovered data. /// An LRU cache of recently recovered data.
availability_lru: LruCache<CandidateHash, CachedRecovery>, availability_lru: LruMap<CandidateHash, CachedRecovery>,
} }
impl Default for State { impl Default for State {
@@ -935,7 +932,7 @@ impl Default for State {
Self { Self {
ongoing_recoveries: FuturesUnordered::new(), ongoing_recoveries: FuturesUnordered::new(),
live_block: (0, Hash::default()), live_block: (0, Hash::default()),
availability_lru: LruCache::new(LRU_SIZE), availability_lru: LruMap::new(ByLength::new(LRU_SIZE)),
} }
} }
} }
@@ -1334,7 +1331,7 @@ impl AvailabilityRecoverySubsystem {
output = state.ongoing_recoveries.select_next_some() => { output = state.ongoing_recoveries.select_next_some() => {
if let Some((candidate_hash, result)) = output { if let Some((candidate_hash, result)) = output {
if let Ok(recovery) = CachedRecovery::try_from(result) { if let Ok(recovery) = CachedRecovery::try_from(result) {
state.availability_lru.put(candidate_hash, recovery); state.availability_lru.insert(candidate_hash, recovery);
} }
} }
} }
@@ -22,7 +22,7 @@ sp-application-crypto = { path = "../../../../substrate/primitives/application-c
sp-keystore = { path = "../../../../substrate/primitives/keystore" } sp-keystore = { path = "../../../../substrate/primitives/keystore" }
thiserror = "1.0.31" thiserror = "1.0.31"
fatality = "0.0.6" fatality = "0.0.6"
lru = "0.11.0" schnellru = "0.2.1"
indexmap = "1.9.1" indexmap = "1.9.1"
[dev-dependencies] [dev-dependencies]
@@ -24,7 +24,7 @@
//! The sender is responsible for getting our vote out, see [`sender`]. The receiver handles //! The sender is responsible for getting our vote out, see [`sender`]. The receiver handles
//! incoming [`DisputeRequest`]s and offers spam protection, see [`receiver`]. //! incoming [`DisputeRequest`]s and offers spam protection, see [`receiver`].
use std::{num::NonZeroUsize, time::Duration}; use std::time::Duration;
use futures::{channel::mpsc, FutureExt, StreamExt, TryFutureExt}; use futures::{channel::mpsc, FutureExt, StreamExt, TryFutureExt};
@@ -165,8 +165,7 @@ where
) -> Self { ) -> Self {
let runtime = RuntimeInfo::new_with_config(runtime::Config { let runtime = RuntimeInfo::new_with_config(runtime::Config {
keystore: Some(keystore), keystore: Some(keystore),
session_cache_lru_size: NonZeroUsize::new(DISPUTE_WINDOW.get() as usize) session_cache_lru_size: DISPUTE_WINDOW.get(),
.expect("Dispute window can not be 0; qed"),
}); });
let (tx, sender_rx) = NestingSender::new_root(1); let (tx, sender_rx) = NestingSender::new_root(1);
let disputes_sender = DisputeSender::new(tx, metrics.clone()); let disputes_sender = DisputeSender::new(tx, metrics.clone());
@@ -15,7 +15,6 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::{ use std::{
num::NonZeroUsize,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
time::Duration, time::Duration,
@@ -161,8 +160,7 @@ where
) -> Self { ) -> Self {
let runtime = RuntimeInfo::new_with_config(runtime::Config { let runtime = RuntimeInfo::new_with_config(runtime::Config {
keystore: None, keystore: None,
session_cache_lru_size: NonZeroUsize::new(DISPUTE_WINDOW.get() as usize) session_cache_lru_size: DISPUTE_WINDOW.get(),
.expect("Dispute window can not be 0; qed"),
}); });
Self { Self {
runtime, runtime,
+1 -1
View File
@@ -18,7 +18,7 @@ polkadot-node-metrics = { path = "../metrics" }
polkadot-primitives = { path = "../../primitives" } polkadot-primitives = { path = "../../primitives" }
orchestra = "0.0.5" orchestra = "0.0.5"
gum = { package = "tracing-gum", path = "../gum" } gum = { package = "tracing-gum", path = "../gum" }
lru = "0.11.0" schnellru = "0.2.1"
sp-core = { path = "../../../substrate/primitives/core" } sp-core = { path = "../../../substrate/primitives/core" }
async-trait = "0.1.57" async-trait = "0.1.57"
tikv-jemalloc-ctl = { version = "0.5.0", optional = true } tikv-jemalloc-ctl = { version = "0.5.0", optional = true }
+2 -2
View File
@@ -19,9 +19,9 @@ use crate::{
Overseer, OverseerMetrics, OverseerSignal, OverseerSubsystemContext, SpawnGlue, Overseer, OverseerMetrics, OverseerSignal, OverseerSubsystemContext, SpawnGlue,
KNOWN_LEAVES_CACHE_SIZE, KNOWN_LEAVES_CACHE_SIZE,
}; };
use lru::LruCache;
use orchestra::{FromOrchestra, SpawnedSubsystem, Subsystem, SubsystemContext}; use orchestra::{FromOrchestra, SpawnedSubsystem, Subsystem, SubsystemContext};
use polkadot_node_subsystem_types::{errors::SubsystemError, messages::*}; use polkadot_node_subsystem_types::{errors::SubsystemError, messages::*};
use schnellru::{ByLength, LruMap};
// Generated dummy messages // Generated dummy messages
use crate::messages::*; use crate::messages::*;
@@ -193,7 +193,7 @@ where
.activation_external_listeners(Default::default()) .activation_external_listeners(Default::default())
.span_per_active_leaf(Default::default()) .span_per_active_leaf(Default::default())
.active_leaves(Default::default()) .active_leaves(Default::default())
.known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE)) .known_leaves(LruMap::new(ByLength::new(KNOWN_LEAVES_CACHE_SIZE)))
.spawner(SpawnGlue(spawner)) .spawner(SpawnGlue(spawner))
.metrics(metrics) .metrics(metrics)
.supports_parachains(supports_parachains); .supports_parachains(supports_parachains);
+5 -8
View File
@@ -62,14 +62,13 @@
use std::{ use std::{
collections::{hash_map, HashMap}, collections::{hash_map, HashMap},
fmt::{self, Debug}, fmt::{self, Debug},
num::NonZeroUsize,
pin::Pin, pin::Pin,
sync::Arc, sync::Arc,
time::Duration, time::Duration,
}; };
use futures::{channel::oneshot, future::BoxFuture, select, Future, FutureExt, StreamExt}; use futures::{channel::oneshot, future::BoxFuture, select, Future, FutureExt, StreamExt};
use lru::LruCache; use schnellru::LruMap;
use client::{BlockImportNotification, BlockchainEvents, FinalityNotification}; use client::{BlockImportNotification, BlockchainEvents, FinalityNotification};
use polkadot_primitives::{Block, BlockNumber, Hash}; use polkadot_primitives::{Block, BlockNumber, Hash};
@@ -113,10 +112,7 @@ pub use orchestra::{
/// Store 2 days worth of blocks, not accounting for forks, /// Store 2 days worth of blocks, not accounting for forks,
/// in the LRU cache. Assumes a 6-second block time. /// in the LRU cache. Assumes a 6-second block time.
pub const KNOWN_LEAVES_CACHE_SIZE: NonZeroUsize = match NonZeroUsize::new(2 * 24 * 3600 / 6) { pub const KNOWN_LEAVES_CACHE_SIZE: u32 = 2 * 24 * 3600 / 6;
Some(cap) => cap,
None => panic!("Known leaves cache size must be non-zero"),
};
#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
mod memory_stats; mod memory_stats;
@@ -632,7 +628,7 @@ pub struct Overseer<SupportsParachains> {
pub supports_parachains: SupportsParachains, pub supports_parachains: SupportsParachains,
/// An LRU cache for keeping track of relay-chain heads that have already been seen. /// An LRU cache for keeping track of relay-chain heads that have already been seen.
pub known_leaves: LruCache<Hash, ()>, pub known_leaves: LruMap<Hash, ()>,
/// Various Prometheus metrics. /// Various Prometheus metrics.
pub metrics: OverseerMetrics, pub metrics: OverseerMetrics,
@@ -880,9 +876,10 @@ where
let span = Arc::new(span); let span = Arc::new(span);
self.span_per_active_leaf.insert(*hash, span.clone()); self.span_per_active_leaf.insert(*hash, span.clone());
let status = if let Some(_) = self.known_leaves.put(*hash, ()) { let status = if self.known_leaves.get(hash).is_some() {
LeafStatus::Stale LeafStatus::Stale
} else { } else {
self.known_leaves.insert(*hash, ());
LeafStatus::Fresh LeafStatus::Fresh
}; };
+1 -7
View File
@@ -22,7 +22,7 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use std::{num::NonZeroUsize, pin::Pin}; use std::pin::Pin;
use bounded_vec::BoundedVec; use bounded_vec::BoundedVec;
use futures::Future; use futures::Future;
@@ -143,12 +143,6 @@ impl SessionWindowSize {
} }
} }
impl From<SessionWindowSize> for NonZeroUsize {
fn from(value: SessionWindowSize) -> Self {
NonZeroUsize::new(value.get() as usize).expect("SessionWindowSize can't be 0. qed.")
}
}
/// The cumulative weight of a block in a fork-choice rule. /// The cumulative weight of a block in a fork-choice rule.
pub type BlockWeight = u32; pub type BlockWeight = u32;
+1 -1
View File
@@ -86,7 +86,7 @@ parity-db = { version = "0.4.8", optional = true }
codec = { package = "parity-scale-codec", version = "3.6.1" } codec = { package = "parity-scale-codec", version = "3.6.1" }
async-trait = "0.1.57" async-trait = "0.1.57"
lru = "0.11.0" schnellru = "0.2.1"
log = "0.4.17" log = "0.4.17"
is_executable = "1.0.1" is_executable = "1.0.1"
+2 -2
View File
@@ -19,7 +19,6 @@ use polkadot_node_subsystem_types::DefaultSubsystemClient;
use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sp_core::traits::SpawnNamed; use sp_core::traits::SpawnNamed;
use lru::LruCache;
use polkadot_availability_distribution::IncomingRequestReceivers; use polkadot_availability_distribution::IncomingRequestReceivers;
use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig; use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
use polkadot_node_core_av_store::Config as AvailabilityConfig; use polkadot_node_core_av_store::Config as AvailabilityConfig;
@@ -41,6 +40,7 @@ use polkadot_overseer::{
metrics::Metrics as OverseerMetrics, InitializedOverseerBuilder, MetricsTrait, Overseer, metrics::Metrics as OverseerMetrics, InitializedOverseerBuilder, MetricsTrait, Overseer,
OverseerConnector, OverseerHandle, SpawnGlue, OverseerConnector, OverseerHandle, SpawnGlue,
}; };
use schnellru::{ByLength, LruMap};
use polkadot_primitives::runtime_api::ParachainHost; use polkadot_primitives::runtime_api::ParachainHost;
use sc_authority_discovery::Service as AuthorityDiscoveryService; use sc_authority_discovery::Service as AuthorityDiscoveryService;
@@ -344,7 +344,7 @@ where
.span_per_active_leaf(Default::default()) .span_per_active_leaf(Default::default())
.active_leaves(Default::default()) .active_leaves(Default::default())
.supports_parachains(runtime_api_client) .supports_parachains(runtime_api_client)
.known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE)) .known_leaves(LruMap::new(ByLength::new(KNOWN_LEAVES_CACHE_SIZE)))
.metrics(metrics) .metrics(metrics)
.spawner(spawner); .spawner(spawner);
+1 -1
View File
@@ -19,7 +19,7 @@ thiserror = "1.0.31"
fatality = "0.0.6" fatality = "0.0.6"
gum = { package = "tracing-gum", path = "../gum" } gum = { package = "tracing-gum", path = "../gum" }
derive_more = "0.99.17" derive_more = "0.99.17"
lru = "0.11.0" schnellru = "0.2.1"
polkadot-node-subsystem = { path = "../subsystem" } polkadot-node-subsystem = { path = "../subsystem" }
polkadot-node-jaeger = { path = "../jaeger" } polkadot-node-jaeger = { path = "../jaeger" }
+10 -15
View File
@@ -16,9 +16,7 @@
//! Convenient interface to runtime information. //! Convenient interface to runtime information.
use std::num::NonZeroUsize; use schnellru::{ByLength, LruMap};
use lru::LruCache;
use parity_scale_codec::Encode; use parity_scale_codec::Encode;
use sp_application_crypto::AppCrypto; use sp_application_crypto::AppCrypto;
@@ -58,7 +56,7 @@ pub struct Config {
pub keystore: Option<KeystorePtr>, pub keystore: Option<KeystorePtr>,
/// How many sessions should we keep in the cache? /// How many sessions should we keep in the cache?
pub session_cache_lru_size: NonZeroUsize, pub session_cache_lru_size: u32,
} }
/// Caching of session info. /// Caching of session info.
@@ -69,10 +67,10 @@ pub struct RuntimeInfo {
/// ///
/// We query this up to a 100 times per block, so caching it here without roundtrips over the /// We query this up to a 100 times per block, so caching it here without roundtrips over the
/// overseer seems sensible. /// overseer seems sensible.
session_index_cache: LruCache<Hash, SessionIndex>, session_index_cache: LruMap<Hash, SessionIndex>,
/// Look up cached sessions by `SessionIndex`. /// Look up cached sessions by `SessionIndex`.
session_info_cache: LruCache<SessionIndex, ExtendedSessionInfo>, session_info_cache: LruMap<SessionIndex, ExtendedSessionInfo>,
/// Key store for determining whether we are a validator and what `ValidatorIndex` we have. /// Key store for determining whether we are a validator and what `ValidatorIndex` we have.
keystore: Option<KeystorePtr>, keystore: Option<KeystorePtr>,
@@ -101,7 +99,7 @@ impl Default for Config {
Self { Self {
keystore: None, keystore: None,
// Usually we need to cache the current and the last session. // Usually we need to cache the current and the last session.
session_cache_lru_size: NonZeroUsize::new(2).expect("2 is larger than 0; qed"), session_cache_lru_size: 2,
} }
} }
} }
@@ -115,11 +113,8 @@ impl RuntimeInfo {
/// Create with more elaborate configuration options. /// Create with more elaborate configuration options.
pub fn new_with_config(cfg: Config) -> Self { pub fn new_with_config(cfg: Config) -> Self {
Self { Self {
session_index_cache: LruCache::new( session_index_cache: LruMap::new(ByLength::new(cfg.session_cache_lru_size.max(10))),
cfg.session_cache_lru_size session_info_cache: LruMap::new(ByLength::new(cfg.session_cache_lru_size)),
.max(NonZeroUsize::new(10).expect("10 is larger than 0; qed")),
),
session_info_cache: LruCache::new(cfg.session_cache_lru_size),
keystore: cfg.keystore, keystore: cfg.keystore,
} }
} }
@@ -139,7 +134,7 @@ impl RuntimeInfo {
None => { None => {
let index = let index =
recv_runtime(request_session_index_for_child(parent, sender).await).await?; recv_runtime(request_session_index_for_child(parent, sender).await).await?;
self.session_index_cache.put(parent, index); self.session_index_cache.insert(parent, index);
Ok(index) Ok(index)
}, },
} }
@@ -172,7 +167,7 @@ impl RuntimeInfo {
where where
Sender: SubsystemSender<RuntimeApiMessage>, Sender: SubsystemSender<RuntimeApiMessage>,
{ {
if !self.session_info_cache.contains(&session_index) { if self.session_info_cache.get(&session_index).is_none() {
let session_info = let session_info =
recv_runtime(request_session_info(parent, session_index, sender).await) recv_runtime(request_session_info(parent, session_index, sender).await)
.await? .await?
@@ -181,7 +176,7 @@ impl RuntimeInfo {
let full_info = ExtendedSessionInfo { session_info, validator_info }; let full_info = ExtendedSessionInfo { session_info, validator_info };
self.session_info_cache.put(session_index, full_info); self.session_info_cache.insert(session_index, full_info);
} }
Ok(self Ok(self
.session_info_cache .session_info_cache
@@ -30,7 +30,7 @@ struct State {
/// A recent block hash for which state should be available. /// A recent block hash for which state should be available.
live_block_hash: Hash, live_block_hash: Hash,
// An LRU cache of recently recovered data. // An LRU cache of recently recovered data.
availability_lru: LruCache<CandidateHash, Result<AvailableData, RecoveryError>>, availability_lru: LruMap<CandidateHash, Result<AvailableData, RecoveryError>>,
} }
/// This is a future, which concludes either when a response is received from the recovery tasks, /// This is a future, which concludes either when a response is received from the recovery tasks,
@@ -678,7 +678,7 @@ struct State {
// It can be a `Vec` if the need to track more arises. // It can be a `Vec` if the need to track more arises.
error: Option<SessionsUnavailable>, error: Option<SessionsUnavailable>,
/// Latest relay blocks that have been successfully scraped. /// Latest relay blocks that have been successfully scraped.
last_scraped_blocks: LruCache<Hash, ()>, last_scraped_blocks: LruMap<Hash, ()>,
} }
``` ```