package forkchoice import ( "context" "math/big" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/prysmaticlabs/prysm/beacon-chain/blockchain" mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" "github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache" coreTime "github.com/prysmaticlabs/prysm/beacon-chain/core/time" testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing" "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray" "github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations" "github.com/prysmaticlabs/prysm/beacon-chain/state" "github.com/prysmaticlabs/prysm/beacon-chain/state/stategen" "github.com/prysmaticlabs/prysm/config/params" "github.com/prysmaticlabs/prysm/encoding/bytesutil" pb "github.com/prysmaticlabs/prysm/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" "github.com/prysmaticlabs/prysm/testing/require" ) func startChainService(t *testing.T, st state.BeaconState, block block.SignedBeaconBlock, engineMock *engineMock) *blockchain.Service { db := testDB.SetupDB(t) ctx := context.Background() require.NoError(t, db.SaveBlock(ctx, block)) r, err := block.Block().HashTreeRoot() require.NoError(t, err) require.NoError(t, db.SaveGenesisBlockRoot(ctx, r)) require.NoError(t, db.SaveState(ctx, st, r)) cp := ðpb.Checkpoint{ Epoch: coreTime.CurrentEpoch(st), Root: r[:], } require.NoError(t, db.SaveJustifiedCheckpoint(ctx, cp)) require.NoError(t, db.SaveFinalizedCheckpoint(ctx, cp)) attPool, err := attestations.NewService(ctx, &attestations.Config{ Pool: attestations.NewPool(), }) require.NoError(t, err) depositCache, err := depositcache.New() require.NoError(t, err) opts := append([]blockchain.Option{}, blockchain.WithExecutionEngineCaller(engineMock), blockchain.WithFinalizedStateAtStartUp(st), blockchain.WithDatabase(db), blockchain.WithAttestationService(attPool), blockchain.WithForkChoiceStore(protoarray.New(0, 0, params.BeaconConfig().ZeroHash)), blockchain.WithStateGen(stategen.New(db)), blockchain.WithStateNotifier(&mock.MockStateNotifier{}), blockchain.WithAttestationPool(attestations.NewPool()), blockchain.WithDepositCache(depositCache), ) service, err := blockchain.NewService(context.Background(), opts...) require.NoError(t, err) require.NoError(t, service.StartFromSavedState(st)) return service } type engineMock struct { powBlocks map[[32]byte]*ethpb.PowBlock } func (m *engineMock) GetPayload(context.Context, [8]byte) (*pb.ExecutionPayload, error) { return nil, nil } func (m *engineMock) ForkchoiceUpdated(context.Context, *pb.ForkchoiceState, *pb.PayloadAttributes) (*pb.PayloadIDBytes, []byte, error) { return nil, nil, nil } func (m *engineMock) NewPayload(context.Context, *pb.ExecutionPayload) ([]byte, error) { return nil, nil } func (m *engineMock) LatestExecutionBlock(context.Context) (*pb.ExecutionBlock, error) { return nil, nil } func (m *engineMock) ExchangeTransitionConfiguration(context.Context, *pb.TransitionConfiguration) error { return nil } func (m *engineMock) ExecutionBlockByHash(_ context.Context, hash common.Hash) (*pb.ExecutionBlock, error) { b, ok := m.powBlocks[bytesutil.ToBytes32(hash.Bytes())] if !ok { return nil, nil } td := new(big.Int).SetBytes(bytesutil.ReverseByteOrder(b.TotalDifficulty)) tdHex := hexutil.EncodeBig(td) return &pb.ExecutionBlock{ ParentHash: b.ParentHash, TotalDifficulty: tdHex, Hash: b.BlockHash, }, nil }