mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Update to spec v0.8.3 (#3355)
* Ignore latest messages in fork choice prior to latest justified * Make sure Compact Committee Roots isn't changed by process_final_updates * WIP add attestation bitfields length to match committee length * Begin work on updating spec tests to 0.8.2 * WIP set up for new spec test structure * Fix slashings * Get mainnet tests mostly passing for attestations and attester slashings * Fix process attestation test * Undo change * Complete spec tests for all operations Still need sanity block tests * Fix BLS sigs * Reduce amount of reused code in core/blocks/spectests/ * Fix tests * Update block sanity tests to 0.8.2 * Update epoch spec tests to 0.8.2 * Clean up all tests and fix shuffling/epoch tests * WIP update bls tests to 0.8.2 * WIP update bls tests to 0.8.3 * Finish BLS spectest update to 0.8.3 * Fix shuffling spec tests * Fix more tests * Update proto ssz spec tests to 0.8.3 * Attempt to fix PrevEpochFFGDataMismatches test * Goimports * Fix documentation * fix test * Use custom general spec tests * Reduce code footprint * Remove unneeded minimal skip * Fix for comments * Fix for comments * Fix test * Small fixes * Cleanup block spec tests a bit * Undo change * fix validator * Fix validator tests * Run gazelle * Fix error output for epoch spec tests
This commit is contained in:
committed by
Preston Van Loon
parent
d94522510f
commit
5e939378d0
@@ -92,8 +92,12 @@ func (s *Store) GenesisStore(
|
||||
// Spec pseudocode definition:
|
||||
// def get_ancestor(store: Store, root: Hash, slot: Slot) -> Hash:
|
||||
// block = store.blocks[root]
|
||||
// assert block.slot >= slot
|
||||
// return root if block.slot == slot else get_ancestor(store, block.parent_root, slot)
|
||||
// if block.slot > slot:
|
||||
// return get_ancestor(store, block.parent_root, slot)
|
||||
// elif block.slot == slot:
|
||||
// return root
|
||||
// else:
|
||||
// return Bytes32() # root is older than queried slot: no results.
|
||||
func (s *Store) ancestor(ctx context.Context, root []byte, slot uint64) ([]byte, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "forkchoice.ancestor")
|
||||
defer span.End()
|
||||
|
||||
@@ -525,9 +525,15 @@ func ProcessAttestationsNoVerify(
|
||||
// Process ``Attestation`` operation.
|
||||
// """
|
||||
// data = attestation.data
|
||||
// assert data.crosslink.shard < SHARD_COUNT
|
||||
// assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state))
|
||||
//
|
||||
// attestation_slot = get_attestation_data_slot(state, data)
|
||||
// assert attestation_slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= attestation_slot + SLOTS_PER_EPOCH
|
||||
//
|
||||
// committee = get_crosslink_committee(state, data.target.epoch, data.crosslink.shard)
|
||||
// assert len(attestation.aggregation_bits) == len(attestation.custody_bits) == len(committee)
|
||||
//
|
||||
// pending_attestation = PendingAttestation(
|
||||
// data=data,
|
||||
// aggregation_bitfield=attestation.aggregation_bitfield,
|
||||
@@ -535,23 +541,23 @@ func ProcessAttestationsNoVerify(
|
||||
// proposer_index=get_beacon_proposer_index(state),
|
||||
// )
|
||||
//
|
||||
// assert data.target_epoch in (get_previous_epoch(state), get_current_epoch(state))
|
||||
// if data.target_epoch == get_current_epoch(state):
|
||||
// ffg_data = (state.current_justified_epoch, state.current_justified_root, get_current_epoch(state))
|
||||
// parent_crosslink = state.current_crosslinks[data.crosslink.shard]
|
||||
// state.current_epoch_attestations.append(pending_attestation)
|
||||
// assert data.source == state.current_justified_checkpoint
|
||||
// parent_crosslink = state.current_crosslinks[data.crosslink.shard]
|
||||
// state.current_epoch_attestations.append(pending_attestation)
|
||||
// else:
|
||||
// ffg_data = (state.previous_justified_epoch, state.previous_justified_root, get_previous_epoch(state))
|
||||
// parent_crosslink = state.previous_crosslinks[data.crosslink.shard]
|
||||
// state.previous_epoch_attestations.append(pending_attestation)
|
||||
// assert data.source == state.previous_justified_checkpoint
|
||||
// parent_crosslink = state.previous_crosslinks[data.crosslink.shard]
|
||||
// state.previous_epoch_attestations.append(pending_attestation)
|
||||
//
|
||||
// # Check FFG data, crosslink data, and signature
|
||||
// assert ffg_data == (data.source_epoch, data.source_root, data.target_epoch)
|
||||
// assert data.crosslink.start_epoch == parent_crosslink.end_epoch
|
||||
// assert data.crosslink.end_epoch == min(data.target_epoch, parent_crosslink.end_epoch + MAX_EPOCHS_PER_CROSSLINK)
|
||||
// # Check crosslink against expected parent crosslink
|
||||
// assert data.crosslink.parent_root == hash_tree_root(parent_crosslink)
|
||||
// assert data.crosslink.start_epoch == parent_crosslink.end_epoch
|
||||
// assert data.crosslink.end_epoch == min(data.target.epoch, parent_crosslink.end_epoch + MAX_EPOCHS_PER_CROSSLINK)
|
||||
// assert data.crosslink.data_root == Bytes32() # [to be removed in phase 1]
|
||||
// validate_indexed_attestation(state, convert_to_indexed(state, attestation))
|
||||
//
|
||||
// # Check signature
|
||||
// assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
|
||||
func ProcessAttestation(beaconState *pb.BeaconState, att *ethpb.Attestation) (*pb.BeaconState, error) {
|
||||
beaconState, err := ProcessAttestationNoVerify(beaconState, att)
|
||||
if err != nil {
|
||||
@@ -564,6 +570,24 @@ func ProcessAttestation(beaconState *pb.BeaconState, att *ethpb.Attestation) (*p
|
||||
// method is used to validate attestations whose signatures have already been verified.
|
||||
func ProcessAttestationNoVerify(beaconState *pb.BeaconState, att *ethpb.Attestation) (*pb.BeaconState, error) {
|
||||
data := att.Data
|
||||
|
||||
if data.Crosslink.Shard > params.BeaconConfig().ShardCount {
|
||||
return nil, fmt.Errorf(
|
||||
"expected crosslink shard %d to be less than SHARD_COUNT %d",
|
||||
data.Crosslink.Shard,
|
||||
params.BeaconConfig().ShardCount,
|
||||
)
|
||||
}
|
||||
|
||||
if data.Target.Epoch != helpers.PrevEpoch(beaconState) && data.Target.Epoch != helpers.CurrentEpoch(beaconState) {
|
||||
return nil, fmt.Errorf(
|
||||
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
|
||||
data.Target.Epoch,
|
||||
helpers.PrevEpoch(beaconState),
|
||||
helpers.CurrentEpoch(beaconState),
|
||||
)
|
||||
}
|
||||
|
||||
attestationSlot, err := helpers.AttestationDataSlot(beaconState, data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get attestation slot")
|
||||
@@ -586,6 +610,11 @@ func ProcessAttestationNoVerify(beaconState *pb.BeaconState, att *ethpb.Attestat
|
||||
params.BeaconConfig().SlotsPerEpoch,
|
||||
)
|
||||
}
|
||||
|
||||
if err := helpers.VerifyAttestationBitfieldLengths(beaconState, att); err != nil {
|
||||
return nil, errors.Wrap(err, "could not verify attestation bitfields")
|
||||
}
|
||||
|
||||
proposerIndex, err := helpers.BeaconProposerIndex(beaconState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -597,15 +626,6 @@ func ProcessAttestationNoVerify(beaconState *pb.BeaconState, att *ethpb.Attestat
|
||||
ProposerIndex: proposerIndex,
|
||||
}
|
||||
|
||||
if !(data.Target.Epoch == helpers.PrevEpoch(beaconState) || data.Target.Epoch == helpers.CurrentEpoch(beaconState)) {
|
||||
return nil, fmt.Errorf(
|
||||
"expected target epoch %d == %d or %d",
|
||||
data.Target.Epoch,
|
||||
helpers.PrevEpoch(beaconState),
|
||||
helpers.CurrentEpoch(beaconState),
|
||||
)
|
||||
}
|
||||
|
||||
var ffgSourceEpoch uint64
|
||||
var ffgSourceRoot []byte
|
||||
var ffgTargetEpoch uint64
|
||||
@@ -664,6 +684,7 @@ func ProcessAttestationNoVerify(beaconState *pb.BeaconState, att *ethpb.Attestat
|
||||
data.Crosslink.ParentRoot,
|
||||
)
|
||||
}
|
||||
|
||||
// To be removed in Phase 1
|
||||
if !bytes.Equal(data.Crosslink.DataRoot, params.BeaconConfig().ZeroHash[:]) {
|
||||
return nil, fmt.Errorf("expected data root %#x == ZERO_HASH", data.Crosslink.DataRoot)
|
||||
|
||||
@@ -906,20 +906,20 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
|
||||
helpers.ClearActiveCountCache()
|
||||
helpers.ClearStartShardCache()
|
||||
|
||||
attestations := []*ethpb.Attestation{
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 0,
|
||||
},
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 0,
|
||||
StartEpoch: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
block := ðpb.BeaconBlock{
|
||||
Body: ðpb.BeaconBlockBody{
|
||||
Attestations: attestations,
|
||||
Attestations: []*ethpb.Attestation{att},
|
||||
},
|
||||
}
|
||||
deposits, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
@@ -929,10 +929,17 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
|
||||
}
|
||||
helpers.ClearAllCaches()
|
||||
beaconState.Slot += params.BeaconConfig().SlotsPerEpoch*4 + params.BeaconConfig().MinAttestationInclusionDelay
|
||||
beaconState.PreviousCrosslinks = []*ethpb.Crosslink{
|
||||
{
|
||||
Shard: 0,
|
||||
},
|
||||
}
|
||||
beaconState.PreviousJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
beaconState.PreviousEpochAttestations = []*pb.PendingAttestation{}
|
||||
|
||||
want := fmt.Sprintf(
|
||||
"expected target epoch %d == %d or %d",
|
||||
attestations[0].Data.Target.Epoch,
|
||||
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
|
||||
att.Data.Target.Epoch,
|
||||
helpers.PrevEpoch(beaconState),
|
||||
helpers.CurrentEpoch(beaconState),
|
||||
)
|
||||
@@ -944,15 +951,20 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
|
||||
func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
aggBits := bitfield.NewBitlist(1)
|
||||
custodyBits := bitfield.NewBitlist(1)
|
||||
attestations := []*ethpb.Attestation{
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Source: ðpb.Checkpoint{Epoch: 1},
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 0,
|
||||
Shard: 0,
|
||||
StartEpoch: 0,
|
||||
},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
}
|
||||
block := ðpb.BeaconBlock{
|
||||
@@ -999,15 +1011,26 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
|
||||
func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
deposits, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
aggBits := bitfield.NewBitlist(1)
|
||||
aggBits.SetBitAt(0, true)
|
||||
custodyBits := bitfield.NewBitlist(1)
|
||||
attestations := []*ethpb.Attestation{
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 1},
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 0,
|
||||
},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
}
|
||||
block := ðpb.BeaconBlock{
|
||||
@@ -1015,12 +1038,8 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
|
||||
Attestations: attestations,
|
||||
},
|
||||
}
|
||||
deposits, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
beaconState.Slot += params.BeaconConfig().SlotsPerEpoch + params.BeaconConfig().MinAttestationInclusionDelay
|
||||
beaconState.PreviousCrosslinks = []*ethpb.Crosslink{
|
||||
{
|
||||
@@ -1038,13 +1057,15 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
|
||||
if _, err := blocks.ProcessAttestations(beaconState, block.Body); !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("Expected %s, received %v", want, err)
|
||||
}
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
|
||||
block.Body.Attestations[0].Data.Target.Epoch = helpers.CurrentEpoch(beaconState)
|
||||
block.Body.Attestations[0].Data.Source.Root = []byte{}
|
||||
|
||||
want = fmt.Sprintf(
|
||||
"expected source root %#x, received %#x",
|
||||
beaconState.PreviousJustifiedCheckpoint.Root,
|
||||
beaconState.CurrentJustifiedCheckpoint.Root,
|
||||
attestations[0].Data.Source.Root,
|
||||
)
|
||||
if _, err := blocks.ProcessAttestations(beaconState, block.Body); !strings.Contains(err.Error(), want) {
|
||||
@@ -1055,6 +1076,9 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
|
||||
func TestProcessAttestations_CrosslinkMismatches(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
aggBits := bitfield.NewBitlist(1)
|
||||
aggBits.SetBitAt(0, true)
|
||||
custodyBits := bitfield.NewBitlist(1)
|
||||
attestations := []*ethpb.Attestation{
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
@@ -1064,6 +1088,8 @@ func TestProcessAttestations_CrosslinkMismatches(t *testing.T) {
|
||||
Shard: 0,
|
||||
},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
}
|
||||
block := ðpb.BeaconBlock{
|
||||
@@ -1108,14 +1134,16 @@ func TestProcessAttestations_CrosslinkMismatches(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessAttestations_OK(t *testing.T) {
|
||||
func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
deposits, privKeys := testutil.SetupInitialDeposits(t, 100)
|
||||
deposits, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
aggBits := bitfield.NewBitlist(2)
|
||||
custodyBits := bitfield.NewBitlist(2)
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
|
||||
@@ -1125,30 +1153,10 @@ func TestProcessAttestations_OK(t *testing.T) {
|
||||
StartEpoch: 0,
|
||||
},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
}
|
||||
|
||||
attestingIndices, err := helpers.AttestingIndices(beaconState, att.Data, att.AggregationBits)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
domain := helpers.Domain(beaconState, 0, params.BeaconConfig().DomainAttestation)
|
||||
sigs := make([]*bls.Signature, len(attestingIndices))
|
||||
for i, indice := range attestingIndices {
|
||||
dataAndCustodyBit := &pb.AttestationDataAndCustodyBit{
|
||||
Data: att.Data,
|
||||
CustodyBit: false,
|
||||
}
|
||||
hashTreeRoot, err := ssz.HashTreeRoot(dataAndCustodyBit)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
sig := privKeys[indice].Sign(hashTreeRoot[:], domain)
|
||||
sigs[i] = sig
|
||||
}
|
||||
att.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
|
||||
|
||||
block := ðpb.BeaconBlock{
|
||||
Body: ðpb.BeaconBlockBody{
|
||||
Attestations: []*ethpb.Attestation{att},
|
||||
@@ -1172,6 +1180,80 @@ func TestProcessAttestations_OK(t *testing.T) {
|
||||
block.Body.Attestations[0].Data.Crosslink.ParentRoot = encoded[:]
|
||||
block.Body.Attestations[0].Data.Crosslink.DataRoot = params.BeaconConfig().ZeroHash[:]
|
||||
|
||||
expected := "failed to verify aggregation bitfield: wanted participants bitfield length 1, got: 2"
|
||||
_, err = blocks.ProcessAttestations(beaconState, block.Body)
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected error checking aggregation and custody bit length, received: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessAttestations_OK(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
deposits, privKeys := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
aggBits := bitfield.NewBitlist(1)
|
||||
aggBits.SetBitAt(0, true)
|
||||
custodyBits := bitfield.NewBitlist(1)
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
|
||||
Target: ðpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 0,
|
||||
StartEpoch: 0,
|
||||
},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
}
|
||||
|
||||
beaconState.CurrentCrosslinks = []*ethpb.Crosslink{
|
||||
{
|
||||
Shard: 0,
|
||||
StartEpoch: 0,
|
||||
},
|
||||
}
|
||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||
encoded, err := ssz.HashTreeRoot(beaconState.CurrentCrosslinks[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
att.Data.Crosslink.ParentRoot = encoded[:]
|
||||
att.Data.Crosslink.DataRoot = params.BeaconConfig().ZeroHash[:]
|
||||
|
||||
attestingIndices, err := helpers.AttestingIndices(beaconState, att.Data, att.AggregationBits)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dataAndCustodyBit := &pb.AttestationDataAndCustodyBit{
|
||||
Data: att.Data,
|
||||
CustodyBit: false,
|
||||
}
|
||||
hashTreeRoot, err := ssz.HashTreeRoot(dataAndCustodyBit)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
domain := helpers.Domain(beaconState, 0, params.BeaconConfig().DomainAttestation)
|
||||
sigs := make([]*bls.Signature, len(attestingIndices))
|
||||
for i, indice := range attestingIndices {
|
||||
sig := privKeys[indice].Sign(hashTreeRoot[:], domain)
|
||||
sigs[i] = sig
|
||||
}
|
||||
att.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
|
||||
|
||||
block := ðpb.BeaconBlock{
|
||||
Body: ðpb.BeaconBlockBody{
|
||||
Attestations: []*ethpb.Attestation{att},
|
||||
},
|
||||
}
|
||||
|
||||
beaconState.Slot += params.BeaconConfig().MinAttestationInclusionDelay
|
||||
|
||||
if _, err := blocks.ProcessAttestations(beaconState, block.Body); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1186,6 +1268,9 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
aggBits := bitfield.NewBitlist(1)
|
||||
aggBits.SetBitAt(1, true)
|
||||
custodyBits := bitfield.NewBitlist(1)
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
|
||||
@@ -1195,8 +1280,8 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
|
||||
StartEpoch: 0,
|
||||
},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
}
|
||||
|
||||
zeroSig := [96]byte{}
|
||||
|
||||
@@ -2,19 +2,9 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"attestation_test.yaml.go",
|
||||
"block_operations.yaml.go",
|
||||
"blocks_mainnet.yaml.go",
|
||||
"blocks_minimal.yaml.go",
|
||||
],
|
||||
srcs = ["block_processing_test.yaml.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks/spectest",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
test_suite(
|
||||
@@ -34,7 +24,7 @@ go_test(
|
||||
exclude = ["*_minimal_test.go"],
|
||||
),
|
||||
data = glob(["*.yaml"]) + [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_mainnet//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
shard_count = 4,
|
||||
@@ -44,10 +34,12 @@ go_test(
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//beacon-chain/core/state/stateutils:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
@@ -61,7 +53,7 @@ go_test(
|
||||
exclude = ["*_mainnet_test.go"],
|
||||
),
|
||||
data = glob(["*.yaml"]) + [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_minimal//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["spectest"],
|
||||
@@ -70,10 +62,12 @@ go_test(
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//beacon-chain/core/state/stateutils:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func TestAttestationMainnet(t *testing.T) {
|
||||
runAttestationTest(t, "attestation_mainnet.yaml")
|
||||
runAttestationTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func TestAttestationMinimal(t *testing.T) {
|
||||
runAttestationTest(t, "attestation_minimal.yaml")
|
||||
runAttestationTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,78 +1,36 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
func runAttestationTest(t *testing.T, filename string) {
|
||||
filepath, err := bazel.Runfile("tests/operations/attestation/" + filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
test := &AttestationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
func runAttestationTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
body := ðpb.BeaconBlockBody{
|
||||
Attestations: []*ethpb.Attestation{
|
||||
tt.Attestation,
|
||||
},
|
||||
}
|
||||
|
||||
post, err := blocks.ProcessAttestations(tt.Pre, body)
|
||||
if !reflect.ValueOf(tt.Post).IsValid() {
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if err == nil {
|
||||
t.Fatal("did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
t.Logf("Expected failure; failure reason = %v", err)
|
||||
return
|
||||
} else if err != nil {
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/attestation/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
attestationFile, err := testutil.BazelFileBytes(folderPath, "attestation.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(post, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(post, tt.Post)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
att := ðpb.Attestation{}
|
||||
if err := ssz.Unmarshal(attestationFile, att); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
body := ðpb.BeaconBlockBody{Attestations: []*ethpb.Attestation{att}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessAttestations)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: attestation_minimal.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
type AttestationTest struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Pre *pb.BeaconState `json:"pre"`
|
||||
Attestation *ethpb.Attestation `json:"attestation"`
|
||||
Post *pb.BeaconState `json:"post"`
|
||||
BlsSetting uint64 `json:"bls_setting,omitempty"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestAttesterSlashingMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(attesterSlashingPrefix + "attester_slashing_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runAttesterSlashingTest(t, filepath)
|
||||
runAttesterSlashingTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestAttesterSlashingMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(attesterSlashingPrefix + "attester_slashing_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runAttesterSlashingTest(t, filepath)
|
||||
runAttesterSlashingTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,63 +1,36 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const attesterSlashingPrefix = "tests/operations/attester_slashing/"
|
||||
|
||||
func runAttesterSlashingTest(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
test := &BlockOperationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
func runAttesterSlashingTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
body := ðpb.BeaconBlockBody{AttesterSlashings: []*ethpb.AttesterSlashing{tt.AttesterSlashing}}
|
||||
|
||||
postState, err := blocks.ProcessAttesterSlashings(tt.Pre, body)
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/attester_slashing/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
attSlashingFile, err := testutil.BazelFileBytes(folderPath, "attester_slashing.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(postState, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(postState, tt.Post)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
attSlashing := ðpb.AttesterSlashing{}
|
||||
if err := ssz.Unmarshal(attSlashingFile, attSlashing); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
body := ðpb.BeaconBlockBody{AttesterSlashings: []*ethpb.AttesterSlashing{attSlashing}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessAttesterSlashings)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestBlockHeaderMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(blkHeaderPrefix + "block_header_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runBlockHeaderTest(t, filepath)
|
||||
runBlockHeaderTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestBlockHeaderMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(blkHeaderPrefix + "block_header_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runBlockHeaderTest(t, filepath)
|
||||
runBlockHeaderTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -2,63 +2,87 @@ package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const blkHeaderPrefix = "tests/operations/block_header/"
|
||||
|
||||
// Block header test is actually a full block processing test. Not sure why it
|
||||
// was named "block_header". The note in the test format readme says "Note that
|
||||
// block_header is not strictly an operation (and is a full Block), but
|
||||
// processed in the same manner, and hence included here."
|
||||
func runBlockHeaderTest(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
test := &BlockOperationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
func runBlockHeaderTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/block_header/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
post, err := blocks.ProcessBlockHeader(tt.Pre, tt.Block)
|
||||
|
||||
if tt.Post == nil {
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if err == nil {
|
||||
t.Fatal("did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "block.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
block := ðpb.BeaconBlock{}
|
||||
if err := ssz.Unmarshal(blockFile, block); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if !proto.Equal(post, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(post, tt.Post)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
preBeaconState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(preBeaconStateFile, preBeaconState); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
// If the post.ssz is not present, it means the test should fail on our end.
|
||||
postSSZFilepath, err := bazel.Runfile(path.Join(testsFolderPath, folder.Name(), "post.ssz"))
|
||||
postSSZExists := true
|
||||
if err != nil && strings.Contains(err.Error(), "could not locate file") {
|
||||
postSSZExists = false
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
beaconState, err := blocks.ProcessBlockHeader(preBeaconState, block)
|
||||
if postSSZExists {
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
postBeaconState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(postBeaconStateFile, postBeaconState); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if !proto.Equal(beaconState, postBeaconState) {
|
||||
diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
}
|
||||
} else {
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
t.Logf("Expected failure; failure reason = %v", err)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: voluntary_exit_minimal.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
type BlockOperationTest struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
BlsSetting uint64 `json:"bls_setting,omitempty"`
|
||||
Description string `json:"description"`
|
||||
Pre *pb.BeaconState `json:"pre"`
|
||||
VoluntaryExit *ethpb.VoluntaryExit `json:"voluntary_exit"`
|
||||
ProposerSlashing *ethpb.ProposerSlashing `json:"proposer_slashing"`
|
||||
AttesterSlashing *ethpb.AttesterSlashing `json:"attester_slashing"`
|
||||
Deposit *ethpb.Deposit `json:"deposit"`
|
||||
Transfer *ethpb.Transfer `json:"transfer"`
|
||||
Block *ethpb.BeaconBlock `json:"block"`
|
||||
Post *pb.BeaconState `json:"post"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func TestBlockProcessingMainnetYaml(t *testing.T) {
|
||||
runBlockProcessingTest(t, "sanity_blocks_mainnet.yaml")
|
||||
runBlockProcessingTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func TestBlockProcessingMinimalYaml(t *testing.T) {
|
||||
t.Skip("This test suite requires --define ssz=minimal to be provided and there isn't a great way to do that without breaking //... See https://github.com/prysmaticlabs/prysm/issues/3066")
|
||||
|
||||
runBlockProcessingTest(t, "sanity_blocks_minimal.yaml")
|
||||
runBlockProcessingTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -2,67 +2,103 @@ package spectest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
func runBlockProcessingTest(t *testing.T, filename string) {
|
||||
filepath, err := bazel.Runfile("tests/sanity/blocks/" + filename)
|
||||
if err != nil {
|
||||
func runBlockProcessingTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &BlocksMainnet{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
t.Fatalf("Could not set config: %v", err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "sanity/blocks/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
blocks.ClearEth1DataVoteCache()
|
||||
|
||||
s := tt.Pre
|
||||
for _, b := range tt.Blocks {
|
||||
tt.Pre, err = state.ExecuteStateTransition(ctx, tt.Pre, b)
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Transition did not fail despite being invalid")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("Transition failed with block at slot %d: %v", b.Slot, err)
|
||||
}
|
||||
preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if tt.Post != nil {
|
||||
if !proto.Equal(s, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(s, tt.Post)
|
||||
beaconState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(preBeaconStateFile, beaconState); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
file, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "meta.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
metaYaml := &SanityConfig{}
|
||||
if err := testutil.UnmarshalYaml(file, metaYaml); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
var transitionError error
|
||||
for i := 0; i < metaYaml.BlocksCount; i++ {
|
||||
filename := fmt.Sprintf("blocks_%d.ssz", i)
|
||||
blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
block := ðpb.BeaconBlock{}
|
||||
if err := ssz.Unmarshal(blockFile, block); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
beaconState, transitionError = state.ExecuteStateTransition(context.Background(), beaconState, block)
|
||||
}
|
||||
|
||||
// If the post.ssz is not present, it means the test should fail on our end.
|
||||
postSSZFilepath, readError := bazel.Runfile(path.Join(testsFolderPath, folder.Name(), "post.ssz"))
|
||||
postSSZExists := true
|
||||
if readError != nil && strings.Contains(readError.Error(), "could not locate file") {
|
||||
postSSZExists = false
|
||||
} else if readError != nil {
|
||||
t.Fatal(readError)
|
||||
}
|
||||
|
||||
if postSSZExists {
|
||||
if transitionError != nil {
|
||||
t.Fatalf("Unexpected error: %v", transitionError)
|
||||
}
|
||||
|
||||
postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
postBeaconState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(postBeaconStateFile, postBeaconState); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if !proto.Equal(beaconState, postBeaconState) {
|
||||
diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
}
|
||||
} else {
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if transitionError == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
t.Logf("Expected failure; failure reason = %v", transitionError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package spectest
|
||||
|
||||
// SanityConfig --
|
||||
type SanityConfig struct {
|
||||
BlocksCount int `json:"blocks_count"`
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: sanity_blocks_mainnet.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
type BlocksMainnet struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Pre *pb.BeaconState `json:"pre"`
|
||||
Blocks []*ethpb.BeaconBlock `json:"blocks"`
|
||||
Post *pb.BeaconState `json:"post"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: sanity_blocks_minimal.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
type BlocksMinimal struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Pre *pb.BeaconState `json:"pre"`
|
||||
Blocks []*ethpb.BeaconBlock `json:"blocks"`
|
||||
Post *pb.BeaconState `json:"post"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestDepositMainnetYaml(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(depositPrefix + "deposit_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runDepositTest(t, filepath)
|
||||
runDepositTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestDepositMinimalYaml(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(depositPrefix + "deposit_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runDepositTest(t, filepath)
|
||||
runDepositTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,58 +1,36 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state/stateutils"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
const depositPrefix = "tests/operations/deposit/"
|
||||
|
||||
func runDepositTest(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
test := &BlockOperationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
func runDepositTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
helpers.ClearAllCaches()
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
valMap := stateutils.ValidatorIndexMap(tt.Pre)
|
||||
post, err := blocks.ProcessDeposit(tt.Pre, tt.Deposit, valMap)
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/deposit/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
depositFile, err := testutil.BazelFileBytes(folderPath, "deposit.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(post, tt.Post) {
|
||||
t.Error("Post state does not match expected")
|
||||
deposit := ðpb.Deposit{}
|
||||
if err := ssz.Unmarshal(depositFile, deposit); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
body := ðpb.BeaconBlockBody{Deposits: []*ethpb.Deposit{deposit}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessDeposits)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestProposerSlashingMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(proposerSlashingPrefix + "proposer_slashing_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runProposerSlashingTest(t, filepath)
|
||||
runProposerSlashingTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestProposerSlashingMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(proposerSlashingPrefix + "proposer_slashing_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runProposerSlashingTest(t, filepath)
|
||||
runProposerSlashingTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,63 +1,36 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const proposerSlashingPrefix = "tests/operations/proposer_slashing/"
|
||||
|
||||
func runProposerSlashingTest(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
test := &BlockOperationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
func runProposerSlashingTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
body := ðpb.BeaconBlockBody{ProposerSlashings: []*ethpb.ProposerSlashing{tt.ProposerSlashing}}
|
||||
|
||||
postState, err := blocks.ProcessProposerSlashings(tt.Pre, body)
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/proposer_slashing/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
proposerSlashingFile, err := testutil.BazelFileBytes(folderPath, "proposer_slashing.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(postState, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(postState, tt.Post)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
proposerSlashing := ðpb.ProposerSlashing{}
|
||||
if err := ssz.Unmarshal(proposerSlashingFile, proposerSlashing); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
body := ðpb.BeaconBlockBody{ProposerSlashings: []*ethpb.ProposerSlashing{proposerSlashing}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessProposerSlashings)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestTransferMainnet(t *testing.T) {
|
||||
t.Skip("Transfer tests are disabled. See https://github.com/ethereum/eth2.0-specs/pull/1238#issuecomment-507054595")
|
||||
filepath, err := bazel.Runfile(transferPrefix + "transfer_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runTransferTest(t, filepath)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestTransferMinimal(t *testing.T) {
|
||||
t.Skip("Transfer tests are disabled. See https://github.com/ethereum/eth2.0-specs/pull/1238#issuecomment-507054595")
|
||||
filepath, err := bazel.Runfile(transferPrefix + "transfer_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runTransferTest(t, filepath)
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const transferPrefix = "tests/operations/transfer/"
|
||||
|
||||
func runTransferTest(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
test := &BlockOperationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
body := ðpb.BeaconBlockBody{Transfers: []*ethpb.Transfer{tt.Transfer}}
|
||||
|
||||
postState, err := blocks.ProcessTransfers(tt.Pre, body)
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(postState, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(postState, tt.Post)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestVoluntaryExitMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(exitPrefix + "voluntary_exit_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runVoluntaryExitTest(t, filepath)
|
||||
runVoluntaryExitTest(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestVoluntaryExitMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(exitPrefix + "voluntary_exit_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runVoluntaryExitTest(t, filepath)
|
||||
runVoluntaryExitTest(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,63 +1,36 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const exitPrefix = "tests/operations/voluntary_exit/"
|
||||
|
||||
func runVoluntaryExitTest(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
test := &BlockOperationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, test); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(test.Config); err != nil {
|
||||
func runVoluntaryExitTest(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(test.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range test.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
body := ðpb.BeaconBlockBody{VoluntaryExits: []*ethpb.VoluntaryExit{tt.VoluntaryExit}}
|
||||
|
||||
postState, err := blocks.ProcessVoluntaryExits(tt.Pre, body)
|
||||
// Note: This doesn't test anything worthwhile. It essentially tests
|
||||
// that *any* error has occurred, not any specific error.
|
||||
if tt.Post == nil {
|
||||
if err == nil {
|
||||
t.Fatal("Did not fail when expected")
|
||||
}
|
||||
return
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/voluntary_exit/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
exitFile, err := testutil.BazelFileBytes(folderPath, "voluntary_exit.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(postState, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(postState, tt.Post)
|
||||
t.Log(diff)
|
||||
t.Fatal("Post state does not match expected")
|
||||
voluntaryExit := ðpb.VoluntaryExit{}
|
||||
if err := ssz.Unmarshal(exitFile, voluntaryExit); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
body := ðpb.BeaconBlockBody{VoluntaryExits: []*ethpb.VoluntaryExit{voluntaryExit}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessVoluntaryExits)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ type MatchedAttestations struct {
|
||||
// def get_matching_head_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
|
||||
// return [
|
||||
// a for a in get_matching_source_attestations(state, epoch)
|
||||
// if a.data.beacon_block_root == get_block_root_at_slot(state, a.data.slot)
|
||||
// if a.data.beacon_block_root == get_block_root_at_slot(state, get_attestation_data_slot(state, a.data))
|
||||
// ]
|
||||
func MatchAttestations(state *pb.BeaconState, epoch uint64) (*MatchedAttestations, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
@@ -443,8 +443,6 @@ func ProcessSlashings(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
// HALF_INCREMENT = EFFECTIVE_BALANCE_INCREMENT // 2
|
||||
// if balance < validator.effective_balance or validator.effective_balance + 3 * HALF_INCREMENT < balance:
|
||||
// validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
||||
// # Update start shard
|
||||
// state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT)
|
||||
// # Set active index root
|
||||
// index_epoch = Epoch(next_epoch + ACTIVATION_EXIT_DELAY)
|
||||
// index_root_position = index_epoch % EPOCHS_PER_HISTORICAL_VECTOR
|
||||
@@ -461,6 +459,8 @@ func ProcessSlashings(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
// if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0:
|
||||
// historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots)
|
||||
// state.historical_roots.append(hash_tree_root(historical_batch))
|
||||
// # Update start shard
|
||||
// state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT)
|
||||
// # Rotate current/previous epoch attestations
|
||||
// state.previous_epoch_attestations = state.current_epoch_attestations
|
||||
// state.current_epoch_attestations = []
|
||||
@@ -485,14 +485,6 @@ func ProcessFinalUpdates(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Update start shard.
|
||||
delta, err := helpers.ShardDelta(state, currentEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get shard delta")
|
||||
}
|
||||
state.StartShard = (state.StartShard + delta) %
|
||||
params.BeaconConfig().ShardCount
|
||||
|
||||
// Set active index root.
|
||||
// index_epoch = Epoch(next_epoch + ACTIVATION_EXIT_DELAY)
|
||||
// index_root_position = index_epoch % EPOCHS_PER_HISTORICAL_VECTOR
|
||||
@@ -540,6 +532,13 @@ func ProcessFinalUpdates(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
state.HistoricalRoots = append(state.HistoricalRoots, batchRoot[:])
|
||||
}
|
||||
|
||||
// Update start shard.
|
||||
delta, err := helpers.ShardDelta(state, currentEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get shard delta")
|
||||
}
|
||||
state.StartShard = (state.StartShard + delta) % params.BeaconConfig().ShardCount
|
||||
|
||||
// Rotate current and previous epoch attestations.
|
||||
state.PreviousEpochAttestations = state.CurrentEpochAttestations
|
||||
state.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["epoch_processing_test.yaml.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/spectest",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = ["//proto/beacon/p2p/v1:go_default_library"],
|
||||
)
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_test")
|
||||
|
||||
test_suite(
|
||||
name = "go_default_test",
|
||||
@@ -25,9 +17,8 @@ go_test(
|
||||
exclude = ["*_minimal_test.go"],
|
||||
),
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_mainnet//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
shard_count = 4,
|
||||
tags = [
|
||||
"spectest",
|
||||
@@ -39,6 +30,7 @@ go_test(
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
@@ -52,9 +44,8 @@ go_test(
|
||||
exclude = ["*_mainnet_test.go"],
|
||||
),
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_minimal//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = [
|
||||
"spectest",
|
||||
],
|
||||
|
||||
@@ -2,16 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
)
|
||||
|
||||
func TestCrosslinksProcessingMainnet(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
filepath, err := bazel.Runfile(crosslinkPrefix + "crosslinks_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runCrosslinkProcessingTests(t, filepath)
|
||||
runCrosslinkProcessingTests(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestCrosslinksProcessingMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(crosslinkPrefix + "crosslinks_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runCrosslinkProcessingTests(t, filepath)
|
||||
runCrosslinkProcessingTests(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,47 +1,33 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
const crosslinkPrefix = "tests/epoch_processing/crosslinks/"
|
||||
|
||||
func runCrosslinkProcessingTests(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &EpochProcessingTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
func runCrosslinkProcessingTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
|
||||
postState, err := epoch.ProcessCrosslinks(tt.Pre)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(postState, tt.Post) {
|
||||
t.Error("Did not get expected state")
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "epoch_processing/crosslinks/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
testutil.RunEpochOperationTest(t, folderPath, processCrosslinksWrapper)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func processCrosslinksWrapper(t *testing.T, state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
state, err := epoch.ProcessCrosslinks(state)
|
||||
if err != nil {
|
||||
t.Fatalf("could not process crosslinks: %v", err)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
package spectest
|
||||
|
||||
import pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
|
||||
type EpochProcessingTest struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Pre *pb.BeaconState `json:"pre"`
|
||||
Post *pb.BeaconState `json:"post"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestFinalUpdatesMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(finalUpdatesPrefix + "final_updates_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runFinalUpdatesTests(t, filepath)
|
||||
runFinalUpdatesTests(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestFinalUpdatesMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(finalUpdatesPrefix + "final_updates_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runFinalUpdatesTests(t, filepath)
|
||||
runFinalUpdatesTests(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,54 +1,33 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const finalUpdatesPrefix = "tests/epoch_processing/final_updates/"
|
||||
|
||||
func runFinalUpdatesTests(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &EpochProcessingTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
func runFinalUpdatesTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
var postState *pb.BeaconState
|
||||
postState, err = epoch.ProcessFinalUpdates(tt.Pre)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(postState, tt.Post) {
|
||||
t.Error("Did not get expected state")
|
||||
diff, _ := messagediff.PrettyDiff(tt.Post, postState)
|
||||
t.Log(diff)
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "epoch_processing/final_updates/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
testutil.RunEpochOperationTest(t, folderPath, processFinalUpdatesWrapper)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func processFinalUpdatesWrapper(t *testing.T, state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
state, err := epoch.ProcessFinalUpdates(state)
|
||||
if err != nil {
|
||||
t.Fatalf("could not process final updates: %v", err)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestJustificationAndFinalizationMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(justificationAndFinalizationPrefix + "justification_and_finalization_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runJustificationAndFinalizationTests(t, filepath)
|
||||
runJustificationAndFinalizationTests(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,15 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestJustificationAndFinalizationMinimal(t *testing.T) {
|
||||
t.Skip("This test suite requires --define ssz=minimal to be provided and there isn't a great way to do that without breaking //... See https://github.com/prysmaticlabs/prysm/issues/3066")
|
||||
filepath, err := bazel.Runfile(justificationAndFinalizationPrefix + "justification_and_finalization_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runJustificationAndFinalizationTests(t, filepath)
|
||||
runJustificationAndFinalizationTests(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,102 +1,55 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const justificationAndFinalizationPrefix = "tests/epoch_processing/justification_and_finalization/"
|
||||
func runJustificationAndFinalizationTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testPath := "epoch_processing/justification_and_finalization/pyspec_tests"
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, testPath)
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
testutil.RunEpochOperationTest(t, folderPath, processJustificationAndFinalizationWrapper)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// This is a subset of state.ProcessEpoch. The spec test defines input data for
|
||||
// `justification_and_finalization` only.
|
||||
func processJustificationAndFinalizationWrapper(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
// This process mutates the state, so we'll make a copy in order to print debug before/after.
|
||||
state = proto.Clone(state).(*pb.BeaconState)
|
||||
|
||||
func processJustificationAndFinalizationWrapper(t *testing.T, state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
prevEpochAtts, err := epoch.MatchAttestations(state, helpers.PrevEpoch(state))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get target atts prev epoch %d: %v",
|
||||
helpers.PrevEpoch(state), err)
|
||||
t.Fatalf("could not get target atts prev epoch %d: %v", helpers.PrevEpoch(state), err)
|
||||
}
|
||||
currentEpochAtts, err := epoch.MatchAttestations(state, helpers.CurrentEpoch(state))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get target atts current epoch %d: %v",
|
||||
helpers.CurrentEpoch(state), err)
|
||||
t.Fatalf("could not get target atts current epoch %d: %v", helpers.CurrentEpoch(state), err)
|
||||
}
|
||||
prevEpochAttestedBalance, err := epoch.AttestingBalance(state, prevEpochAtts.Target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get attesting balance prev epoch: %v", err)
|
||||
t.Fatalf("could not get attesting balance prev epoch: %v", err)
|
||||
}
|
||||
currentEpochAttestedBalance, err := epoch.AttestingBalance(state, currentEpochAtts.Target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get attesting balance current epoch: %v", err)
|
||||
t.Fatalf("could not get attesting balance current epoch: %v", err)
|
||||
}
|
||||
|
||||
state, err = epoch.ProcessJustificationAndFinalization(state, prevEpochAttestedBalance, currentEpochAttestedBalance)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not process justification: %v", err)
|
||||
t.Fatalf("could not process justification: %v", err)
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func runJustificationAndFinalizationTests(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &EpochProcessingTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
preState := &pb.BeaconState{}
|
||||
if err := testutil.ConvertToPb(tt.Pre, preState); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
postState, err := processJustificationAndFinalizationWrapper(preState)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expectedPostState := &pb.BeaconState{}
|
||||
if err := testutil.ConvertToPb(tt.Post, expectedPostState); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if postState.JustificationBits[0] != expectedPostState.JustificationBits[0] {
|
||||
t.Errorf("Justification bits mismatch. PreState.JustificationBits=%v. PostState.JustificationBits=%v. Expected=%v", preState.JustificationBits, postState.JustificationBits, expectedPostState.JustificationBits)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(postState, expectedPostState) {
|
||||
diff, _ := messagediff.PrettyDiff(postState, expectedPostState)
|
||||
t.Log(diff)
|
||||
t.Error("Did not get expected state")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestRegistryProcessingMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(registryUpdatesPrefix + "registry_updates_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runRegisteryProcessingTests(t, filepath)
|
||||
func TestRegistryUpdatesMainnet(t *testing.T) {
|
||||
runRegistryUpdatesTests(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestRegistryProcessingMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(registryUpdatesPrefix + "registry_updates_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runRegisteryProcessingTests(t, filepath)
|
||||
func TestRegistryUpdatesMinimal(t *testing.T) {
|
||||
runRegistryUpdatesTests(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,46 +1,33 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
const registryUpdatesPrefix = "tests/epoch_processing/registry_updates/"
|
||||
|
||||
func runRegisteryProcessingTests(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &EpochProcessingTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
func runRegistryUpdatesTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
postState, err := epoch.ProcessRegistryUpdates(tt.Pre)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(postState, tt.Post) {
|
||||
t.Error("Did not get expected state")
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "epoch_processing/registry_updates/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
testutil.RunEpochOperationTest(t, folderPath, processRegistryUpdatesWrapper)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func processRegistryUpdatesWrapper(t *testing.T, state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
state, err := epoch.ProcessRegistryUpdates(state)
|
||||
if err != nil {
|
||||
t.Fatalf("could not process registry updates: %v", err)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestSlashingsMainnet(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(slashingsPrefix + "slashings_mainnet.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runSlashingsTests(t, filepath)
|
||||
runSlashingsTests(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
func TestSlashingsMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile(slashingsPrefix + "slashings_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runSlashingsTests(t, filepath)
|
||||
runSlashingsTests(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -1,48 +1,33 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
const slashingsPrefix = "tests/epoch_processing/slashings/"
|
||||
|
||||
func runSlashingsTests(t *testing.T, filename string) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &EpochProcessingTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
func runSlashingsTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
postState, err := epoch.ProcessSlashings(tt.Pre)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(postState, tt.Post) {
|
||||
t.Error("Did not get expected state")
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "epoch_processing/slashings/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
testutil.RunEpochOperationTest(t, folderPath, processSlashingsWrapper)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func processSlashingsWrapper(t *testing.T, state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
state, err := epoch.ProcessSlashings(state)
|
||||
if err != nil {
|
||||
t.Fatalf("could not process slashings: %v", err)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// assert slot < state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
|
||||
// return state.block_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
|
||||
func BlockRootAtSlot(state *pb.BeaconState, slot uint64) ([]byte, error) {
|
||||
if !(slot < state.Slot && state.Slot <= slot+params.BeaconConfig().SlotsPerHistoricalRoot) {
|
||||
if slot >= state.Slot || state.Slot > slot+params.BeaconConfig().SlotsPerHistoricalRoot {
|
||||
return []byte{}, errors.New("slot out of bounds")
|
||||
}
|
||||
return state.BlockRoots[slot%params.BeaconConfig().SlotsPerHistoricalRoot], nil
|
||||
|
||||
@@ -175,6 +175,17 @@ func AttestingIndices(state *pb.BeaconState, data *ethpb.AttestationData, bf bit
|
||||
return indices, nil
|
||||
}
|
||||
|
||||
// VerifyBitfieldLength verifies that a bitfield length matches the given committee size.
|
||||
func VerifyBitfieldLength(bf bitfield.Bitfield, committeeSize uint64) error {
|
||||
if bf.Len() != committeeSize {
|
||||
return fmt.Errorf(
|
||||
"wanted participants bitfield length %d, got: %d",
|
||||
committeeSize,
|
||||
bf.Len())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommitteeAssignment is used to query committee assignment from
|
||||
// current and previous epoch.
|
||||
//
|
||||
@@ -346,6 +357,27 @@ func StartShard(state *pb.BeaconState, epoch uint64) (uint64, error) {
|
||||
return startShard, nil
|
||||
}
|
||||
|
||||
// VerifyAttestationBitfieldLengths verifies that an attestations aggregation and custody bitfields are
|
||||
// a valid length matching the size of the committee.
|
||||
func VerifyAttestationBitfieldLengths(bState *pb.BeaconState, att *ethpb.Attestation) error {
|
||||
committee, err := CrosslinkCommittee(bState, att.Data.Target.Epoch, att.Data.Crosslink.Shard)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve crosslink committees")
|
||||
}
|
||||
|
||||
if committee == nil {
|
||||
return errors.New("no committee exist for shard in the attestation")
|
||||
}
|
||||
|
||||
if err := VerifyBitfieldLength(att.AggregationBits, uint64(len(committee))); err != nil {
|
||||
return errors.Wrap(err, "failed to verify aggregation bitfield")
|
||||
}
|
||||
if err := VerifyBitfieldLength(att.CustodyBits, uint64(len(committee))); err != nil {
|
||||
return errors.Wrap(err, "failed to verify custody bitfield")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompactCommitteesRoot returns the index root of a given epoch.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
|
||||
@@ -3,6 +3,7 @@ package helpers
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
@@ -318,6 +319,20 @@ func TestAttestationParticipants_EmptyBitfield(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyBitfieldLength_OK(t *testing.T) {
|
||||
bf := bitfield.Bitlist{0xFF, 0x01}
|
||||
committeeSize := uint64(8)
|
||||
if err := VerifyBitfieldLength(bf, committeeSize); err != nil {
|
||||
t.Errorf("bitfield is not validated when it was supposed to be: %v", err)
|
||||
}
|
||||
|
||||
bf = bitfield.Bitlist{0xFF, 0x07}
|
||||
committeeSize = 10
|
||||
if err := VerifyBitfieldLength(bf, committeeSize); err != nil {
|
||||
t.Errorf("bitfield is not validated when it was supposed to be: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitteeAssignment_CanRetrieve(t *testing.T) {
|
||||
// Initialize test with 128 validators, each slot and each shard gets 2 validators.
|
||||
validators := make([]*ethpb.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
|
||||
@@ -572,6 +587,139 @@ func TestEpochStartShard_MixedActivationValidators(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyAttestationBitfieldLengths_OK(t *testing.T) {
|
||||
if params.BeaconConfig().SlotsPerEpoch != 64 {
|
||||
t.Errorf("SlotsPerEpoch should be 64 for these tests to pass")
|
||||
}
|
||||
|
||||
validators := make([]*ethpb.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
|
||||
activeRoots := make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector)
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = ðpb.Validator{
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
}
|
||||
activeRoots[i] = []byte{'A'}
|
||||
}
|
||||
|
||||
state := &pb.BeaconState{
|
||||
Validators: validators,
|
||||
ActiveIndexRoots: activeRoots,
|
||||
RandaoMixes: activeRoots,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
attestation *ethpb.Attestation
|
||||
stateSlot uint64
|
||||
invalidCustodyBits bool
|
||||
verificationFailure bool
|
||||
}{
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x05},
|
||||
CustodyBits: bitfield.Bitlist{0x05},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 5,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 5,
|
||||
},
|
||||
{
|
||||
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x06},
|
||||
CustodyBits: bitfield.Bitlist{0x06},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 10,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 10,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x06},
|
||||
CustodyBits: bitfield.Bitlist{0x06},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 20,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 20,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x06},
|
||||
CustodyBits: bitfield.Bitlist{0x10},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 20,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 20,
|
||||
verificationFailure: true,
|
||||
invalidCustodyBits: true,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0xFF, 0xC0, 0x01},
|
||||
CustodyBits: bitfield.Bitlist{0xFF, 0xC0, 0x01},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 5,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 5,
|
||||
verificationFailure: true,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0xFF, 0x01},
|
||||
CustodyBits: bitfield.Bitlist{0xFF, 0x01},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 20,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 20,
|
||||
verificationFailure: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
ClearAllCaches()
|
||||
state.Slot = tt.stateSlot
|
||||
err := VerifyAttestationBitfieldLengths(state, tt.attestation)
|
||||
if tt.verificationFailure {
|
||||
if tt.invalidCustodyBits {
|
||||
if !strings.Contains(err.Error(), "custody bitfield") {
|
||||
t.Errorf("%d expected custody bits to fail: %v", i, err)
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
t.Error("verification succeeded when it was supposed to fail")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("%d Failed to verify bitfield: %v", i, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactCommitteesRoot_OK(t *testing.T) {
|
||||
ClearAllCaches()
|
||||
// Create 10 committees
|
||||
|
||||
@@ -12,15 +12,16 @@ go_test(
|
||||
size = "small",
|
||||
srcs = ["shuffle_yaml_test.go"],
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_mainnet//:test_data",
|
||||
"@eth2_spec_tests_minimal//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_go_yaml_yaml//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
package spectest
|
||||
|
||||
// ShuffleTest --
|
||||
type ShuffleTest struct {
|
||||
Title string `yaml:"title"`
|
||||
Summary string `yaml:"summary"`
|
||||
ForksTimeline string `yaml:"forks_timeline"`
|
||||
Forks []string `yaml:"forks"`
|
||||
Config string `yaml:"config"`
|
||||
Runner string `yaml:"runner"`
|
||||
Handler string `yaml:"handler"`
|
||||
TestCases []*ShuffleTestCase `yaml:"test_cases"`
|
||||
}
|
||||
|
||||
// ShuffleTestCase --
|
||||
type ShuffleTestCase struct {
|
||||
Seed string `yaml:"seed"`
|
||||
Count uint64 `yaml:"count"`
|
||||
Shuffled []uint64 `yaml:"shuffled"`
|
||||
Seed string `yaml:"seed"`
|
||||
Count uint64 `yaml:"count"`
|
||||
Mapping []uint64 `yaml:"mapping"`
|
||||
}
|
||||
|
||||
@@ -1,68 +1,56 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/go-yaml/yaml"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
const shufflePrefix = "tests/shuffling/core/"
|
||||
|
||||
func TestShufflingMinimal(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
filepath, err := bazel.Runfile(shufflePrefix + "shuffling_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runShuffleTests(t, filepath)
|
||||
runShuffleTests(t, "minimal")
|
||||
}
|
||||
|
||||
func TestShufflingMainnet(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
filepath, err := bazel.Runfile(shufflePrefix + "shuffling_full.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runShuffleTests(t, filepath)
|
||||
runShuffleTests(t, "mainnet")
|
||||
}
|
||||
|
||||
func runShuffleTests(t *testing.T, filepath string) {
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("could not read YAML tests directory: %v", err)
|
||||
}
|
||||
|
||||
shuffleTest := &ShuffleTest{}
|
||||
if err := yaml.Unmarshal(file, shuffleTest); err != nil {
|
||||
t.Fatalf("could not unmarshal YAML file into test struct: %v", err)
|
||||
}
|
||||
if err := spectest.SetConfig(shuffleTest.Config); err != nil {
|
||||
func runShuffleTests(t *testing.T, config string) {
|
||||
helpers.ClearAllCaches()
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("Title: %v", shuffleTest.Title)
|
||||
t.Logf("Summary: %v", shuffleTest.Summary)
|
||||
t.Logf("Fork: %v", shuffleTest.Forks)
|
||||
t.Logf("Config: %v", shuffleTest.Config)
|
||||
for _, testCase := range shuffleTest.TestCases {
|
||||
if err := runShuffleTest(testCase); err != nil {
|
||||
t.Fatalf("shuffle test failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "shuffling/core/shuffle")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
testCaseFile, err := testutil.BazelFileBytes(path.Join(testsFolderPath, folder.Name(), "mapping.yaml"))
|
||||
if err != nil {
|
||||
t.Fatalf("could not read YAML tests directory: %v", err)
|
||||
}
|
||||
|
||||
testCase := &ShuffleTestCase{}
|
||||
if err := yaml.Unmarshal(testCaseFile, testCase); err != nil {
|
||||
t.Fatalf("could not unmarshal YAML file into test struct: %v", err)
|
||||
}
|
||||
if err := runShuffleTest(testCase); err != nil {
|
||||
t.Fatalf("shuffle test failed: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// RunShuffleTest uses validator set specified from a YAML file, runs the validator shuffle
|
||||
// algorithm, then compare the output with the expected output from the YAML file.
|
||||
func runShuffleTest(testCase *ShuffleTestCase) error {
|
||||
baseSeed, err := base64.StdEncoding.DecodeString(testCase.Seed)
|
||||
baseSeed, err := hex.DecodeString(testCase.Seed[2:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -80,8 +68,8 @@ func runShuffleTest(testCase *ShuffleTestCase) error {
|
||||
}
|
||||
shuffledList[i] = si
|
||||
}
|
||||
if !reflect.DeepEqual(shuffledList, testCase.Shuffled) {
|
||||
return fmt.Errorf("shuffle result error: expected %v, actual %v", testCase.Shuffled, shuffledList)
|
||||
if !reflect.DeepEqual(shuffledList, testCase.Mapping) {
|
||||
return fmt.Errorf("shuffle result error: expected %v, actual %v", testCase.Mapping, shuffledList)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,19 +1,4 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"genesis_initialization.yaml.go",
|
||||
"genesis_validity.yaml.go",
|
||||
"sanity_slots_test.yaml.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/state/spectest",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_test")
|
||||
|
||||
test_suite(
|
||||
name = "go_default_test",
|
||||
@@ -32,14 +17,14 @@ go_test(
|
||||
exclude = ["*_minimal_test.go"],
|
||||
),
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_mainnet//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
shard_count = 2,
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
@@ -59,13 +44,13 @@ go_test(
|
||||
exclude = ["*_mainnet_test.go"],
|
||||
),
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_minimal//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: genesis_initialization_minimal.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
type GenesisInitializationTest struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Eth1BlockHash []byte `json:"eth1_block_hash"`
|
||||
Eth1Timestamp uint64 `json:"eth1_timestamp"`
|
||||
Deposits []*ethpb.Deposit `json:"deposits"`
|
||||
State *pb.BeaconState `json:"state"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestGenesisInitializationMinimal(t *testing.T) {
|
||||
t.Skip("This test suite requires --define ssz=minimal to be provided and there isn't a great way to do that without breaking //... See https://github.com/prysmaticlabs/prysm/issues/3066")
|
||||
filepath, err := bazel.Runfile("tests/genesis/initialization/genesis_initialization_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &GenesisInitializationTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
deposits := tt.Deposits
|
||||
dataLeaves := make([]*ethpb.Deposit_Data, len(deposits))
|
||||
for i := range deposits {
|
||||
dataLeaves[i] = deposits[i].Data
|
||||
}
|
||||
depositRoot, err := ssz.HashTreeRootWithCapacity(dataLeaves, 1<<params.BeaconConfig().DepositContractTreeDepth)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
eth1Data := ðpb.Eth1Data{
|
||||
DepositRoot: depositRoot[:],
|
||||
DepositCount: uint64(len(deposits)),
|
||||
BlockHash: tt.Eth1BlockHash,
|
||||
}
|
||||
|
||||
genesisState, err := state.GenesisBeaconState(deposits, tt.Eth1Timestamp, eth1Data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(genesisState, tt.State) {
|
||||
t.Error("States are not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: genesis_initialization_minimal.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
|
||||
type GenesisValidityTest struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Genesis *pb.BeaconState `json:"genesis"`
|
||||
IsValid bool `json:"is_valid"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestGenesisValidityMinimal(t *testing.T) {
|
||||
filepath, err := bazel.Runfile("tests/genesis/validity/genesis_validity_minimal.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &GenesisValidityTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
genesisState := tt.Genesis
|
||||
validatorCount, err := helpers.ActiveValidatorCount(genesisState, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get active validator count: %v", err)
|
||||
}
|
||||
isValid := state.IsValidGenesisState(validatorCount, genesisState.GenesisTime)
|
||||
if isValid != tt.IsValid {
|
||||
t.Fatalf(
|
||||
"Genesis state does not have expected validity. Expected to be valid: %d, %d. %t %t",
|
||||
tt.Genesis.GenesisTime,
|
||||
validatorCount,
|
||||
isValid,
|
||||
tt.IsValid,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: sanity_slots_minimal.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
import pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
|
||||
type SanitySlotsTest struct {
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ForksTimeline string `json:"forks_timeline"`
|
||||
Forks []string `json:"forks"`
|
||||
Config string `json:"config"`
|
||||
Runner string `json:"runner"`
|
||||
Handler string `json:"handler"`
|
||||
TestCases []struct {
|
||||
Description string `json:"description"`
|
||||
Pre *pb.BeaconState `json:"pre"`
|
||||
Slots uint64 `json:"slots"`
|
||||
Post *pb.BeaconState `json:"post"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func TestSlotProcessingMainnet(t *testing.T) {
|
||||
runSlotProcessingTests(t, "sanity_slots_mainnet.yaml")
|
||||
runSlotProcessingTests(t, "mainnet")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func TestSlotProcessingMinimal(t *testing.T) {
|
||||
t.Skip("This test suite requires --define ssz=minimal to be provided and there isn't a great way to do that without breaking //... See https://github.com/prysmaticlabs/prysm/issues/3066")
|
||||
runSlotProcessingTests(t, "sanity_slots_minimal.yaml")
|
||||
runSlotProcessingTests(t, "minimal")
|
||||
}
|
||||
|
||||
@@ -2,53 +2,65 @@ package spectest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
const slotProcessingPrefix = "tests/sanity/slots/"
|
||||
|
||||
func runSlotProcessingTests(t *testing.T, filename string) {
|
||||
filepath, err := bazel.Runfile(slotProcessingPrefix + filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
|
||||
s := &SanitySlotsTest{}
|
||||
if err := testutil.UnmarshalYaml(file, s); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if err := spectest.SetConfig(s.Config); err != nil {
|
||||
func runSlotProcessingTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(s.TestCases) == 0 {
|
||||
t.Fatal("No tests!")
|
||||
}
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "sanity/slots/pyspec_tests")
|
||||
|
||||
for _, tt := range s.TestCases {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
postState, err := state.ProcessSlots(context.Background(), tt.Pre, tt.Pre.Slot+tt.Slots)
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(preBeaconStateFile, beaconState); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
file, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "slots.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fileStr := string(file)
|
||||
slotsCount, err := strconv.Atoi(fileStr[:len(fileStr)-5])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(postState, tt.Post) {
|
||||
diff, _ := messagediff.PrettyDiff(postState, tt.Post)
|
||||
postBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "post.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
postBeaconState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(postBeaconStateFile, postBeaconState); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
postState, err := state.ProcessSlots(context.Background(), beaconState, beaconState.Slot+uint64(slotsCount))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !proto.Equal(postState, postBeaconState) {
|
||||
diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState)
|
||||
t.Log(diff)
|
||||
_ = diff
|
||||
t.Fatal("Post state does not match expected")
|
||||
}
|
||||
})
|
||||
|
||||
@@ -453,6 +453,19 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
BodyRoot: bodyRoot[:],
|
||||
}
|
||||
beaconState.Slashings = make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector)
|
||||
beaconState.CurrentCrosslinks = []*ethpb.Crosslink{
|
||||
{
|
||||
Shard: 0,
|
||||
StartEpoch: helpers.SlotToEpoch(beaconState.Slot),
|
||||
DataRoot: []byte{1},
|
||||
},
|
||||
}
|
||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||
encoded, err := ssz.HashTreeRoot(beaconState.CurrentCrosslinks[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
proposerSlashIdx := uint64(3)
|
||||
slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
|
||||
@@ -553,11 +566,10 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
blockRoots = append(blockRoots, []byte{byte(i)})
|
||||
}
|
||||
beaconState.BlockRoots = blockRoots
|
||||
beaconState.CurrentCrosslinks = []*ethpb.Crosslink{
|
||||
{
|
||||
DataRoot: []byte{1},
|
||||
},
|
||||
}
|
||||
|
||||
aggBits := bitfield.NewBitlist(1)
|
||||
aggBits.SetBitAt(1, true)
|
||||
custodyBits := bitfield.NewBitlist(1)
|
||||
blockAtt := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: helpers.SlotToEpoch(beaconState.Slot)},
|
||||
@@ -566,27 +578,29 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
Root: []byte("hello-world"),
|
||||
},
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 0,
|
||||
EndEpoch: 64,
|
||||
Shard: 0,
|
||||
EndEpoch: 64,
|
||||
DataRoot: params.BeaconConfig().ZeroHash[:],
|
||||
ParentRoot: encoded[:],
|
||||
},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
}
|
||||
attestingIndices, err := helpers.AttestingIndices(beaconState, blockAtt.Data, blockAtt.AggregationBits)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dataAndCustodyBit = &pb.AttestationDataAndCustodyBit{
|
||||
Data: blockAtt.Data,
|
||||
CustodyBit: false,
|
||||
}
|
||||
hashTreeRoot, err = ssz.HashTreeRoot(dataAndCustodyBit)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
sigs := make([]*bls.Signature, len(attestingIndices))
|
||||
for i, indice := range attestingIndices {
|
||||
dataAndCustodyBit := &pb.AttestationDataAndCustodyBit{
|
||||
Data: blockAtt.Data,
|
||||
CustodyBit: false,
|
||||
}
|
||||
hashTreeRoot, err := ssz.HashTreeRoot(dataAndCustodyBit)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
sig := privKeys[indice].Sign(hashTreeRoot[:], domain)
|
||||
sigs[i] = sig
|
||||
}
|
||||
@@ -607,18 +621,6 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState.CurrentCrosslinks = []*ethpb.Crosslink{
|
||||
{
|
||||
Shard: 0,
|
||||
StartEpoch: helpers.SlotToEpoch(beaconState.Slot),
|
||||
},
|
||||
}
|
||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||
encoded, err := ssz.HashTreeRoot(beaconState.CurrentCrosslinks[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
randaoReveal, err := testutil.CreateRandaoReveal(beaconState, currentEpoch, privKeys)
|
||||
if err != nil {
|
||||
@@ -639,8 +641,6 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
block.Body.Attestations[0].Data.Crosslink.ParentRoot = encoded[:]
|
||||
block.Body.Attestations[0].Data.Crosslink.DataRoot = params.BeaconConfig().ZeroHash[:]
|
||||
|
||||
block, err = testutil.SignBlock(beaconState, block, privKeys)
|
||||
if err != nil {
|
||||
|
||||
@@ -196,6 +196,20 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
currentEpoch := helpers.CurrentEpoch(beaconState)
|
||||
activeCount, err := helpers.ActiveValidatorCount(beaconState, currentEpoch)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
committeeCount, err := helpers.CommitteeCount(beaconState, currentEpoch)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
aggBits := bitfield.NewBitlist(activeCount / committeeCount)
|
||||
for i := uint64(0); i < aggBits.Len(); i++ {
|
||||
aggBits.SetBitAt(i, true)
|
||||
}
|
||||
custodyBits := bitfield.NewBitlist(activeCount / committeeCount)
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
@@ -205,15 +219,22 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) {
|
||||
Source: ðpb.Checkpoint{},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
CustodyBits: []byte{0x00, 0x00, 0x00, 0x00},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
}
|
||||
|
||||
attestingIndices, err := helpers.AttestingIndices(beaconState, att.Data, att.AggregationBits)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
currentEpoch := helpers.CurrentEpoch(beaconState)
|
||||
dataAndCustodyBit := &pbp2p.AttestationDataAndCustodyBit{
|
||||
Data: att.Data,
|
||||
CustodyBit: false,
|
||||
}
|
||||
hashTreeRoot, err := ssz.HashTreeRoot(dataAndCustodyBit)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
domain := helpers.Domain(beaconState, currentEpoch, params.BeaconConfig().DomainAttestation)
|
||||
sigs := make([]*bls.Signature, len(attestingIndices))
|
||||
for i, indice := range attestingIndices {
|
||||
@@ -221,14 +242,6 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dataAndCustodyBit := &pbp2p.AttestationDataAndCustodyBit{
|
||||
Data: att.Data,
|
||||
CustodyBit: false,
|
||||
}
|
||||
hashTreeRoot, err := ssz.HashTreeRoot(dataAndCustodyBit)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
beaconState.Validators[indice].PublicKey = priv.PublicKey().Marshal()[:]
|
||||
sigs[i] = priv.Sign(hashTreeRoot[:], domain)
|
||||
}
|
||||
@@ -310,14 +323,30 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
||||
LatestBlockHeader: ðpb.BeaconBlockHeader{StateRoot: []byte{}},
|
||||
}
|
||||
|
||||
currentEpoch := helpers.CurrentEpoch(beaconState)
|
||||
activeCount, err := helpers.ActiveValidatorCount(beaconState, currentEpoch)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
committeeCount, err := helpers.CommitteeCount(beaconState, currentEpoch)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
aggBits := bitfield.NewBitlist(activeCount / committeeCount)
|
||||
for i := uint64(0); i < aggBits.Len(); i++ {
|
||||
aggBits.SetBitAt(i, true)
|
||||
}
|
||||
custodyBits := bitfield.NewBitlist(activeCount / committeeCount)
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{EndEpoch: 10, DataRoot: params.BeaconConfig().ZeroHash[:], ParentRoot: encoded[:]},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
}
|
||||
|
||||
attestingIndices, err := helpers.AttestingIndices(beaconState, att.Data, att.AggregationBits)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -349,38 +378,60 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
||||
opService := &mockOperationService{
|
||||
pendingAttestations: []*ethpb.Attestation{
|
||||
//Expired attestations
|
||||
{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
}},
|
||||
{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
}},
|
||||
{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
}},
|
||||
{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
}},
|
||||
{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
}},
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits},
|
||||
// Non-expired attestation with incorrect justified epoch
|
||||
{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch - 1},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
}},
|
||||
{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 10},
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch - 1},
|
||||
Crosslink: ðpb.Crosslink{DataRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
},
|
||||
// Non-expired attestations with correct justified epoch
|
||||
att,
|
||||
att2,
|
||||
@@ -421,7 +472,8 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{EndEpoch: 10, DataRoot: params.BeaconConfig().ZeroHash[:], ParentRoot: encoded[:]},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
Signature: aggregateSig,
|
||||
},
|
||||
{
|
||||
@@ -430,7 +482,8 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{EndEpoch: 10, DataRoot: params.BeaconConfig().ZeroHash[:], ParentRoot: encoded[:]},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
Signature: aggregateSig,
|
||||
},
|
||||
{
|
||||
@@ -439,7 +492,8 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
||||
Source: ðpb.Checkpoint{Epoch: expectedEpoch},
|
||||
Crosslink: ðpb.Crosslink{EndEpoch: 10, DataRoot: params.BeaconConfig().ZeroHash[:], ParentRoot: encoded[:]},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
|
||||
AggregationBits: aggBits,
|
||||
CustodyBits: custodyBits,
|
||||
Signature: aggregateSig,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user