Skip to content

Commit ee803b7

Browse files
alindimasandreim
andauthored
runtime: remove ttl (#5461)
Resolves #4776 This will enable proper core-sharing between paras, even if one of them is not producing blocks. TODO: - [x] duplicate first entry in the claim queue if the queue used to be empty - [x] don't back anything if at the end of the block there'll be a session change - [x] write migration for removing the availability core storage - [x] update and write unit tests - [x] prdoc - [x] add zombienet test for synchronous backing - [x] add zombienet test for core-sharing paras where one of them is not producing any blocks _Important note:_ The `ttl` and `max_availability_timeouts` fields of the HostConfiguration are not removed in this PR, due to #64. Adding the workaround with the storage version check for every use of the active HostConfiguration in all runtime APIs would be insane, as it's used in almost all runtime APIs. So even though the ttl and max_availability_timeouts fields will now be unused, they will remain part of the host configuration. These will be removed in a separate PR once #64 is fixed. Tracked by #6067 --------- Signed-off-by: Andrei Sandu <[email protected]> Co-authored-by: Andrei Sandu <[email protected]> Co-authored-by: Andrei Sandu <[email protected]> Co-authored-by: command-bot <>
1 parent 225536c commit ee803b7

File tree

41 files changed

+1510
-1967
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1510
-1967
lines changed

.gitlab/pipeline/zombienet/polkadot.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,25 @@ zombienet-polkadot-functional-0016-approval-voting-parallel:
233233
--local-dir="${LOCAL_DIR}/functional"
234234
--test="0016-approval-voting-parallel.zndsl"
235235

236+
zombienet-polkadot-functional-0017-sync-backing:
237+
extends:
238+
- .zombienet-polkadot-common
239+
script:
240+
- /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
241+
--local-dir="${LOCAL_DIR}/functional"
242+
--test="0017-sync-backing.zndsl"
243+
244+
zombienet-polkadot-functional-0018-shared-core-idle-parachain:
245+
extends:
246+
- .zombienet-polkadot-common
247+
before_script:
248+
- !reference [ .zombienet-polkadot-common, before_script ]
249+
- cp --remove-destination ${LOCAL_DIR}/assign-core.js ${LOCAL_DIR}/functional
250+
script:
251+
- /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
252+
--local-dir="${LOCAL_DIR}/functional"
253+
--test="0018-shared-core-idle-parachain.zndsl"
254+
236255
zombienet-polkadot-smoke-0001-parachains-smoke-test:
237256
extends:
238257
- .zombienet-polkadot-common

polkadot/primitives/src/v8/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,7 +2093,9 @@ pub struct SchedulerParams<BlockNumber> {
20932093
pub lookahead: u32,
20942094
/// How many cores are managed by the coretime chain.
20952095
pub num_cores: u32,
2096-
/// The max number of times a claim can time out in availability.
2096+
/// Deprecated and no longer used by the runtime.
2097+
/// Removal is tracked by <https://github.com/paritytech/polkadot-sdk/issues/6067>.
2098+
#[deprecated]
20972099
pub max_availability_timeouts: u32,
20982100
/// The maximum queue size of the pay as you go module.
20992101
pub on_demand_queue_max_size: u32,
@@ -2104,13 +2106,14 @@ pub struct SchedulerParams<BlockNumber> {
21042106
pub on_demand_fee_variability: Perbill,
21052107
/// The minimum amount needed to claim a slot in the spot pricing queue.
21062108
pub on_demand_base_fee: Balance,
2107-
/// The number of blocks a claim stays in the scheduler's claim queue before getting cleared.
2108-
/// This number should go reasonably higher than the number of blocks in the async backing
2109-
/// lookahead.
2109+
/// Deprecated and no longer used by the runtime.
2110+
/// Removal is tracked by <https://github.com/paritytech/polkadot-sdk/issues/6067>.
2111+
#[deprecated]
21102112
pub ttl: BlockNumber,
21112113
}
21122114

21132115
impl<BlockNumber: Default + From<u32>> Default for SchedulerParams<BlockNumber> {
2116+
#[allow(deprecated)]
21142117
fn default() -> Self {
21152118
Self {
21162119
group_rotation_frequency: 1u32.into(),

polkadot/runtime/parachains/src/assigner_coretime/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,12 @@ impl<T: Config> AssignmentProvider<BlockNumberFor<T>> for Pallet<T> {
318318
Assignment::Bulk(para_id)
319319
}
320320

321-
fn session_core_count() -> u32 {
322-
let config = configuration::ActiveConfig::<T>::get();
323-
config.scheduler_params.num_cores
321+
fn assignment_duplicated(assignment: &Assignment) {
322+
match assignment {
323+
Assignment::Pool { para_id, core_index } =>
324+
on_demand::Pallet::<T>::assignment_duplicated(*para_id, *core_index),
325+
Assignment::Bulk(_) => {},
326+
}
324327
}
325328
}
326329

polkadot/runtime/parachains/src/assigner_coretime/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use crate::{
2626
paras::{ParaGenesisArgs, ParaKind},
2727
scheduler::common::Assignment,
2828
};
29-
use alloc::collections::btree_map::BTreeMap;
3029
use frame_support::{assert_noop, assert_ok, pallet_prelude::*, traits::Currency};
3130
use pallet_broker::TaskId;
3231
use polkadot_primitives::{BlockNumber, Id as ParaId, SessionIndex, ValidationCode};
@@ -78,7 +77,7 @@ fn run_to_block(
7877
OnDemand::on_initialize(b + 1);
7978

8079
// In the real runtime this is expected to be called by the `InclusionInherent` pallet.
81-
Scheduler::free_cores_and_fill_claim_queue(BTreeMap::new(), b + 1);
80+
Scheduler::advance_claim_queue(&Default::default());
8281
}
8382
}
8483

polkadot/runtime/parachains/src/assigner_parachains.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,5 @@ impl<T: Config> AssignmentProvider<BlockNumberFor<T>> for Pallet<T> {
6363
Assignment::Bulk(para_id)
6464
}
6565

66-
fn session_core_count() -> u32 {
67-
paras::Parachains::<T>::decode_len().unwrap_or(0) as u32
68-
}
66+
fn assignment_duplicated(_: &Assignment) {}
6967
}

polkadot/runtime/parachains/src/assigner_parachains/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use crate::{
2323
},
2424
paras::{ParaGenesisArgs, ParaKind},
2525
};
26-
use alloc::collections::btree_map::BTreeMap;
2726
use frame_support::{assert_ok, pallet_prelude::*};
2827
use polkadot_primitives::{BlockNumber, Id as ParaId, SessionIndex, ValidationCode};
2928

@@ -71,7 +70,7 @@ fn run_to_block(
7170
Scheduler::initializer_initialize(b + 1);
7271

7372
// In the real runtime this is expected to be called by the `InclusionInherent` pallet.
74-
Scheduler::free_cores_and_fill_claim_queue(BTreeMap::new(), b + 1);
73+
Scheduler::advance_claim_queue(&Default::default());
7574
}
7675
}
7776

polkadot/runtime/parachains/src/builder.rs

Lines changed: 59 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ use crate::{
1818
configuration, inclusion, initializer, paras,
1919
paras::ParaKind,
2020
paras_inherent,
21-
scheduler::{self, common::AssignmentProvider, CoreOccupied, ParasEntry},
21+
scheduler::{
22+
self,
23+
common::{Assignment, AssignmentProvider},
24+
},
2225
session_info, shared,
2326
};
2427
use alloc::{
@@ -138,8 +141,6 @@ pub(crate) struct BenchBuilder<T: paras_inherent::Config> {
138141
/// Make every candidate include a code upgrade by setting this to `Some` where the interior
139142
/// value is the byte length of the new code.
140143
code_upgrade: Option<u32>,
141-
/// Specifies whether the claimqueue should be filled.
142-
fill_claimqueue: bool,
143144
/// Cores which should not be available when being populated with pending candidates.
144145
unavailable_cores: Vec<u32>,
145146
/// Use v2 candidate descriptor.
@@ -178,7 +179,6 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
178179
backed_in_inherent_paras: Default::default(),
179180
elastic_paras: Default::default(),
180181
code_upgrade: None,
181-
fill_claimqueue: true,
182182
unavailable_cores: vec![],
183183
candidate_descriptor_v2: false,
184184
candidate_modifier: None,
@@ -322,13 +322,6 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
322322
self.max_validators() / self.max_validators_per_core()
323323
}
324324

325-
/// Set whether the claim queue should be filled.
326-
#[cfg(not(feature = "runtime-benchmarks"))]
327-
pub(crate) fn set_fill_claimqueue(mut self, f: bool) -> Self {
328-
self.fill_claimqueue = f;
329-
self
330-
}
331-
332325
/// Get the minimum number of validity votes in order for a backed candidate to be included.
333326
#[cfg(feature = "runtime-benchmarks")]
334327
pub(crate) fn fallback_min_backing_votes() -> u32 {
@@ -340,10 +333,13 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
340333
HeadData(vec![0xFF; max_head_size as usize])
341334
}
342335

343-
fn candidate_descriptor_mock(candidate_descriptor_v2: bool) -> CandidateDescriptorV2<T::Hash> {
336+
fn candidate_descriptor_mock(
337+
para_id: ParaId,
338+
candidate_descriptor_v2: bool,
339+
) -> CandidateDescriptorV2<T::Hash> {
344340
if candidate_descriptor_v2 {
345341
CandidateDescriptorV2::new(
346-
0.into(),
342+
para_id,
347343
Default::default(),
348344
CoreIndex(200),
349345
2,
@@ -356,7 +352,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
356352
} else {
357353
// Convert v1 to v2.
358354
CandidateDescriptor::<T::Hash> {
359-
para_id: 0.into(),
355+
para_id,
360356
relay_parent: Default::default(),
361357
collator: junk_collator(),
362358
persisted_validation_data_hash: Default::default(),
@@ -373,6 +369,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
373369

374370
/// Create a mock of `CandidatePendingAvailability`.
375371
fn candidate_availability_mock(
372+
para_id: ParaId,
376373
group_idx: GroupIndex,
377374
core_idx: CoreIndex,
378375
candidate_hash: CandidateHash,
@@ -381,15 +378,16 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
381378
candidate_descriptor_v2: bool,
382379
) -> inclusion::CandidatePendingAvailability<T::Hash, BlockNumberFor<T>> {
383380
inclusion::CandidatePendingAvailability::<T::Hash, BlockNumberFor<T>>::new(
384-
core_idx, // core
385-
candidate_hash, // hash
386-
Self::candidate_descriptor_mock(candidate_descriptor_v2), // candidate descriptor
387-
commitments, // commitments
388-
availability_votes, // availability votes
389-
Default::default(), // backers
390-
Zero::zero(), // relay parent
391-
One::one(), /* relay chain block this
392-
* was backed in */
381+
core_idx, // core
382+
candidate_hash, // hash
383+
Self::candidate_descriptor_mock(para_id, candidate_descriptor_v2), /* candidate descriptor */
384+
commitments, // commitments
385+
availability_votes, /* availability
386+
* votes */
387+
Default::default(), // backers
388+
Zero::zero(), // relay parent
389+
One::one(), /* relay chain block this
390+
* was backed in */
393391
group_idx, // backing group
394392
)
395393
}
@@ -416,6 +414,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
416414
hrmp_watermark: 0u32.into(),
417415
};
418416
let candidate_availability = Self::candidate_availability_mock(
417+
para_id,
419418
group_idx,
420419
core_idx,
421420
candidate_hash,
@@ -886,14 +885,11 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
886885
extra_cores;
887886

888887
assert!(used_cores <= max_cores);
889-
let fill_claimqueue = self.fill_claimqueue;
890888

891889
// NOTE: there is an n+2 session delay for these actions to take effect.
892890
// We are currently in Session 0, so these changes will take effect in Session 2.
893891
Self::setup_para_ids(used_cores - extra_cores);
894-
configuration::ActiveConfig::<T>::mutate(|c| {
895-
c.scheduler_params.num_cores = used_cores as u32;
896-
});
892+
configuration::Pallet::<T>::set_coretime_cores_unchecked(used_cores as u32).unwrap();
897893

898894
let validator_ids = generate_validator_pairs::<T>(self.max_validators());
899895
let target_session = SessionIndex::from(self.target_session);
@@ -902,7 +898,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
902898
let bitfields = builder.create_availability_bitfields(
903899
&builder.backed_and_concluding_paras,
904900
&builder.elastic_paras,
905-
used_cores,
901+
scheduler::Pallet::<T>::num_availability_cores(),
906902
);
907903

908904
let mut backed_in_inherent = BTreeMap::new();
@@ -930,66 +926,57 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
930926

931927
assert_eq!(inclusion::PendingAvailability::<T>::iter().count(), used_cores - extra_cores);
932928

933-
// Mark all the used cores as occupied. We expect that there are
934-
// `backed_and_concluding_paras` that are pending availability and that there are
935-
// `used_cores - backed_and_concluding_paras ` which are about to be disputed.
936-
let now = frame_system::Pallet::<T>::block_number() + One::one();
937-
929+
// Sanity check that the occupied cores reported by the inclusion module are what we expect
930+
// to be.
938931
let mut core_idx = 0u32;
939932
let elastic_paras = &builder.elastic_paras;
940-
// Assign potentially multiple cores to same parachains,
941-
let cores = all_cores
933+
934+
let mut occupied_cores = inclusion::Pallet::<T>::get_occupied_cores()
935+
.map(|(core, candidate)| (core, candidate.candidate_descriptor().para_id()))
936+
.collect::<Vec<_>>();
937+
occupied_cores.sort_by(|(core_a, _), (core_b, _)| core_a.0.cmp(&core_b.0));
938+
939+
let mut expected_cores = all_cores
942940
.iter()
943941
.flat_map(|(para_id, _)| {
944942
(0..elastic_paras.get(&para_id).cloned().unwrap_or(1))
945943
.map(|_para_local_core_idx| {
946-
let ttl = configuration::ActiveConfig::<T>::get().scheduler_params.ttl;
947-
// Load an assignment into provider so that one is present to pop
948-
let assignment =
949-
<T as scheduler::Config>::AssignmentProvider::get_mock_assignment(
950-
CoreIndex(core_idx),
951-
ParaId::from(*para_id),
952-
);
944+
let old_core_idx = core_idx;
953945
core_idx += 1;
954-
CoreOccupied::Paras(ParasEntry::new(assignment, now + ttl))
946+
(CoreIndex(old_core_idx), ParaId::from(*para_id))
955947
})
956-
.collect::<Vec<CoreOccupied<_>>>()
948+
.collect::<Vec<_>>()
957949
})
958-
.collect::<Vec<CoreOccupied<_>>>();
950+
.collect::<Vec<_>>();
959951

960-
scheduler::AvailabilityCores::<T>::set(cores);
952+
expected_cores.sort_by(|(core_a, _), (core_b, _)| core_a.0.cmp(&core_b.0));
961953

962-
core_idx = 0u32;
954+
assert_eq!(expected_cores, occupied_cores);
963955

964956
// We need entries in the claim queue for those:
965957
all_cores.append(&mut builder.backed_in_inherent_paras.clone());
966958

967-
if fill_claimqueue {
968-
let cores = all_cores
969-
.keys()
970-
.flat_map(|para_id| {
971-
(0..elastic_paras.get(&para_id).cloned().unwrap_or(1))
972-
.map(|_para_local_core_idx| {
973-
let ttl = configuration::ActiveConfig::<T>::get().scheduler_params.ttl;
974-
// Load an assignment into provider so that one is present to pop
975-
let assignment =
976-
<T as scheduler::Config>::AssignmentProvider::get_mock_assignment(
977-
CoreIndex(core_idx),
978-
ParaId::from(*para_id),
979-
);
980-
981-
core_idx += 1;
982-
(
983-
CoreIndex(core_idx - 1),
984-
[ParasEntry::new(assignment, now + ttl)].into(),
985-
)
986-
})
987-
.collect::<Vec<(CoreIndex, VecDeque<ParasEntry<_>>)>>()
988-
})
989-
.collect::<BTreeMap<CoreIndex, VecDeque<ParasEntry<_>>>>();
959+
let mut core_idx = 0u32;
960+
let cores = all_cores
961+
.keys()
962+
.flat_map(|para_id| {
963+
(0..elastic_paras.get(&para_id).cloned().unwrap_or(1))
964+
.map(|_para_local_core_idx| {
965+
// Load an assignment into provider so that one is present to pop
966+
let assignment =
967+
<T as scheduler::Config>::AssignmentProvider::get_mock_assignment(
968+
CoreIndex(core_idx),
969+
ParaId::from(*para_id),
970+
);
990971

991-
scheduler::ClaimQueue::<T>::set(cores);
992-
}
972+
core_idx += 1;
973+
(CoreIndex(core_idx - 1), [assignment].into())
974+
})
975+
.collect::<Vec<(CoreIndex, VecDeque<Assignment>)>>()
976+
})
977+
.collect::<BTreeMap<CoreIndex, VecDeque<Assignment>>>();
978+
979+
scheduler::ClaimQueue::<T>::set(cores);
993980

994981
Bench::<T> {
995982
data: ParachainsInherentData {

0 commit comments

Comments
 (0)