I was making some changes in the code and I saw this method which is for reward calculation:
// WithUpdatedRewards returns an updated number of algos in an AccountData
// to reflect rewards up to some rewards level.
func (u AccountData) WithUpdatedRewards(proto config.ConsensusParams, rewardsLevel uint64) AccountData {
if u.Status != NotParticipating {
var ot OverflowTracker
rewardsUnits := u.MicroAlgos.RewardUnits(proto)
rewardsDelta := ot.Sub(rewardsLevel, u.RewardsBase)
rewards := MicroAlgos{Raw: ot.Mul(rewardsUnits, rewardsDelta)}
u.MicroAlgos = ot.AddA(u.MicroAlgos, rewards)
if ot.Overflowed {
logging.Base().Panicf("AccountData.WithUpdatedRewards(): overflowed account balance when applying rewards %v + %d*(%d-%d)", u.MicroAlgos, rewardsUnits, rewardsLevel, u.RewardsBase)
}
u.RewardsBase = rewardsLevel
// The total reward over the lifetime of the account could exceed a 64-bit value. As a result
// this rewardAlgos counter could potentially roll over.
u.RewardedMicroAlgos = MicroAlgos{Raw: (u.RewardedMicroAlgos.Raw + rewards.Raw)}
}
return u
}
With this code a nonparticipating account can get all his deferred rewards if at some time he changes his status to “participating”. Is this intentional? Shouldn’t the code be something like this:
// WithUpdatedRewards returns an updated number of algos in an AccountData
// to reflect rewards up to some rewards level.
func (u AccountData) WithUpdatedRewards(proto config.ConsensusParams, rewardsLevel uint64) AccountData {
if u.Status != NotParticipating {
var ot OverflowTracker
rewardsUnits := u.MicroAlgos.RewardUnits(proto)
rewardsDelta := ot.Sub(rewardsLevel, u.RewardsBase)
rewards := MicroAlgos{Raw: ot.Mul(rewardsUnits, rewardsDelta)}
u.MicroAlgos = ot.AddA(u.MicroAlgos, rewards)
if ot.Overflowed {
logging.Base().Panicf("AccountData.WithUpdatedRewards(): overflowed account balance when applying rewards %v + %d*(%d-%d)", u.MicroAlgos, rewardsUnits, rewardsLevel, u.RewardsBase)
}
// The total reward over the lifetime of the account could exceed a 64-bit value. As a result
// this rewardAlgos counter could potentially roll over.
u.RewardedMicroAlgos = MicroAlgos{Raw: (u.RewardedMicroAlgos.Raw + rewards.Raw)}
}
// we should update the RewardsBase for non-participants to make sure they can't get rewards later
u.RewardsBase = rewardsLevel
return u
}
And if non-participants are eligible to receive rewards, why shouldn’t we omit the if clause?