code.vegaprotocol.io/vega@v0.79.0/core/rewards/staking_reward_calculator_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package rewards 17 18 import ( 19 "math/rand" 20 "testing" 21 "time" 22 23 bmocks "code.vegaprotocol.io/vega/core/broker/mocks" 24 "code.vegaprotocol.io/vega/core/types" 25 vmock "code.vegaprotocol.io/vega/core/validators/mocks" 26 "code.vegaprotocol.io/vega/libs/num" 27 "code.vegaprotocol.io/vega/logging" 28 29 "github.com/golang/mock/gomock" 30 "github.com/stretchr/testify/require" 31 ) 32 33 var rng *rand.Rand 34 35 func init() { 36 rng = rand.New(rand.NewSource(time.Now().Unix())) 37 } 38 39 func TestStakingRewards(t *testing.T) { 40 t.Run("Calculate the reward when the balance of the reward account is 0", testCalcRewardNoBalance) 41 t.Run("Calculate the reward when the validator scores are 0", testCalcRewardsZeroScores) 42 t.Run("Reward is calculated correctly when max reward per participant is zero (i.e. unrestricted)", testCalcRewardsNoMaxPayout) 43 t.Run("Reward is calculated correctly when max reward per participant restricted but not breached", testCalcRewardsMaxPayoutNotBreached) 44 t.Run("Reward is calculated correctly when max reward per participant restricted and breached - no participant can be topped up", testCalcRewardSmallMaxPayoutBreached) 45 t.Run("Reward is calculated correctly when max reward per participant restricted and breached - participant can be topped up", testCalcRewardsMaxPayoutBreachedPartyCanTakeMore) 46 t.Run("Stop distributing leftover to delegation when remaining is less than 0.1% of max per participant", testEarlyStopCalcRewardsMaxPayoutBreachedPartyCanTakeMore) 47 } 48 49 func testCalcRewardNoBalance(t *testing.T) { 50 delegatorShare, _ := num.DecimalFromString("0.3") 51 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.UintZero(), map[string]num.Decimal{}, []*types.ValidatorData{}, delegatorShare, num.UintZero(), logging.NewTestLogger()) 52 require.Equal(t, num.UintZero(), res.totalReward) 53 require.Equal(t, 0, len(res.partyToAmount)) 54 } 55 56 func testCalcRewardsZeroScores(t *testing.T) { 57 delegatorShare, _ := num.DecimalFromString("0.3") 58 scores := map[string]num.Decimal{} 59 scores["node1"] = num.DecimalZero() 60 scores["node2"] = num.DecimalZero() 61 scores["node3"] = num.DecimalZero() 62 scores["node4"] = num.DecimalZero() 63 64 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(100000), scores, []*types.ValidatorData{}, delegatorShare, num.UintZero(), logging.NewTestLogger()) 65 require.Equal(t, num.UintZero(), res.totalReward) 66 require.Equal(t, 0, len(res.partyToAmount)) 67 } 68 69 func TestFilterZeros(t *testing.T) { 70 delegatorShare, _ := num.DecimalFromString("0.3") 71 scores := map[string]num.Decimal{} 72 scores["node1"] = num.NewDecimalFromFloat(1) 73 scores["node2"] = num.DecimalZero() 74 scores["node3"] = num.DecimalZero() 75 scores["node4"] = num.DecimalZero() 76 77 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(100000), scores, []*types.ValidatorData{{NodeID: "node1", PubKey: "node1", StakeByDelegators: num.NewUint(500), SelfStake: num.NewUint(1000), Delegators: map[string]*num.Uint{"zohar": num.UintZero(), "jeremy": num.NewUint(500)}}}, delegatorShare, num.UintZero(), logging.NewTestLogger()) 78 require.Equal(t, num.NewUint(100000), res.totalReward) 79 require.Equal(t, 2, len(res.partyToAmount)) 80 _, ok := res.partyToAmount["zohar"] 81 require.False(t, ok) 82 83 _, ok = res.partyToAmount["jeremy"] 84 require.True(t, ok) 85 86 _, ok = res.partyToAmount["node1"] 87 require.True(t, ok) 88 } 89 90 // nolint 91 func testCalcRewardsMaxPayoutRepsected(t *testing.T, maxPayout *num.Uint) { 92 delegatorShare, _ := num.DecimalFromString("0.3") 93 ctrl := gomock.NewController(t) 94 broker := bmocks.NewMockBroker(ctrl) 95 broker.EXPECT().SendBatch(gomock.Any()).AnyTimes() 96 valPerformance := vmock.NewMockValidatorPerformance(ctrl) 97 valPerformance.EXPECT().ValidatorPerformanceScore(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(num.DecimalFromFloat(1)).AnyTimes() 98 99 delegatorForVal1 := map[string]*num.Uint{} 100 delegatorForVal1["party1"] = num.NewUint(6000) 101 delegatorForVal1["party2"] = num.NewUint(4000) 102 validator1 := &types.ValidatorData{ 103 NodeID: "node1", 104 PubKey: "node1", 105 SelfStake: num.UintZero(), 106 StakeByDelegators: num.NewUint(10000), 107 Delegators: delegatorForVal1, 108 } 109 validator2 := &types.ValidatorData{ 110 NodeID: "node2", 111 PubKey: "node2", 112 SelfStake: num.NewUint(20000), 113 StakeByDelegators: num.UintZero(), 114 Delegators: map[string]*num.Uint{}, 115 } 116 117 delegatorForVal3 := map[string]*num.Uint{} 118 delegatorForVal3["party1"] = num.NewUint(40000) 119 validator3 := &types.ValidatorData{ 120 NodeID: "node3", 121 PubKey: "node3", 122 SelfStake: num.NewUint(30000), 123 StakeByDelegators: num.NewUint(40000), 124 Delegators: delegatorForVal3, 125 } 126 127 validator4 := &types.ValidatorData{ 128 NodeID: "node4", 129 PubKey: "node4", 130 SelfStake: num.UintZero(), 131 StakeByDelegators: num.UintZero(), 132 Delegators: map[string]*num.Uint{}, 133 } 134 135 validatorData := []*types.ValidatorData{validator1, validator2, validator3, validator4} 136 valScores := map[string]num.Decimal{"node1": num.DecimalFromFloat(0.25), "node2": num.DecimalFromFloat(0.5), "node3": num.DecimalFromFloat(0.25), "node4": num.DecimalZero()} 137 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(1000000), valScores, validatorData, delegatorShare, maxPayout, logging.NewTestLogger()) 138 139 // the normalised scores are as follows (from the test above) 140 // node1 - 0.25 141 // node2 - 0.5 142 // node3 - 0.25 143 // node4 - 0 144 // as node3 and node4 has 0 score they get nothing. 145 // given a reward of 1000000, 146 // 147 // node1 and its delegators get 250,000 148 // node2 and its delegators get 500,000 149 // node3 and its delegators get 250,000 150 // with a delegator share of 0.3, 151 // delegators to node1 get 0.3 * 250000 = 75000 152 // party1 gets 0.6 * 75000 = 45000 153 // party2 gets 0.4 * 75000 = 30000 154 // node1 gets 175000 155 // node2 gets 1 * 500000 = 500000 156 // delegators to node3 get 0.3 * 4/7 * 250000 = 68571 157 // party1 gets 42857 158 // node3 gets 1 - (0.3*4/7) = 207142 159 160 // node1, node2, node3, party1, party2 161 require.Equal(t, 5, len(res.partyToAmount)) 162 163 require.Equal(t, num.NewUint(87857), res.partyToAmount["party1"]) 164 require.Equal(t, num.NewUint(30000), res.partyToAmount["party2"]) 165 require.Equal(t, num.NewUint(175000), res.partyToAmount["node1"]) 166 require.Equal(t, num.NewUint(500000), res.partyToAmount["node2"]) 167 require.Equal(t, num.NewUint(207142), res.partyToAmount["node3"]) 168 169 require.Equal(t, num.NewUint(999999), res.totalReward) 170 } 171 172 func testCalcRewardsNoMaxPayout(t *testing.T) { 173 testCalcRewardsMaxPayoutRepsected(t, num.UintZero()) 174 } 175 176 func testCalcRewardsMaxPayoutNotBreached(t *testing.T) { 177 testCalcRewardsMaxPayoutRepsected(t, num.NewUint(1000000)) 178 } 179 180 func testCalcRewardSmallMaxPayoutBreached(t *testing.T) { 181 delegatorShare, _ := num.DecimalFromString("0.3") 182 delegatorForVal1 := map[string]*num.Uint{} 183 delegatorForVal1["party1"] = num.NewUint(6000) 184 delegatorForVal1["party2"] = num.NewUint(4000) 185 validator1 := &types.ValidatorData{ 186 NodeID: "node1", 187 PubKey: "node1", 188 SelfStake: num.UintZero(), 189 StakeByDelegators: num.NewUint(10000), 190 Delegators: delegatorForVal1, 191 } 192 validator2 := &types.ValidatorData{ 193 NodeID: "node2", 194 PubKey: "node2", 195 SelfStake: num.NewUint(20000), 196 StakeByDelegators: num.UintZero(), 197 Delegators: map[string]*num.Uint{}, 198 } 199 200 delegatorForVal3 := map[string]*num.Uint{} 201 delegatorForVal3["party1"] = num.NewUint(40000) 202 validator3 := &types.ValidatorData{ 203 NodeID: "node3", 204 PubKey: "node3", 205 SelfStake: num.NewUint(30000), 206 StakeByDelegators: num.NewUint(40000), 207 Delegators: delegatorForVal3, 208 } 209 210 validator4 := &types.ValidatorData{ 211 NodeID: "node4", 212 PubKey: "node4", 213 SelfStake: num.UintZero(), 214 StakeByDelegators: num.UintZero(), 215 Delegators: map[string]*num.Uint{}, 216 } 217 218 ctrl := gomock.NewController(t) 219 broker := bmocks.NewMockBroker(ctrl) 220 broker.EXPECT().SendBatch(gomock.Any()).AnyTimes() 221 valPerformance := vmock.NewMockValidatorPerformance(ctrl) 222 valPerformance.EXPECT().ValidatorPerformanceScore(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(num.DecimalFromFloat(1)).AnyTimes() 223 224 validatorData := []*types.ValidatorData{validator1, validator2, validator3, validator4} 225 valScores := map[string]num.Decimal{"node1": num.DecimalFromFloat(0.2), "node2": num.DecimalFromFloat(0.4), "node3": num.DecimalFromFloat(0.4), "node4": num.DecimalZero()} 226 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(1000000), valScores, validatorData, delegatorShare, num.NewUint(20000), logging.NewTestLogger()) 227 228 // the normalised scores are as follows (from the test above) 229 // node1 - 0.2 230 // node2 - 0.4 231 // node3 - 0.4 232 // node4 - 0 233 // as node3 and node4 has 0 score they get nothing. 234 // given a reward of 1000000, 235 // 236 // node1 and its delegators get 200,000 237 // node2 and its delegators get 400,000 238 // node3 and its delegators get 400,000 239 // with a delegator share of 0.3, 240 // delegators to node1 get 0.3 * 200000 = 60000 241 // party1 gets 0.6 * 60000 = 36000 -> 20000 242 // party2 gets 0.4 * 60000 = 24000 -> 20000 243 // node1 gets 140000 -> -> 20000 244 // node2 gets 1 * 400000 = 400000 -> -> 20000 245 // delegators to node3 get 0.3 * 4/7 * 400000 = 68571 246 // party1 gets 68571 -> -> 20000 247 // node3 gets 1 - (0.3*4/7) = 331428 -> -> 20000 248 249 // node1, node2, node3, party1, party2 250 require.Equal(t, 5, len(res.partyToAmount)) 251 252 require.Equal(t, num.NewUint(20000), res.partyToAmount["party1"]) 253 require.Equal(t, num.NewUint(20000), res.partyToAmount["party2"]) 254 require.Equal(t, num.NewUint(20000), res.partyToAmount["node1"]) 255 require.Equal(t, num.NewUint(20000), res.partyToAmount["node2"]) 256 require.Equal(t, num.NewUint(20000), res.partyToAmount["node3"]) 257 require.Equal(t, num.NewUint(100000), res.totalReward) 258 } 259 260 func testCalcRewardsMaxPayoutBreachedPartyCanTakeMore(t *testing.T) { 261 delegatorShare, _ := num.DecimalFromString("0.3") 262 delegatorForVal1 := map[string]*num.Uint{} 263 delegatorForVal1["party1"] = num.NewUint(6000) 264 delegatorForVal1["party2"] = num.NewUint(4000) 265 validator1 := &types.ValidatorData{ 266 NodeID: "node1", 267 PubKey: "node1", 268 SelfStake: num.UintZero(), 269 StakeByDelegators: num.NewUint(10000), 270 Delegators: delegatorForVal1, 271 } 272 validator2 := &types.ValidatorData{ 273 NodeID: "node2", 274 PubKey: "node2", 275 SelfStake: num.NewUint(20000), 276 StakeByDelegators: num.UintZero(), 277 Delegators: map[string]*num.Uint{}, 278 } 279 280 delegatorForVal3 := map[string]*num.Uint{} 281 delegatorForVal3["party1"] = num.NewUint(40000) 282 validator3 := &types.ValidatorData{ 283 NodeID: "node3", 284 PubKey: "node3", 285 SelfStake: num.NewUint(30000), 286 StakeByDelegators: num.NewUint(40000), 287 Delegators: delegatorForVal3, 288 } 289 290 validator4 := &types.ValidatorData{ 291 NodeID: "node4", 292 PubKey: "node4", 293 SelfStake: num.UintZero(), 294 StakeByDelegators: num.UintZero(), 295 Delegators: map[string]*num.Uint{}, 296 } 297 298 ctrl := gomock.NewController(t) 299 broker := bmocks.NewMockBroker(ctrl) 300 broker.EXPECT().SendBatch(gomock.Any()).AnyTimes() 301 valPerformance := vmock.NewMockValidatorPerformance(ctrl) 302 valPerformance.EXPECT().ValidatorPerformanceScore(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(num.DecimalFromFloat(1)).AnyTimes() 303 304 validatorData := []*types.ValidatorData{validator1, validator2, validator3, validator4} 305 306 valScores := map[string]num.Decimal{"node1": num.DecimalFromFloat(0.25), "node2": num.DecimalFromFloat(0.5), "node3": num.DecimalFromFloat(0.25), "node4": num.DecimalZero()} 307 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(1000000), valScores, validatorData, delegatorShare, num.NewUint(40000), logging.NewTestLogger()) 308 309 // the normalised scores are as follows (from the test above) 310 // node1 - 0.25 311 // node2 - 0.5 312 // node3 - 0.25 313 // node4 - 0 314 // as node3 and node4 has 0 score they get nothing. 315 // given a reward of 1000000, 316 // 317 // node1 and its delegators get 250,000 318 // node2 and its delegators get 500,000 319 // node3 and its delegators get 250,000 320 // with a delegator share of 0.3, 321 // delegators to node1 get 0.3 * 250000 = 75000 322 // party1 gets 0.6 * 75000 = 45000 -> 40000 323 // party2 gets 0.4 * 75000 = 30000 -> party can take 5k more from what's left => 324 // when distributing the 5k leftover: 325 // iteration 0: party2 gets 0.4 * 75000 = 30000 = 2000 326 // iteration 1: party2 gets 0.4*5000 = 2000 327 // iteration 2: party2 gets 0.4*3000 = 1200 328 // iteration 3: party2 gets 0.4*1800 = 720 329 // iteration 4: party2 gets 0.4*1080 = 432 330 // iteration 5: party2 gets 0.4*648 = 259 331 // iteration 6: party2 gets 0.4*388 = 155 332 // iteration 7: party2 gets 0.4*233 = 93 333 // iteration 8: party2 gets 0.4*140 = 56 334 // iteration 9: party2 gets 0.4*84 = 34 335 // this runs for 10 iteration and stops therefore: 336 // and party 2 gets: 30000 + 2000 + 1200 + 720 +432 + 259 + 155 + 93 + 56 + 34 = 34949 337 // node1 gets 175000 -> 40000 338 // node2 gets 1 * 500000 = 500000 -> 40000 339 // delegators to node3 get 0.3 * 4/7 * 250000 = 42857 340 // party1 gets 42857 -> 40000 341 // node3 gets 1 - (0.3*4/7) = 207142 -> 40000 342 // node1, node2, party1, party2 343 require.Equal(t, 5, len(res.partyToAmount)) 344 345 require.Equal(t, num.NewUint(40000), res.partyToAmount["party1"]) 346 require.Equal(t, num.NewUint(34949), res.partyToAmount["party2"]) 347 require.Equal(t, num.NewUint(40000), res.partyToAmount["node1"]) 348 require.Equal(t, num.NewUint(40000), res.partyToAmount["node2"]) 349 require.Equal(t, num.NewUint(40000), res.partyToAmount["node3"]) 350 require.Equal(t, num.NewUint(194949), res.totalReward) 351 } 352 353 func testEarlyStopCalcRewardsMaxPayoutBreachedPartyCanTakeMore(t *testing.T) { 354 delegatorShare, _ := num.DecimalFromString("0.3") 355 delegatorForVal1 := map[string]*num.Uint{} 356 delegatorForVal1["party1"] = num.NewUint(6000) 357 delegatorForVal1["party2"] = num.NewUint(4000) 358 validator1 := &types.ValidatorData{ 359 NodeID: "node1", 360 PubKey: "node1", 361 SelfStake: num.UintZero(), 362 StakeByDelegators: num.NewUint(10000), 363 Delegators: delegatorForVal1, 364 } 365 validator2 := &types.ValidatorData{ 366 NodeID: "node2", 367 PubKey: "node2", 368 SelfStake: num.NewUint(20000), 369 StakeByDelegators: num.UintZero(), 370 Delegators: map[string]*num.Uint{}, 371 } 372 373 delegatorForVal3 := map[string]*num.Uint{} 374 delegatorForVal3["party1"] = num.NewUint(40000) 375 validator3 := &types.ValidatorData{ 376 NodeID: "node3", 377 PubKey: "node3", 378 SelfStake: num.NewUint(30000), 379 StakeByDelegators: num.NewUint(40000), 380 Delegators: delegatorForVal3, 381 } 382 383 validator4 := &types.ValidatorData{ 384 NodeID: "node4", 385 PubKey: "node4", 386 SelfStake: num.UintZero(), 387 StakeByDelegators: num.UintZero(), 388 Delegators: map[string]*num.Uint{}, 389 } 390 391 ctrl := gomock.NewController(t) 392 broker := bmocks.NewMockBroker(ctrl) 393 broker.EXPECT().SendBatch(gomock.Any()).AnyTimes() 394 valPerformance := vmock.NewMockValidatorPerformance(ctrl) 395 valPerformance.EXPECT().ValidatorPerformanceScore(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(num.DecimalFromFloat(1)).AnyTimes() 396 397 validatorData := []*types.ValidatorData{validator1, validator2, validator3, validator4} 398 valScores := map[string]num.Decimal{"node1": num.DecimalFromFloat(0.25), "node2": num.DecimalFromFloat(0.5), "node3": num.DecimalFromFloat(0.25), "node4": num.DecimalZero()} 399 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(1000000), valScores, validatorData, delegatorShare, num.NewUint(1000000000), logging.NewTestLogger()) 400 401 // 0.1% of 1000000000 = 1000000 - this test is demonstrating that regardless of the remaining balance to give to delegators is less than 0.1% of the max 402 // payout per participant, we still run one round and then stop. 403 404 // the normalised scores are as follows (from the test above) 405 // node1 - 0.25 406 // node2 - 0.5 407 // node3 - 0.25 408 // node4 - 0 409 // as node3 and node4 has 0 score they get nothing. 410 // given a reward of 1000000, 411 // 412 // node1 and its delegators get 250,000 413 // node2 and its delegators get 500,000 414 // node3 and its delegators get 250,000 415 // with a delegator share of 0.3, 416 // delegators to node1 get 0.3 * 250000 = 75000 417 // party1 gets 0.6 * 75000 = 45000 418 // party2 gets 0.4 * 75000 = 30000 419 // node1 gets 175000 420 // node2 gets 1 * 500000 = 500000 421 // delegators to node3 get 0.3 * 4/7 * 250000 = 42857 422 // party1 gets 42857 423 // node3 gets 1 - (0.3*4/7) = 207142 -> 207142 424 // node1, node2, party1, party2 425 require.Equal(t, 5, len(res.partyToAmount)) 426 427 require.Equal(t, num.NewUint(87857), res.partyToAmount["party1"]) 428 require.Equal(t, num.NewUint(30000), res.partyToAmount["party2"]) 429 require.Equal(t, num.NewUint(175000), res.partyToAmount["node1"]) 430 require.Equal(t, num.NewUint(500000), res.partyToAmount["node2"]) 431 require.Equal(t, num.NewUint(207142), res.partyToAmount["node3"]) 432 require.Equal(t, num.NewUint(999999), res.totalReward) 433 } 434 435 func TestValidatorIsNotBeingStarved(t *testing.T) { 436 delegatorShare, _ := num.DecimalFromString("0.3") 437 delegatorForVal1 := map[string]*num.Uint{} 438 delegatorForVal1["party1"] = num.NewUint(6000) 439 delegatorForVal1["party2"] = num.NewUint(3000) 440 delegatorForVal1["n2"] = num.NewUint(1000) 441 validator1 := &types.ValidatorData{ 442 NodeID: "node1", 443 PubKey: "n1", 444 SelfStake: num.UintZero(), 445 StakeByDelegators: num.NewUint(10000), 446 Delegators: delegatorForVal1, 447 } 448 validator2 := &types.ValidatorData{ 449 NodeID: "node2", 450 PubKey: "n2", 451 SelfStake: num.NewUint(20000), 452 StakeByDelegators: num.UintZero(), 453 Delegators: map[string]*num.Uint{}, 454 } 455 456 delegatorForVal3 := map[string]*num.Uint{} 457 delegatorForVal3["party1"] = num.NewUint(40000) 458 validator3 := &types.ValidatorData{ 459 NodeID: "node3", 460 PubKey: "n3", 461 SelfStake: num.NewUint(30000), 462 StakeByDelegators: num.NewUint(40000), 463 Delegators: delegatorForVal3, 464 } 465 466 validator4 := &types.ValidatorData{ 467 NodeID: "node4", 468 PubKey: "n4", 469 SelfStake: num.UintZero(), 470 StakeByDelegators: num.UintZero(), 471 Delegators: map[string]*num.Uint{}, 472 } 473 ctrl := gomock.NewController(t) 474 broker := bmocks.NewMockBroker(ctrl) 475 broker.EXPECT().SendBatch(gomock.Any()).AnyTimes() 476 valPerformance := vmock.NewMockValidatorPerformance(ctrl) 477 valPerformance.EXPECT().ValidatorPerformanceScore(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(num.DecimalFromFloat(1)).AnyTimes() 478 479 validatorData := []*types.ValidatorData{validator1, validator2, validator3, validator4} 480 valScores := map[string]num.Decimal{"node1": num.DecimalFromFloat(0.25), "node2": num.DecimalFromFloat(0.5), "node3": num.DecimalFromFloat(0.25), "node4": num.DecimalZero()} 481 res := calculateRewardsByStake("1", "asset", "rewardsAccountID", num.NewUint(1000000), valScores, validatorData, delegatorShare, num.NewUint(1000000000), logging.NewTestLogger()) 482 483 // 0.1% of 1000000000 = 1000000 - this test is demonstrating that regardless of the remaining balance to give to delegators is less than 0.1% of the max 484 // payout per participant, we still run one round and then stop. 485 486 // the normalised scores are as follows (from the test above) 487 // node1 - 0.25 488 // node2 - 0.5 489 // node3 - 0.25 490 // node4 - 0 491 // as node4 has 0 score they get nothing. 492 // given a reward of 1000000, 493 // 494 // node1 and its delegators get 250,000 495 // node2 and its delegators get 500,000 496 // node3 and its delegators get 250,000 497 // with a delegator share of 0.3, 498 // delegators to node1 get 0.3 * 250000 = 75000 499 // party1 gets 0.6 * 75000 = 45000 500 // party2 gets 0.3 * 75000 = 22500 501 // n2 gets 0.1 * 75000 = 7500 502 // node1 gets 175000 503 // node2 gets 1 * 500000 = 500000 + 7500 (from the delegation to node1) = 507500 504 // delegators to node3 get 0.3 * 4/7 * 250000 = 42857 505 // party1 gets 42857 506 // node3 gets 1 - (0.3*4/7) = 207142 -> 207142 507 // node1, node2, party1, party2 508 require.Equal(t, 5, len(res.partyToAmount)) 509 510 require.Equal(t, num.NewUint(87857), res.partyToAmount["party1"]) 511 require.Equal(t, num.NewUint(22500), res.partyToAmount["party2"]) 512 require.Equal(t, num.NewUint(175000), res.partyToAmount["n1"]) 513 require.Equal(t, num.NewUint(507500), res.partyToAmount["n2"]) 514 require.Equal(t, num.NewUint(207142), res.partyToAmount["n3"]) 515 require.Equal(t, num.NewUint(999999), res.totalReward) 516 }