From 264a6dc9dbeb60752fe0af71db9fef875a5a6157 Mon Sep 17 00:00:00 2001 From: parmarrushabh Date: Sat, 20 Oct 2018 16:20:30 +0530 Subject: [PATCH] Fixed calculate reward for holders. --- cmd/XDC/main.go | 2 +- common/types.go | 8 ++-- contracts/utils.go | 68 +++++++++++++-------------- contracts/utils_test.go | 2 +- contracts/validator/validator_test.go | 9 ++-- eth/backend.go | 19 ++++++-- 6 files changed, 61 insertions(+), 47 deletions(-) diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 455d82626d..531eb902c3 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -360,7 +360,7 @@ func startNode(ctx *cli.Context, stack *node.Node) { if err != nil { utils.Fatalf("Fail to connect RPC: %v", err) } - addr := common.HexToAddress(common.Validator) + addr := common.HexToAddress(common.MasternodeVotingSMC) validator, err := validatorContract.NewXDCValidator(addr, client) if err != nil { utils.Fatalf("Fail to get validator smc: %v", err) diff --git a/common/types.go b/common/types.go index cb54ada91e..0e98608182 100644 --- a/common/types.go +++ b/common/types.go @@ -28,10 +28,10 @@ import ( ) const ( - HashLength = 32 - AddressLength = 20 - BlockSigners = "0x0000000000000000000000000000000000000089" - XDCValidator = "0x0000000000000000000000000000000000000088" + HashLength = 32 + AddressLength = 20 + BlockSigners = "0x0000000000000000000000000000000000000089" + MasternodeVotingSMC = "0x0000000000000000000000000000000000000088" ) var ( diff --git a/contracts/utils.go b/contracts/utils.go index 70f7857ee0..2aa2a3228d 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -6,8 +6,9 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts/blocksigner/contract" - contract2 "github.com/ethereum/go-ethereum/contracts/validator/contract" + contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -116,36 +117,13 @@ func GetRewardForCheckpoint(blockSignerAddr common.Address, number uint64, rChec } } - // Get validator. - validator, err := contract2.NewXDCValidator(common.HexToAddress(common.XDCValidator), client) - if err != nil { - log.Error("Fail get instance of XDC Validator", "error", err) - return nil, err - } - - // Get Owner for signers. - owners := make(map[common.Address]*rewardLog) - if len(signers) > 0 { - 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 + rwLog.Sign - } else { - owners[owner] = rwLog - } - } - } - log.Info("Calculate reward at checkpoint", "startBlock", startBlockNumber, "endBlock", endBlockNumber) - return owners, nil + return signers, nil } // Calculate reward for signers. -func CalculateReward(chainReward *big.Int, signers map[common.Address]*rewardLog, totalSigner uint64) (map[common.Address]*big.Int, error) { +func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*rewardLog, totalSigner uint64) (map[common.Address]*big.Int, error) { resultSigners := make(map[common.Address]*big.Int) // Add reward for signers. for signer, rLog := range signers { @@ -168,24 +146,39 @@ func CalculateReward(chainReward *big.Int, signers map[common.Address]*rewardLog } // Get candidate owner by address. -func GetCandidatesOwnerByAddress(validator *contract2.XDCValidator, addr common.Address) (common.Address, error) { - owner := common.Address{} +func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address { + owner := signerAddr opts := new(bind.CallOpts) - owner, err := validator.GetCandidateOwner(opts, addr) + owner, err := validator.GetCandidateOwner(opts, signerAddr) if err != nil { log.Error("Fail get candidate owner", "error", err) - return owner, err + return owner } - return owner, nil + return owner } -// Get reward balance rates. -func GetRewardBalancesRate(masterAddr common.Address, totalReward *big.Int, validator *contract2.XDCValidator) (map[common.Address]*big.Int, error) { +// Calculate reward for holders. +func CalculateRewardForHolders(validator *contractValidator.XDCValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) error { + rewards, err := GetRewardBalancesRate(signer, calcReward, validator) + if err != nil { + return err + } + if len(rewards) > 0 { + for holder, reward := range rewards { + state.AddBalance(holder, reward) + } + } + return nil +} + +// Get reward balance rates for master node, founder and holders. +func GetRewardBalancesRate(masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) { + owner := GetCandidatesOwnerBySigner(validator, masterAddr) balances := make(map[common.Address]*big.Int) 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 + balances[owner] = rewardMaster // Get voters for masternode. opts := new(bind.CallOpts) voters, err := validator.GetVoters(opts, masterAddr) @@ -219,5 +212,12 @@ func GetRewardBalancesRate(masterAddr common.Address, totalReward *big.Int, vali foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100)) balances[common.HexToAddress(FoudationWalletAddr)] = foudationReward + jsonHolders, err := json.Marshal(balances) + if err != nil { + log.Error("Fail to parse json holders", "error", err) + return nil, err + } + log.Info("Holders reward", "holders", string(jsonHolders), "master node", masterAddr.String()) + return balances, nil } \ No newline at end of file diff --git a/contracts/utils_test.go b/contracts/utils_test.go index 556efb5377..a3297e98de 100644 --- a/contracts/utils_test.go +++ b/contracts/utils_test.go @@ -102,7 +102,7 @@ func TestSendTxSign(t *testing.T) { signers[common.HexToAddress("0x12f588d7d03bb269b382b842fc15d874e8c055a7")] = &rewardLog{5, new(big.Int).SetUint64(0)} signers[common.HexToAddress("0x1f9e122c0921a4504fc116d967baf7a7bf2604ef")] = &rewardLog{6, new(big.Int).SetUint64(0)} signers[common.HexToAddress("0xea489e4e673c25ff0614617ebe88efd853efe00c")] = &rewardLog{6, new(big.Int).SetUint64(0)} - rewardSigners, err := CalculateReward(chainReward, signers, totalSigner) + rewardSigners, err := CalculateRewardForSigner(chainReward, signers, totalSigner) if err != nil { t.Errorf("Fail to calculate reward for signers: %v", err) } diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index 0fe062b730..a46ee4d01e 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -6,12 +6,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "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" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" "math/rand" + "time" ) var ( @@ -100,6 +100,9 @@ func TestRewardBalance(t *testing.T) { totalReward := new(big.Int).SetInt64(15 * 1000) rewards, err := contracts.GetRewardBalancesRate(acc3Addr, totalReward, baseValidator) + if err != nil { + t.Error("Fail to get reward balances rate.", err) + } afterReward := new(big.Int) for _, value := range rewards { diff --git a/eth/backend.go b/eth/backend.go index dc44639756..d6ffa97d66 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/contracts" + "github.com/ethereum/go-ethereum/contracts/validator/contract" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/state" @@ -195,7 +196,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { importedHook := func(block *types.Block) { snap, err := c.GetSnapshot(eth.blockchain, block.Header()) if err != nil { - log.Error("Fail to get snapshot for sign tx validator.") + log.Error("Fail to get snapshot for sign tx validator.", "error", err) return } if _, authorized := snap.Signers[eth.etherbase]; authorized { @@ -227,14 +228,24 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { if err != nil { log.Error("Fail to get signers for reward checkpoint", "error", err) } - rewardSigners, err := contracts.CalculateReward(chainReward, signers, *totalSigner) + rewardSigners, err := contracts.CalculateRewardForSigner(chainReward, signers, *totalSigner) if err != nil { log.Error("Fail to calculate reward for signers", "error", err) } - // Add reward for signers. + //// Get validator. + validator, err := contract.NewXDCValidator(common.HexToAddress(common.MasternodeVotingSMC), client) + if err != nil { + log.Error("Fail get instance of XDC Validator", "error", err) + + return err + } + // Add reward for coin holders. if len(signers) > 0 { for signer, calcReward := range rewardSigners { - state.AddBalance(signer, calcReward) + err := contracts.CalculateRewardForHolders(validator, state, signer, calcReward) + if err != nil { + log.Error("Fail to calculate reward for holders.", "error", err) + } } } }