diff --git a/consensus/istanbul/backend/engine.go b/consensus/istanbul/backend/engine.go index 711b0882b7..5a1c30e898 100644 --- a/consensus/istanbul/backend/engine.go +++ b/consensus/istanbul/backend/engine.go @@ -471,6 +471,7 @@ func (sb *Backend) Finalize(chain consensus.ChainReader, header *types.Header, s snapshot = state.Snapshot() err = sb.distributeEpochRewards(header, state) if err != nil { + sb.logger.Error("Failed to distribute epoch rewards", "blockNumber", header.Number, "err", err) state.RevertToSnapshot(snapshot) } } diff --git a/consensus/istanbul/backend/pos.go b/consensus/istanbul/backend/pos.go index 2024ca693b..03217da26e 100644 --- a/consensus/istanbul/backend/pos.go +++ b/consensus/istanbul/backend/pos.go @@ -41,6 +41,15 @@ import ( func (sb *Backend) distributeEpochRewards(header *types.Header, state *state.StateDB) error { start := time.Now() defer sb.rewardDistributionTimer.UpdateSince(start) + logger := sb.logger.New("func", "Backend.distributeEpochPaymentsAndRewards", "blocknum", header.Number.Uint64()) + + // Check if reward distribution has been frozen and return early without error if it is. + if frozen, err := epoch_rewards.EpochRewardsIsFrozen(header, state); err != nil { + logger.Warn("Failed to determine if epoch rewards are frozen", "err", err) + } else if frozen { + logger.Debug("Epoch rewards are frozen, skipping distribution") + return nil + } err := epoch_rewards.UpdateTargetVotingYield(header, state) if err != nil { @@ -50,14 +59,16 @@ func (sb *Backend) distributeEpochRewards(header *types.Header, state *state.Sta if err != nil { return err } - log.Debug("Calculated target rewards", "validatorReward", validatorReward, "totalVoterRewards", totalVoterRewards, "communityReward", communityReward) + + logger.Debug("Calculated target rewards", "validatorReward", validatorReward, "totalVoterRewards", totalVoterRewards, "communityReward", communityReward) // The validator set that signs off on the last block of the epoch is the one that we need to // iterate over. valSet := sb.GetValidators(big.NewInt(header.Number.Int64()-1), header.ParentHash) if len(valSet) == 0 { + err := errors.New("Unable to fetch validator set to update scores and distribute rewards") - sb.logger.Error(err.Error()) + logger.Error(err.Error()) return err } diff --git a/contract_comm/epoch_rewards/epoch_rewards.go b/contract_comm/epoch_rewards/epoch_rewards.go index af38fcc2b6..bc6035b1ae 100644 --- a/contract_comm/epoch_rewards/epoch_rewards.go +++ b/contract_comm/epoch_rewards/epoch_rewards.go @@ -91,6 +91,20 @@ const epochRewardsABIString string = `[ "payable": false, "stateMutability": "view", "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "frozen", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" } ] ` @@ -135,3 +149,12 @@ func GetCarbonOffsettingPartnerAddress(header *types.Header, state vm.StateDB) ( } return carbonOffsettingPartner, nil } + +func EpochRewardsIsFrozen(header *types.Header, state vm.StateDB) (bool, error) { + var frozen bool + _, err := contract_comm.MakeStaticCall(params.EpochRewardsRegistryId, epochRewardsABI, "frozen", []interface{}{}, &[]interface{}{&frozen}, params.MaxGasForIsFrozen, header, state) + if err != nil { + return false, err + } + return frozen, nil +}