mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 07:03:58 -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
3
.bazelrc
3
.bazelrc
@@ -14,3 +14,6 @@ run --host_force_python=PY2
|
||||
# is required within the sandbox. This flag is no longer experimental after 0.29.0.
|
||||
# Network sandboxing only works on linux.
|
||||
--experimental_sandbox_default_allow_network=false
|
||||
|
||||
# Use minimal protobufs at runtime
|
||||
run --define ssz=minimal
|
||||
|
||||
40
WORKSPACE
40
WORKSPACE
@@ -146,18 +146,52 @@ http_archive(
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "eth2_spec_tests",
|
||||
name = "eth2_spec_tests_general",
|
||||
build_file_content = """
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.ssz",
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "a531804ac35d2398d37cfa755a686280d8cb3a9649e993e3cf89640f06191d5e",
|
||||
url = "https://github.com/prysmaticlabs/eth2.0-spec-tests/releases/download/v0.8.1/base64_encoded_archive.tar.gz",
|
||||
sha256 = "386335fc3b055fad37088bd821929ff684bc00bb1a74e044e4b377ebd6e88fce",
|
||||
# File names are normally too long, see: https://github.com/ethereum/eth2.0-spec-tests/issues/15
|
||||
url = "https://prysmaticlabs.com/uploads/v0.8.3_general_spectests.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "eth2_spec_tests_minimal",
|
||||
build_file_content = """
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.ssz",
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "7ab89a364796e3f8a9af84750c241e9c9e2170a34c1a4e160fdfa2cee5b03fb7",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.8.3/minimal.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "eth2_spec_tests_mainnet",
|
||||
build_file_content = """
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.ssz",
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "6274e3b77f393faf7b17cef10e93244c16316d3b7ae9c6b844501b12f432a7c3",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.8.3/mainnet.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -35,10 +35,12 @@ go_test(
|
||||
size = "small",
|
||||
srcs = [
|
||||
"ssz_regression_test.go",
|
||||
"ssz_static_test.go",
|
||||
"tags_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"],
|
||||
@@ -46,6 +48,7 @@ go_test(
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_ghodss_yaml//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
@@ -58,16 +61,18 @@ go_test(
|
||||
name = "go_minimal_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"ssz_minimal_compatibility_test.go",
|
||||
"ssz_static_minimal_test.go",
|
||||
"ssz_static_test.go",
|
||||
],
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_minimal//:test_data",
|
||||
],
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_ghodss_yaml//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
@@ -80,16 +85,18 @@ go_test(
|
||||
name = "go_mainnet_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"ssz_mainnet_compatibility_test.go",
|
||||
"ssz_static_mainnet_test.go",
|
||||
"ssz_static_test.go",
|
||||
],
|
||||
data = [
|
||||
"@eth2_spec_tests//:test_data",
|
||||
"@eth2_spec_tests_mainnet//:test_data",
|
||||
],
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_ghodss_yaml//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
sszspectest "github.com/prysmaticlabs/go-ssz/spectests"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestYamlStatic_Mainnet(t *testing.T) {
|
||||
topPath := "tests/ssz_static/core/"
|
||||
yamlFileNames := []string{
|
||||
"ssz_mainnet_random.yaml",
|
||||
}
|
||||
|
||||
for _, f := range yamlFileNames {
|
||||
fullPath := path.Join(topPath, f)
|
||||
filepath, err := bazel.Runfile(fullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
s := &sszspectest.SszMainnetTest{}
|
||||
if err := yaml.Unmarshal(file, s); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
runTestCasesMainnet(t, s)
|
||||
}
|
||||
}
|
||||
|
||||
func runTestCasesMainnet(t *testing.T, s *sszspectest.SszMainnetTest) {
|
||||
for _, testCase := range s.TestCases {
|
||||
if !testutil.IsEmpty(testCase.Attestation.Value) {
|
||||
p := ðpb.Attestation{}
|
||||
if err := testutil.ConvertToPb(testCase.Attestation.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Attestation.Root) {
|
||||
t.Errorf("Expected attestation root %#x, received %#x", testCase.Attestation.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Attestation.SigningRoot) {
|
||||
t.Errorf("Expected attestation signing root data %#x, received %#x", testCase.AttestationData.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.AttestationData.Value) {
|
||||
p := ðpb.AttestationData{}
|
||||
if err := testutil.ConvertToPb(testCase.AttestationData.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.AttestationData.Root) {
|
||||
t.Errorf("Expected attestation data %#x, received %#x", testCase.AttestationData.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.AttestationDataAndCustodyBit.Value) {
|
||||
p := &pb.AttestationDataAndCustodyBit{}
|
||||
if err := testutil.ConvertToPb(testCase.AttestationDataAndCustodyBit.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.AttestationDataAndCustodyBit.Root) {
|
||||
t.Errorf("Expected attestation data and custody bit %#x, received %#x", testCase.AttestationDataAndCustodyBit.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.AttesterSlashing.Value) {
|
||||
p := ðpb.AttesterSlashing{}
|
||||
if err := testutil.ConvertToPb(testCase.AttesterSlashing.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.AttesterSlashing.Root) {
|
||||
t.Errorf("Expected attester slashing bit %#x, received %#x", testCase.AttesterSlashing.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconBlock.Value) {
|
||||
p := ðpb.BeaconBlock{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconBlock.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlock.Root) {
|
||||
t.Errorf("Expected beacon block root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlock.SigningRoot) {
|
||||
t.Errorf("Expected beacon block signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconBlockBody.Value) {
|
||||
p := ðpb.BeaconBlockBody{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconBlockBody.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlockBody.Root) {
|
||||
t.Errorf("Expected beacon block body %#x, received %#x", testCase.BeaconBlockBody.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconBlockHeader.Value) {
|
||||
p := ðpb.BeaconBlockHeader{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconBlockHeader.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlockHeader.Root) {
|
||||
t.Errorf("Expected beacon block header root %#x, received %#x", testCase.BeaconBlockHeader.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlockHeader.SigningRoot) {
|
||||
t.Errorf("Expected beacon block header signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconState.Value) {
|
||||
p := &pb.BeaconState{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconState.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconState.Root) {
|
||||
t.Errorf("Expected beacon state %#x, received %#x", testCase.BeaconState.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Crosslink.Value) {
|
||||
c := ðpb.Crosslink{}
|
||||
if err := testutil.ConvertToPb(testCase.Crosslink.Value, c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Crosslink.Root) {
|
||||
t.Errorf("Expected crosslink %#x, received %#x", testCase.Crosslink.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Deposit.Value) {
|
||||
p := ðpb.Deposit{}
|
||||
if err := testutil.ConvertToPb(testCase.Deposit.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Deposit.Root) {
|
||||
t.Errorf("Expected deposit root %#x, received %#x", testCase.Deposit.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.DepositData.Value) {
|
||||
p := ðpb.Deposit_Data{}
|
||||
if err := testutil.ConvertToPb(testCase.DepositData.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.DepositData.Root) {
|
||||
t.Errorf("Expected deposit data root %#x, received %#x", testCase.DepositData.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.DepositData.SigningRoot) {
|
||||
t.Errorf("Expected deposit data signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Eth1Data.Value) {
|
||||
p := ðpb.Eth1Data{}
|
||||
if err := testutil.ConvertToPb(testCase.Eth1Data.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Eth1Data.Root) {
|
||||
t.Errorf("Expected pb data %#x, received %#x", testCase.Eth1Data.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Fork.Value) {
|
||||
p := &pb.Fork{}
|
||||
if err := testutil.ConvertToPb(testCase.Fork.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Fork.Root) {
|
||||
t.Errorf("Expected fork %#x, received %#x", testCase.Fork.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.HistoricalBatch.Value) {
|
||||
p := &pb.HistoricalBatch{}
|
||||
if err := testutil.ConvertToPb(testCase.HistoricalBatch.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.HistoricalBatch.Root) {
|
||||
t.Errorf("Expected historical batch %#x, received %#x", testCase.HistoricalBatch.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.IndexedAttestation.Value) {
|
||||
p := ðpb.IndexedAttestation{}
|
||||
if err := testutil.ConvertToPb(testCase.IndexedAttestation.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.IndexedAttestation.Root) {
|
||||
t.Errorf("Expected indexed attestation root %#x, received %#x", testCase.IndexedAttestation.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.IndexedAttestation.SigningRoot) {
|
||||
t.Errorf("Expected indexed attestation signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.PendingAttestation.Value) {
|
||||
p := &pb.PendingAttestation{}
|
||||
if err := testutil.ConvertToPb(testCase.PendingAttestation.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.PendingAttestation.Root) {
|
||||
t.Errorf("Expected pending attestation %#x, received %#x", testCase.PendingAttestation.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.ProposerSlashing.Value) {
|
||||
p := ðpb.ProposerSlashing{}
|
||||
if err := testutil.ConvertToPb(testCase.ProposerSlashing.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.ProposerSlashing.Root) {
|
||||
t.Errorf("Expected proposer slashing %#x, received %#x", testCase.ProposerSlashing.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Transfer.Value) {
|
||||
p := ðpb.Transfer{}
|
||||
if err := testutil.ConvertToPb(testCase.Transfer.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Transfer.Root) {
|
||||
t.Errorf("Expected transfer root %#x, received %#x", testCase.Transfer.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Transfer.SigningRoot) {
|
||||
t.Errorf("Expected transfer signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Validator.Value) {
|
||||
p := ðpb.Validator{}
|
||||
if err := testutil.ConvertToPb(testCase.Validator.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Validator.Root) {
|
||||
t.Errorf("Expected validator %#x, received %#x", testCase.Validator.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.VoluntaryExit.Value) {
|
||||
p := ðpb.VoluntaryExit{}
|
||||
if err := testutil.ConvertToPb(testCase.VoluntaryExit.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.VoluntaryExit.Root) {
|
||||
t.Errorf("Expected voluntary exit root %#x, received %#x", testCase.VoluntaryExit.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.VoluntaryExit.SigningRoot) {
|
||||
t.Errorf("Expected voluntary exit signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,356 +0,0 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
sszspectest "github.com/prysmaticlabs/go-ssz/spectests"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestYamlStatic_Minimal(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 //...")
|
||||
|
||||
topPath := "tests/ssz_static/core/"
|
||||
yamlFileNames := []string{
|
||||
"ssz_minimal_random.yaml",
|
||||
}
|
||||
|
||||
for _, f := range yamlFileNames {
|
||||
fullPath := path.Join(topPath, f)
|
||||
filepath, err := bazel.Runfile(fullPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not load file %v", err)
|
||||
}
|
||||
s := &sszspectest.SszMinimalTest{}
|
||||
if err := yaml.Unmarshal(file, s); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
runTestCasesMinimal(t, s)
|
||||
}
|
||||
}
|
||||
|
||||
func runTestCasesMinimal(t *testing.T, s *sszspectest.SszMinimalTest) {
|
||||
for _, testCase := range s.TestCases {
|
||||
if !testutil.IsEmpty(testCase.Attestation.Value) {
|
||||
p := ðpb.Attestation{}
|
||||
if err := testutil.ConvertToPb(testCase.Attestation.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Attestation.Root) {
|
||||
t.Errorf("Expected attestation root %#x, received %#x", testCase.Attestation.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Attestation.SigningRoot) {
|
||||
t.Errorf("Expected attestation signing root data %#x, received %#x", testCase.AttestationData.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.AttestationData.Value) {
|
||||
p := ðpb.AttestationData{}
|
||||
if err := testutil.ConvertToPb(testCase.AttestationData.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.AttestationData.Root) {
|
||||
t.Errorf("Expected attestation data %#x, received %#x", testCase.AttestationData.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.AttestationDataAndCustodyBit.Value) {
|
||||
p := &pb.AttestationDataAndCustodyBit{}
|
||||
if err := testutil.ConvertToPb(testCase.AttestationDataAndCustodyBit.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.AttestationDataAndCustodyBit.Root) {
|
||||
t.Errorf("Expected attestation data and custody bit %#x, received %#x", testCase.AttestationDataAndCustodyBit.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.AttesterSlashing.Value) {
|
||||
p := ðpb.AttesterSlashing{}
|
||||
if err := testutil.ConvertToPb(testCase.AttesterSlashing.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.AttesterSlashing.Root) {
|
||||
t.Errorf("Expected attester slashing bit %#x, received %#x", testCase.AttesterSlashing.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconBlock.Value) {
|
||||
p := ðpb.BeaconBlock{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconBlock.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlock.Root) {
|
||||
t.Errorf("Expected beacon block root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlock.SigningRoot) {
|
||||
t.Errorf("Expected beacon block signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconBlockBody.Value) {
|
||||
p := ðpb.BeaconBlockBody{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconBlockBody.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlockBody.Root) {
|
||||
t.Errorf("Expected beacon block body %#x, received %#x", testCase.BeaconBlockBody.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconBlockHeader.Value) {
|
||||
p := ðpb.BeaconBlockHeader{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconBlockHeader.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlockHeader.Root) {
|
||||
t.Errorf("Expected beacon block header root %#x, received %#x", testCase.BeaconBlockHeader.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconBlockHeader.SigningRoot) {
|
||||
t.Errorf("Expected beacon block header signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.BeaconState.Value) {
|
||||
p := &pb.BeaconState{}
|
||||
if err := testutil.ConvertToPb(testCase.BeaconState.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.BeaconState.Root) {
|
||||
t.Errorf("Expected beacon state %#x, received %#x", testCase.BeaconState.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Crosslink.Value) {
|
||||
c := ðpb.Crosslink{}
|
||||
if err := testutil.ConvertToPb(testCase.Crosslink.Value, c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Crosslink.Root) {
|
||||
t.Errorf("Expected crosslink %#x, received %#x", testCase.Crosslink.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Deposit.Value) {
|
||||
p := ðpb.Deposit{}
|
||||
if err := testutil.ConvertToPb(testCase.Deposit.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Deposit.Root) {
|
||||
t.Errorf("Expected deposit root %#x, received %#x", testCase.Deposit.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.DepositData.Value) {
|
||||
p := ðpb.Deposit_Data{}
|
||||
if err := testutil.ConvertToPb(testCase.DepositData.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.DepositData.Root) {
|
||||
t.Errorf("Expected deposit data root %#x, received %#x", testCase.DepositData.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.DepositData.SigningRoot) {
|
||||
t.Errorf("Expected deposit data signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Eth1Data.Value) {
|
||||
p := ðpb.Eth1Data{}
|
||||
if err := testutil.ConvertToPb(testCase.Eth1Data.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Eth1Data.Root) {
|
||||
t.Errorf("Expected pb data %#x, received %#x", testCase.Eth1Data.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Fork.Value) {
|
||||
p := &pb.Fork{}
|
||||
if err := testutil.ConvertToPb(testCase.Fork.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Fork.Root) {
|
||||
t.Errorf("Expected fork %#x, received %#x", testCase.Fork.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.HistoricalBatch.Value) {
|
||||
p := &pb.HistoricalBatch{}
|
||||
if err := testutil.ConvertToPb(testCase.HistoricalBatch.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.HistoricalBatch.Root) {
|
||||
t.Errorf("Expected historical batch %#x, received %#x", testCase.HistoricalBatch.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.IndexedAttestation.Value) {
|
||||
p := ðpb.IndexedAttestation{}
|
||||
if err := testutil.ConvertToPb(testCase.IndexedAttestation.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.IndexedAttestation.Root) {
|
||||
t.Errorf("Expected indexed attestation root %#x, received %#x", testCase.IndexedAttestation.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.IndexedAttestation.SigningRoot) {
|
||||
t.Errorf("Expected indexed attestation signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.PendingAttestation.Value) {
|
||||
p := &pb.PendingAttestation{}
|
||||
if err := testutil.ConvertToPb(testCase.PendingAttestation.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.PendingAttestation.Root) {
|
||||
t.Errorf("Expected pending attestation %#x, received %#x", testCase.PendingAttestation.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.ProposerSlashing.Value) {
|
||||
p := ðpb.ProposerSlashing{}
|
||||
if err := testutil.ConvertToPb(testCase.ProposerSlashing.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.ProposerSlashing.Root) {
|
||||
t.Errorf("Expected proposer slashing %#x, received %#x", testCase.ProposerSlashing.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Transfer.Value) {
|
||||
p := ðpb.Transfer{}
|
||||
if err := testutil.ConvertToPb(testCase.Transfer.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Transfer.Root) {
|
||||
t.Errorf("Expected transfer root %#x, received %#x", testCase.Transfer.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Transfer.SigningRoot) {
|
||||
t.Errorf("Expected transfer signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.Validator.Value) {
|
||||
p := ðpb.Validator{}
|
||||
if err := testutil.ConvertToPb(testCase.Validator.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.Validator.Root) {
|
||||
t.Errorf("Expected validator %#x, received %#x", testCase.Validator.Root, root[:])
|
||||
}
|
||||
}
|
||||
if !testutil.IsEmpty(testCase.VoluntaryExit.Value) {
|
||||
p := ðpb.VoluntaryExit{}
|
||||
if err := testutil.ConvertToPb(testCase.VoluntaryExit.Value, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := ssz.HashTreeRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.VoluntaryExit.Root) {
|
||||
t.Errorf("Expected voluntary exit root %#x, received %#x", testCase.VoluntaryExit.Root, root[:])
|
||||
}
|
||||
root, err = ssz.SigningRoot(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], testCase.VoluntaryExit.SigningRoot) {
|
||||
t.Errorf("Expected voluntary exit signing root %#x, received %#x", testCase.BeaconBlock.Root, root[:])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
proto/testing/ssz_static_mainnet_test.go
Normal file
9
proto/testing/ssz_static_mainnet_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSZZStatic_Mainnet(t *testing.T) {
|
||||
runSSZStaticTests(t, "mainnet")
|
||||
}
|
||||
9
proto/testing/ssz_static_minimal_test.go
Normal file
9
proto/testing/ssz_static_minimal_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSSZStatic_Minimal(t *testing.T) {
|
||||
runSSZStaticTests(t, "minimal")
|
||||
}
|
||||
144
proto/testing/ssz_static_test.go
Normal file
144
proto/testing/ssz_static_test.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
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"
|
||||
)
|
||||
|
||||
// SSZRoots --
|
||||
type SSZRoots struct {
|
||||
Root string `json:"root"`
|
||||
SigningRoot string `json:"signing_root"`
|
||||
}
|
||||
|
||||
func runSSZStaticTests(t *testing.T, config string) {
|
||||
if err := spectest.SetConfig(config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testFolders, _ := testutil.TestFolders(t, config, "ssz_static")
|
||||
for _, folder := range testFolders {
|
||||
innerPath := path.Join("ssz_static", folder.Name(), "ssz_random")
|
||||
innerTestFolders, innerTestsFolderPath := testutil.TestFolders(t, config, innerPath)
|
||||
|
||||
for _, innerFolder := range innerTestFolders {
|
||||
t.Run(path.Join(folder.Name(), innerFolder.Name()), func(t *testing.T) {
|
||||
serializedBytes, err := testutil.BazelFileBytes(innerTestsFolderPath, innerFolder.Name(), "serialized.ssz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
object, err := UnmarshalledSSZ(serializedBytes, folder.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Could not unmarshall serialized SSZ: %v", err)
|
||||
}
|
||||
|
||||
rootsYamlFile, err := testutil.BazelFileBytes(innerTestsFolderPath, innerFolder.Name(), "roots.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rootsYaml := &SSZRoots{}
|
||||
if err := testutil.UnmarshalYaml(rootsYamlFile, rootsYaml); err != nil {
|
||||
t.Fatalf("Failed to Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
root, err := ssz.HashTreeRoot(object)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rootBytes, err := hex.DecodeString(rootsYaml.Root[2:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(root[:], rootBytes) {
|
||||
t.Fatalf(
|
||||
"Did not receive expected hash tree root, received: %#x, expected: %#x",
|
||||
root[:],
|
||||
rootBytes,
|
||||
)
|
||||
}
|
||||
|
||||
if rootsYaml.SigningRoot == "" {
|
||||
return
|
||||
}
|
||||
signingRoot, err := ssz.SigningRoot(object)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
signingRootBytes, err := hex.DecodeString(rootsYaml.SigningRoot[2:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(signingRoot[:], signingRootBytes) {
|
||||
t.Fatalf(
|
||||
"Did not receive expected signing root, received: %#x, expected: %#x",
|
||||
signingRoot[:],
|
||||
signingRootBytes,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalledSSZ(serializedBytes []byte, folderName string) (interface{}, error) {
|
||||
var obj interface{}
|
||||
switch folderName {
|
||||
case "Attestation":
|
||||
obj = ðpb.Attestation{}
|
||||
case "AttestationData":
|
||||
obj = ðpb.AttestationData{}
|
||||
case "AttestationDataAndCustodyBit":
|
||||
obj = &pb.AttestationDataAndCustodyBit{}
|
||||
case "AttesterSlashing":
|
||||
obj = ðpb.AttesterSlashing{}
|
||||
case "BeaconBlock":
|
||||
obj = ðpb.BeaconBlock{}
|
||||
case "BeaconBlockBody":
|
||||
obj = ðpb.BeaconBlockBody{}
|
||||
case "BeaconBlockHeader":
|
||||
obj = ðpb.BeaconBlockHeader{}
|
||||
case "BeaconState":
|
||||
obj = &pb.BeaconState{}
|
||||
case "Checkpoint":
|
||||
obj = ðpb.Checkpoint{}
|
||||
case "CompactCommittee":
|
||||
obj = &pb.CompactCommittee{}
|
||||
case "Crosslink":
|
||||
obj = ðpb.Crosslink{}
|
||||
case "Deposit":
|
||||
obj = ðpb.Deposit{}
|
||||
case "DepositData":
|
||||
obj = ðpb.Deposit_Data{}
|
||||
case "Eth1Data":
|
||||
obj = ðpb.Eth1Data{}
|
||||
case "Fork":
|
||||
obj = &pb.Fork{}
|
||||
case "HistoricalBatch":
|
||||
obj = &pb.HistoricalBatch{}
|
||||
case "IndexedAttestation":
|
||||
obj = ðpb.IndexedAttestation{}
|
||||
case "PendingAttestation":
|
||||
obj = &pb.PendingAttestation{}
|
||||
case "ProposerSlashing":
|
||||
obj = ðpb.ProposerSlashing{}
|
||||
case "Transfer":
|
||||
obj = ðpb.Transfer{}
|
||||
case "Validator":
|
||||
obj = ðpb.Validator{}
|
||||
case "VoluntaryExit":
|
||||
obj = ðpb.VoluntaryExit{}
|
||||
default:
|
||||
return nil, errors.New("type not found")
|
||||
}
|
||||
err := ssz.Unmarshal(serializedBytes, obj)
|
||||
return obj, err
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (s *SecretKey) PublicKey() *PublicKey {
|
||||
// Sign a message using a secret key - in a beacon/validator client,
|
||||
func (s *SecretKey) Sign(msg []byte, domain uint64) *Signature {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, domain)
|
||||
binary.LittleEndian.PutUint64(b, domain)
|
||||
sig := g1.SignWithDomain(bytesutil.ToBytes32(msg), s.val, bytesutil.ToBytes8(b))
|
||||
return &Signature{val: sig}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ func (p *PublicKey) Aggregate(p2 *PublicKey) *PublicKey {
|
||||
// Verify a bls signature given a public key, a message, and a domain.
|
||||
func (s *Signature) Verify(msg []byte, pub *PublicKey, domain uint64) bool {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, domain)
|
||||
binary.LittleEndian.PutUint64(b, domain)
|
||||
return g1.VerifyWithDomain(bytesutil.ToBytes32(msg), pub.val, s.val, bytesutil.ToBytes8(b))
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func (s *Signature) VerifyAggregate(pubKeys []*PublicKey, msg [][32]byte, domain
|
||||
keys = append(keys, v.val)
|
||||
}
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, domain)
|
||||
binary.LittleEndian.PutUint64(b, domain)
|
||||
return s.val.VerifyAggregateWithDomain(keys, msg, bytesutil.ToBytes8(b))
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ func (s *Signature) VerifyAggregateCommon(pubKeys []*PublicKey, msg []byte, doma
|
||||
keys = append(keys, v.val)
|
||||
}
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, domain)
|
||||
binary.LittleEndian.PutUint64(b, domain)
|
||||
return s.val.VerifyAggregateCommonWithDomain(keys, bytesutil.ToBytes32(msg), bytesutil.ToBytes8(b))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ go_library(
|
||||
srcs = [
|
||||
"aggregate_pubkeys_test.yaml.go",
|
||||
"aggregate_sigs_test.yaml.go",
|
||||
"g2_compressed_test.yaml.go",
|
||||
"g2_uncompressed_test.yaml.go",
|
||||
"msg_hash_compressed_test.yaml.go",
|
||||
"msg_hash_uncompressed_test.yaml.go",
|
||||
"priv_to_pub_test.yaml.go",
|
||||
"sign_message_test.yaml.go",
|
||||
"sign_msg_test.yaml.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/shared/bls/spectest",
|
||||
visibility = ["//visibility:public"],
|
||||
@@ -21,20 +21,21 @@ go_test(
|
||||
srcs = [
|
||||
"aggregate_pubkeys_test.go",
|
||||
"aggregate_sigs_test.go",
|
||||
"g2_compressed_test.go",
|
||||
"g2_uncompressed_test.go",
|
||||
"helper_test.go",
|
||||
"msg_hash_compressed_test.go",
|
||||
"msg_hash_uncompressed_test.go",
|
||||
"priv_to_pub_test.go",
|
||||
"sign_message_test.go",
|
||||
"sign_msg_test.go",
|
||||
],
|
||||
data = [
|
||||
"@eth2_spec_tests_general//:test_data",
|
||||
],
|
||||
data = ["@eth2_spec_tests//:test_data"],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//shared/bls:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_ghodss_yaml//:go_default_library",
|
||||
"@com_github_phoreproject_bls//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -2,15 +2,17 @@ package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
)
|
||||
|
||||
func TestAggregatePubkeysYaml(t *testing.T) {
|
||||
file, err := loadBlsYaml("aggregate_pubkeys/aggregate_pubkeys.yaml")
|
||||
file, err := testutil.BazelFileBytes("tests/general/phase0/bls/aggregate_pubkeys/small/agg_pub_keys/data.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
@@ -20,24 +22,32 @@ func TestAggregatePubkeysYaml(t *testing.T) {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
for i, tt := range test.TestCases {
|
||||
t.Run(fmt.Sprintf("Test %d", i), func(t *testing.T) {
|
||||
pk, err := bls.PublicKeyFromBytes(tt.Input[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, pk2 := range tt.Input[1:] {
|
||||
p, err := bls.PublicKeyFromBytes(pk2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pk.Aggregate(p)
|
||||
}
|
||||
pubBytes, err := hex.DecodeString(test.Input[0][2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
pk, err := bls.PublicKeyFromBytes(pubBytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, pk2 := range test.Input[1:] {
|
||||
pubBytes2, err := hex.DecodeString(pk2[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
p, err := bls.PublicKeyFromBytes(pubBytes2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pk.Aggregate(p)
|
||||
}
|
||||
|
||||
if !bytes.Equal(tt.Output, pk.Marshal()) {
|
||||
t.Fatal("Output does not equal marshaled aggregated public " +
|
||||
"key bytes")
|
||||
}
|
||||
})
|
||||
outputBytes, err := hex.DecodeString(test.Output[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
if !bytes.Equal(outputBytes, pk.Marshal()) {
|
||||
t.Fatal("Output does not equal marshaled aggregated public " +
|
||||
"key bytes")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,6 @@
|
||||
package spectest
|
||||
|
||||
type AggregatePubkeysTest 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 {
|
||||
Input [][]byte `json:"input"`
|
||||
Output []byte `json:"output" ssz:"size=48"`
|
||||
} `json:"test_cases"`
|
||||
Input []string `json:"input"`
|
||||
Output string `json:"output" ssz:"size=48"`
|
||||
}
|
||||
|
||||
@@ -2,37 +2,49 @@ package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"encoding/hex"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestAggregateSignaturesYaml(t *testing.T) {
|
||||
file, err := loadBlsYaml("aggregate_sigs/aggregate_sigs.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
testFolders, testFolderPath := testutil.TestFolders(t, "general", "bls/aggregate_sigs/small")
|
||||
|
||||
test := &AggregateSigsTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
file, err := testutil.BazelFileBytes(path.Join(testFolderPath, folder.Name(), "data.yaml"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
test := &AggregateSigsTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
for i, tt := range test.TestCases {
|
||||
t.Run(fmt.Sprintf("Test %d", i), func(t *testing.T) {
|
||||
var sigs []*bls.Signature
|
||||
for _, s := range tt.Input {
|
||||
sig, err := bls.SignatureFromBytes(s)
|
||||
for _, s := range test.Input {
|
||||
sigBytes, err := hex.DecodeString(s[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
sig, err := bls.SignatureFromBytes(sigBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to unmarshal signature from bytes: %v", err)
|
||||
}
|
||||
sigs = append(sigs, sig)
|
||||
}
|
||||
sig := bls.AggregateSignatures(sigs)
|
||||
if !bytes.Equal(tt.Output, sig.Marshal()) {
|
||||
|
||||
outputBytes, err := hex.DecodeString(test.Output[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
if !bytes.Equal(outputBytes, sig.Marshal()) {
|
||||
t.Fatal("Output does not equal marshaled aggregated sig bytes")
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,15 +4,6 @@
|
||||
package spectest
|
||||
|
||||
type AggregateSigsTest 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 {
|
||||
Input [][]byte `json:"input"`
|
||||
Output []byte `json:"output" ssz:"size=96"`
|
||||
} `json:"test_cases"`
|
||||
Input []string `json:"input"`
|
||||
Output string `json:"output" ssz:"size=96"`
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/phoreproject/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
)
|
||||
|
||||
// Note: This actually tests the underlying library as we don't have a need for
|
||||
// HashG2Compressed in our local BLS API.
|
||||
func TestG2CompressedHash(t *testing.T) {
|
||||
file, err := loadBlsYaml("msg_hash_g2_compressed/g2_compressed.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
test := &G2CompressedTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
for i, tt := range test.TestCases {
|
||||
t.Run(fmt.Sprintf("Test %d", i), func(t *testing.T) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, tt.Input.Domain)
|
||||
|
||||
projective := bls.HashG2WithDomain(
|
||||
bytesutil.ToBytes32(tt.Input.Message),
|
||||
bytesutil.ToBytes8(b),
|
||||
)
|
||||
hash := bls.CompressG2(projective.ToAffine())
|
||||
|
||||
var buf []byte
|
||||
for _, slice := range tt.Output {
|
||||
buf = append(buf, slice...)
|
||||
}
|
||||
if !bytes.Equal(buf, hash[:]) {
|
||||
t.Logf("Domain=%d", tt.Input.Domain)
|
||||
t.Fatalf("Hash does not match the expected output. "+
|
||||
"Expected %#x but received %#x", buf, hash)
|
||||
}
|
||||
t.Logf("Success. Domain=%d", tt.Input.Domain)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: g2_compressed.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
type G2CompressedTest 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 {
|
||||
Input struct {
|
||||
Message []byte `json:"message" ssz:"size=32"`
|
||||
Domain uint64 `json:"domain"`
|
||||
} `json:"input"`
|
||||
Output [][]byte `json:"output"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/phoreproject/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
)
|
||||
|
||||
// Note: This actually tests the underlying library as we don't have a need for
|
||||
// HashG2Uncompressed in our local BLS API.
|
||||
func TestG2UncompressedHash(t *testing.T) {
|
||||
t.Skip("The python uncompressed method does not match the go uncompressed method and this isn't very important")
|
||||
file, err := loadBlsYaml("msg_hash_g2_uncompressed/g2_uncompressed.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
test := &G2UncompressedTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
for i, tt := range test.TestCases {
|
||||
t.Run(fmt.Sprintf("Test %d", i), func(t *testing.T) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, tt.Input.Domain)
|
||||
|
||||
projective := bls.HashG2WithDomain(
|
||||
bytesutil.ToBytes32(tt.Input.Message),
|
||||
bytesutil.ToBytes8(b),
|
||||
)
|
||||
hash := projective.ToAffine().SerializeBytes()
|
||||
|
||||
var buf []byte
|
||||
for _, slice := range tt.Output {
|
||||
for _, innerSlice := range slice {
|
||||
buf = append(buf, innerSlice...)
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(buf, hash[:]) {
|
||||
t.Logf("Domain=%d", tt.Input.Domain)
|
||||
t.Fatalf("Hash does not match the expected output. "+
|
||||
"Expected %#x but received %#x", buf, hash)
|
||||
}
|
||||
t.Logf("Success. Domain=%d", tt.Input.Domain)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: g2_uncompressed.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
type G2UncompressedTest 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 {
|
||||
Input struct {
|
||||
Message []byte `json:"message" ssz:"size=32"`
|
||||
Domain uint64 `json:"domain"`
|
||||
} `json:"input"`
|
||||
Output [][][]byte `json:"output"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
)
|
||||
|
||||
const prefix = "tests/bls/"
|
||||
|
||||
// Load BLS yaml from spec test bls directory. The file parameter should be in
|
||||
// the format of the path starting at the bls directory.
|
||||
// Example: aggregate_pubkeys/aggregate_pubkeys.yaml where the full path would
|
||||
// be tests/bls/aggregate_pubkeys/aggregate_pubkeys.yaml.
|
||||
func loadBlsYaml(file string) ([]byte, error) {
|
||||
filepath, err := bazel.Runfile(prefix + file)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return ioutil.ReadFile(filepath)
|
||||
}
|
||||
61
shared/bls/spectest/msg_hash_compressed_test.go
Normal file
61
shared/bls/spectest/msg_hash_compressed_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/phoreproject/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
// Note: This actually tests the underlying library as we don't have a need for
|
||||
// HashG2Compressed in our local BLS API.
|
||||
func TestMsgHashCompressed(t *testing.T) {
|
||||
testFolders, testFolderPath := testutil.TestFolders(t, "general", "bls/msg_hash_compressed/small")
|
||||
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
file, err := testutil.BazelFileBytes(path.Join(testFolderPath, folder.Name(), "data.yaml"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
test := &MsgHashCompressedTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
msgBytes, err := hex.DecodeString(test.Input.Message[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
domain, err := hex.DecodeString(test.Input.Domain[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
projective := bls.HashG2WithDomain(
|
||||
bytesutil.ToBytes32(msgBytes),
|
||||
bytesutil.ToBytes8(domain),
|
||||
)
|
||||
hash := bls.CompressG2(projective.ToAffine())
|
||||
|
||||
var buf []byte
|
||||
for _, innerString := range test.Output {
|
||||
slice, err := hex.DecodeString(innerString[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
buf = append(buf, slice...)
|
||||
}
|
||||
if !bytes.Equal(buf, hash[:]) {
|
||||
t.Logf("Domain=%d", domain)
|
||||
t.Fatalf("Hash does not match the expected output. "+
|
||||
"Expected %#x but received %#x", buf, hash)
|
||||
}
|
||||
t.Logf("Success. Domain=%d", domain)
|
||||
})
|
||||
}
|
||||
}
|
||||
12
shared/bls/spectest/msg_hash_compressed_test.yaml.go
Normal file
12
shared/bls/spectest/msg_hash_compressed_test.yaml.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: g2_compressed.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
type MsgHashCompressedTest struct {
|
||||
Input struct {
|
||||
Message string `json:"message"`
|
||||
Domain string `json:"domain"`
|
||||
} `json:"input"`
|
||||
Output []string `json:"output"`
|
||||
}
|
||||
65
shared/bls/spectest/msg_hash_uncompressed_test.go
Normal file
65
shared/bls/spectest/msg_hash_uncompressed_test.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/phoreproject/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
// Note: This actually tests the underlying library as we don't have a need for
|
||||
// HashG2Uncompressed in our local BLS API.
|
||||
func TestMsgHashUncompressed(t *testing.T) {
|
||||
t.Skip("The python uncompressed method does not match the go uncompressed method and this isn't very important")
|
||||
testFolders, testFolderPath := testutil.TestFolders(t, "general", "bls/msg_hash_uncompressed/small")
|
||||
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
file, err := testutil.BazelFileBytes(path.Join(testFolderPath, folder.Name(), "data.yaml"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
test := &MsgHashUncompressedTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
domain, err := hex.DecodeString(test.Input.Domain[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
msgBytes, err := hex.DecodeString(test.Input.Message[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
projective := bls.HashG2WithDomain(
|
||||
bytesutil.ToBytes32(msgBytes),
|
||||
bytesutil.ToBytes8(domain),
|
||||
)
|
||||
hash := projective.ToAffine().SerializeBytes()
|
||||
|
||||
var buf []byte
|
||||
for _, outputStrings := range test.Output {
|
||||
for _, innerString := range outputStrings {
|
||||
slice, err := hex.DecodeString(innerString[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
buf = append(buf, slice...)
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(buf, hash[:]) {
|
||||
t.Logf("Domain=%d", domain)
|
||||
t.Logf("Message=%#x", msgBytes)
|
||||
t.Fatalf("Hash does not match the expected output. "+
|
||||
"Expected %#x but received %#x", buf, hash)
|
||||
}
|
||||
t.Logf("Success. Domain=%d", domain)
|
||||
})
|
||||
}
|
||||
}
|
||||
12
shared/bls/spectest/msg_hash_uncompressed_test.yaml.go
Normal file
12
shared/bls/spectest/msg_hash_uncompressed_test.yaml.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: g2_uncompressed.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
type MsgHashUncompressedTest struct {
|
||||
Input struct {
|
||||
Message string `json:"message"`
|
||||
Domain string `json:"domain"`
|
||||
} `json:"input"`
|
||||
Output [][]string `json:"output"`
|
||||
}
|
||||
@@ -2,31 +2,43 @@ package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"encoding/hex"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestPrivToPubYaml(t *testing.T) {
|
||||
file, err := loadBlsYaml("priv_to_pub/priv_to_pub.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
testFolders, testFolderPath := testutil.TestFolders(t, "general", "bls/priv_to_pub/small")
|
||||
|
||||
test := &PrivToPubTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
file, err := testutil.BazelFileBytes(path.Join(testFolderPath, folder.Name(), "data.yaml"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
test := &PrivToPubTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
for i, tt := range test.TestCases {
|
||||
t.Run(fmt.Sprintf("Test %d", i), func(t *testing.T) {
|
||||
sk, err := bls.SecretKeyFromBytes(tt.Input)
|
||||
pkBytes, err := hex.DecodeString(test.Input[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
sk, err := bls.SecretKeyFromBytes(pkBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot unmarshal input to secret key: %v", err)
|
||||
}
|
||||
if !bytes.Equal(tt.Output, sk.PublicKey().Marshal()) {
|
||||
|
||||
outputBytes, err := hex.DecodeString(test.Output[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
if !bytes.Equal(outputBytes, sk.PublicKey().Marshal()) {
|
||||
t.Fatal("Output does not marshaled public key bytes")
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,15 +4,6 @@
|
||||
package spectest
|
||||
|
||||
type PrivToPubTest 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 {
|
||||
Input []byte `json:"input" ssz:"size=32"`
|
||||
Output []byte `json:"output" ssz:"size=48"`
|
||||
} `json:"test_cases"`
|
||||
Input string `json:"input"`
|
||||
Output string `json:"output"`
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
)
|
||||
|
||||
func TestSignMessageYaml(t *testing.T) {
|
||||
file, err := loadBlsYaml("sign_msg/sign_msg.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
test := &SignMessageTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
for i, tt := range test.TestCases {
|
||||
t.Run(fmt.Sprintf("Test %d", i), func(t *testing.T) {
|
||||
sk, err := bls.SecretKeyFromBytes(tt.Input.Privkey)
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot unmarshal input to secret key: %v", err)
|
||||
}
|
||||
|
||||
sig := sk.Sign(tt.Input.Message, tt.Input.Domain)
|
||||
if !bytes.Equal(tt.Output, sig.Marshal()) {
|
||||
t.Logf("Domain=%d", tt.Input.Domain)
|
||||
t.Fatalf("Signature does not match the expected output. "+
|
||||
"Expected %#x but received %#x", tt.Output, sig.Marshal())
|
||||
}
|
||||
t.Logf("Success. Domain=%d", tt.Input.Domain)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: sign_msg.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
type SignMessageTest 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 {
|
||||
Input struct {
|
||||
Privkey []byte `json:"privkey" ssz:"size=32"`
|
||||
Message []byte `json:"message" ssz:"size=32"`
|
||||
Domain uint64 `json:"domain"`
|
||||
} `json:"input"`
|
||||
Output []byte `json:"output" ssz:"size=96"`
|
||||
} `json:"test_cases"`
|
||||
}
|
||||
61
shared/bls/spectest/sign_msg_test.go
Normal file
61
shared/bls/spectest/sign_msg_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestSignMessageYaml(t *testing.T) {
|
||||
testFolders, testFolderPath := testutil.TestFolders(t, "general", "bls/sign_msg/small")
|
||||
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
file, err := testutil.BazelFileBytes(path.Join(testFolderPath, folder.Name(), "data.yaml"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
test := &SignMsgTest{}
|
||||
if err := yaml.Unmarshal(file, test); err != nil {
|
||||
t.Fatalf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
pkBytes, err := hex.DecodeString(test.Input.Privkey[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
sk, err := bls.SecretKeyFromBytes(pkBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot unmarshal input to secret key: %v", err)
|
||||
}
|
||||
|
||||
msgBytes, err := hex.DecodeString(test.Input.Message[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
domain, err := hex.DecodeString(test.Input.Domain[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
num := binary.LittleEndian.Uint64(domain)
|
||||
sig := sk.Sign(msgBytes, num)
|
||||
|
||||
outputBytes, err := hex.DecodeString(test.Output[2:])
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot decode string to bytes: %v", err)
|
||||
}
|
||||
if !bytes.Equal(outputBytes, sig.Marshal()) {
|
||||
t.Logf("Domain=%d", domain)
|
||||
t.Fatalf("Signature does not match the expected output. "+
|
||||
"Expected %#x but received %#x", outputBytes, sig.Marshal())
|
||||
}
|
||||
t.Logf("Success. Domain=%d", domain)
|
||||
})
|
||||
}
|
||||
}
|
||||
13
shared/bls/spectest/sign_msg_test.yaml.go
Normal file
13
shared/bls/spectest/sign_msg_test.yaml.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// Code generated by yaml_to_go. DO NOT EDIT.
|
||||
// source: sign_msg.yaml
|
||||
|
||||
package spectest
|
||||
|
||||
type SignMsgTest struct {
|
||||
Input struct {
|
||||
Privkey string `json:"privkey"`
|
||||
Message string `json:"message"`
|
||||
Domain string `json:"domain"`
|
||||
} `json:"input"`
|
||||
Output string `json:"output"`
|
||||
}
|
||||
@@ -241,55 +241,70 @@ func DemoBeaconConfig() *BeaconChainConfig {
|
||||
// MinimalSpecConfig retrieves the minimal config used in spec tests.
|
||||
func MinimalSpecConfig() *BeaconChainConfig {
|
||||
minimalConfig := *defaultBeaconConfig
|
||||
// Misc
|
||||
minimalConfig.ShardCount = 8
|
||||
minimalConfig.TargetCommitteeSize = 4
|
||||
minimalConfig.MaxValidatorsPerCommittee = 4096
|
||||
minimalConfig.MinPerEpochChurnLimit = 4
|
||||
minimalConfig.ChurnLimitQuotient = 65536
|
||||
minimalConfig.BaseRewardsPerEpoch = 5
|
||||
minimalConfig.ShuffleRoundCount = 10
|
||||
minimalConfig.MinGenesisActiveValidatorCount = 64
|
||||
minimalConfig.DepositContractTreeDepth = 32
|
||||
minimalConfig.MinGenesisTime = 1578009600
|
||||
|
||||
// Gwei values
|
||||
minimalConfig.MinDepositAmount = 1e9
|
||||
minimalConfig.MaxEffectiveBalance = 32e9
|
||||
minimalConfig.EjectionBalance = 16e9
|
||||
minimalConfig.EffectiveBalanceIncrement = 1e9
|
||||
minimalConfig.FarFutureEpoch = 1<<64 - 1
|
||||
|
||||
// Initial values
|
||||
minimalConfig.BLSWithdrawalPrefixByte = byte(0)
|
||||
|
||||
// Time parameters
|
||||
minimalConfig.SecondsPerSlot = 6
|
||||
minimalConfig.MinAttestationInclusionDelay = 1
|
||||
minimalConfig.SlotsPerEpoch = 8
|
||||
minimalConfig.MinSeedLookahead = 1
|
||||
minimalConfig.ActivationExitDelay = 4
|
||||
minimalConfig.SlotsPerEth1VotingPeriod = 16
|
||||
minimalConfig.HistoricalRootsLimit = 64
|
||||
minimalConfig.SlotsPerHistoricalRoot = 64
|
||||
minimalConfig.MinValidatorWithdrawabilityDelay = 256
|
||||
minimalConfig.PersistentCommitteePeriod = 2048
|
||||
minimalConfig.MaxEpochsPerCrosslink = 4
|
||||
minimalConfig.MinEpochsToInactivityPenalty = 4
|
||||
|
||||
// State vector lengths
|
||||
minimalConfig.EpochsPerHistoricalVector = 64
|
||||
minimalConfig.EpochsPerSlashingsVector = 64
|
||||
minimalConfig.HistoricalRootsLimit = 16777216
|
||||
minimalConfig.ValidatorRegistryLimit = 1099511627776
|
||||
|
||||
// Reward and penalty quotients
|
||||
minimalConfig.BaseRewardFactor = 64
|
||||
minimalConfig.WhistleBlowerRewardQuotient = 512
|
||||
minimalConfig.ProposerRewardQuotient = 8
|
||||
minimalConfig.InactivityPenaltyQuotient = 33554432
|
||||
minimalConfig.MinSlashingPenaltyQuotient = 32
|
||||
minimalConfig.BaseRewardsPerEpoch = 5
|
||||
|
||||
// Max operations per block
|
||||
minimalConfig.MaxProposerSlashings = 16
|
||||
minimalConfig.MaxAttesterSlashings = 1
|
||||
minimalConfig.MaxAttestations = 128
|
||||
minimalConfig.MaxDeposits = 16
|
||||
minimalConfig.MaxVoluntaryExits = 16
|
||||
minimalConfig.MaxTransfers = 0
|
||||
|
||||
// Signature domains
|
||||
minimalConfig.DomainBeaconProposer = bytesutil.Bytes4(0)
|
||||
minimalConfig.DomainRandao = bytesutil.Bytes4(1)
|
||||
minimalConfig.DomainAttestation = bytesutil.Bytes4(2)
|
||||
minimalConfig.DomainDeposit = bytesutil.Bytes4(3)
|
||||
minimalConfig.DomainVoluntaryExit = bytesutil.Bytes4(4)
|
||||
minimalConfig.DomainTransfer = bytesutil.Bytes4(5)
|
||||
minimalConfig.MinGenesisTime = 1578009600
|
||||
|
||||
minimalConfig.DepositContractTreeDepth = 32
|
||||
minimalConfig.FarFutureEpoch = 1<<64 - 1
|
||||
return &minimalConfig
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ go_library(
|
||||
"json_to_pb_converter.go",
|
||||
"log.go",
|
||||
"random_bytes.go",
|
||||
"spectest.go",
|
||||
"tempdir.go",
|
||||
"wait_timeout.go",
|
||||
],
|
||||
@@ -28,6 +29,8 @@ go_library(
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
171
shared/testutil/spectest.go
Normal file
171
shared/testutil/spectest.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"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/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
type blockOperation func(*pb.BeaconState, *ethpb.BeaconBlockBody) (*pb.BeaconState, error)
|
||||
type epochOperation func(*testing.T, *pb.BeaconState) (*pb.BeaconState, error)
|
||||
|
||||
// TestFolders sets the proper config and returns the result of ReadDir
|
||||
// on the passed in eth2-spec-tests directory along with its path.
|
||||
func TestFolders(t *testing.T, config string, folderPath string) ([]os.FileInfo, string) {
|
||||
if config == "minimal" {
|
||||
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")
|
||||
}
|
||||
testsFolderPath := path.Join("tests", config, "phase0", folderPath)
|
||||
filepath, err := bazel.Runfile(testsFolderPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testFolders, err := ioutil.ReadDir(filepath)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file: %v", err)
|
||||
}
|
||||
|
||||
return testFolders, testsFolderPath
|
||||
}
|
||||
|
||||
// BazelFileBytes returns the byte array of the bazel file path given.
|
||||
func BazelFileBytes(filePaths ...string) ([]byte, error) {
|
||||
filepath, err := bazel.Runfile(path.Join(filePaths...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileBytes, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fileBytes, nil
|
||||
}
|
||||
|
||||
// RunBlockOperationTest takes in the prestate and the beacon block body, processes it through the
|
||||
// passed in block operation function and checks the post state with the expected post state.
|
||||
func RunBlockOperationTest(
|
||||
t *testing.T,
|
||||
folderPath string,
|
||||
body *ethpb.BeaconBlockBody,
|
||||
operationFn blockOperation,
|
||||
) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
preBeaconStateFile, err := BazelFileBytes(path.Join(folderPath, "pre.ssz"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
preState := &pb.BeaconState{}
|
||||
if err := ssz.Unmarshal(preBeaconStateFile, preState); 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(folderPath, "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 := operationFn(preState, body)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// RunEpochOperationTest takes in the prestate and processes it through the
|
||||
// passed in epoch operation function and checks the post state with the expected post state.
|
||||
func RunEpochOperationTest(
|
||||
t *testing.T,
|
||||
testFolderPath string,
|
||||
operationFn epochOperation,
|
||||
) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
preBeaconStateFile, err := BazelFileBytes(path.Join(testFolderPath, "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(testFolderPath, "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 := operationFn(t, preBeaconState)
|
||||
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
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user