Update "attestation" family of structs in types
Also adds/splits up some testing builders.
This commit is contained in:
parent
8050ed7a26
commit
20a439101e
@ -8,7 +8,7 @@ use test_random_derive::TestRandom;
|
|||||||
|
|
||||||
/// The data upon which an attestation is based.
|
/// The data upon which an attestation is based.
|
||||||
///
|
///
|
||||||
/// Spec v0.4.0
|
/// Spec v0.5.0
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
Clone,
|
Clone,
|
||||||
@ -24,14 +24,19 @@ use test_random_derive::TestRandom;
|
|||||||
SignedRoot,
|
SignedRoot,
|
||||||
)]
|
)]
|
||||||
pub struct AttestationData {
|
pub struct AttestationData {
|
||||||
|
// LMD GHOST vote
|
||||||
pub slot: Slot,
|
pub slot: Slot,
|
||||||
pub shard: u64,
|
|
||||||
pub beacon_block_root: Hash256,
|
pub beacon_block_root: Hash256,
|
||||||
pub epoch_boundary_root: Hash256,
|
|
||||||
|
// FFG Vote
|
||||||
|
pub source_epoch: Epoch,
|
||||||
|
pub source_root: Hash256,
|
||||||
|
pub target_root: Hash256,
|
||||||
|
|
||||||
|
// Crosslink Vote
|
||||||
|
pub shard: u64,
|
||||||
|
pub previous_crosslink: Crosslink,
|
||||||
pub crosslink_data_root: Hash256,
|
pub crosslink_data_root: Hash256,
|
||||||
pub latest_crosslink: Crosslink,
|
|
||||||
pub justified_epoch: Epoch,
|
|
||||||
pub justified_block_root: Hash256,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for AttestationData {}
|
impl Eq for AttestationData {}
|
||||||
|
@ -6,7 +6,7 @@ use ssz_derive::{Decode, Encode, TreeHash};
|
|||||||
|
|
||||||
/// Used for pairing an attestation with a proof-of-custody.
|
/// Used for pairing an attestation with a proof-of-custody.
|
||||||
///
|
///
|
||||||
/// Spec v0.4.0
|
/// Spec v0.5.0
|
||||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode, TreeHash)]
|
#[derive(Debug, Clone, PartialEq, Default, Serialize, Encode, Decode, TreeHash)]
|
||||||
pub struct AttestationDataAndCustodyBit {
|
pub struct AttestationDataAndCustodyBit {
|
||||||
pub data: AttestationData,
|
pub data: AttestationData,
|
||||||
|
@ -9,7 +9,7 @@ use test_random_derive::TestRandom;
|
|||||||
///
|
///
|
||||||
/// To be included in an `AttesterSlashing`.
|
/// To be included in an `AttesterSlashing`.
|
||||||
///
|
///
|
||||||
/// Spec v0.4.0
|
/// Spec v0.5.0
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -33,17 +33,17 @@ pub struct SlashableAttestation {
|
|||||||
impl SlashableAttestation {
|
impl SlashableAttestation {
|
||||||
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
|
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
|
||||||
///
|
///
|
||||||
/// Spec v0.4.0
|
/// Spec v0.5.0
|
||||||
pub fn is_double_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
|
pub fn is_double_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
|
||||||
self.data.slot.epoch(spec.slots_per_epoch) == other.data.slot.epoch(spec.slots_per_epoch)
|
self.data.slot.epoch(spec.slots_per_epoch) == other.data.slot.epoch(spec.slots_per_epoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||||
///
|
///
|
||||||
/// Spec v0.4.0
|
/// Spec v0.5.0
|
||||||
pub fn is_surround_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
|
pub fn is_surround_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
|
||||||
let source_epoch_1 = self.data.justified_epoch;
|
let source_epoch_1 = self.data.source_epoch;
|
||||||
let source_epoch_2 = other.data.justified_epoch;
|
let source_epoch_2 = other.data.source_epoch;
|
||||||
let target_epoch_1 = self.data.slot.epoch(spec.slots_per_epoch);
|
let target_epoch_1 = self.data.slot.epoch(spec.slots_per_epoch);
|
||||||
let target_epoch_2 = other.data.slot.epoch(spec.slots_per_epoch);
|
let target_epoch_2 = other.data.slot.epoch(spec.slots_per_epoch);
|
||||||
|
|
||||||
@ -134,14 +134,14 @@ mod tests {
|
|||||||
|
|
||||||
fn create_slashable_attestation(
|
fn create_slashable_attestation(
|
||||||
slot_factor: u64,
|
slot_factor: u64,
|
||||||
justified_epoch: u64,
|
source_epoch: u64,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> SlashableAttestation {
|
) -> SlashableAttestation {
|
||||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
let mut slashable_vote = SlashableAttestation::random_for_test(&mut rng);
|
let mut slashable_vote = SlashableAttestation::random_for_test(&mut rng);
|
||||||
|
|
||||||
slashable_vote.data.slot = Slot::new(slot_factor * spec.slots_per_epoch);
|
slashable_vote.data.slot = Slot::new(slot_factor * spec.slots_per_epoch);
|
||||||
slashable_vote.data.justified_epoch = Epoch::new(justified_epoch);
|
slashable_vote.data.source_epoch = Epoch::new(source_epoch);
|
||||||
slashable_vote
|
slashable_vote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,12 @@ mod generate_deterministic_keypairs;
|
|||||||
mod keypairs_file;
|
mod keypairs_file;
|
||||||
mod test_random;
|
mod test_random;
|
||||||
mod testing_attestation_builder;
|
mod testing_attestation_builder;
|
||||||
|
mod testing_attestation_data_builder;
|
||||||
mod testing_attester_slashing_builder;
|
mod testing_attester_slashing_builder;
|
||||||
mod testing_beacon_block_builder;
|
mod testing_beacon_block_builder;
|
||||||
mod testing_beacon_state_builder;
|
mod testing_beacon_state_builder;
|
||||||
mod testing_deposit_builder;
|
mod testing_deposit_builder;
|
||||||
|
mod testing_pending_attestation_builder;
|
||||||
mod testing_proposer_slashing_builder;
|
mod testing_proposer_slashing_builder;
|
||||||
mod testing_transfer_builder;
|
mod testing_transfer_builder;
|
||||||
mod testing_voluntary_exit_builder;
|
mod testing_voluntary_exit_builder;
|
||||||
@ -17,10 +19,12 @@ pub use keypairs_file::KeypairsFile;
|
|||||||
pub use rand::{prng::XorShiftRng, SeedableRng};
|
pub use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
pub use test_random::TestRandom;
|
pub use test_random::TestRandom;
|
||||||
pub use testing_attestation_builder::TestingAttestationBuilder;
|
pub use testing_attestation_builder::TestingAttestationBuilder;
|
||||||
|
pub use testing_attestation_data_builder::TestingAttestationDataBuilder;
|
||||||
pub use testing_attester_slashing_builder::TestingAttesterSlashingBuilder;
|
pub use testing_attester_slashing_builder::TestingAttesterSlashingBuilder;
|
||||||
pub use testing_beacon_block_builder::TestingBeaconBlockBuilder;
|
pub use testing_beacon_block_builder::TestingBeaconBlockBuilder;
|
||||||
pub use testing_beacon_state_builder::{keypairs_path, TestingBeaconStateBuilder};
|
pub use testing_beacon_state_builder::{keypairs_path, TestingBeaconStateBuilder};
|
||||||
pub use testing_deposit_builder::TestingDepositBuilder;
|
pub use testing_deposit_builder::TestingDepositBuilder;
|
||||||
|
pub use testing_pending_attestation_builder::TestingPendingAttestationBuilder;
|
||||||
pub use testing_proposer_slashing_builder::TestingProposerSlashingBuilder;
|
pub use testing_proposer_slashing_builder::TestingProposerSlashingBuilder;
|
||||||
pub use testing_transfer_builder::TestingTransferBuilder;
|
pub use testing_transfer_builder::TestingTransferBuilder;
|
||||||
pub use testing_voluntary_exit_builder::TestingVoluntaryExitBuilder;
|
pub use testing_voluntary_exit_builder::TestingVoluntaryExitBuilder;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::test_utils::TestingAttestationDataBuilder;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use ssz::TreeHash;
|
use ssz::TreeHash;
|
||||||
|
|
||||||
@ -18,31 +19,7 @@ impl TestingAttestationBuilder {
|
|||||||
shard: u64,
|
shard: u64,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let current_epoch = state.current_epoch(spec);
|
let data_builder = TestingAttestationDataBuilder::new(state, shard, slot, spec);
|
||||||
let previous_epoch = state.previous_epoch(spec);
|
|
||||||
|
|
||||||
let is_previous_epoch =
|
|
||||||
state.slot.epoch(spec.slots_per_epoch) != slot.epoch(spec.slots_per_epoch);
|
|
||||||
|
|
||||||
let justified_epoch = if is_previous_epoch {
|
|
||||||
state.previous_justified_epoch
|
|
||||||
} else {
|
|
||||||
state.justified_epoch
|
|
||||||
};
|
|
||||||
|
|
||||||
let epoch_boundary_root = if is_previous_epoch {
|
|
||||||
*state
|
|
||||||
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec)
|
|
||||||
.unwrap()
|
|
||||||
} else {
|
|
||||||
*state
|
|
||||||
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch), spec)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
let justified_block_root = *state
|
|
||||||
.get_block_root(justified_epoch.start_slot(spec.slots_per_epoch), spec)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut aggregation_bitfield = Bitfield::new();
|
let mut aggregation_bitfield = Bitfield::new();
|
||||||
let mut custody_bitfield = Bitfield::new();
|
let mut custody_bitfield = Bitfield::new();
|
||||||
@ -54,16 +31,7 @@ impl TestingAttestationBuilder {
|
|||||||
|
|
||||||
let attestation = Attestation {
|
let attestation = Attestation {
|
||||||
aggregation_bitfield,
|
aggregation_bitfield,
|
||||||
data: AttestationData {
|
data: data_builder.build(),
|
||||||
slot,
|
|
||||||
shard,
|
|
||||||
beacon_block_root: *state.get_block_root(slot, spec).unwrap(),
|
|
||||||
epoch_boundary_root,
|
|
||||||
crosslink_data_root: Hash256::zero(),
|
|
||||||
latest_crosslink: state.latest_crosslinks[shard as usize].clone(),
|
|
||||||
justified_epoch,
|
|
||||||
justified_block_root,
|
|
||||||
},
|
|
||||||
custody_bitfield,
|
custody_bitfield,
|
||||||
aggregate_signature: AggregateSignature::new(),
|
aggregate_signature: AggregateSignature::new(),
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
/// Builds an `AttestationData` to be used for testing purposes.
|
||||||
|
///
|
||||||
|
/// This struct should **never be used for production purposes.**
|
||||||
|
pub struct TestingAttestationDataBuilder {
|
||||||
|
data: AttestationData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestingAttestationDataBuilder {
|
||||||
|
/// Configures a new `AttestationData` which attests to all of the same parameters as the
|
||||||
|
/// state.
|
||||||
|
pub fn new(state: &BeaconState, shard: u64, slot: Slot, spec: &ChainSpec) -> Self {
|
||||||
|
let current_epoch = state.current_epoch(spec);
|
||||||
|
let previous_epoch = state.previous_epoch(spec);
|
||||||
|
|
||||||
|
let is_previous_epoch =
|
||||||
|
state.slot.epoch(spec.slots_per_epoch) != slot.epoch(spec.slots_per_epoch);
|
||||||
|
|
||||||
|
let source_epoch = if is_previous_epoch {
|
||||||
|
state.previous_justified_epoch
|
||||||
|
} else {
|
||||||
|
state.justified_epoch
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_root = if is_previous_epoch {
|
||||||
|
*state
|
||||||
|
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec)
|
||||||
|
.unwrap()
|
||||||
|
} else {
|
||||||
|
*state
|
||||||
|
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch), spec)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let source_root = *state
|
||||||
|
.get_block_root(source_epoch.start_slot(spec.slots_per_epoch), spec)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let data = AttestationData {
|
||||||
|
// LMD GHOST vote
|
||||||
|
slot,
|
||||||
|
beacon_block_root: *state.get_block_root(slot, spec).unwrap(),
|
||||||
|
|
||||||
|
// FFG Vote
|
||||||
|
source_epoch,
|
||||||
|
source_root,
|
||||||
|
target_root,
|
||||||
|
|
||||||
|
// Crosslink vote
|
||||||
|
shard,
|
||||||
|
previous_crosslink: Crosslink {
|
||||||
|
epoch: slot.epoch(spec.slots_per_epoch),
|
||||||
|
crosslink_data_root: spec.zero_hash,
|
||||||
|
},
|
||||||
|
crosslink_data_root: spec.zero_hash,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self { data }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `AttestationData`, consuming the builder.
|
||||||
|
pub fn build(self) -> AttestationData {
|
||||||
|
self.data
|
||||||
|
}
|
||||||
|
}
|
@ -23,45 +23,39 @@ impl TestingAttesterSlashingBuilder {
|
|||||||
{
|
{
|
||||||
let double_voted_slot = Slot::new(0);
|
let double_voted_slot = Slot::new(0);
|
||||||
let shard = 0;
|
let shard = 0;
|
||||||
let justified_epoch = Epoch::new(0);
|
|
||||||
let epoch = Epoch::new(0);
|
let epoch = Epoch::new(0);
|
||||||
let hash_1 = Hash256::from_low_u64_le(1);
|
let hash_1 = Hash256::from_low_u64_le(1);
|
||||||
let hash_2 = Hash256::from_low_u64_le(2);
|
let hash_2 = Hash256::from_low_u64_le(2);
|
||||||
|
|
||||||
let mut slashable_attestation_1 = SlashableAttestation {
|
let data_1 = AttestationData {
|
||||||
validator_indices: validator_indices.to_vec(),
|
|
||||||
data: AttestationData {
|
|
||||||
slot: double_voted_slot,
|
slot: double_voted_slot,
|
||||||
shard,
|
|
||||||
beacon_block_root: hash_1,
|
beacon_block_root: hash_1,
|
||||||
epoch_boundary_root: hash_1,
|
source_epoch: epoch,
|
||||||
crosslink_data_root: hash_1,
|
source_root: hash_1,
|
||||||
latest_crosslink: Crosslink {
|
target_root: hash_1,
|
||||||
|
shard,
|
||||||
|
previous_crosslink: Crosslink {
|
||||||
epoch,
|
epoch,
|
||||||
crosslink_data_root: hash_1,
|
crosslink_data_root: hash_1,
|
||||||
},
|
},
|
||||||
justified_epoch,
|
crosslink_data_root: hash_1,
|
||||||
justified_block_root: hash_1,
|
};
|
||||||
},
|
|
||||||
|
let data_2 = AttestationData {
|
||||||
|
beacon_block_root: hash_2,
|
||||||
|
..data_1.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut slashable_attestation_1 = SlashableAttestation {
|
||||||
|
validator_indices: validator_indices.to_vec(),
|
||||||
|
data: data_1,
|
||||||
custody_bitfield: Bitfield::new(),
|
custody_bitfield: Bitfield::new(),
|
||||||
aggregate_signature: AggregateSignature::new(),
|
aggregate_signature: AggregateSignature::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut slashable_attestation_2 = SlashableAttestation {
|
let mut slashable_attestation_2 = SlashableAttestation {
|
||||||
validator_indices: validator_indices.to_vec(),
|
validator_indices: validator_indices.to_vec(),
|
||||||
data: AttestationData {
|
data: data_2,
|
||||||
slot: double_voted_slot,
|
|
||||||
shard,
|
|
||||||
beacon_block_root: hash_2,
|
|
||||||
epoch_boundary_root: hash_2,
|
|
||||||
crosslink_data_root: hash_2,
|
|
||||||
latest_crosslink: Crosslink {
|
|
||||||
epoch,
|
|
||||||
crosslink_data_root: hash_2,
|
|
||||||
},
|
|
||||||
justified_epoch,
|
|
||||||
justified_block_root: hash_2,
|
|
||||||
},
|
|
||||||
custody_bitfield: Bitfield::new(),
|
custody_bitfield: Bitfield::new(),
|
||||||
aggregate_signature: AggregateSignature::new(),
|
aggregate_signature: AggregateSignature::new(),
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::{generate_deterministic_keypairs, KeypairsFile};
|
use super::{generate_deterministic_keypairs, KeypairsFile};
|
||||||
use crate::beacon_state::BeaconStateBuilder;
|
use crate::beacon_state::BeaconStateBuilder;
|
||||||
|
use crate::test_utils::TestingPendingAttestationBuilder;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use bls::get_withdrawal_credentials;
|
use bls::get_withdrawal_credentials;
|
||||||
use dirs;
|
use dirs;
|
||||||
@ -227,76 +228,13 @@ impl TestingBeaconStateBuilder {
|
|||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
for (committee, shard) in committees {
|
for (committee, shard) in committees {
|
||||||
state
|
let mut builder = TestingPendingAttestationBuilder::new(state, shard, slot, spec);
|
||||||
.latest_attestations
|
// The entire committee should have signed the pending attestation.
|
||||||
.push(committee_to_pending_attestation(
|
let signers = vec![true; committee.len()];
|
||||||
state, &committee, shard, slot, spec,
|
builder.add_committee_participation(signers);
|
||||||
))
|
|
||||||
|
state.latest_attestations.push(builder.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps a committee to a `PendingAttestation`.
|
|
||||||
///
|
|
||||||
/// The committee will be signed by all validators in the committee.
|
|
||||||
fn committee_to_pending_attestation(
|
|
||||||
state: &BeaconState,
|
|
||||||
committee: &[usize],
|
|
||||||
shard: u64,
|
|
||||||
slot: Slot,
|
|
||||||
spec: &ChainSpec,
|
|
||||||
) -> PendingAttestation {
|
|
||||||
let current_epoch = state.current_epoch(spec);
|
|
||||||
let previous_epoch = state.previous_epoch(spec);
|
|
||||||
|
|
||||||
let mut aggregation_bitfield = Bitfield::new();
|
|
||||||
let mut custody_bitfield = Bitfield::new();
|
|
||||||
|
|
||||||
for (i, _) in committee.iter().enumerate() {
|
|
||||||
aggregation_bitfield.set(i, true);
|
|
||||||
custody_bitfield.set(i, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
let is_previous_epoch =
|
|
||||||
state.slot.epoch(spec.slots_per_epoch) != slot.epoch(spec.slots_per_epoch);
|
|
||||||
|
|
||||||
let justified_epoch = if is_previous_epoch {
|
|
||||||
state.previous_justified_epoch
|
|
||||||
} else {
|
|
||||||
state.justified_epoch
|
|
||||||
};
|
|
||||||
|
|
||||||
let epoch_boundary_root = if is_previous_epoch {
|
|
||||||
*state
|
|
||||||
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec)
|
|
||||||
.unwrap()
|
|
||||||
} else {
|
|
||||||
*state
|
|
||||||
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch), spec)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
let justified_block_root = *state
|
|
||||||
.get_block_root(justified_epoch.start_slot(spec.slots_per_epoch), spec)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
PendingAttestation {
|
|
||||||
aggregation_bitfield,
|
|
||||||
data: AttestationData {
|
|
||||||
slot,
|
|
||||||
shard,
|
|
||||||
beacon_block_root: *state.get_block_root(slot, spec).unwrap(),
|
|
||||||
epoch_boundary_root,
|
|
||||||
crosslink_data_root: Hash256::zero(),
|
|
||||||
latest_crosslink: Crosslink {
|
|
||||||
epoch: slot.epoch(spec.slots_per_epoch),
|
|
||||||
crosslink_data_root: Hash256::zero(),
|
|
||||||
},
|
|
||||||
justified_epoch,
|
|
||||||
justified_block_root,
|
|
||||||
},
|
|
||||||
custody_bitfield,
|
|
||||||
inclusion_slot: slot + spec.min_attestation_inclusion_delay,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
use crate::test_utils::TestingAttestationDataBuilder;
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
/// Builds an `AttesterSlashing` to be used for testing purposes.
|
||||||
|
///
|
||||||
|
/// This struct should **never be used for production purposes.**
|
||||||
|
pub struct TestingPendingAttestationBuilder {
|
||||||
|
pending_attestation: PendingAttestation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestingPendingAttestationBuilder {
|
||||||
|
/// Create a new valid* `PendingAttestation` for the given parameters.
|
||||||
|
///
|
||||||
|
/// The `inclusion_slot` will be set to be the earliest possible slot the `Attestation` could
|
||||||
|
/// have been included (`slot + MIN_ATTESTATION_INCLUSION_DELAY`).
|
||||||
|
///
|
||||||
|
/// * The aggregation and custody bitfields will all be empty, they need to be set with
|
||||||
|
/// `Self::add_committee_participation`.
|
||||||
|
pub fn new(state: &BeaconState, shard: u64, slot: Slot, spec: &ChainSpec) -> Self {
|
||||||
|
let data_builder = TestingAttestationDataBuilder::new(state, shard, slot, spec);
|
||||||
|
|
||||||
|
let pending_attestation = PendingAttestation {
|
||||||
|
aggregation_bitfield: Bitfield::new(),
|
||||||
|
data: data_builder.build(),
|
||||||
|
custody_bitfield: Bitfield::new(),
|
||||||
|
inclusion_slot: slot + spec.min_attestation_inclusion_delay,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pending_attestation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the committee participation in the `PendingAttestation`.
|
||||||
|
///
|
||||||
|
/// The `PendingAttestation` will appear to be signed by each committee member who's value in
|
||||||
|
/// `signers` is true.
|
||||||
|
pub fn add_committee_participation(&mut self, signers: Vec<bool>) {
|
||||||
|
let mut aggregation_bitfield = Bitfield::new();
|
||||||
|
let mut custody_bitfield = Bitfield::new();
|
||||||
|
|
||||||
|
for (i, signed) in signers.iter().enumerate() {
|
||||||
|
aggregation_bitfield.set(i, *signed);
|
||||||
|
custody_bitfield.set(i, false); // Fixed to `false` for phase 0.
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pending_attestation.aggregation_bitfield = aggregation_bitfield;
|
||||||
|
self.pending_attestation.custody_bitfield = custody_bitfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `PendingAttestation`, consuming the builder.
|
||||||
|
pub fn build(self) -> PendingAttestation {
|
||||||
|
self.pending_attestation
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user