2018-11-21 06:23:18 +00:00
|
|
|
package incentives
|
2018-08-24 04:09:59 +00:00
|
|
|
|
|
|
|
import (
|
2018-09-21 19:56:39 +00:00
|
|
|
"math"
|
2018-08-24 04:09:59 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
2018-11-08 03:22:31 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/mathutil"
|
2018-11-18 16:39:35 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
2018-08-24 04:09:59 +00:00
|
|
|
)
|
|
|
|
|
2018-11-21 06:23:18 +00:00
|
|
|
func newValidators() []*pb.ValidatorRecord {
|
2018-08-24 04:09:59 +00:00
|
|
|
var validators []*pb.ValidatorRecord
|
2018-09-21 19:56:39 +00:00
|
|
|
for i := 0; i < 10; i++ {
|
2018-10-10 02:34:50 +00:00
|
|
|
validator := &pb.ValidatorRecord{Balance: 32 * 1e9, Status: uint64(params.Active)}
|
2018-08-24 04:09:59 +00:00
|
|
|
validators = append(validators, validator)
|
|
|
|
}
|
2018-09-21 19:56:39 +00:00
|
|
|
return validators
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestComputeValidatorRewardsAndPenalties(t *testing.T) {
|
2018-11-21 06:23:18 +00:00
|
|
|
validators := newValidators()
|
2018-10-10 02:34:50 +00:00
|
|
|
defaultBalance := uint64(32 * 1e9)
|
2018-09-21 19:56:39 +00:00
|
|
|
|
|
|
|
participatedDeposit := 4 * defaultBalance
|
|
|
|
totalDeposit := 10 * defaultBalance
|
2018-11-21 06:23:18 +00:00
|
|
|
rewQuotient := RewardQuotient(totalDeposit)
|
|
|
|
penaltyQuotient := QuadraticPenaltyQuotient()
|
2018-09-21 19:56:39 +00:00
|
|
|
timeSinceFinality := uint64(5)
|
2018-08-24 04:09:59 +00:00
|
|
|
|
|
|
|
data := &pb.CrystallizedState{
|
2018-10-14 02:12:06 +00:00
|
|
|
Validators: validators,
|
|
|
|
ValidatorSetChangeSlot: 1,
|
|
|
|
LastJustifiedSlot: 4,
|
|
|
|
LastFinalizedSlot: 3,
|
2018-08-24 04:09:59 +00:00
|
|
|
}
|
|
|
|
|
2018-11-21 06:23:18 +00:00
|
|
|
activeValidatorIndices := make([]uint32, 0, len(validators))
|
|
|
|
for i, v := range validators {
|
|
|
|
if v.Status == uint64(params.Active) {
|
|
|
|
activeValidatorIndices = append(activeValidatorIndices, uint32(i))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-21 19:56:39 +00:00
|
|
|
rewardedValidators := CalculateRewards(
|
|
|
|
[]uint32{2, 3, 6, 9},
|
2018-11-21 06:23:18 +00:00
|
|
|
activeValidatorIndices,
|
2018-08-25 18:59:46 +00:00
|
|
|
data.Validators,
|
2018-11-21 06:23:18 +00:00
|
|
|
totalDeposit,
|
2018-09-21 19:56:39 +00:00
|
|
|
participatedDeposit,
|
2018-11-21 06:23:18 +00:00
|
|
|
timeSinceFinality,
|
|
|
|
)
|
2018-09-21 19:56:39 +00:00
|
|
|
|
|
|
|
expectedBalance := defaultBalance - defaultBalance/uint64(rewQuotient)
|
|
|
|
|
|
|
|
if rewardedValidators[0].Balance != expectedBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[0].Balance, expectedBalance)
|
|
|
|
}
|
|
|
|
|
2018-11-22 19:18:06 +00:00
|
|
|
expectedBalance = uint64(int64(defaultBalance) + int64(defaultBalance/rewQuotient)*(2*int64(participatedDeposit)-int64(totalDeposit))/int64(totalDeposit))
|
2018-09-21 19:56:39 +00:00
|
|
|
|
|
|
|
if rewardedValidators[6].Balance != expectedBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[6].Balance, expectedBalance)
|
|
|
|
}
|
|
|
|
|
|
|
|
if rewardedValidators[9].Balance != expectedBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[9].Balance, expectedBalance)
|
|
|
|
}
|
|
|
|
|
2018-11-21 06:23:18 +00:00
|
|
|
validators = newValidators()
|
2018-09-27 03:20:59 +00:00
|
|
|
timeSinceFinality = 200
|
2018-09-21 19:56:39 +00:00
|
|
|
|
2018-11-21 06:23:18 +00:00
|
|
|
activeValidatorIndices = make([]uint32, 0, len(validators))
|
|
|
|
for i, v := range validators {
|
|
|
|
if v.Status == uint64(params.Active) {
|
|
|
|
activeValidatorIndices = append(activeValidatorIndices, uint32(i))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-21 19:56:39 +00:00
|
|
|
rewardedValidators = CalculateRewards(
|
|
|
|
[]uint32{1, 2, 7, 8},
|
2018-11-21 06:23:18 +00:00
|
|
|
activeValidatorIndices,
|
2018-09-21 19:56:39 +00:00
|
|
|
validators,
|
2018-11-21 06:23:18 +00:00
|
|
|
totalDeposit,
|
2018-09-21 19:56:39 +00:00
|
|
|
participatedDeposit,
|
|
|
|
timeSinceFinality)
|
|
|
|
|
|
|
|
if rewardedValidators[1].Balance != defaultBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[1].Balance, defaultBalance)
|
|
|
|
}
|
|
|
|
|
|
|
|
if rewardedValidators[7].Balance != defaultBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[7].Balance, defaultBalance)
|
|
|
|
}
|
2018-09-19 14:23:26 +00:00
|
|
|
|
2018-09-21 19:56:39 +00:00
|
|
|
expectedBalance = defaultBalance - (defaultBalance/rewQuotient + defaultBalance*timeSinceFinality/penaltyQuotient)
|
|
|
|
|
|
|
|
if rewardedValidators[0].Balance != expectedBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[0].Balance, expectedBalance)
|
|
|
|
}
|
|
|
|
|
|
|
|
if rewardedValidators[9].Balance != expectedBalance {
|
|
|
|
t.Fatalf("validator balance not updated correctly: %d, %d", rewardedValidators[9].Balance, expectedBalance)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRewardQuotient(t *testing.T) {
|
2018-11-21 06:23:18 +00:00
|
|
|
defaultBalance := uint64(2 * 1e9)
|
|
|
|
totalDeposit := defaultBalance
|
|
|
|
rewQuotient := RewardQuotient(totalDeposit)
|
2018-09-21 19:56:39 +00:00
|
|
|
|
2018-11-18 16:39:35 +00:00
|
|
|
if rewQuotient != params.BeaconConfig().BaseRewardQuotient {
|
2018-09-21 19:56:39 +00:00
|
|
|
t.Errorf("incorrect reward quotient: %d", rewQuotient)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestQuadraticPenaltyQuotient(t *testing.T) {
|
2018-11-21 06:23:18 +00:00
|
|
|
penaltyQuotient := QuadraticPenaltyQuotient()
|
2018-10-23 16:07:43 +00:00
|
|
|
if penaltyQuotient != uint64(math.Pow(2, 32)) {
|
2018-09-21 19:56:39 +00:00
|
|
|
t.Errorf("incorrect penalty quotient %d", penaltyQuotient)
|
2018-08-24 04:09:59 +00:00
|
|
|
}
|
2018-09-21 19:56:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestQuadraticPenalty(t *testing.T) {
|
|
|
|
numOfSlots := uint64(4)
|
|
|
|
penalty := QuadraticPenalty(numOfSlots)
|
|
|
|
penaltyQuotient := uint64(math.Pow(math.Pow(2, 17), 0.5))
|
|
|
|
|
|
|
|
expectedPenalty := (numOfSlots * numOfSlots / 2) / penaltyQuotient
|
|
|
|
|
|
|
|
if expectedPenalty != penalty {
|
|
|
|
t.Errorf("quadric penalty is not the expected amount for %d slots %d", numOfSlots, penalty)
|
2018-08-24 04:09:59 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-27 03:20:59 +00:00
|
|
|
|
|
|
|
func TestRewardCrosslink(t *testing.T) {
|
|
|
|
totalDeposit := uint64(6e18)
|
|
|
|
participatedDeposit := uint64(3e18)
|
2018-11-18 16:39:35 +00:00
|
|
|
rewardQuotient := params.BeaconConfig().BaseRewardQuotient * mathutil.IntegerSquareRoot(totalDeposit)
|
2018-09-27 03:20:59 +00:00
|
|
|
validator := &pb.ValidatorRecord{
|
|
|
|
Balance: 1e18,
|
|
|
|
}
|
|
|
|
|
2018-11-22 19:18:06 +00:00
|
|
|
RewardValidatorCrosslink(totalDeposit, participatedDeposit, rewardQuotient, validator)
|
2018-09-27 03:20:59 +00:00
|
|
|
|
|
|
|
if validator.Balance != 1e18 {
|
|
|
|
t.Errorf("validator balances have changed when they were not supposed to %d", validator.Balance)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPenaltyCrosslink(t *testing.T) {
|
|
|
|
totalDeposit := uint64(6e18)
|
2018-11-18 16:39:35 +00:00
|
|
|
rewardQuotient := params.BeaconConfig().BaseRewardQuotient * mathutil.IntegerSquareRoot(totalDeposit)
|
2018-09-27 03:20:59 +00:00
|
|
|
validator := &pb.ValidatorRecord{
|
|
|
|
Balance: 1e18,
|
|
|
|
}
|
2018-10-04 04:49:18 +00:00
|
|
|
timeSinceConfirmation := uint64(10)
|
2018-11-21 06:23:18 +00:00
|
|
|
quadraticQuotient := QuadraticPenaltyQuotient()
|
2018-09-27 03:20:59 +00:00
|
|
|
|
2018-11-22 19:18:06 +00:00
|
|
|
PenaliseValidatorCrosslink(timeSinceConfirmation, rewardQuotient, validator)
|
2018-10-06 15:30:15 +00:00
|
|
|
expectedBalance := 1e18 - (1e18/rewardQuotient + 1e18*timeSinceConfirmation/quadraticQuotient)
|
2018-09-27 03:20:59 +00:00
|
|
|
|
|
|
|
if validator.Balance != expectedBalance {
|
|
|
|
t.Fatalf("balances not updated correctly %d, %d", validator.Balance, expectedBalance)
|
|
|
|
}
|
|
|
|
}
|