mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge pull request #2 from AnilChinchawale/master
hot fix smart contract
This commit is contained in:
commit
f18df27240
6 changed files with 644 additions and 606 deletions
|
|
@ -436,7 +436,7 @@ func (_MultiSigWallet *MultiSigWalletCallerSession) Owners(arg0 *big.Int) (commo
|
||||||
return _MultiSigWallet.Contract.Owners(&_MultiSigWallet.CallOpts, arg0)
|
return _MultiSigWallet.Contract.Owners(&_MultiSigWallet.CallOpts, arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required is a free data retrieval call binding the contract method 0XDC8452cd.
|
// Required is a free data retrieval call binding the contract method 0xdc8452cd.
|
||||||
//
|
//
|
||||||
// Solidity: function required() constant returns(uint256)
|
// Solidity: function required() constant returns(uint256)
|
||||||
func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big.Int, error) {
|
func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big.Int, error) {
|
||||||
|
|
@ -448,14 +448,14 @@ func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big
|
||||||
return *ret0, err
|
return *ret0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required is a free data retrieval call binding the contract method 0XDC8452cd.
|
// Required is a free data retrieval call binding the contract method 0xdc8452cd.
|
||||||
//
|
//
|
||||||
// Solidity: function required() constant returns(uint256)
|
// Solidity: function required() constant returns(uint256)
|
||||||
func (_MultiSigWallet *MultiSigWalletSession) Required() (*big.Int, error) {
|
func (_MultiSigWallet *MultiSigWalletSession) Required() (*big.Int, error) {
|
||||||
return _MultiSigWallet.Contract.Required(&_MultiSigWallet.CallOpts)
|
return _MultiSigWallet.Contract.Required(&_MultiSigWallet.CallOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required is a free data retrieval call binding the contract method 0XDC8452cd.
|
// Required is a free data retrieval call binding the contract method 0xdc8452cd.
|
||||||
//
|
//
|
||||||
// Solidity: function required() constant returns(uint256)
|
// Solidity: function required() constant returns(uint256)
|
||||||
func (_MultiSigWallet *MultiSigWalletCallerSession) Required() (*big.Int, error) {
|
func (_MultiSigWallet *MultiSigWalletCallerSession) Required() (*big.Int, error) {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
||||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -85,7 +84,8 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
// Add tx signed to local tx pool.
|
// Add tx signed to local tx pool.
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
log.Error("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create secret tx.
|
// Create secret tx.
|
||||||
|
|
@ -114,6 +114,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put randomize key into chainDb.
|
// Put randomize key into chainDb.
|
||||||
|
|
@ -125,6 +126,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get randomize key from state db.", "error", err)
|
log.Error("Fail to get randomize key from state db.", "error", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
|
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
|
||||||
|
|
@ -141,6 +143,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear randomize key in state db.
|
// Clear randomize key in state db.
|
||||||
|
|
@ -195,7 +198,12 @@ func BuildTxOpeningRandomize(nonce uint64, randomizeAddr common.Address, randomi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get signers signed for blockNumber from blockSigner contract.
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
func GetSignersFromContract(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
func GetSignersFromContract(state *state.StateDB, block *types.Block) ([]common.Address, error) {
|
||||||
|
return GetSigners(state, block), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
|
func GetSignersByExecutingEVM(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
||||||
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get instance of blockSigner", "error", err)
|
log.Error("Fail get instance of blockSigner", "error", err)
|
||||||
|
|
@ -207,7 +215,6 @@ func GetSignersFromContract(addrBlockSigner common.Address, client bind.Contract
|
||||||
log.Error("Fail get block signers", "error", err)
|
log.Error("Fail get block signers", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return addrs, nil
|
return addrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
||||||
intNumber, err := strconv.Atoi(decryptSecret)
|
intNumber, err := strconv.Atoi(decryptSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Can not convert string to integer", "error", err)
|
log.Error("Can not convert string to integer", "error", err)
|
||||||
|
return -1, err
|
||||||
}
|
}
|
||||||
random = int64(intNumber)
|
random = int64(intNumber)
|
||||||
}
|
}
|
||||||
|
|
@ -299,23 +307,44 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for reward checkpoint.
|
// Calculate reward for reward checkpoint.
|
||||||
func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common.Address, number uint64, rCheckpoint uint64, client bind.ContractBackend, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
func GetRewardForCheckpoint(c *XDPoS.XDPoS, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
||||||
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
|
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
|
||||||
|
number := header.Number.Uint64()
|
||||||
prevCheckpoint := number - (rCheckpoint * 2)
|
prevCheckpoint := number - (rCheckpoint * 2)
|
||||||
startBlockNumber := prevCheckpoint + 1
|
startBlockNumber := prevCheckpoint + 1
|
||||||
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
||||||
signers := make(map[common.Address]*rewardLog)
|
signers := make(map[common.Address]*rewardLog)
|
||||||
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint)
|
mapBlkHash := map[uint64]common.Hash{}
|
||||||
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
|
|
||||||
|
|
||||||
if len(masternodes) > 0 {
|
data := make(map[common.Hash][]common.Address)
|
||||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||||
block := chain.GetHeaderByNumber(i)
|
header = chain.GetHeader(header.ParentHash, i)
|
||||||
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
|
mapBlkHash[i] = header.Hash()
|
||||||
if err != nil {
|
signData, ok := c.BlockSigners.Get(header.Hash())
|
||||||
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
if !ok {
|
||||||
return nil, err
|
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
||||||
|
block := chain.GetBlock(header.Hash(), i)
|
||||||
|
txs := block.Transactions()
|
||||||
|
if !chain.Config().IsTIPSigning(header.Number) {
|
||||||
|
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
|
||||||
|
signData = c.CacheData(header, txs, receipts)
|
||||||
|
} else {
|
||||||
|
signData = c.CacheSigner(header.Hash(), txs)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
txs := signData.([]*types.Transaction)
|
||||||
|
for _, tx := range txs {
|
||||||
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
|
from := *tx.From()
|
||||||
|
data[blkHash] = append(data[blkHash], from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header = chain.GetHeader(header.ParentHash, prevCheckpoint)
|
||||||
|
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(header)
|
||||||
|
|
||||||
|
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
||||||
|
if i%common.MergeSignRange == 0 || !chain.Config().IsTIP2019(big.NewInt(int64(i))) {
|
||||||
|
addrs := data[mapBlkHash[i]]
|
||||||
// Filter duplicate address.
|
// Filter duplicate address.
|
||||||
if len(addrs) > 0 {
|
if len(addrs) > 0 {
|
||||||
addrSigners := make(map[common.Address]bool)
|
addrSigners := make(map[common.Address]bool)
|
||||||
|
|
@ -374,46 +403,27 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get candidate owner by address.
|
// Get candidate owner by address.
|
||||||
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
|
||||||
owner := signerAddr
|
owner := GetCandidateOwner(state, signerAddr)
|
||||||
opts := new(bind.CallOpts)
|
|
||||||
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail get candidate owner", "error", err)
|
|
||||||
return owner
|
|
||||||
}
|
|
||||||
|
|
||||||
return owner
|
return owner
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for holders.
|
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) {
|
||||||
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.XDCValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward, blockNumber)
|
||||||
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
if len(rewards) > 0 {
|
|
||||||
for holder, reward := range rewards {
|
|
||||||
state.AddBalance(holder, reward)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, rewards
|
return nil, rewards
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reward balance rates for master node, founder and holders.
|
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) {
|
||||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
owner := GetCandidatesOwnerBySigner(state, masterAddr)
|
||||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
|
||||||
balances := make(map[common.Address]*big.Int)
|
balances := make(map[common.Address]*big.Int)
|
||||||
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
balances[owner] = rewardMaster
|
balances[owner] = rewardMaster
|
||||||
// Get voters for masternode.
|
// Get voters for masternode.
|
||||||
opts := new(bind.CallOpts)
|
voters := GetVoters(state, masterAddr)
|
||||||
voters, err := validator.GetVoters(opts, masterAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail to get voters", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(voters) > 0 {
|
if len(voters) > 0 {
|
||||||
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
||||||
|
|
@ -422,12 +432,10 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
||||||
// Get voters capacities.
|
// Get voters capacities.
|
||||||
voterCaps := make(map[common.Address]*big.Int)
|
voterCaps := make(map[common.Address]*big.Int)
|
||||||
for _, voteAddr := range voters {
|
for _, voteAddr := range voters {
|
||||||
voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr)
|
if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber {
|
||||||
if err != nil {
|
continue
|
||||||
log.Error("Fail to get vote capacity", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
voterCap := GetVoterCap(state, masterAddr, voteAddr)
|
||||||
totalCap.Add(totalCap, voterCap)
|
totalCap.Add(totalCap, voterCap)
|
||||||
voterCaps[voteAddr] = voterCap
|
voterCaps[voteAddr] = voterCap
|
||||||
}
|
}
|
||||||
|
|
@ -447,9 +455,9 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
|
||||||
balances[foudationWalletAddr] = foudationReward
|
balances[foundationWalletAddr] = foundationReward
|
||||||
|
|
||||||
jsonHolders, err := json.Marshal(balances)
|
jsonHolders, err := json.Marshal(balances)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ pragma solidity ^0.4.21;
|
||||||
|
|
||||||
import "./libs/SafeMath.sol";
|
import "./libs/SafeMath.sol";
|
||||||
|
|
||||||
contract XDCValidator {
|
contract XDCalidator {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
|
|
||||||
event Vote(address _voter, address _candidate, uint256 _cap);
|
event Vote(address _voter, address _candidate, uint256 _cap);
|
||||||
|
|
@ -37,7 +37,7 @@ contract XDCValidator {
|
||||||
uint256 public voterWithdrawDelay;
|
uint256 public voterWithdrawDelay;
|
||||||
|
|
||||||
modifier onlyValidCandidateCap {
|
modifier onlyValidCandidateCap {
|
||||||
// anyone can deposit X XDC to become a candidate
|
// anyone can deposit X XDCto become a candidate
|
||||||
require(msg.value >= minCandidateCap);
|
require(msg.value >= minCandidateCap);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +83,7 @@ contract XDCValidator {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
function XDCValidator (
|
function XDCalidator (
|
||||||
address[] _candidates,
|
address[] _candidates,
|
||||||
uint256[] _caps,
|
uint256[] _caps,
|
||||||
address _firstOwner,
|
address _firstOwner,
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 XDCchain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,19 @@ package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/rand"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -94,7 +95,7 @@ func TestRewardBalance(t *testing.T) {
|
||||||
// validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100))
|
// validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100))
|
||||||
validatorCap := new(big.Int)
|
validatorCap := new(big.Int)
|
||||||
validatorCap.SetString("50000000000000000000000", 10)
|
validatorCap.SetString("50000000000000000000000", 10)
|
||||||
validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(
|
validatorAddr, _, baseValidator, err := contractValidator.DeployXDCValidator(
|
||||||
transactOpts,
|
transactOpts,
|
||||||
contractBackend,
|
contractBackend,
|
||||||
[]common.Address{addr},
|
[]common.Address{addr},
|
||||||
|
|
@ -144,7 +145,7 @@ func TestRewardBalance(t *testing.T) {
|
||||||
|
|
||||||
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
||||||
totalReward := new(big.Int).SetInt64(15 * 1000)
|
totalReward := new(big.Int).SetInt64(15 * 1000)
|
||||||
rewards, err := contracts.GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator)
|
rewards, err := GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Fail to get reward balances rate.", err)
|
t.Error("Fail to get reward balances rate.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -175,3 +176,76 @@ func TestRewardBalance(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetRewardBalancesRate(foudationWalletAddr common.Address, 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(common.RewardMasterPercent))
|
||||||
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
|
balances[owner] = rewardMaster
|
||||||
|
// Get voters for masternode.
|
||||||
|
opts := new(bind.CallOpts)
|
||||||
|
voters, err := validator.GetVoters(opts, masterAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Crit("Fail to get voters", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(voters) > 0 {
|
||||||
|
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.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 {
|
||||||
|
var voterCap *big.Int
|
||||||
|
|
||||||
|
voterCap, err = validator.GetVoterCap(opts, masterAddr, voteAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Crit("Fail to get vote capacity", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCap.Add(totalCap, voterCap)
|
||||||
|
voterCaps[voteAddr] = voterCap
|
||||||
|
}
|
||||||
|
if totalCap.Cmp(new(big.Int).SetInt64(0)) > 0 {
|
||||||
|
for addr, voteCap := range voterCaps {
|
||||||
|
// Only valid voter has cap > 0.
|
||||||
|
if voteCap.Cmp(new(big.Int).SetInt64(0)) > 0 {
|
||||||
|
rcap := new(big.Int).Mul(totalVoterReward, voteCap)
|
||||||
|
rcap = new(big.Int).Div(rcap, totalCap)
|
||||||
|
if balances[addr] != nil {
|
||||||
|
balances[addr].Add(balances[addr], rcap)
|
||||||
|
} else {
|
||||||
|
balances[addr] = rcap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
|
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
||||||
|
balances[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
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
||||||
|
owner := signerAddr
|
||||||
|
opts := new(bind.CallOpts)
|
||||||
|
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail get candidate owner", "error", err)
|
||||||
|
return owner
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue