Add attestation strategy to chain harness

This commit is contained in:
Paul Hauner 2019-06-21 11:44:15 +10:00
parent 46c0e17682
commit 723283bd01
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C

View File

@ -20,6 +20,11 @@ pub enum BuildStrategy {
ForkCanonicalChainAt(Slot), ForkCanonicalChainAt(Slot),
} }
#[derive(Clone, Copy, Debug)]
pub enum AttestationStrategy {
AllValidators,
}
pub struct CommonTypes<L, E> pub struct CommonTypes<L, E>
where where
L: LmdGhost<MemoryStore, E>, L: LmdGhost<MemoryStore, E>,
@ -95,7 +100,12 @@ where
self.chain.catchup_state().expect("should catchup state"); self.chain.catchup_state().expect("should catchup state");
} }
pub fn extend_chain(&self, build_strategy: BuildStrategy, blocks: usize) { pub fn extend_chain(
&self,
build_strategy: BuildStrategy,
blocks: usize,
attestation_strategy: AttestationStrategy,
) {
// Get an initial state to build the block upon, based on the build strategy. // Get an initial state to build the block upon, based on the build strategy.
let mut state = match build_strategy { let mut state = match build_strategy {
BuildStrategy::OnCanonicalHead => self.chain.current_state().clone(), BuildStrategy::OnCanonicalHead => self.chain.current_state().clone(),
@ -134,7 +144,12 @@ where
.expect("should not error during block processing"); .expect("should not error during block processing");
if let BlockProcessingOutcome::Processed { block_root } = outcome { if let BlockProcessingOutcome::Processed { block_root } = outcome {
self.add_attestations_to_op_pool(&new_state, block_root, slot); self.add_attestations_to_op_pool(
attestation_strategy,
&new_state,
block_root,
slot,
);
} else { } else {
panic!("block should be successfully processed"); panic!("block should be successfully processed");
} }
@ -198,6 +213,7 @@ where
fn add_attestations_to_op_pool( fn add_attestations_to_op_pool(
&self, &self,
attestation_strategy: AttestationStrategy,
state: &BeaconState<E>, state: &BeaconState<E>,
head_block_root: Hash256, head_block_root: Hash256,
head_block_slot: Slot, head_block_slot: Slot,
@ -205,6 +221,10 @@ where
let spec = &self.spec; let spec = &self.spec;
let fork = &state.fork; let fork = &state.fork;
let attesting_validators: Vec<usize> = match attestation_strategy {
AttestationStrategy::AllValidators => (0..self.keypairs.len()).collect(),
};
state state
.get_crosslink_committees_at_slot(state.slot) .get_crosslink_committees_at_slot(state.slot)
.expect("should get committees") .expect("should get committees")
@ -213,52 +233,57 @@ where
let committee_size = cc.committee.len(); let committee_size = cc.committee.len();
for (i, validator_index) in cc.committee.iter().enumerate() { for (i, validator_index) in cc.committee.iter().enumerate() {
let data = self // Note: searching this array is worst-case `O(n)`. A hashset could be a better
.chain // alternative.
.produce_attestation_data_for_block( if attesting_validators.contains(validator_index) {
cc.shard, let data = self
head_block_root, .chain
head_block_slot, .produce_attestation_data_for_block(
state, cc.shard,
) head_block_root,
.expect("should produce attestation data"); head_block_slot,
state,
)
.expect("should produce attestation data");
let mut aggregation_bitfield = Bitfield::new(); let mut aggregation_bitfield = Bitfield::new();
aggregation_bitfield.set(i, true); aggregation_bitfield.set(i, true);
aggregation_bitfield.set(committee_size, false); aggregation_bitfield.set(committee_size, false);
let mut custody_bitfield = Bitfield::new(); let mut custody_bitfield = Bitfield::new();
custody_bitfield.set(committee_size, false); custody_bitfield.set(committee_size, false);
let signature = { let signature = {
let message = AttestationDataAndCustodyBit { let message = AttestationDataAndCustodyBit {
data: data.clone(), data: data.clone(),
custody_bit: false, custody_bit: false,
} }
.tree_hash_root(); .tree_hash_root();
let domain = spec.get_domain(data.target_epoch, Domain::Attestation, fork); let domain =
spec.get_domain(data.target_epoch, Domain::Attestation, fork);
let mut agg_sig = AggregateSignature::new(); let mut agg_sig = AggregateSignature::new();
agg_sig.add(&Signature::new( agg_sig.add(&Signature::new(
&message, &message,
domain, domain,
self.get_sk(*validator_index), self.get_sk(*validator_index),
)); ));
agg_sig agg_sig
}; };
let attestation = Attestation { let attestation = Attestation {
aggregation_bitfield, aggregation_bitfield,
data, data,
custody_bitfield, custody_bitfield,
signature, signature,
}; };
self.chain self.chain
.process_attestation(attestation) .process_attestation(attestation)
.expect("should process attestation"); .expect("should process attestation");
}
} }
}); });
} }
@ -295,7 +320,11 @@ mod test {
let harness = get_harness(VALIDATOR_COUNT); let harness = get_harness(VALIDATOR_COUNT);
harness.extend_chain(BuildStrategy::OnCanonicalHead, num_blocks_produced as usize); harness.extend_chain(
BuildStrategy::OnCanonicalHead,
num_blocks_produced as usize,
AttestationStrategy::AllValidators,
);
let state = &harness.chain.head().beacon_state; let state = &harness.chain.head().beacon_state;