func (s *server) GetEpochInformation(ctx context.Context, in *pb.EpochInformationRequest) (*pb.EpochInformationResponse, error) {
	state := s.chain.GetState()
	config := s.chain.GetConfig()

	requestedEpochSlot := uint64(in.EpochIndex) * s.chain.GetConfig().EpochLength

	if requestedEpochSlot > state.Slot {
		updatedState, err := s.chain.GetUpdatedState(requestedEpochSlot)
		if err != nil {
			return nil, err
		}
		state = *updatedState
	}

	if state.EpochIndex < in.EpochIndex {
		state = state.Copy()

		_, err := state.ProcessEpochTransition(s.chain.GetConfig())
		if err != nil {
			return nil, err
		}
	}

	epochBoundaryRoot := s.chain.View.Chain.GetBlockBySlot(in.EpochIndex * config.EpochLength)
	previousEpochBoundaryRoot := s.chain.View.Chain.GetBlockBySlot((in.EpochIndex - 1) * config.EpochLength)

	latestCrosslinks := make([]*pb.Crosslink, len(state.LatestCrosslinks))
	for i := range latestCrosslinks {
		latestCrosslinks[i] = state.LatestCrosslinks[i].ToProto()
	}

	previousCrosslinks := make([]*pb.Crosslink, len(state.PreviousCrosslinks))
	for i := range previousCrosslinks {
		previousCrosslinks[i] = state.PreviousCrosslinks[i].ToProto()
	}

	justifiedNode := s.chain.View.Chain.GetBlockBySlot(state.JustifiedEpoch * config.EpochLength)
	previousJustifiedNode := s.chain.View.Chain.GetBlockBySlot(state.PreviousJustifiedEpoch * config.EpochLength)

	earliestSlot := int64(state.Slot) - int64(state.Slot%config.EpochLength) - int64(config.EpochLength)

	newShuffling := state.GetAssignmentsAssumingShuffle(config)

	slotsAssumingShuffle := make([]*pb.ShardCommitteesForSlot, len(newShuffling))
	for s := range slotsAssumingShuffle {
		shardAndCommittees := make([]*pb.ShardCommittee, len(newShuffling[s]))
		for i := range shardAndCommittees {
			shardAndCommittees[i] = newShuffling[s][i].ToProto()
		}
		slotsAssumingShuffle[s] = &pb.ShardCommitteesForSlot{
			Committees: shardAndCommittees,
		}
	}

	slots := make([]*pb.ShardCommitteesForSlot, len(state.ShardAndCommitteeForSlots))
	for s := range slots {
		shardAndCommittees := make([]*pb.ShardCommittee, len(state.ShardAndCommitteeForSlots[s]))
		for i := range shardAndCommittees {
			shardAndCommittees[i] = state.ShardAndCommitteeForSlots[s][i].ToProto()
		}
		slots[s] = &pb.ShardCommitteesForSlot{
			Committees: shardAndCommittees,
		}
	}

	return &pb.EpochInformationResponse{
		HasEpochInformation: true,
		Information: &pb.EpochInformation{
			ShardCommitteesForSlots:     slots,
			ShardCommitteesForNextEpoch: slotsAssumingShuffle,
			Slot:                        earliestSlot,
			TargetHash:                  epochBoundaryRoot.Hash[:],
			JustifiedEpoch:              state.JustifiedEpoch,
			LatestCrosslinks:            latestCrosslinks,
			PreviousCrosslinks:          previousCrosslinks,
			JustifiedHash:               justifiedNode.Hash[:],
			PreviousTargetHash:          previousEpochBoundaryRoot.Hash[:],
			PreviousJustifiedEpoch:      state.PreviousJustifiedEpoch,
			PreviousJustifiedHash:       previousJustifiedNode.Hash[:],
		},
	}, nil
}
// GetEpochInformation gets information about the current epoch used for attestation
// assignment and generation.
GetEpochInformation gets information about the current epoch used for attestation
assignment and generation.
// GetEpochInformation gets information about the current epoch used for attestation // assignment and generation .
func (s *server) GetEpochInformation(ctx context.Context, in *pb.EpochInformationRequest) (*pb.EpochInformationResponse, error) {
	state := s.chain.GetState()
	config := s.chain.GetConfig()
	requestedEpochSlot := uint64(in.EpochIndex) * s.chain.GetConfig().EpochLength
	if requestedEpochSlot > state.Slot {
		updatedState, err := s.chain.GetUpdatedState(requestedEpochSlot)
		if err != nil {
			return nil, err
		}
		state = *updatedState
	}
	if state.EpochIndex < in.EpochIndex {
		state = state.Copy()
		_, err := state.ProcessEpochTransition(s.chain.GetConfig())
		if err != nil {
			return nil, err
		}
	}
	epochBoundaryRoot := s.chain.View.Chain.GetBlockBySlot(in.EpochIndex * config.EpochLength)
	previousEpochBoundaryRoot := s.chain.View.Chain.GetBlockBySlot((in.EpochIndex - 1) * config.EpochLength)
	latestCrosslinks := make([]*pb.Crosslink, len(state.LatestCrosslinks))
	for i := range latestCrosslinks {
		latestCrosslinks[i] = state.LatestCrosslinks[i].ToProto()
	}
	previousCrosslinks := make([]*pb.Crosslink, len(state.PreviousCrosslinks))
	for i := range previousCrosslinks {
		previousCrosslinks[i] = state.PreviousCrosslinks[i].ToProto()
	}
	justifiedNode := s.chain.View.Chain.GetBlockBySlot(state.JustifiedEpoch * config.EpochLength)
	previousJustifiedNode := s.chain.View.Chain.GetBlockBySlot(state.PreviousJustifiedEpoch * config.EpochLength)
	earliestSlot := int64(state.Slot) - int64(state.Slot%config.EpochLength) - int64(config.EpochLength)
	newShuffling := state.GetAssignmentsAssumingShuffle(config)
	slotsAssumingShuffle := make([]*pb.ShardCommitteesForSlot, len(newShuffling))
	for s := range slotsAssumingShuffle {
		shardAndCommittees := make([]*pb.ShardCommittee, len(newShuffling[s]))
		for i := range shardAndCommittees {
			shardAndCommittees[i] = newShuffling[s][i].ToProto()
		}
		slotsAssumingShuffle[s] = &pb.ShardCommitteesForSlot{
			Committees: shardAndCommittees,
		}
	}
	slots := make([]*pb.ShardCommitteesForSlot, len(state.ShardAndCommitteeForSlots))
	for s := range slots {
		shardAndCommittees := make([]*pb.ShardCommittee, len(state.ShardAndCommitteeForSlots[s]))
		for i := range shardAndCommittees {
			shardAndCommittees[i] = state.ShardAndCommitteeForSlots[s][i].ToProto()
		}
		slots[s] = &pb.ShardCommitteesForSlot{
			Committees: shardAndCommittees,
		}
	}
	return &pb.EpochInformationResponse{
		HasEpochInformation: true,
		Information: &pb.EpochInformation{
			ShardCommitteesForSlots:     slots,
			ShardCommitteesForNextEpoch: slotsAssumingShuffle,
			Slot:                        earliestSlot,
			TargetHash:                  epochBoundaryRoot.Hash[:],
			JustifiedEpoch:              state.JustifiedEpoch,
			LatestCrosslinks:            latestCrosslinks,
			PreviousCrosslinks:          previousCrosslinks,
			JustifiedHash:               justifiedNode.Hash[:],
			PreviousTargetHash:          previousEpochBoundaryRoot.Hash[:],
			PreviousJustifiedEpoch:      state.PreviousJustifiedEpoch,
			PreviousJustifiedHash:       previousJustifiedNode.Hash[:],
		},
	}, nil
}
func ( s * server ) GetEpochInformation ( ctx context . Context , in * pb . EpochInformationRequest ) ( * pb . EpochInformationResponse , error ) { state := s . chain . GetState ( ) config := s . chain . GetConfig ( ) requestedEpochSlot := uint64 ( in . EpochIndex ) * s . chain . GetConfig ( ) . EpochLength if requestedEpochSlot > state . Slot { updatedState , err := s . chain . GetUpdatedState ( requestedEpochSlot ) if err != nil { return nil , err } state = * updatedState } if state . EpochIndex < in . EpochIndex { state = state . Copy ( ) _ , err := state . ProcessEpochTransition ( s . chain . GetConfig ( ) ) if err != nil { return nil , err } } epochBoundaryRoot := s . chain . View . Chain . GetBlockBySlot ( in . EpochIndex * config . EpochLength ) previousEpochBoundaryRoot := s . chain . View . Chain . GetBlockBySlot ( ( in . EpochIndex - 1 ) * config . EpochLength ) latestCrosslinks := make ( [ ] * pb . Crosslink , len ( state . LatestCrosslinks ) ) for i := range latestCrosslinks { latestCrosslinks [ i ] = state . LatestCrosslinks [ i ] . ToProto ( ) } previousCrosslinks := make ( [ ] * pb . Crosslink , len ( state . PreviousCrosslinks ) ) for i := range previousCrosslinks { previousCrosslinks [ i ] = state . PreviousCrosslinks [ i ] . ToProto ( ) } justifiedNode := s . chain . View . Chain . GetBlockBySlot ( state . JustifiedEpoch * config . EpochLength ) previousJustifiedNode := s . chain . View . Chain . GetBlockBySlot ( state . PreviousJustifiedEpoch * config . EpochLength ) earliestSlot := int64 ( state . Slot ) - int64 ( state . Slot % config . EpochLength ) - int64 ( config . EpochLength ) newShuffling := state . GetAssignmentsAssumingShuffle ( config ) slotsAssumingShuffle := make ( [ ] * pb . ShardCommitteesForSlot , len ( newShuffling ) ) for s := range slotsAssumingShuffle { shardAndCommittees := make ( [ ] * pb . ShardCommittee , len ( newShuffling [ s ] ) ) for i := range shardAndCommittees { shardAndCommittees [ i ] = newShuffling [ s ] [ i ] . ToProto ( ) } slotsAssumingShuffle [ s ] = & pb . ShardCommitteesForSlot { Committees : shardAndCommittees , } } slots := make ( [ ] * pb . ShardCommitteesForSlot , len ( state . ShardAndCommitteeForSlots ) ) for s := range slots { shardAndCommittees := make ( [ ] * pb . ShardCommittee , len ( state . ShardAndCommitteeForSlots [ s ] ) ) for i := range shardAndCommittees { shardAndCommittees [ i ] = state . ShardAndCommitteeForSlots [ s ] [ i ] . ToProto ( ) } slots [ s ] = & pb . ShardCommitteesForSlot { Committees : shardAndCommittees , } } return & pb . EpochInformationResponse { HasEpochInformation : true , Information : & pb . EpochInformation { ShardCommitteesForSlots : slots , ShardCommitteesForNextEpoch : slotsAssumingShuffle , Slot : earliestSlot , TargetHash : epochBoundaryRoot . Hash [ : ] , JustifiedEpoch : state . JustifiedEpoch , LatestCrosslinks : latestCrosslinks , PreviousCrosslinks : previousCrosslinks , JustifiedHash : justifiedNode . Hash [ : ] , PreviousTargetHash : previousEpochBoundaryRoot . Hash [ : ] , PreviousJustifiedEpoch : state . PreviousJustifiedEpoch , PreviousJustifiedHash : previousJustifiedNode . Hash [ : ] , } , } , nil }
GetEpochInformation gets information about the current epoch used for attestation
assignment and generation.
GetEpochInformation gets information about the current epoch used for attestation assignment and generation .