github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/state/transition_test.go (about)

     1  package state_test
     2  
     3  import (
     4  	"context"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"testing"
     8  
     9  	types "github.com/prysmaticlabs/eth2-types"
    10  	"github.com/prysmaticlabs/go-bitfield"
    11  	"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
    12  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    13  	"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
    14  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    15  	"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
    16  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    17  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    18  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    19  	"github.com/prysmaticlabs/prysm/shared/attestationutil"
    20  	"github.com/prysmaticlabs/prysm/shared/bls"
    21  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    22  	"github.com/prysmaticlabs/prysm/shared/hashutil"
    23  	"github.com/prysmaticlabs/prysm/shared/params"
    24  	"github.com/prysmaticlabs/prysm/shared/testutil"
    25  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    26  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    27  	"github.com/prysmaticlabs/prysm/shared/trieutil"
    28  	"github.com/sirupsen/logrus"
    29  )
    30  
    31  func init() {
    32  	state.SkipSlotCache.Disable()
    33  }
    34  
    35  func TestExecuteStateTransition_IncorrectSlot(t *testing.T) {
    36  	base := &pb.BeaconState{
    37  		Slot: 5,
    38  	}
    39  	beaconState, err := v1.InitializeFromProto(base)
    40  	require.NoError(t, err)
    41  	block := &ethpb.SignedBeaconBlock{
    42  		Block: &ethpb.BeaconBlock{
    43  			Slot: 4,
    44  			Body: &ethpb.BeaconBlockBody{},
    45  		},
    46  	}
    47  	want := "expected state.slot"
    48  	_, err = state.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
    49  	assert.ErrorContains(t, want, err)
    50  }
    51  
    52  func TestExecuteStateTransition_FullProcess(t *testing.T) {
    53  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
    54  
    55  	eth1Data := &ethpb.Eth1Data{
    56  		DepositCount: 100,
    57  		DepositRoot:  bytesutil.PadTo([]byte{2}, 32),
    58  		BlockHash:    make([]byte, 32),
    59  	}
    60  	require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch-1))
    61  	e := beaconState.Eth1Data()
    62  	e.DepositCount = 100
    63  	require.NoError(t, beaconState.SetEth1Data(e))
    64  	bh := beaconState.LatestBlockHeader()
    65  	bh.Slot = beaconState.Slot()
    66  	require.NoError(t, beaconState.SetLatestBlockHeader(bh))
    67  	require.NoError(t, beaconState.SetEth1DataVotes([]*ethpb.Eth1Data{eth1Data}))
    68  
    69  	oldMix, err := beaconState.RandaoMixAtIndex(1)
    70  	require.NoError(t, err)
    71  
    72  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()+1))
    73  	epoch := helpers.CurrentEpoch(beaconState)
    74  	randaoReveal, err := testutil.RandaoReveal(beaconState, epoch, privKeys)
    75  	require.NoError(t, err)
    76  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
    77  
    78  	nextSlotState, err := state.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1)
    79  	require.NoError(t, err)
    80  	parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
    81  	require.NoError(t, err)
    82  	proposerIdx, err := helpers.BeaconProposerIndex(nextSlotState)
    83  	require.NoError(t, err)
    84  	block := testutil.NewBeaconBlock()
    85  	block.Block.ProposerIndex = proposerIdx
    86  	block.Block.Slot = beaconState.Slot() + 1
    87  	block.Block.ParentRoot = parentRoot[:]
    88  	block.Block.Body.RandaoReveal = randaoReveal
    89  	block.Block.Body.Eth1Data = eth1Data
    90  
    91  	stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
    92  	require.NoError(t, err)
    93  
    94  	block.Block.StateRoot = stateRoot[:]
    95  
    96  	sig, err := testutil.BlockSignature(beaconState, block.Block, privKeys)
    97  	require.NoError(t, err)
    98  	block.Signature = sig.Marshal()
    99  
   100  	beaconState, err = state.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   101  	require.NoError(t, err)
   102  
   103  	assert.Equal(t, params.BeaconConfig().SlotsPerEpoch, beaconState.Slot(), "Unexpected Slot number")
   104  
   105  	mix, err := beaconState.RandaoMixAtIndex(1)
   106  	require.NoError(t, err)
   107  	assert.DeepNotEqual(t, oldMix, mix, "Did not expect new and old randao mix to equal")
   108  }
   109  
   110  func TestProcessBlock_IncorrectProposerSlashing(t *testing.T) {
   111  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
   112  
   113  	block, err := testutil.GenerateFullBlock(beaconState, privKeys, nil, 1)
   114  	require.NoError(t, err)
   115  	slashing := &ethpb.ProposerSlashing{
   116  		Header_1: testutil.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
   117  			Header: &ethpb.BeaconBlockHeader{
   118  				Slot: params.BeaconConfig().SlotsPerEpoch,
   119  			},
   120  		}),
   121  		Header_2: testutil.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
   122  			Header: &ethpb.BeaconBlockHeader{
   123  				Slot: params.BeaconConfig().SlotsPerEpoch * 2,
   124  			},
   125  		}),
   126  	}
   127  	block.Block.Body.ProposerSlashings = []*ethpb.ProposerSlashing{slashing}
   128  
   129  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()+1))
   130  	proposerIdx, err := helpers.BeaconProposerIndex(beaconState)
   131  	require.NoError(t, err)
   132  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
   133  	block.Signature, err = helpers.ComputeDomainAndSign(beaconState, helpers.CurrentEpoch(beaconState), block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
   134  	require.NoError(t, err)
   135  
   136  	beaconState, err = state.ProcessSlots(context.Background(), beaconState, 1)
   137  	require.NoError(t, err)
   138  	want := "could not verify proposer slashing"
   139  	_, err = state.ProcessBlock(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   140  	assert.ErrorContains(t, want, err)
   141  }
   142  
   143  func TestProcessBlock_IncorrectProcessBlockAttestations(t *testing.T) {
   144  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
   145  	priv, err := bls.RandKey()
   146  	require.NoError(t, err)
   147  	att := testutil.HydrateAttestation(&ethpb.Attestation{
   148  		AggregationBits: bitfield.NewBitlist(3),
   149  		Signature:       priv.Sign([]byte("foo")).Marshal(),
   150  	})
   151  
   152  	block, err := testutil.GenerateFullBlock(beaconState, privKeys, nil, 1)
   153  	require.NoError(t, err)
   154  	block.Block.Body.Attestations = []*ethpb.Attestation{att}
   155  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()+1))
   156  	proposerIdx, err := helpers.BeaconProposerIndex(beaconState)
   157  	require.NoError(t, err)
   158  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
   159  	block.Signature, err = helpers.ComputeDomainAndSign(beaconState, helpers.CurrentEpoch(beaconState), block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
   160  	require.NoError(t, err)
   161  
   162  	beaconState, err = state.ProcessSlots(context.Background(), beaconState, 1)
   163  	require.NoError(t, err)
   164  
   165  	want := "could not verify attestation"
   166  	_, err = state.ProcessBlock(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   167  	assert.ErrorContains(t, want, err)
   168  }
   169  
   170  func TestProcessBlock_IncorrectProcessExits(t *testing.T) {
   171  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   172  
   173  	proposerSlashings := []*ethpb.ProposerSlashing{
   174  		{
   175  			Header_1: testutil.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
   176  				Header: &ethpb.BeaconBlockHeader{
   177  					ProposerIndex: 3,
   178  					Slot:          1,
   179  				},
   180  				Signature: bytesutil.PadTo([]byte("A"), 96),
   181  			}),
   182  			Header_2: testutil.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
   183  				Header: &ethpb.BeaconBlockHeader{
   184  					ProposerIndex: 3,
   185  					Slot:          1,
   186  				},
   187  				Signature: bytesutil.PadTo([]byte("B"), 96),
   188  			}),
   189  		},
   190  	}
   191  	attesterSlashings := []*ethpb.AttesterSlashing{
   192  		{
   193  			Attestation_1: &ethpb.IndexedAttestation{
   194  				Data:             testutil.HydrateAttestationData(&ethpb.AttestationData{}),
   195  				AttestingIndices: []uint64{0, 1},
   196  				Signature:        make([]byte, 96),
   197  			},
   198  			Attestation_2: &ethpb.IndexedAttestation{
   199  				Data:             testutil.HydrateAttestationData(&ethpb.AttestationData{}),
   200  				AttestingIndices: []uint64{0, 1},
   201  				Signature:        make([]byte, 96),
   202  			},
   203  		},
   204  	}
   205  	var blockRoots [][]byte
   206  	for i := uint64(0); i < uint64(params.BeaconConfig().SlotsPerHistoricalRoot); i++ {
   207  		blockRoots = append(blockRoots, []byte{byte(i)})
   208  	}
   209  	require.NoError(t, beaconState.SetBlockRoots(blockRoots))
   210  	blockAtt := testutil.HydrateAttestation(&ethpb.Attestation{
   211  		Data: &ethpb.AttestationData{
   212  			Target: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   213  		},
   214  		AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
   215  	})
   216  	attestations := []*ethpb.Attestation{blockAtt}
   217  	var exits []*ethpb.SignedVoluntaryExit
   218  	for i := uint64(0); i < params.BeaconConfig().MaxVoluntaryExits+1; i++ {
   219  		exits = append(exits, &ethpb.SignedVoluntaryExit{})
   220  	}
   221  	genesisBlock := blocks.NewGenesisBlock([]byte{})
   222  	bodyRoot, err := genesisBlock.Block.HashTreeRoot()
   223  	require.NoError(t, err)
   224  	err = beaconState.SetLatestBlockHeader(testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
   225  		Slot:       genesisBlock.Block.Slot,
   226  		ParentRoot: genesisBlock.Block.ParentRoot,
   227  		BodyRoot:   bodyRoot[:],
   228  	}))
   229  	require.NoError(t, err)
   230  	parentRoot, err := beaconState.LatestBlockHeader().HashTreeRoot()
   231  	require.NoError(t, err)
   232  	block := testutil.NewBeaconBlock()
   233  	block.Block.Slot = 1
   234  	block.Block.ParentRoot = parentRoot[:]
   235  	block.Block.Body.ProposerSlashings = proposerSlashings
   236  	block.Block.Body.Attestations = attestations
   237  	block.Block.Body.AttesterSlashings = attesterSlashings
   238  	block.Block.Body.VoluntaryExits = exits
   239  	block.Block.Body.Eth1Data.DepositRoot = bytesutil.PadTo([]byte{2}, 32)
   240  	block.Block.Body.Eth1Data.BlockHash = bytesutil.PadTo([]byte{3}, 32)
   241  	err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
   242  	require.NoError(t, err)
   243  	cp := beaconState.CurrentJustifiedCheckpoint()
   244  	cp.Root = []byte("hello-world")
   245  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cp))
   246  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   247  	_, err = state.VerifyOperationLengths(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   248  	wanted := "number of voluntary exits (17) in block body exceeds allowed threshold of 16"
   249  	assert.ErrorContains(t, wanted, err)
   250  }
   251  
   252  func createFullBlockWithOperations(t *testing.T) (iface.BeaconState,
   253  	*ethpb.SignedBeaconBlock, []*ethpb.Attestation, []*ethpb.ProposerSlashing, []*ethpb.SignedVoluntaryExit) {
   254  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 32)
   255  	genesisBlock := blocks.NewGenesisBlock([]byte{})
   256  	bodyRoot, err := genesisBlock.Block.HashTreeRoot()
   257  	require.NoError(t, err)
   258  	err = beaconState.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
   259  		Slot:       genesisBlock.Block.Slot,
   260  		ParentRoot: genesisBlock.Block.ParentRoot,
   261  		StateRoot:  params.BeaconConfig().ZeroHash[:],
   262  		BodyRoot:   bodyRoot[:],
   263  	})
   264  	require.NoError(t, err)
   265  	err = beaconState.SetSlashings(make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector))
   266  	require.NoError(t, err)
   267  	cp := beaconState.CurrentJustifiedCheckpoint()
   268  	mockRoot := [32]byte{}
   269  	copy(mockRoot[:], "hello-world")
   270  	cp.Root = mockRoot[:]
   271  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cp))
   272  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   273  
   274  	proposerSlashIdx := types.ValidatorIndex(3)
   275  	slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
   276  	err = beaconState.SetSlot(slotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)) + params.BeaconConfig().MinAttestationInclusionDelay)
   277  	require.NoError(t, err)
   278  
   279  	currentEpoch := helpers.CurrentEpoch(beaconState)
   280  	header1 := testutil.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
   281  		Header: &ethpb.BeaconBlockHeader{
   282  			ProposerIndex: proposerSlashIdx,
   283  			Slot:          1,
   284  			StateRoot:     bytesutil.PadTo([]byte("A"), 32),
   285  		},
   286  	})
   287  	header1.Signature, err = helpers.ComputeDomainAndSign(beaconState, currentEpoch, header1.Header, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerSlashIdx])
   288  	require.NoError(t, err)
   289  
   290  	header2 := testutil.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
   291  		Header: &ethpb.BeaconBlockHeader{
   292  			ProposerIndex: proposerSlashIdx,
   293  			Slot:          1,
   294  			StateRoot:     bytesutil.PadTo([]byte("B"), 32),
   295  		},
   296  	})
   297  	header2.Signature, err = helpers.ComputeDomainAndSign(beaconState, helpers.CurrentEpoch(beaconState), header2.Header, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerSlashIdx])
   298  	require.NoError(t, err)
   299  
   300  	proposerSlashings := []*ethpb.ProposerSlashing{
   301  		{
   302  			Header_1: header1,
   303  			Header_2: header2,
   304  		},
   305  	}
   306  	validators := beaconState.Validators()
   307  	validators[proposerSlashIdx].PublicKey = privKeys[proposerSlashIdx].PublicKey().Marshal()
   308  	require.NoError(t, beaconState.SetValidators(validators))
   309  
   310  	mockRoot2 := [32]byte{'A'}
   311  	att1 := testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
   312  		Data: &ethpb.AttestationData{
   313  			Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot2[:]},
   314  		},
   315  		AttestingIndices: []uint64{0, 1},
   316  	})
   317  	domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
   318  	require.NoError(t, err)
   319  	hashTreeRoot, err := helpers.ComputeSigningRoot(att1.Data, domain)
   320  	require.NoError(t, err)
   321  	sig0 := privKeys[0].Sign(hashTreeRoot[:])
   322  	sig1 := privKeys[1].Sign(hashTreeRoot[:])
   323  	aggregateSig := bls.AggregateSignatures([]bls.Signature{sig0, sig1})
   324  	att1.Signature = aggregateSig.Marshal()
   325  
   326  	mockRoot3 := [32]byte{'B'}
   327  	att2 := testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
   328  		Data: &ethpb.AttestationData{
   329  			Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot3[:]},
   330  			Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
   331  		},
   332  		AttestingIndices: []uint64{0, 1},
   333  	})
   334  
   335  	hashTreeRoot, err = helpers.ComputeSigningRoot(att2.Data, domain)
   336  	require.NoError(t, err)
   337  	sig0 = privKeys[0].Sign(hashTreeRoot[:])
   338  	sig1 = privKeys[1].Sign(hashTreeRoot[:])
   339  	aggregateSig = bls.AggregateSignatures([]bls.Signature{sig0, sig1})
   340  	att2.Signature = aggregateSig.Marshal()
   341  
   342  	attesterSlashings := []*ethpb.AttesterSlashing{
   343  		{
   344  			Attestation_1: att1,
   345  			Attestation_2: att2,
   346  		},
   347  	}
   348  
   349  	var blockRoots [][]byte
   350  	for i := uint64(0); i < uint64(params.BeaconConfig().SlotsPerHistoricalRoot); i++ {
   351  		blockRoots = append(blockRoots, []byte{byte(i)})
   352  	}
   353  	require.NoError(t, beaconState.SetBlockRoots(blockRoots))
   354  
   355  	aggBits := bitfield.NewBitlist(1)
   356  	aggBits.SetBitAt(0, true)
   357  	blockAtt := testutil.HydrateAttestation(&ethpb.Attestation{
   358  		Data: &ethpb.AttestationData{
   359  			Slot:   beaconState.Slot(),
   360  			Target: &ethpb.Checkpoint{Epoch: helpers.CurrentEpoch(beaconState)},
   361  			Source: &ethpb.Checkpoint{Root: mockRoot[:]}},
   362  		AggregationBits: aggBits,
   363  	})
   364  
   365  	committee, err := helpers.BeaconCommitteeFromState(beaconState, blockAtt.Data.Slot, blockAtt.Data.CommitteeIndex)
   366  	assert.NoError(t, err)
   367  	attestingIndices, err := attestationutil.AttestingIndices(blockAtt.AggregationBits, committee)
   368  	require.NoError(t, err)
   369  	assert.NoError(t, err)
   370  	hashTreeRoot, err = helpers.ComputeSigningRoot(blockAtt.Data, domain)
   371  	assert.NoError(t, err)
   372  	sigs := make([]bls.Signature, len(attestingIndices))
   373  	for i, indice := range attestingIndices {
   374  		sig := privKeys[indice].Sign(hashTreeRoot[:])
   375  		sigs[i] = sig
   376  	}
   377  	blockAtt.Signature = bls.AggregateSignatures(sigs).Marshal()
   378  
   379  	exit := &ethpb.SignedVoluntaryExit{
   380  		Exit: &ethpb.VoluntaryExit{
   381  			ValidatorIndex: 10,
   382  			Epoch:          0,
   383  		},
   384  	}
   385  	exit.Signature, err = helpers.ComputeDomainAndSign(beaconState, currentEpoch, exit.Exit, params.BeaconConfig().DomainVoluntaryExit, privKeys[exit.Exit.ValidatorIndex])
   386  	require.NoError(t, err)
   387  
   388  	header := beaconState.LatestBlockHeader()
   389  	prevStateRoot, err := beaconState.HashTreeRoot(context.Background())
   390  	require.NoError(t, err)
   391  	header.StateRoot = prevStateRoot[:]
   392  	require.NoError(t, beaconState.SetLatestBlockHeader(header))
   393  	parentRoot, err := beaconState.LatestBlockHeader().HashTreeRoot()
   394  	require.NoError(t, err)
   395  	copied := beaconState.Copy()
   396  	require.NoError(t, copied.SetSlot(beaconState.Slot()+1))
   397  	randaoReveal, err := testutil.RandaoReveal(copied, currentEpoch, privKeys)
   398  	require.NoError(t, err)
   399  	proposerIndex, err := helpers.BeaconProposerIndex(copied)
   400  	require.NoError(t, err)
   401  	block := testutil.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{
   402  		Block: &ethpb.BeaconBlock{
   403  			ParentRoot:    parentRoot[:],
   404  			Slot:          beaconState.Slot() + 1,
   405  			ProposerIndex: proposerIndex,
   406  			Body: &ethpb.BeaconBlockBody{
   407  				RandaoReveal:      randaoReveal,
   408  				ProposerSlashings: proposerSlashings,
   409  				AttesterSlashings: attesterSlashings,
   410  				Attestations:      []*ethpb.Attestation{blockAtt},
   411  				VoluntaryExits:    []*ethpb.SignedVoluntaryExit{exit},
   412  			},
   413  		},
   414  	})
   415  
   416  	sig, err := testutil.BlockSignature(beaconState, block.Block, privKeys)
   417  	require.NoError(t, err)
   418  	block.Signature = sig.Marshal()
   419  
   420  	require.NoError(t, beaconState.SetSlot(block.Block.Slot))
   421  	return beaconState, block, []*ethpb.Attestation{blockAtt}, proposerSlashings, []*ethpb.SignedVoluntaryExit{exit}
   422  }
   423  
   424  func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
   425  	beaconState, block, _, proposerSlashings, exits := createFullBlockWithOperations(t)
   426  	exit := exits[0]
   427  
   428  	beaconState, err := state.ProcessBlock(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   429  	require.NoError(t, err, "Expected block to pass processing conditions")
   430  
   431  	v, err := beaconState.ValidatorAtIndex(proposerSlashings[0].Header_1.Header.ProposerIndex)
   432  	require.NoError(t, err)
   433  	assert.Equal(t, true, v.Slashed, "Expected validator at index %d to be slashed", proposerSlashings[0].Header_1.Header.ProposerIndex)
   434  	v, err = beaconState.ValidatorAtIndex(1)
   435  	require.NoError(t, err)
   436  	assert.Equal(t, true, v.Slashed, "Expected validator at index 1 to be slashed, received false")
   437  
   438  	v, err = beaconState.ValidatorAtIndex(exit.Exit.ValidatorIndex)
   439  	require.NoError(t, err)
   440  	received := v.ExitEpoch
   441  	wanted := params.BeaconConfig().FarFutureEpoch
   442  	assert.NotEqual(t, wanted, received, "Expected validator at index %d to be exiting", exit.Exit.ValidatorIndex)
   443  }
   444  
   445  func TestProcessEpochPrecompute_CanProcess(t *testing.T) {
   446  	epoch := types.Epoch(1)
   447  
   448  	atts := []*pb.PendingAttestation{{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: make([]byte, 32)}}, InclusionDelay: 1}}
   449  	slashing := make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector)
   450  	base := &pb.BeaconState{
   451  		Slot:                       params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epoch)) + 1,
   452  		BlockRoots:                 make([][]byte, 128),
   453  		Slashings:                  slashing,
   454  		RandaoMixes:                make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
   455  		CurrentEpochAttestations:   atts,
   456  		FinalizedCheckpoint:        &ethpb.Checkpoint{Root: make([]byte, 32)},
   457  		JustificationBits:          bitfield.Bitvector4{0x00},
   458  		CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
   459  	}
   460  	s, err := v1.InitializeFromProto(base)
   461  	require.NoError(t, err)
   462  	require.NoError(t, s.SetValidators([]*ethpb.Validator{}))
   463  	newState, err := state.ProcessEpochPrecompute(context.Background(), s)
   464  	require.NoError(t, err)
   465  	assert.Equal(t, uint64(0), newState.Slashings()[2], "Unexpected slashed balance")
   466  }
   467  
   468  func BenchmarkProcessBlk_65536Validators_FullBlock(b *testing.B) {
   469  	logrus.SetLevel(logrus.PanicLevel)
   470  
   471  	validatorCount := params.BeaconConfig().MinGenesisActiveValidatorCount * 4
   472  	committeeCount := validatorCount / params.BeaconConfig().TargetCommitteeSize
   473  	validators := make([]*ethpb.Validator, validatorCount)
   474  	for i := 0; i < len(validators); i++ {
   475  		validators[i] = &ethpb.Validator{
   476  			EffectiveBalance:           params.BeaconConfig().MaxEffectiveBalance,
   477  			ExitEpoch:                  params.BeaconConfig().FarFutureEpoch,
   478  			WithdrawableEpoch:          params.BeaconConfig().FarFutureEpoch,
   479  			ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch,
   480  		}
   481  	}
   482  	validatorBalances := make([]uint64, len(validators))
   483  	for i := 0; i < len(validatorBalances); i++ {
   484  		validatorBalances[i] = params.BeaconConfig().MaxEffectiveBalance
   485  	}
   486  
   487  	randaoMixes := make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector)
   488  	for i := 0; i < len(randaoMixes); i++ {
   489  		randaoMixes[i] = params.BeaconConfig().ZeroHash[:]
   490  	}
   491  
   492  	base := &pb.BeaconState{
   493  		Slot:              20,
   494  		LatestBlockHeader: &ethpb.BeaconBlockHeader{},
   495  		BlockRoots:        make([][]byte, 254),
   496  		RandaoMixes:       randaoMixes,
   497  		Validators:        validators,
   498  		Balances:          validatorBalances,
   499  		Slashings:         make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
   500  		CurrentJustifiedCheckpoint: &ethpb.Checkpoint{
   501  			Root: []byte("hello-world"),
   502  		},
   503  		Fork: &pb.Fork{
   504  			PreviousVersion: []byte{0, 0, 0, 0},
   505  			CurrentVersion:  []byte{0, 0, 0, 0},
   506  		},
   507  	}
   508  	s, err := v1.InitializeFromProto(base)
   509  	require.NoError(b, err)
   510  
   511  	// Set up proposer slashing object for block
   512  	proposerSlashings := []*ethpb.ProposerSlashing{
   513  		{
   514  			Header_1: &ethpb.SignedBeaconBlockHeader{
   515  				Header: &ethpb.BeaconBlockHeader{
   516  					ProposerIndex: 1,
   517  					Slot:          0,
   518  				},
   519  				Signature: bytesutil.PadTo([]byte("A"), 96),
   520  			},
   521  			Header_2: &ethpb.SignedBeaconBlockHeader{
   522  				Header: &ethpb.BeaconBlockHeader{
   523  					ProposerIndex: 1,
   524  					Slot:          0,
   525  				},
   526  				Signature: bytesutil.PadTo([]byte("B"), 96),
   527  			},
   528  		},
   529  	}
   530  
   531  	// Set up attester slashing object for block
   532  	attesterSlashings := []*ethpb.AttesterSlashing{
   533  		{
   534  			Attestation_1: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
   535  				AttestingIndices: []uint64{2, 3},
   536  			}),
   537  			Attestation_2: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
   538  				AttestingIndices: []uint64{2, 3},
   539  			}),
   540  		},
   541  	}
   542  
   543  	// Set up deposit object for block
   544  	deposit := &ethpb.Deposit{
   545  		Data: &ethpb.Deposit_Data{
   546  			PublicKey: []byte{1, 2, 3},
   547  			Amount:    params.BeaconConfig().MaxEffectiveBalance,
   548  		},
   549  	}
   550  	leaf, err := deposit.Data.HashTreeRoot()
   551  	require.NoError(b, err)
   552  	depositTrie, err := trieutil.GenerateTrieFromItems([][]byte{leaf[:]}, params.BeaconConfig().DepositContractTreeDepth)
   553  	require.NoError(b, err, "Could not generate trie")
   554  	proof, err := depositTrie.MerkleProof(0)
   555  	require.NoError(b, err, "Could not generate proof")
   556  	deposit.Proof = proof
   557  	root := depositTrie.Root()
   558  
   559  	// Set up randao reveal object for block
   560  	proposerIdx, err := helpers.BeaconProposerIndex(s)
   561  	require.NoError(b, err)
   562  	priv, err := bls.RandKey()
   563  	require.NoError(b, err)
   564  	v := s.Validators()
   565  	v[proposerIdx].PublicKey = priv.PublicKey().Marshal()
   566  	buf := make([]byte, 32)
   567  	binary.LittleEndian.PutUint64(buf, 0)
   568  	domain, err := helpers.Domain(s.Fork(), 0, params.BeaconConfig().DomainRandao, s.GenesisValidatorRoot())
   569  	require.NoError(b, err)
   570  	ctr := &pb.SigningData{
   571  		ObjectRoot: buf,
   572  		Domain:     domain,
   573  	}
   574  	root, err = ctr.HashTreeRoot()
   575  	require.NoError(b, err)
   576  	epochSignature := priv.Sign(root[:])
   577  
   578  	buf = []byte{params.BeaconConfig().BLSWithdrawalPrefixByte}
   579  	pubKey := []byte("A")
   580  	hashed := hashutil.Hash(pubKey)
   581  	buf = append(buf, hashed[:]...)
   582  	v[3].WithdrawalCredentials = buf
   583  
   584  	require.NoError(b, s.SetValidators(v))
   585  
   586  	attestations := make([]*ethpb.Attestation, 128)
   587  	for i := 0; i < len(attestations); i++ {
   588  		attestations[i] = &ethpb.Attestation{
   589  			Data: &ethpb.AttestationData{
   590  				Source: &ethpb.Checkpoint{Root: []byte("hello-world")}},
   591  			AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
   592  				0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x01},
   593  		}
   594  	}
   595  
   596  	blk := &ethpb.SignedBeaconBlock{
   597  		Block: &ethpb.BeaconBlock{
   598  			Slot: s.Slot(),
   599  			Body: &ethpb.BeaconBlockBody{
   600  				Eth1Data: &ethpb.Eth1Data{
   601  					DepositRoot: root[:],
   602  					BlockHash:   root[:],
   603  				},
   604  				RandaoReveal:      epochSignature.Marshal(),
   605  				Attestations:      attestations,
   606  				ProposerSlashings: proposerSlashings,
   607  				AttesterSlashings: attesterSlashings,
   608  			},
   609  		},
   610  	}
   611  
   612  	// Precache the shuffled indices
   613  	for i := uint64(0); i < committeeCount; i++ {
   614  		_, err := helpers.BeaconCommitteeFromState(s, 0, types.CommitteeIndex(i))
   615  		require.NoError(b, err)
   616  	}
   617  
   618  	b.ResetTimer()
   619  	for n := 0; n < b.N; n++ {
   620  		_, err := state.ProcessBlock(context.Background(), s, wrapper.WrappedPhase0SignedBeaconBlock(blk))
   621  		require.NoError(b, err)
   622  		// Reset state fields to process block again
   623  		v := s.Validators()
   624  		v[1].Slashed = false
   625  		v[2].Slashed = false
   626  		require.NoError(b, s.SetValidators(v))
   627  		balances := s.Balances()
   628  		balances[3] += 2 * params.BeaconConfig().MinDepositAmount
   629  		require.NoError(b, s.SetBalances(balances))
   630  	}
   631  }
   632  
   633  func TestProcessBlk_AttsBasedOnValidatorCount(t *testing.T) {
   634  	logrus.SetLevel(logrus.PanicLevel)
   635  
   636  	// Default at 256 validators, can raise this number with faster BLS.
   637  	validatorCount := uint64(256)
   638  	s, privKeys := testutil.DeterministicGenesisState(t, validatorCount)
   639  	require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch))
   640  
   641  	bitCount := validatorCount / uint64(params.BeaconConfig().SlotsPerEpoch)
   642  	aggBits := bitfield.NewBitlist(bitCount)
   643  	for i := uint64(1); i < bitCount; i++ {
   644  		aggBits.SetBitAt(i, true)
   645  	}
   646  	atts := make([]*ethpb.Attestation, 1)
   647  
   648  	for i := 0; i < len(atts); i++ {
   649  		att := testutil.HydrateAttestation(&ethpb.Attestation{
   650  			Data:            &ethpb.AttestationData{Slot: 1},
   651  			AggregationBits: aggBits,
   652  		})
   653  
   654  		committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex)
   655  		assert.NoError(t, err)
   656  		attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   657  		require.NoError(t, err)
   658  		domain, err := helpers.Domain(s.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, s.GenesisValidatorRoot())
   659  		require.NoError(t, err)
   660  		sigs := make([]bls.Signature, len(attestingIndices))
   661  		for i, indice := range attestingIndices {
   662  			hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, domain)
   663  			assert.NoError(t, err)
   664  			sig := privKeys[indice].Sign(hashTreeRoot[:])
   665  			sigs[i] = sig
   666  		}
   667  		att.Signature = bls.AggregateSignatures(sigs).Marshal()
   668  		atts[i] = att
   669  	}
   670  
   671  	copied := s.Copy()
   672  	require.NoError(t, copied.SetSlot(s.Slot()+1))
   673  	epochSignature, err := testutil.RandaoReveal(copied, helpers.CurrentEpoch(copied), privKeys)
   674  	require.NoError(t, err)
   675  	header := s.LatestBlockHeader()
   676  	prevStateRoot, err := s.HashTreeRoot(context.Background())
   677  	require.NoError(t, err)
   678  	header.StateRoot = prevStateRoot[:]
   679  	require.NoError(t, s.SetLatestBlockHeader(header))
   680  
   681  	parentRoot, err := s.LatestBlockHeader().HashTreeRoot()
   682  	require.NoError(t, err)
   683  
   684  	nextSlotState := s.Copy()
   685  	require.NoError(t, nextSlotState.SetSlot(s.Slot()+1))
   686  	proposerIdx, err := helpers.BeaconProposerIndex(nextSlotState)
   687  	require.NoError(t, err)
   688  	blk := testutil.NewBeaconBlock()
   689  	blk.Block.ProposerIndex = proposerIdx
   690  	blk.Block.Slot = s.Slot() + 1
   691  	blk.Block.ParentRoot = parentRoot[:]
   692  	blk.Block.Body.RandaoReveal = epochSignature
   693  	blk.Block.Body.Attestations = atts
   694  	sig, err := testutil.BlockSignature(s, blk.Block, privKeys)
   695  	require.NoError(t, err)
   696  	blk.Signature = sig.Marshal()
   697  
   698  	params.SetupTestConfigCleanup(t)
   699  	config := params.BeaconConfig()
   700  	config.MinAttestationInclusionDelay = 0
   701  	params.OverrideBeaconConfig(config)
   702  
   703  	require.NoError(t, s.SetSlot(s.Slot()+1))
   704  	_, err = state.ProcessBlock(context.Background(), s, wrapper.WrappedPhase0SignedBeaconBlock(blk))
   705  	require.NoError(t, err)
   706  }
   707  
   708  func TestCanProcessEpoch_TrueOnEpochs(t *testing.T) {
   709  	tests := []struct {
   710  		slot            types.Slot
   711  		canProcessEpoch bool
   712  	}{
   713  		{
   714  			slot:            1,
   715  			canProcessEpoch: false,
   716  		}, {
   717  			slot:            63,
   718  			canProcessEpoch: true,
   719  		},
   720  		{
   721  			slot:            64,
   722  			canProcessEpoch: false,
   723  		}, {
   724  			slot:            127,
   725  			canProcessEpoch: true,
   726  		}, {
   727  			slot:            1000000000,
   728  			canProcessEpoch: false,
   729  		},
   730  	}
   731  
   732  	for _, tt := range tests {
   733  		b := &pb.BeaconState{Slot: tt.slot}
   734  		s, err := v1.InitializeFromProto(b)
   735  		require.NoError(t, err)
   736  		assert.Equal(t, tt.canProcessEpoch, state.CanProcessEpoch(s), "CanProcessEpoch(%d)", tt.slot)
   737  	}
   738  }
   739  
   740  func TestProcessBlock_OverMaxProposerSlashings(t *testing.T) {
   741  	maxSlashings := params.BeaconConfig().MaxProposerSlashings
   742  	b := &ethpb.SignedBeaconBlock{
   743  		Block: &ethpb.BeaconBlock{
   744  			Body: &ethpb.BeaconBlockBody{
   745  				ProposerSlashings: make([]*ethpb.ProposerSlashing, maxSlashings+1),
   746  			},
   747  		},
   748  	}
   749  	want := fmt.Sprintf("number of proposer slashings (%d) in block body exceeds allowed threshold of %d",
   750  		len(b.Block.Body.ProposerSlashings), params.BeaconConfig().MaxProposerSlashings)
   751  	_, err := state.VerifyOperationLengths(context.Background(), &v1.BeaconState{}, wrapper.WrappedPhase0SignedBeaconBlock(b))
   752  	assert.ErrorContains(t, want, err)
   753  }
   754  
   755  func TestProcessBlock_OverMaxAttesterSlashings(t *testing.T) {
   756  	maxSlashings := params.BeaconConfig().MaxAttesterSlashings
   757  	b := &ethpb.SignedBeaconBlock{
   758  		Block: &ethpb.BeaconBlock{
   759  			Body: &ethpb.BeaconBlockBody{
   760  				AttesterSlashings: make([]*ethpb.AttesterSlashing, maxSlashings+1),
   761  			},
   762  		},
   763  	}
   764  	want := fmt.Sprintf("number of attester slashings (%d) in block body exceeds allowed threshold of %d",
   765  		len(b.Block.Body.AttesterSlashings), params.BeaconConfig().MaxAttesterSlashings)
   766  	_, err := state.VerifyOperationLengths(context.Background(), &v1.BeaconState{}, wrapper.WrappedPhase0SignedBeaconBlock(b))
   767  	assert.ErrorContains(t, want, err)
   768  }
   769  
   770  func TestProcessBlock_OverMaxAttestations(t *testing.T) {
   771  	b := &ethpb.SignedBeaconBlock{
   772  		Block: &ethpb.BeaconBlock{
   773  			Body: &ethpb.BeaconBlockBody{
   774  				Attestations: make([]*ethpb.Attestation, params.BeaconConfig().MaxAttestations+1),
   775  			},
   776  		},
   777  	}
   778  	want := fmt.Sprintf("number of attestations (%d) in block body exceeds allowed threshold of %d",
   779  		len(b.Block.Body.Attestations), params.BeaconConfig().MaxAttestations)
   780  	_, err := state.VerifyOperationLengths(context.Background(), &v1.BeaconState{}, wrapper.WrappedPhase0SignedBeaconBlock(b))
   781  	assert.ErrorContains(t, want, err)
   782  }
   783  
   784  func TestProcessBlock_OverMaxVoluntaryExits(t *testing.T) {
   785  	maxExits := params.BeaconConfig().MaxVoluntaryExits
   786  	b := &ethpb.SignedBeaconBlock{
   787  		Block: &ethpb.BeaconBlock{
   788  			Body: &ethpb.BeaconBlockBody{
   789  				VoluntaryExits: make([]*ethpb.SignedVoluntaryExit, maxExits+1),
   790  			},
   791  		},
   792  	}
   793  	want := fmt.Sprintf("number of voluntary exits (%d) in block body exceeds allowed threshold of %d",
   794  		len(b.Block.Body.VoluntaryExits), maxExits)
   795  	_, err := state.VerifyOperationLengths(context.Background(), &v1.BeaconState{}, wrapper.WrappedPhase0SignedBeaconBlock(b))
   796  	assert.ErrorContains(t, want, err)
   797  }
   798  
   799  func TestProcessBlock_IncorrectDeposits(t *testing.T) {
   800  	base := &pb.BeaconState{
   801  		Eth1Data:         &ethpb.Eth1Data{DepositCount: 100},
   802  		Eth1DepositIndex: 98,
   803  	}
   804  	s, err := v1.InitializeFromProto(base)
   805  	require.NoError(t, err)
   806  	b := &ethpb.SignedBeaconBlock{
   807  		Block: &ethpb.BeaconBlock{
   808  			Body: &ethpb.BeaconBlockBody{
   809  				Deposits: []*ethpb.Deposit{{}},
   810  			},
   811  		},
   812  	}
   813  	want := fmt.Sprintf("incorrect outstanding deposits in block body, wanted: %d, got: %d",
   814  		s.Eth1Data().DepositCount-s.Eth1DepositIndex(), len(b.Block.Body.Deposits))
   815  	_, err = state.VerifyOperationLengths(context.Background(), s, wrapper.WrappedPhase0SignedBeaconBlock(b))
   816  	assert.ErrorContains(t, want, err)
   817  }
   818  
   819  func TestProcessSlots_SameSlotAsParentState(t *testing.T) {
   820  	slot := types.Slot(2)
   821  	parentState, err := v1.InitializeFromProto(&pb.BeaconState{Slot: slot})
   822  	require.NoError(t, err)
   823  
   824  	_, err = state.ProcessSlots(context.Background(), parentState, slot)
   825  	assert.ErrorContains(t, "expected state.slot 2 < slot 2", err)
   826  }
   827  
   828  func TestProcessSlots_LowerSlotAsParentState(t *testing.T) {
   829  	slot := types.Slot(2)
   830  	parentState, err := v1.InitializeFromProto(&pb.BeaconState{Slot: slot})
   831  	require.NoError(t, err)
   832  
   833  	_, err = state.ProcessSlots(context.Background(), parentState, slot-1)
   834  	assert.ErrorContains(t, "expected state.slot 2 < slot 1", err)
   835  }
   836  
   837  func TestProcessSlotsUsingNextSlotCache(t *testing.T) {
   838  	ctx := context.Background()
   839  	s, _ := testutil.DeterministicGenesisState(t, 1)
   840  	r := []byte{'a'}
   841  	s, err := state.ProcessSlotsUsingNextSlotCache(ctx, s, r, 5)
   842  	require.NoError(t, err)
   843  	require.Equal(t, types.Slot(5), s.Slot())
   844  }