Newer
Older
let signed_0 = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
bare_bitfield.clone(),
&signing_context,
));
let signed_1 = block_on(sign_bitfield(
&keystore,
&validators[1],
1,
bare_bitfield,
&signing_context,
));
Peter Goodspeed-Niklaus
committed
vec![signed_1, signed_0],
&core_lookup,
).is_err());
}
// non-pending bit set.
{
let mut bare_bitfield = default_bitfield();
*bare_bitfield.0.get_mut(0).unwrap() = true;
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
bare_bitfield,
&signing_context,
));
Peter Goodspeed-Niklaus
committed
vec![signed],
&core_lookup,
).is_err());
}
// empty bitfield signed: always OK, but kind of useless.
{
let bare_bitfield = default_bitfield();
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
bare_bitfield,
&signing_context,
));
Peter Goodspeed-Niklaus
committed
vec![signed],
&core_lookup,
).is_ok());
}
// bitfield signed with pending bit signed.
{
let mut bare_bitfield = default_bitfield();
assert_eq!(core_lookup(CoreIndex::from(0)), Some(chain_a));
let default_candidate = TestCandidateBuilder::default().build();
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
core: CoreIndex::from(0),
descriptor: default_candidate.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: 0,
backed_in_number: 0,
});
PendingAvailabilityCommitments::insert(chain_a, default_candidate.commitments);
*bare_bitfield.0.get_mut(0).unwrap() = true;
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
bare_bitfield,
&signing_context,
));
Peter Goodspeed-Niklaus
committed
vec![signed],
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
<PendingAvailability<Test>>::remove(chain_a);
PendingAvailabilityCommitments::remove(chain_a);
}
// bitfield signed with pending bit signed, but no commitments.
{
let mut bare_bitfield = default_bitfield();
assert_eq!(core_lookup(CoreIndex::from(0)), Some(chain_a));
let default_candidate = TestCandidateBuilder::default().build();
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
core: CoreIndex::from(0),
descriptor: default_candidate.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: 0,
backed_in_number: 0,
});
*bare_bitfield.0.get_mut(0).unwrap() = true;
let signed = block_on(sign_bitfield(
&keystore,
&validators[0],
0,
bare_bitfield,
&signing_context,
));
// no core is freed
assert_eq!(
Inclusion::process_bitfields(
vec![signed],
&core_lookup,
),
Ok(vec![]),
);
}
});
}
#[test]
fn supermajority_bitfields_trigger_availability() {
let chain_a = ParaId::from(1);
let chain_b = ParaId::from(2);
let thread_a = ParaId::from(3);
let paras = vec![(chain_a, true), (chain_b, true), (thread_a, false)];
let validators = vec![
Sr25519Keyring::Alice,
Sr25519Keyring::Bob,
Sr25519Keyring::Charlie,
Sr25519Keyring::Dave,
Sr25519Keyring::Ferdie,
];
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
for validator in validators.iter() {
SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap();
}
let validator_public = validator_pubkeys(&validators);
new_test_ext(genesis_config(paras)).execute_with(|| {
Validators::set(validator_public.clone());
CurrentSessionIndex::set(5);
let signing_context = SigningContext {
parent_hash: System::parent_hash(),
session_index: 5,
};
let core_lookup = |core| match core {
core if core == CoreIndex::from(0) => Some(chain_a),
core if core == CoreIndex::from(1) => Some(chain_b),
core if core == CoreIndex::from(2) => Some(thread_a),
_ => panic!("Core out of bounds for 2 parachains and 1 parathread core."),
};
let candidate_a = TestCandidateBuilder {
para_id: chain_a,
head_data: vec![1, 2, 3, 4].into(),
..Default::default()
}.build();
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
core: CoreIndex::from(0),
descriptor: candidate_a.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: 0,
backed_in_number: 0,
});
PendingAvailabilityCommitments::insert(chain_a, candidate_a.commitments);
let candidate_b = TestCandidateBuilder {
para_id: chain_b,
head_data: vec![5, 6, 7, 8].into(),
..Default::default()
}.build();
<PendingAvailability<Test>>::insert(chain_b, CandidatePendingAvailability {
core: CoreIndex::from(1),
descriptor: candidate_b.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: 0,
backed_in_number: 0,
});
PendingAvailabilityCommitments::insert(chain_b, candidate_b.commitments);
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
// this bitfield signals that a and b are available.
let a_and_b_available = {
let mut bare_bitfield = default_bitfield();
*bare_bitfield.0.get_mut(0).unwrap() = true;
*bare_bitfield.0.get_mut(1).unwrap() = true;
bare_bitfield
};
// this bitfield signals that only a is available.
let a_available = {
let mut bare_bitfield = default_bitfield();
*bare_bitfield.0.get_mut(0).unwrap() = true;
bare_bitfield
};
let threshold = availability_threshold(validators.len());
// 4 of 5 first value >= 2/3
assert_eq!(threshold, 4);
let signed_bitfields = validators.iter().enumerate().filter_map(|(i, key)| {
let to_sign = if i < 3 {
a_and_b_available.clone()
} else if i < 4 {
a_available.clone()
} else {
// sign nothing.
return None
};
Some(block_on(sign_bitfield(
&keystore,
key,
i as ValidatorIndex,
to_sign,
&signing_context,
)))
}).collect();
assert!(Inclusion::process_bitfields(
Peter Goodspeed-Niklaus
committed
signed_bitfields,
&core_lookup,
).is_ok());
// chain A had 4 signing off, which is >= threshold.
// chain B has 3 signing off, which is < threshold.
assert!(<PendingAvailability<Test>>::get(&chain_a).is_none());
assert!(<PendingAvailabilityCommitments>::get(&chain_a).is_none());
assert!(<PendingAvailabilityCommitments>::get(&chain_b).is_some());
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
assert_eq!(
<PendingAvailability<Test>>::get(&chain_b).unwrap().availability_votes,
{
// check that votes from first 3 were tracked.
let mut votes = default_availability_votes();
*votes.get_mut(0).unwrap() = true;
*votes.get_mut(1).unwrap() = true;
*votes.get_mut(2).unwrap() = true;
votes
},
);
// and check that chain head was enacted.
assert_eq!(Paras::para_head(&chain_a), Some(vec![1, 2, 3, 4].into()));
});
}
#[test]
fn candidate_checks() {
let chain_a = ParaId::from(1);
let chain_b = ParaId::from(2);
let thread_a = ParaId::from(3);
let paras = vec![(chain_a, true), (chain_b, true), (thread_a, false)];
let validators = vec![
Sr25519Keyring::Alice,
Sr25519Keyring::Bob,
Sr25519Keyring::Charlie,
Sr25519Keyring::Dave,
Sr25519Keyring::Ferdie,
];
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
for validator in validators.iter() {
SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap();
}
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
let validator_public = validator_pubkeys(&validators);
new_test_ext(genesis_config(paras)).execute_with(|| {
Validators::set(validator_public.clone());
CurrentSessionIndex::set(5);
run_to_block(5, |_| None);
let signing_context = SigningContext {
parent_hash: System::parent_hash(),
session_index: 5,
};
let group_validators = |group_index: GroupIndex| match group_index {
group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]),
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"),
};
let thread_collator: CollatorId = Sr25519Keyring::Two.public().into();
let chain_a_assignment = CoreAssignment {
core: CoreIndex::from(0),
para_id: chain_a,
kind: AssignmentKind::Parachain,
group_idx: GroupIndex::from(0),
};
let chain_b_assignment = CoreAssignment {
core: CoreIndex::from(1),
para_id: chain_b,
kind: AssignmentKind::Parachain,
group_idx: GroupIndex::from(1),
};
let thread_a_assignment = CoreAssignment {
core: CoreIndex::from(2),
para_id: thread_a,
kind: AssignmentKind::Parathread(thread_collator.clone(), 0),
group_idx: GroupIndex::from(2),
};
// unscheduled candidate.
{
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_b_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::UnscheduledCandidate.into()),
);
}
// candidates out of order.
{
let mut candidate_a = TestCandidateBuilder {
para_id: chain_a,
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
}.build();
let mut candidate_b = TestCandidateBuilder {
para_id: chain_b,
persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate_a,
);
collator_sign_candidate(
Sr25519Keyring::Two,
&mut candidate_b,
);
let backed_a = block_on(back_candidate(
candidate_a,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
let backed_b = block_on(back_candidate(
candidate_b,
&validators,
group_validators(GroupIndex::from(1)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
// out-of-order manifests as unscheduled.
assert_eq!(
Inclusion::process_candidates(
vec![backed_b, backed_a],
vec![chain_a_assignment.clone(), chain_b_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::UnscheduledCandidate.into()),
);
}
// candidate not backed.
{
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Lacking,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::InsufficientBacking.into()),
);
}
// candidate not in parent context.
{
let wrong_parent_hash = Hash::from([222; 32]);
assert!(System::parent_hash() != wrong_parent_hash);
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::CandidateNotInParentContext.into()),
);
}
// candidate has wrong collator.
{
let mut candidate = TestCandidateBuilder {
para_id: thread_a,
persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(),
assert!(CollatorId::from(Sr25519Keyring::One.public()) != thread_collator);
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(2)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![
chain_a_assignment.clone(),
chain_b_assignment.clone(),
thread_a_assignment.clone(),
],
&group_validators,
),
Err(Error::<Test>::WrongCollator.into()),
);
}
// candidate not well-signed by collator.
{
let mut candidate = TestCandidateBuilder {
para_id: thread_a,
persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(),
assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator);
collator_sign_candidate(
Sr25519Keyring::Two,
&mut candidate,
);
// change the candidate after signing.
candidate.descriptor.pov_hash = Hash::from([2; 32]);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(2)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![thread_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::NotCollatorSigned.into()),
);
}
// para occupied - reject.
{
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
let candidate = TestCandidateBuilder::default().build();
<PendingAvailability<Test>>::insert(&chain_a, CandidatePendingAvailability {
core: CoreIndex::from(0),
descriptor: candidate.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: 3,
backed_in_number: 4,
});
<PendingAvailabilityCommitments>::insert(&chain_a, candidate.commitments);
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::CandidateScheduledBeforeParaFree.into()),
);
<PendingAvailability<Test>>::remove(&chain_a);
<PendingAvailabilityCommitments>::remove(&chain_a);
}
// messed up commitments storage - do not panic - reject.
{
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
relay_parent: System::parent_hash(),
pov_hash: Hash::from([1; 32]),
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
..Default::default()
}.build();
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
// this is not supposed to happen
<PendingAvailabilityCommitments>::insert(&chain_a, candidate.commitments.clone());
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::CandidateScheduledBeforeParaFree.into()),
);
<PendingAvailabilityCommitments>::remove(&chain_a);
}
// interfering code upgrade - reject
{
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
pov_hash: Hash::from([1; 32]),
new_validation_code: Some(vec![5, 6, 7, 8].into()),
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
Paras::schedule_code_upgrade(
chain_a,
vec![1, 2, 3, 4].into(),
10,
);
assert_eq!(Paras::last_code_upgrade(chain_a, true), Some(10));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::PrematureCodeUpgrade.into()),
);
}
// Bad validation data hash - reject
{
let mut candidate = TestCandidateBuilder {
para_id: chain_a,
relay_parent: System::parent_hash(),
pov_hash: Hash::from([1; 32]),
persisted_validation_data_hash: [42u8; 32].into(),
asynchronous rob
committed
..Default::default()
}.build();
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate,
);
let backed = block_on(back_candidate(
asynchronous rob
committed
candidate,
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
asynchronous rob
committed
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
assert_eq!(
Inclusion::process_candidates(
vec![backed],
vec![chain_a_assignment.clone()],
&group_validators,
),
Err(Error::<Test>::ValidationDataHashMismatch.into()),
);
}
});
}
#[test]
fn backing_works() {
let chain_a = ParaId::from(1);
let chain_b = ParaId::from(2);
let thread_a = ParaId::from(3);
let paras = vec![(chain_a, true), (chain_b, true), (thread_a, false)];
let validators = vec![
Sr25519Keyring::Alice,
Sr25519Keyring::Bob,
Sr25519Keyring::Charlie,
Sr25519Keyring::Dave,
Sr25519Keyring::Ferdie,
];
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
for validator in validators.iter() {
SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap();
}
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
let validator_public = validator_pubkeys(&validators);
new_test_ext(genesis_config(paras)).execute_with(|| {
Validators::set(validator_public.clone());
CurrentSessionIndex::set(5);
run_to_block(5, |_| None);
let signing_context = SigningContext {
parent_hash: System::parent_hash(),
session_index: 5,
};
let group_validators = |group_index: GroupIndex| match group_index {
group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]),
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"),
};
let thread_collator: CollatorId = Sr25519Keyring::Two.public().into();
let chain_a_assignment = CoreAssignment {
core: CoreIndex::from(0),
para_id: chain_a,
kind: AssignmentKind::Parachain,
group_idx: GroupIndex::from(0),
};
let chain_b_assignment = CoreAssignment {
core: CoreIndex::from(1),
para_id: chain_b,
kind: AssignmentKind::Parachain,
group_idx: GroupIndex::from(1),
};
let thread_a_assignment = CoreAssignment {
core: CoreIndex::from(2),
para_id: thread_a,
kind: AssignmentKind::Parathread(thread_collator.clone(), 0),
group_idx: GroupIndex::from(2),
};
let mut candidate_a = TestCandidateBuilder {
para_id: chain_a,
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate_a,
);
let mut candidate_b = TestCandidateBuilder {
para_id: chain_b,
persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(),
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate_b,
);
let mut candidate_c = TestCandidateBuilder {
para_id: thread_a,
persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(),
collator_sign_candidate(
Sr25519Keyring::Two,
&mut candidate_c,
);
let backed_a = block_on(back_candidate(
candidate_a.clone(),
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
let backed_b = block_on(back_candidate(
candidate_b.clone(),
&validators,
group_validators(GroupIndex::from(1)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
let backed_c = block_on(back_candidate(
candidate_c.clone(),
&validators,
group_validators(GroupIndex::from(2)).unwrap().as_ref(),
&keystore,
&signing_context,
BackingKind::Threshold,
));
let occupied_cores = Inclusion::process_candidates(
vec![backed_a, backed_b, backed_c],
vec![
chain_a_assignment.clone(),
chain_b_assignment.clone(),
thread_a_assignment.clone(),
],
&group_validators,
).expect("candidates scheduled, in order, and backed");
assert_eq!(occupied_cores, vec![CoreIndex::from(0), CoreIndex::from(1), CoreIndex::from(2)]);
assert_eq!(
<PendingAvailability<Test>>::get(&chain_a),
Some(CandidatePendingAvailability {
core: CoreIndex::from(0),
descriptor: candidate_a.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: System::block_number() - 1,
backed_in_number: System::block_number(),
})
);
assert_eq!(
<PendingAvailabilityCommitments>::get(&chain_a),
Some(candidate_a.commitments),
);
assert_eq!(
<PendingAvailability<Test>>::get(&chain_b),
Some(CandidatePendingAvailability {
core: CoreIndex::from(1),
descriptor: candidate_b.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: System::block_number() - 1,
backed_in_number: System::block_number(),
})
);
assert_eq!(
<PendingAvailabilityCommitments>::get(&chain_b),
Some(candidate_b.commitments),
);
assert_eq!(
<PendingAvailability<Test>>::get(&thread_a),
Some(CandidatePendingAvailability {
core: CoreIndex::from(2),
descriptor: candidate_c.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: System::block_number() - 1,
backed_in_number: System::block_number(),
})
);
assert_eq!(
<PendingAvailabilityCommitments>::get(&thread_a),
Some(candidate_c.commitments),
);
asynchronous rob
committed
#[test]
fn can_include_candidate_with_ok_code_upgrade() {
let chain_a = ParaId::from(1);
let paras = vec![(chain_a, true)];
let validators = vec![
Sr25519Keyring::Alice,
Sr25519Keyring::Bob,
Sr25519Keyring::Charlie,
Sr25519Keyring::Dave,
Sr25519Keyring::Ferdie,
];
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
for validator in validators.iter() {
SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap();
}
asynchronous rob
committed
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
let validator_public = validator_pubkeys(&validators);
new_test_ext(genesis_config(paras)).execute_with(|| {
Validators::set(validator_public.clone());
CurrentSessionIndex::set(5);
run_to_block(5, |_| None);
let signing_context = SigningContext {
parent_hash: System::parent_hash(),
session_index: 5,
};
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"),
};
let chain_a_assignment = CoreAssignment {
core: CoreIndex::from(0),
para_id: chain_a,
kind: AssignmentKind::Parachain,
group_idx: GroupIndex::from(0),
};
let mut candidate_a = TestCandidateBuilder {
para_id: chain_a,
relay_parent: System::parent_hash(),
pov_hash: Hash::from([1; 32]),
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
asynchronous rob
committed
new_validation_code: Some(vec![1, 2, 3].into()),
..Default::default()
}.build();
collator_sign_candidate(
Sr25519Keyring::One,
&mut candidate_a,
);
let backed_a = block_on(back_candidate(
asynchronous rob
committed
candidate_a.clone(),
&validators,
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
&keystore,
asynchronous rob
committed
&signing_context,
BackingKind::Threshold,
));
asynchronous rob
committed
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
let occupied_cores = Inclusion::process_candidates(
vec![backed_a],
vec![
chain_a_assignment.clone(),
],
&group_validators,
).expect("candidates scheduled, in order, and backed");
assert_eq!(occupied_cores, vec![CoreIndex::from(0)]);
assert_eq!(
<PendingAvailability<Test>>::get(&chain_a),
Some(CandidatePendingAvailability {
core: CoreIndex::from(0),
descriptor: candidate_a.descriptor,
availability_votes: default_availability_votes(),
relay_parent_number: System::block_number() - 1,
backed_in_number: System::block_number(),
})
);
assert_eq!(
<PendingAvailabilityCommitments>::get(&chain_a),
Some(candidate_a.commitments),
);
});
}
#[test]
fn session_change_wipes_and_updates_session_info() {