From cc878c6ab7e735422f85dcd7f4024c4132031a3a Mon Sep 17 00:00:00 2001 From: parmarrushabh Date: Sat, 20 Oct 2018 16:08:26 +0530 Subject: [PATCH] Add unit test for calculate reward for holders. --- contracts/utils.go | 23 ++++--- contracts/validator/validator_test.go | 94 ++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 12 deletions(-) diff --git a/contracts/utils.go b/contracts/utils.go index 5aac8ba5a2..70f7857ee0 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -126,15 +126,15 @@ func GetRewardForCheckpoint(blockSignerAddr common.Address, number uint64, rChec // Get Owner for signers. owners := make(map[common.Address]*rewardLog) if len(signers) > 0 { - for addr, log := range signers { + for addr, rwLog := range signers { owner, err := GetCandidatesOwnerByAddress(validator, addr) if err != nil { owner = addr } if _, ok := owners[owner]; ok { - owners[owner].Sign = owners[owner].Sign + log.Sign + owners[owner].Sign = owners[owner].Sign + rwLog.Sign } else { - owners[owner] = log + owners[owner] = rwLog } } } @@ -183,7 +183,8 @@ func GetCandidatesOwnerByAddress(validator *contract2.XDCValidator, addr common. // Get reward balance rates. func GetRewardBalancesRate(masterAddr common.Address, totalReward *big.Int, validator *contract2.XDCValidator) (map[common.Address]*big.Int, error) { balances := make(map[common.Address]*big.Int) - rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(RewardMasterPercent/100)) + rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(RewardMasterPercent)) + rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100)) balances[masterAddr] = rewardMaster // Get voters for masternode. opts := new(bind.CallOpts) @@ -194,18 +195,19 @@ func GetRewardBalancesRate(masterAddr common.Address, totalReward *big.Int, vali } if len(voters) > 0 { - totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(RewardVoterPercent/100)) + totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(RewardVoterPercent)) + totalVoterReward = new(big.Int).Div(totalVoterReward, new(big.Int).SetUint64(100)) totalCap := new(big.Int) // Get voters capacities. voterCaps := make(map[common.Address]*big.Int) for _, voteAddr := range voters { - cap, err := validator.GetVoterCap(opts, masterAddr, voteAddr) + voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr) if err != nil { log.Error("Fail to get vote capacity", "error", err) return nil, err } - totalCap.Add(totalCap, cap) - voterCaps[voteAddr] = cap + totalCap.Add(totalCap, voterCap) + voterCaps[voteAddr] = voterCap } for addr, voteCap := range voterCaps { balances[addr] = new(big.Int).Mul(totalVoterReward, voteCap) @@ -213,8 +215,9 @@ func GetRewardBalancesRate(masterAddr common.Address, totalReward *big.Int, vali } } - balances[common.HexToAddress(FoudationWalletAddr)] = - new(big.Int).Mul(totalReward, new(big.Int).SetInt64(RewardFoundationPercent/100)) + foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(RewardFoundationPercent)) + foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100)) + balances[common.HexToAddress(FoudationWalletAddr)] = foudationReward return balances, nil } \ No newline at end of file diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index b9759e2e9b..0fe062b730 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -8,11 +8,23 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" + "time" + "github.com/ethereum/go-ethereum/contracts" + "github.com/ethereum/go-ethereum/contracts/validator/contract" + "math/rand" ) var ( - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr = crypto.PubkeyToAddress(key.PublicKey) + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr = crypto.PubkeyToAddress(key.PublicKey) + acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") + acc3Key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + acc4Key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee04aefe388d1e14474d32c45c72ce7b7a") + acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey) + acc2Addr = crypto.PubkeyToAddress(acc2Key.PublicKey) + acc3Addr = crypto.PubkeyToAddress(acc3Key.PublicKey) + acc4Addr = crypto.PubkeyToAddress(acc4Key.PublicKey) ) func TestValidator(t *testing.T) { @@ -36,4 +48,82 @@ func TestValidator(t *testing.T) { t.Log("candidate", it.String(), "validator owner", owner.String()) } contractBackend.Commit() +} + +func TestRewardBalance(t *testing.T) { + contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ + acc1Addr: {Balance: new(big.Int).SetUint64(10000000)}, + acc2Addr: {Balance: new(big.Int).SetUint64(10000000)}, + acc4Addr: {Balance: new(big.Int).SetUint64(10000000)}, + }) + acc1Opts := bind.NewKeyedTransactor(acc1Key) + acc2Opts := bind.NewKeyedTransactor(acc2Key) + accounts := []*bind.TransactOpts{acc1Opts, acc2Opts} + transactOpts := bind.NewKeyedTransactor(acc1Key) + + validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100)) + if err != nil { + t.Fatalf("can't deploy root registry: %v", err) + } + contractBackend.Commit() + + // Propose master node acc3Addr. + opts := bind.NewKeyedTransactor(acc4Key) + opts.Value = new(big.Int).SetUint64(50000) + acc4Validator, _ := NewValidator(opts, validatorAddr, contractBackend) + acc4Validator.Propose(acc3Addr, "http://") + contractBackend.Commit() + + totalVote := 0 + type logCap struct { + Addr string + Balance int + } + logCaps := make(map[int]*logCap) + for i := 0; i <= 10; i++ { + rand.Seed(time.Now().UTC().UnixNano()) + randIndex := rand.Intn(len(accounts)) + randCap := rand.Intn(10) * 1000 + if randCap <= 0 { + randCap = 1000 + } + totalVote += randCap + accounts[randIndex].Value = new(big.Int).SetInt64(int64(randCap)) + validator, err := NewValidator(accounts[randIndex], validatorAddr, contractBackend) + if err != nil { + t.Fatalf("can't get current validator: %v", err) + } + validator.Vote(acc3Addr) + contractBackend.Commit() + logCaps[i] = &logCap{accounts[randIndex].From.String(), randCap} + } + + totalReward := new(big.Int).SetInt64(15 * 1000) + rewards, err := contracts.GetRewardBalancesRate(acc3Addr, totalReward, baseValidator) + + afterReward := new(big.Int) + for _, value := range rewards { + afterReward = new(big.Int).Add(afterReward, value) + } + + if totalReward.Int64()+1 < afterReward.Int64() || totalReward.Int64()-1 > afterReward.Int64() { + callOpts := new(bind.CallOpts) + voters, err := baseValidator.GetVoters(callOpts, acc3Addr) + if err != nil { + t.Fatal("Can not get voters in validator contract.", err) + } + for addr, capacity := range logCaps { + t.Errorf("from %v - %v", addr, capacity) + } + for _, voter := range voters { + voteCap, _ := baseValidator.GetVoterCap(callOpts, acc3Addr, voter) + t.Errorf("vote %v - %v", voter.String(), voteCap) + } + for addr, value := range rewards { + t.Errorf("reaward %v - %v", addr.String(), value) + } + + t.Errorf("reward total %v - %v", totalReward, afterReward) + } + } \ No newline at end of file