Implement Justification and finalization Processing (#2448)

This commit is contained in:
terence tsao
2019-05-06 21:09:22 -07:00
committed by nisdas
parent 6fcf25c811
commit d77c3e2dd6
5 changed files with 265 additions and 163 deletions

View File

@@ -9,7 +9,6 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",

View File

@@ -13,7 +13,6 @@ import (
"github.com/gogo/protobuf/proto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -112,100 +111,6 @@ func ProcessEth1Data(state *pb.BeaconState) *pb.BeaconState {
return state
}
// ProcessJustificationAndFinalization processes for justified slot by comparing
// epoch boundary balance and total balance.
// First, update the justification bitfield:
// Let new_justified_epoch = state.justified_epoch.
// Set state.justification_bitfield = state.justification_bitfield << 1.
// Set state.justification_bitfield |= 2 and new_justified_epoch = previous_epoch if
// 3 * previous_epoch_boundary_attesting_balance >= 2 * previous_total_balance.
// Set state.justification_bitfield |= 1 and new_justified_epoch = current_epoch if
// 3 * current_epoch_boundary_attesting_balance >= 2 * current_total_balance.
// Next, update last finalized epoch if possible:
// Set state.finalized_epoch = state.previous_justified_epoch if (state.justification_bitfield >> 1) % 8
// == 0b111 and state.previous_justified_epoch == previous_epoch - 2.
// Set state.finalized_epoch = state.previous_justified_epoch if (state.justification_bitfield >> 1) % 4
// == 0b11 and state.previous_justified_epoch == previous_epoch - 1.
// Set state.finalized_epoch = state.justified_epoch if (state.justification_bitfield >> 0) % 8
// == 0b111 and state.justified_epoch == previous_epoch - 1.
// Set state.finalized_epoch = state.justified_epoch if (state.justification_bitfield >> 0) % 4
// == 0b11 and state.justified_epoch == previous_epoch.
// Finally, update the following:
// Set state.previous_justified_epoch = state.justified_epoch.
// Set state.justified_epoch = new_justified_epoch
func ProcessJustificationAndFinalization(
state *pb.BeaconState,
thisEpochBoundaryAttestingBalance uint64,
prevEpochBoundaryAttestingBalance uint64,
prevTotalBalance uint64,
totalBalance uint64,
) (*pb.BeaconState, error) {
newJustifiedEpoch := state.CurrentJustifiedEpoch
newFinalizedEpoch := state.FinalizedEpoch
prevEpoch := helpers.PrevEpoch(state)
currentEpoch := helpers.CurrentEpoch(state)
// Shifts all the bits over one to create a new bit for the recent epoch.
state.JustificationBitfield <<= 1
// If prev prev epoch was justified then we ensure the 2nd bit in the bitfield is set,
// assign new justified slot to 2 * SLOTS_PER_EPOCH before.
if 3*prevEpochBoundaryAttestingBalance >= 2*prevTotalBalance {
state.JustificationBitfield |= 2
newJustifiedEpoch = prevEpoch
}
// If this epoch was justified then we ensure the 1st bit in the bitfield is set,
// assign new justified slot to 1 * SLOTS_PER_EPOCH before.
if 3*thisEpochBoundaryAttestingBalance >= 2*totalBalance {
state.JustificationBitfield |= 1
newJustifiedEpoch = currentEpoch
}
// Process finality.
// When the 2nd, 3rd and 4th most epochs are all justified, the 2nd can finalize the 4th epoch
// as a source.
if state.PreviousJustifiedEpoch == prevEpoch-2 &&
(state.JustificationBitfield>>1)%8 == 7 {
newFinalizedEpoch = state.PreviousJustifiedEpoch
}
// When the 2nd and 3rd most epochs are all justified, the 2nd can finalize the 3rd epoch
// as a source.
if state.PreviousJustifiedEpoch == prevEpoch-1 &&
(state.JustificationBitfield>>1)%4 == 3 {
newFinalizedEpoch = state.PreviousJustifiedEpoch
}
// When the 1st, 2nd and 3rd most epochs are all justified, the 1st can finalize the 3rd epoch
// as a source.
if state.CurrentJustifiedEpoch == prevEpoch-1 &&
(state.JustificationBitfield>>0)%8 == 7 {
newFinalizedEpoch = state.CurrentJustifiedEpoch
}
// When the 1st and 2nd most epochs are all justified, the 1st can finalize the 2nd epoch
// as a source.
if state.CurrentJustifiedEpoch == prevEpoch &&
(state.JustificationBitfield>>0)%4 == 3 {
newFinalizedEpoch = state.CurrentJustifiedEpoch
}
state.PreviousJustifiedEpoch = state.CurrentJustifiedEpoch
state.PreviousJustifiedRoot = state.CurrentJustifiedRoot
if newJustifiedEpoch != state.CurrentJustifiedEpoch {
state.CurrentJustifiedEpoch = newJustifiedEpoch
newJustifedRoot, err := blocks.BlockRoot(state, helpers.StartSlot(newJustifiedEpoch))
if err != nil {
return state, err
}
state.CurrentJustifiedRoot = newJustifedRoot
}
if newFinalizedEpoch != state.FinalizedEpoch {
state.FinalizedEpoch = newFinalizedEpoch
newFinalizedRoot, err := blocks.BlockRoot(state, helpers.StartSlot(newFinalizedEpoch))
if err != nil {
return state, err
}
state.FinalizedRoot = newFinalizedRoot
}
return state, nil
}
// ProcessCrosslinks goes through each crosslink committee and check
// crosslink committee's attested balance * 3 is greater than total balance *2.
// If it's greater then beacon node updates crosslink committee with
@@ -386,6 +291,119 @@ func UpdateLatestActiveIndexRoots(state *pb.BeaconState) (*pb.BeaconState, error
return state, nil
}
// ProcessJustificationFinalization processes justification and finalization during
// epoch processing. This is where a beacon node can justify and finalize a new epoch.
//
// Spec pseudocode definition:
// def process_justification_and_finalization(state: BeaconState) -> None:
// if get_current_epoch(state) <= GENESIS_EPOCH + 1:
// return
//
// previous_epoch = get_previous_epoch(state)
// current_epoch = get_current_epoch(state)
// old_previous_justified_epoch = state.previous_justified_epoch
// old_current_justified_epoch = state.current_justified_epoch
//
// # Process justifications
// state.previous_justified_epoch = state.current_justified_epoch
// state.previous_justified_root = state.current_justified_root
// state.justification_bitfield = (state.justification_bitfield << 1) % 2**64
// previous_epoch_matching_target_balance = get_attesting_balance(state, get_matching_target_attestations(state, previous_epoch))
// if previous_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
// state.current_justified_epoch = previous_epoch
// state.current_justified_root = get_block_root(state, state.current_justified_epoch)
// state.justification_bitfield |= (1 << 1)
// current_epoch_matching_target_balance = get_attesting_balance(state, get_matching_target_attestations(state, current_epoch))
// if current_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
// state.current_justified_epoch = current_epoch
// state.current_justified_root = get_block_root(state, state.current_justified_epoch)
// state.justification_bitfield |= (1 << 0)
//
// # Process finalizations
// bitfield = state.justification_bitfield
// # The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th as source
// if (bitfield >> 1) % 8 == 0b111 and old_previous_justified_epoch == current_epoch - 3:
// state.finalized_epoch = old_previous_justified_epoch
// state.finalized_root = get_block_root(state, state.finalized_epoch)
// # The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as source
// if (bitfield >> 1) % 4 == 0b11 and old_previous_justified_epoch == current_epoch - 2:
// state.finalized_epoch = old_previous_justified_epoch
// state.finalized_root = get_block_root(state, state.finalized_epoch)
// # The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as source
// if (bitfield >> 0) % 8 == 0b111 and old_current_justified_epoch == current_epoch - 2:
// state.finalized_epoch = old_current_justified_epoch
// state.finalized_root = get_block_root(state, state.finalized_epoch)
// # The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
// if (bitfield >> 0) % 4 == 0b11 and old_current_justified_epoch == current_epoch - 1:
// state.finalized_epoch = old_current_justified_epoch
// state.finalized_root = get_block_root(state, state.finalized_epoch)
func ProcessJustificationFinalization(state *pb.BeaconState, prevAttestedBal uint64, currAttestedBal uint64) (
*pb.BeaconState, error) {
// There's no reason to process justification until the 3rd epoch.
currentEpoch := helpers.CurrentEpoch(state)
if currentEpoch <= params.BeaconConfig().GenesisEpoch+1 {
return state, nil
}
prevEpoch := helpers.PrevEpoch(state)
totalBal := totalActiveBalance(state)
oldPrevJustifiedEpoch := state.PreviousJustifiedEpoch
oldPrevJustifiedRoot := state.PreviousJustifiedRoot
oldCurrJustifiedEpoch := state.CurrentJustifiedEpoch
oldCurrJustifiedRoot := state.CurrentJustifiedRoot
state.PreviousJustifiedEpoch = state.CurrentJustifiedEpoch
state.PreviousJustifiedRoot = state.CurrentJustifiedRoot
state.JustificationBitfield = (state.JustificationBitfield << 1) % (1 << 63)
// Process justification.
if 3*prevAttestedBal >= 2*totalBal {
state.CurrentJustifiedEpoch = prevEpoch
blockRoot, err := helpers.BlockRoot(state, prevEpoch)
if err != nil {
return nil, fmt.Errorf("could not get block root for previous epoch %d: %v",
prevEpoch, err)
}
state.CurrentJustifiedRoot = blockRoot
state.JustificationBitfield |= 2
}
if 3*currAttestedBal >= 2*totalBal {
state.CurrentJustifiedEpoch = currentEpoch
blockRoot, err := helpers.BlockRoot(state, currentEpoch)
if err != nil {
return nil, fmt.Errorf("could not get block root for current epoch %d: %v",
prevEpoch, err)
}
state.CurrentJustifiedRoot = blockRoot
state.JustificationBitfield |= 1
}
// Process finalization.
bitfield := state.JustificationBitfield
// When the 2nd, 3rd and 4th most recent epochs are all justified,
// 2nd epoch can finalize the 4th epoch as a source.
if oldPrevJustifiedEpoch == currentEpoch-3 && (bitfield>>1)%8 == 7 {
state.FinalizedEpoch = oldPrevJustifiedEpoch
state.FinalizedRoot = oldPrevJustifiedRoot
}
// when 2nd and 3rd most recent epochs are all justified,
// 2nd epoch can finalize 3rd as a source.
if oldPrevJustifiedEpoch == currentEpoch-2 && (bitfield>>1)%4 == 3 {
state.FinalizedEpoch = oldPrevJustifiedEpoch
state.FinalizedRoot = oldPrevJustifiedRoot
}
// when 1st, 2nd and 3rd most recent epochs are all justified,
// 1st epoch can finalize 3rd as a source.
if oldCurrJustifiedEpoch == currentEpoch-2 && (bitfield>>0)%8 == 7 {
state.FinalizedEpoch = oldCurrJustifiedEpoch
state.FinalizedRoot = oldCurrJustifiedRoot
}
// when 1st, 2nd most recent epochs are all justified,
// 1st epoch can finalize 2nd as a source.
if oldCurrJustifiedEpoch == currentEpoch-1 && (bitfield>>0)%4 == 3 {
state.FinalizedEpoch = oldCurrJustifiedEpoch
state.FinalizedRoot = oldCurrJustifiedRoot
}
return state, nil
}
// UpdateLatestSlashedBalances updates the latest slashed balances. It transfers
// the amount from the current epoch index to next epoch index.
//
@@ -681,3 +699,11 @@ func attsForCrosslink(state *pb.BeaconState, crosslink *pb.Crosslink, atts []*pb
}
return crosslinkAtts
}
// TotalActiveBalance returns the combined balances of all the active validators.
// Spec pseudocode definition:
// def get_total_active_balance(state: BeaconState) -> Gwei:
// return get_total_balance(state, get_active_validator_indices(state, get_current_epoch(state)))
func totalActiveBalance(state *pb.BeaconState) uint64 {
return TotalBalance(state, helpers.ActiveValidatorIndices(state.ValidatorRegistry, helpers.CurrentEpoch(state)))
}

View File

@@ -211,67 +211,6 @@ func TestProcessEth1Data_InactionSlot(t *testing.T) {
}
}
func TestProcessJustification_PreviousEpochJustified(t *testing.T) {
if params.BeaconConfig().SlotsPerEpoch != 64 {
t.Errorf("SlotsPerEpoch should be 64 for these tests to pass")
}
var latestBlockRoots [][]byte
for i := uint64(0); i < params.BeaconConfig().LatestBlockRootsLength; i++ {
latestBlockRoots = append(latestBlockRoots, []byte("a"))
}
state := &pb.BeaconState{
Slot: 300 + params.BeaconConfig().GenesisSlot,
CurrentJustifiedEpoch: 3,
JustificationBitfield: 4,
LatestBlockRoots: latestBlockRoots,
}
newState, err := ProcessJustificationAndFinalization(
state,
1,
1,
1,
1,
)
if err != nil {
t.Errorf("Could not process justification and finalization of state %v", err)
}
if newState.PreviousJustifiedEpoch != 3 {
t.Errorf("New state's prev justified slot %d != old state's justified slot %d",
newState.PreviousJustifiedEpoch, state.CurrentJustifiedEpoch)
}
// Since this epoch was justified (not prev), justified_epoch = slot_to_epoch(state.slot) -1.
if newState.CurrentJustifiedEpoch != helpers.CurrentEpoch(state) {
t.Errorf("New state's justified epoch %d != state's slot - SLOTS_PER_EPOCH: %d",
newState.CurrentJustifiedEpoch, helpers.CurrentEpoch(state))
}
// The new JustificationBitfield is 11, it went from 0100 to 1011. Two 1's were appended because both
// prev epoch and this epoch were justified.
if newState.JustificationBitfield != 11 {
t.Errorf("New state's justification bitfield %d != 11", newState.JustificationBitfield)
}
// Assume for the case where only prev epoch got justified. Verify
// justified_epoch = slot_to_epoch(state.slot) -2.
newState, err = ProcessJustificationAndFinalization(
state,
0,
1,
1,
1,
)
if err != nil {
t.Errorf("Could not process justification and finalization of state %v", err)
}
if newState.CurrentJustifiedEpoch != helpers.CurrentEpoch(state)-1 {
t.Errorf("New state's justified epoch %d != state's epoch -2: %d",
newState.CurrentJustifiedEpoch, helpers.CurrentEpoch(state)-1)
}
}
func TestProcessCrosslinks_CrosslinksCorrectEpoch(t *testing.T) {
state := buildState(5, params.BeaconConfig().DepositsForChainStart)
state.LatestCrosslinks = []*pb.Crosslink{{}, {}}
@@ -1099,3 +1038,146 @@ func TestWinningCrosslink_CanGetWinningRoot(t *testing.T) {
t.Errorf("Did not get genesis crosslink, got: %v", winner)
}
}
func TestProcessJustificationFinalization_LessThan2ndEpoch(t *testing.T) {
state := &pb.BeaconState{
Slot: params.BeaconConfig().SlotsPerEpoch,
}
newState, err := ProcessJustificationFinalization(state, 0, 0)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(state, newState) {
t.Error("Did not get the original state")
}
}
func TestProcessJustificationFinalization_CantJustifyFinalize(t *testing.T) {
e := params.BeaconConfig().FarFutureEpoch
a := params.BeaconConfig().MaxDepositAmount
state := &pb.BeaconState{
Slot: params.BeaconConfig().GenesisSlot + params.BeaconConfig().SlotsPerEpoch*2,
PreviousJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
PreviousJustifiedRoot: params.BeaconConfig().ZeroHash[:],
CurrentJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
CurrentJustifiedRoot: params.BeaconConfig().ZeroHash[:],
ValidatorRegistry: []*pb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
}
// Since Attested balances are less than total balances, nothing happened.
newState, err := ProcessJustificationFinalization(state, 0, 0)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(state, newState) {
t.Error("Did not get the original state")
}
}
func TestProcessJustificationFinalization_NoBlockRootCurrentEpoch(t *testing.T) {
e := params.BeaconConfig().FarFutureEpoch
a := params.BeaconConfig().MaxDepositAmount
blockRoots := make([][]byte, params.BeaconConfig().SlotsPerEpoch*2+1)
for i := 0; i < len(blockRoots); i++ {
blockRoots[i] = []byte{byte(i)}
}
state := &pb.BeaconState{
Slot: params.BeaconConfig().GenesisSlot + params.BeaconConfig().SlotsPerEpoch*2,
PreviousJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
PreviousJustifiedRoot: params.BeaconConfig().ZeroHash[:],
CurrentJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
CurrentJustifiedRoot: params.BeaconConfig().ZeroHash[:],
JustificationBitfield: 3,
ValidatorRegistry: []*pb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
LatestBlockRoots: blockRoots,
}
attestedBalance := 4 * e * 3 / 2
_, err := ProcessJustificationFinalization(state, 0, attestedBalance)
want := "could not get block root for current epoch"
if !strings.Contains(err.Error(), want) {
t.Fatal("Did not receive correct error")
}
}
func TestProcessJustificationFinalization_JustifyCurrentEpoch(t *testing.T) {
e := params.BeaconConfig().FarFutureEpoch
a := params.BeaconConfig().MaxDepositAmount
blockRoots := make([][]byte, params.BeaconConfig().SlotsPerEpoch*2+1)
for i := 0; i < len(blockRoots); i++ {
blockRoots[i] = []byte{byte(i)}
}
state := &pb.BeaconState{
Slot: params.BeaconConfig().GenesisSlot + params.BeaconConfig().SlotsPerEpoch*2 + 1,
PreviousJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
PreviousJustifiedRoot: params.BeaconConfig().ZeroHash[:],
CurrentJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
CurrentJustifiedRoot: params.BeaconConfig().ZeroHash[:],
JustificationBitfield: 3,
ValidatorRegistry: []*pb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
LatestBlockRoots: blockRoots,
}
attestedBalance := 4 * e * 3 / 2
newState, err := ProcessJustificationFinalization(state, 0, attestedBalance)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(newState.CurrentJustifiedRoot, []byte{byte(128)}) {
t.Errorf("Wanted current justified root: %v, got: %v",
[]byte{byte(128)}, newState.CurrentJustifiedRoot)
}
if newState.CurrentJustifiedEpoch != params.BeaconConfig().GenesisEpoch+2 {
t.Errorf("Wanted justified epoch: %d, got: %d",
params.BeaconConfig().GenesisEpoch+2, newState.CurrentJustifiedEpoch)
}
if !bytes.Equal(newState.FinalizedRoot, params.BeaconConfig().ZeroHash[:]) {
t.Errorf("Wanted current finalized root: %v, got: %v",
params.BeaconConfig().ZeroHash, newState.FinalizedRoot)
}
if newState.FinalizedEpoch != params.BeaconConfig().GenesisEpoch {
t.Errorf("Wanted finalized epoch: %d, got: %d",
params.BeaconConfig().GenesisEpoch, newState.FinalizedEpoch)
}
}
func TestProcessJustificationFinalization_JustifyPrevEpoch(t *testing.T) {
e := params.BeaconConfig().FarFutureEpoch
a := params.BeaconConfig().MaxDepositAmount
blockRoots := make([][]byte, params.BeaconConfig().SlotsPerEpoch*2+1)
for i := 0; i < len(blockRoots); i++ {
blockRoots[i] = []byte{byte(i)}
}
state := &pb.BeaconState{
Slot: params.BeaconConfig().GenesisSlot + params.BeaconConfig().SlotsPerEpoch*2 + 1,
PreviousJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
PreviousJustifiedRoot: params.BeaconConfig().ZeroHash[:],
CurrentJustifiedEpoch: params.BeaconConfig().GenesisEpoch,
CurrentJustifiedRoot: params.BeaconConfig().ZeroHash[:],
JustificationBitfield: 3,
ValidatorRegistry: []*pb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
LatestBlockRoots: blockRoots,
}
attestedBalance := 4 * e * 3 / 2
newState, err := ProcessJustificationFinalization(state, attestedBalance, 0)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(newState.CurrentJustifiedRoot, []byte{byte(64)}) {
t.Errorf("Wanted current justified root: %v, got: %v",
[]byte{byte(128)}, newState.CurrentJustifiedRoot)
}
if newState.CurrentJustifiedEpoch != params.BeaconConfig().GenesisEpoch+1 {
t.Errorf("Wanted justified epoch: %d, got: %d",
params.BeaconConfig().GenesisEpoch+2, newState.CurrentJustifiedEpoch)
}
if !bytes.Equal(newState.FinalizedRoot, params.BeaconConfig().ZeroHash[:]) {
t.Errorf("Wanted current finalized root: %v, got: %v",
params.BeaconConfig().ZeroHash, newState.FinalizedRoot)
}
if newState.FinalizedEpoch != params.BeaconConfig().GenesisEpoch {
t.Errorf("Wanted finalized epoch: %d, got: %d",
params.BeaconConfig().GenesisEpoch, newState.FinalizedEpoch)
}
}

View File

@@ -30,7 +30,6 @@ func BlockRootAtSlot(state *pb.BeaconState, slot uint64) ([]byte, error) {
state.Slot-params.BeaconConfig().GenesisSlot,
)
}
return state.LatestBlockRoots[slot%params.BeaconConfig().SlotsPerHistoricalRoot], nil
}

View File

@@ -305,8 +305,6 @@ func ProcessEpoch(ctx context.Context, state *pb.BeaconState, block *pb.BeaconBl
// Calculate the attesting balances for previous and current epoch.
currentBoundaryAttestingBalances := e.TotalBalance(state, currentBoundaryAttesterIndices)
previousActiveValidatorIndices := helpers.ActiveValidatorIndices(state.ValidatorRegistry, prevEpoch)
prevTotalBalance := e.TotalBalance(state, previousActiveValidatorIndices)
prevEpochAttestingBalance := e.TotalBalance(state, prevEpochAttesterIndices)
prevEpochBoundaryAttestingBalances := e.TotalBalance(state, prevEpochBoundaryAttesterIndices)
prevEpochHeadAttestingBalances := e.TotalBalance(state, prevEpochHeadAttesterIndices)
@@ -317,12 +315,10 @@ func ProcessEpoch(ctx context.Context, state *pb.BeaconState, block *pb.BeaconBl
}
// Update justification and finality.
state, err := e.ProcessJustificationAndFinalization(
state, err := e.ProcessJustificationFinalization(
state,
currentBoundaryAttestingBalances,
prevEpochAttestingBalance,
prevTotalBalance,
totalBalance,
)
if err != nil {
return nil, fmt.Errorf("could not process justification and finalization of state: %v", err)