Request based availability distribution (#2423)

* WIP

* availability distribution, still very wip.

Work on the requesting side of things.

* Some docs on what I intend to do.

* Checkpoint of session cache implementation

as I will likely replace it with something smarter.

* More work, mostly on cache

and getting things to type check.

* Only derive MallocSizeOf and Debug for std.

* availability-distribution: Cache feature complete.

* Sketch out logic in `FetchTask` for actual fetching.

- Compile fixes.
- Cleanup.

* Format cleanup.

* More format fixes.

* Almost feature complete `fetch_task`.

Missing:

- Check for cancel
- Actual querying of peer ids.

* Finish FetchTask so far.

* Directly use AuthorityDiscoveryId in protocol and cache.

* Resolve `AuthorityDiscoveryId` on sending requests.

* Rework fetch_task

- also make it impossible to check the wrong chunk index.
- Export needed function in validator_discovery.

* From<u32> implementation for `ValidatorIndex`.

* Fixes and more integration work.

* Make session cache proper lru cache.

* Use proper lru cache.

* Requester finished.

* ProtocolState -> Requester

Also make sure to not fetch our own chunk.

* Cleanup + fixes.

* Remove unused functions

- FetchTask::is_finished
- SessionCache::fetch_session_info

* availability-distribution responding side.

* Cleanup + Fixes.

* More fixes.

* More fixes.

adder-collator is running!

* Some docs.

* Docs.

* Fix reporting of bad guys.

* Fix tests

* Make all tests compile.

* Fix test.

* Cleanup + get rid of some warnings.

* state -> requester

* Mostly doc fixes.

* Fix test suite.

* Get rid of now redundant message types.

* WIP

* Rob's review remarks.

* Fix test suite.

* core.relay_parent -> leaf for session request.

* Style fix.

* Decrease request timeout.

* Cleanup obsolete errors.

* Metrics + don't fail on non fatal errors.

* requester.rs -> requester/mod.rs

* Panic on invalid BadValidator report.

* Fix indentation.

* Use typed default timeout constant.

* Make channel size 0, as each sender gets one slot anyways.

* Fix incorrect metrics initialization.

* Fix build after merge.

* More fixes.

* Hopefully valid metrics names.

* Better metrics names.

* Some tests that already work.

* Slightly better docs.

* Some more tests.

* Fix network bridge test.
This commit is contained in:
Robert Klotzner
2021-02-26 18:58:07 +01:00
committed by GitHub
parent 241b1f12a7
commit 48409e5548
45 changed files with 2037 additions and 1523 deletions
+37 -37
View File
@@ -281,7 +281,7 @@ impl<T: Config> Module<T> {
);
ensure!(
signed_bitfield.validator_index() < validators.len() as ValidatorIndex,
(signed_bitfield.validator_index().0 as usize) < validators.len(),
Error::<T>::ValidatorIndexOutOfBounds,
);
@@ -290,7 +290,7 @@ impl<T: Config> Module<T> {
Error::<T>::UnoccupiedBitInBitfield,
);
let validator_public = &validators[signed_bitfield.validator_index() as usize];
let validator_public = &validators[signed_bitfield.validator_index().0 as usize];
signed_bitfield.check_signature(
&signing_context,
@@ -312,7 +312,7 @@ impl<T: Config> Module<T> {
// defensive check - this is constructed by loading the availability bitfield record,
// which is always `Some` if the core is occupied - that's why we're here.
let val_idx = signed_bitfield.validator_index() as usize;
let val_idx = signed_bitfield.validator_index().0 as usize;
if let Some(mut bit) = pending_availability.as_mut()
.and_then(|r| r.availability_votes.get_mut(val_idx))
{
@@ -527,7 +527,7 @@ impl<T: Config> Module<T> {
&signing_context,
group_vals.len(),
|idx| group_vals.get(idx)
.and_then(|i| validators.get(*i as usize))
.and_then(|i| validators.get(i.0 as usize))
.map(|v| v.clone()),
);
@@ -546,7 +546,7 @@ impl<T: Config> Module<T> {
let val_idx = group_vals.get(bit_idx)
.expect("this query done above; qed");
backers.set(*val_idx as _, true);
backers.set(val_idx.0 as _, true);
}
}
@@ -658,12 +658,12 @@ impl<T: Config> Module<T> {
T::RewardValidators::reward_backing(backers.iter().enumerate()
.filter(|(_, backed)| **backed)
.map(|(i, _)| i as _)
.map(|(i, _)| ValidatorIndex(i as _))
);
T::RewardValidators::reward_bitfields(availability_votes.iter().enumerate()
.filter(|(_, voted)| **voted)
.map(|(i, _)| i as _)
.map(|(i, _)| ValidatorIndex(i as _))
);
// initial weight is config read.
@@ -988,7 +988,7 @@ mod tests {
let candidate_hash = candidate.hash();
for (idx_in_group, val_idx) in group.iter().enumerate().take(signing) {
let key: Sr25519Keyring = validators[*val_idx as usize];
let key: Sr25519Keyring = validators[val_idx.0 as usize];
*validator_indices.get_mut(idx_in_group).unwrap() = true;
let signature = SignedStatement::sign(
@@ -1017,7 +1017,7 @@ mod tests {
&backed,
signing_context,
group.len(),
|i| Some(validators[group[i] as usize].public().into()),
|i| Some(validators[group[i].0 as usize].public().into()),
).ok().unwrap_or(0) * 2 > group.len();
if should_pass {
@@ -1238,7 +1238,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1256,7 +1256,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1274,7 +1274,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1292,7 +1292,7 @@ mod tests {
let signed_0 = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield.clone(),
&signing_context,
));
@@ -1300,7 +1300,7 @@ mod tests {
let signed_1 = block_on(sign_bitfield(
&keystore,
&validators[1],
1,
ValidatorIndex(1),
bare_bitfield,
&signing_context,
));
@@ -1319,7 +1319,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1337,7 +1337,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1372,7 +1372,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1409,7 +1409,7 @@ mod tests {
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
ValidatorIndex(0),
bare_bitfield,
&signing_context,
));
@@ -1534,7 +1534,7 @@ mod tests {
Some(block_on(sign_bitfield(
&keystore,
key,
i as ValidatorIndex,
ValidatorIndex(i as _),
to_sign,
&signing_context,
)))
@@ -1573,18 +1573,18 @@ mod tests {
let rewards = crate::mock::availability_rewards();
assert_eq!(rewards.len(), 4);
assert_eq!(rewards.get(&0).unwrap(), &1);
assert_eq!(rewards.get(&1).unwrap(), &1);
assert_eq!(rewards.get(&2).unwrap(), &1);
assert_eq!(rewards.get(&3).unwrap(), &1);
assert_eq!(rewards.get(&ValidatorIndex(0)).unwrap(), &1);
assert_eq!(rewards.get(&ValidatorIndex(1)).unwrap(), &1);
assert_eq!(rewards.get(&ValidatorIndex(2)).unwrap(), &1);
assert_eq!(rewards.get(&ValidatorIndex(3)).unwrap(), &1);
}
{
let rewards = crate::mock::backing_rewards();
assert_eq!(rewards.len(), 2);
assert_eq!(rewards.get(&3).unwrap(), &1);
assert_eq!(rewards.get(&4).unwrap(), &1);
assert_eq!(rewards.get(&ValidatorIndex(3)).unwrap(), &1);
assert_eq!(rewards.get(&ValidatorIndex(4)).unwrap(), &1);
}
});
}
@@ -1628,7 +1628,7 @@ mod tests {
group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]),
group_index if group_index == GroupIndex::from(2) => Some(vec![4]),
_ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"),
};
}.map(|m| m.into_iter().map(ValidatorIndex).collect::<Vec<_>>());
let thread_collator: CollatorId = Sr25519Keyring::Two.public().into();
@@ -2115,7 +2115,7 @@ mod tests {
group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]),
group_index if group_index == GroupIndex::from(2) => Some(vec![4]),
_ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"),
};
}.map(|vs| vs.into_iter().map(ValidatorIndex).collect::<Vec<_>>());
let thread_collator: CollatorId = Sr25519Keyring::Two.public().into();
@@ -2310,7 +2310,7 @@ mod tests {
let group_validators = |group_index: GroupIndex| match group_index {
group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1, 2, 3, 4]),
_ => panic!("Group index out of bounds for 1 parachain"),
};
}.map(|vs| vs.into_iter().map(ValidatorIndex).collect::<Vec<_>>());
let chain_a_assignment = CoreAssignment {
core: CoreIndex::from(0),
@@ -2408,7 +2408,7 @@ mod tests {
run_to_block(10, |_| None);
<AvailabilityBitfields<Test>>::insert(
&0,
&ValidatorIndex(0),
AvailabilityBitfieldRecord {
bitfield: default_bitfield(),
submitted_at: 9,
@@ -2416,7 +2416,7 @@ mod tests {
);
<AvailabilityBitfields<Test>>::insert(
&1,
&ValidatorIndex(1),
AvailabilityBitfieldRecord {
bitfield: default_bitfield(),
submitted_at: 9,
@@ -2424,7 +2424,7 @@ mod tests {
);
<AvailabilityBitfields<Test>>::insert(
&4,
&ValidatorIndex(4),
AvailabilityBitfieldRecord {
bitfield: default_bitfield(),
submitted_at: 9,
@@ -2461,9 +2461,9 @@ mod tests {
assert_eq!(Validators::get(), validator_public);
assert_eq!(shared::Module::<Test>::session_index(), 5);
assert!(<AvailabilityBitfields<Test>>::get(&0).is_some());
assert!(<AvailabilityBitfields<Test>>::get(&1).is_some());
assert!(<AvailabilityBitfields<Test>>::get(&4).is_some());
assert!(<AvailabilityBitfields<Test>>::get(&ValidatorIndex(0)).is_some());
assert!(<AvailabilityBitfields<Test>>::get(&ValidatorIndex(1)).is_some());
assert!(<AvailabilityBitfields<Test>>::get(&ValidatorIndex(4)).is_some());
assert!(<PendingAvailability<Test>>::get(&chain_a).is_some());
assert!(<PendingAvailability<Test>>::get(&chain_b).is_some());
@@ -2485,9 +2485,9 @@ mod tests {
assert_eq!(Validators::get(), validator_public_new);
assert_eq!(shared::Module::<Test>::session_index(), 6);
assert!(<AvailabilityBitfields<Test>>::get(&0).is_none());
assert!(<AvailabilityBitfields<Test>>::get(&1).is_none());
assert!(<AvailabilityBitfields<Test>>::get(&4).is_none());
assert!(<AvailabilityBitfields<Test>>::get(&ValidatorIndex(0)).is_none());
assert!(<AvailabilityBitfields<Test>>::get(&ValidatorIndex(1)).is_none());
assert!(<AvailabilityBitfields<Test>>::get(&ValidatorIndex(4)).is_none());
assert!(<PendingAvailability<Test>>::get(&chain_a).is_none());
assert!(<PendingAvailability<Test>>::get(&chain_b).is_none());
@@ -38,7 +38,7 @@ fn reward_by_indices<C, I>(points: u32, indices: I) where
// and we are rewarding for behavior in current session.
let validators = C::SessionInterface::validators();
let rewards = indices.into_iter()
.filter_map(|i| validators.get(i as usize).map(|v| v.clone()))
.filter_map(|i| validators.get(i.0 as usize).map(|v| v.clone()))
.map(|v| (v, points));
<pallet_staking::Module<C>>::reward_by_ids(rewards);
+1 -1
View File
@@ -263,7 +263,7 @@ impl<T: Config> Module<T> {
let mut shuffled_indices: Vec<_> = (0..validators.len())
.enumerate()
.map(|(i, _)| i as ValidatorIndex)
.map(|(i, _)| ValidatorIndex(i as _))
.collect();
shuffled_indices.shuffle(&mut rng);