removed kyc smart contract for stable version

This commit is contained in:
parmarrushabh 2019-03-05 15:44:26 +05:30
parent b493f4b6ca
commit c6886f92f2
13 changed files with 631 additions and 1112 deletions

View file

@ -0,0 +1,33 @@
package contracts
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
)
var (
slotBlockSignerMapping = map[string]uint64{
"blockSigners": 0,
"blocks": 1,
}
)
func GetSigners(statedb *state.StateDB, block *types.Block) []common.Address {
slot := slotBlockSignerMapping["blockSigners"]
keys := []common.Hash{}
keyArrSlot := getLocMappingAtKey(block.Hash(), slot)
arrSlot := statedb.GetState(common.HexToAddress(common.BlockSigners), common.BigToHash(keyArrSlot))
arrLength := arrSlot.Big().Uint64()
for i := uint64(0); i < arrLength; i++ {
key := getLocDynamicArrAtElement(common.BigToHash(keyArrSlot), i, 1)
keys = append(keys, key)
}
rets := []common.Address{}
for _, key := range keys {
ret := statedb.GetState(common.HexToAddress(common.BlockSigners), key)
rets = append(rets, common.HexToAddress(ret.Hex()))
}
return rets
}

View file

@ -436,7 +436,7 @@ func (_MultiSigWallet *MultiSigWalletCallerSession) Owners(arg0 *big.Int) (commo
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)
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
}
// 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)
func (_MultiSigWallet *MultiSigWalletSession) Required() (*big.Int, error) {
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)
func (_MultiSigWallet *MultiSigWalletCallerSession) Required() (*big.Int, error) {

View file

@ -0,0 +1,37 @@
package contracts
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
)
var (
slotRandomizeMapping = map[string]uint64{
"randomSecret": 0,
"randomOpening": 1,
}
)
func GetSecret(statedb *state.StateDB, address common.Address) [][32]byte {
slot := slotRandomizeMapping["randomSecret"]
locSecret := getLocMappingAtKey(address.Hash(), slot)
arrLength := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locSecret))
keys := []common.Hash{}
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
key := getLocDynamicArrAtElement(common.BigToHash(locSecret), i, 1)
keys = append(keys, key)
}
rets := [][32]byte{}
for _, key := range keys {
ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), key)
rets = append(rets, ret)
}
return rets
}
func GetOpening(statedb *state.StateDB, address common.Address) [32]byte {
slot := slotRandomizeMapping["randomOpening"]
locOpening := getLocMappingAtKey(address.Hash(), slot)
ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locOpening))
return ret
}

34
contracts/smcUtils.go Normal file
View file

@ -0,0 +1,34 @@
package contracts
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func getLocSimpleVariable(slot uint64) common.Hash {
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
return slotHash
}
func getLocMappingAtKey(key common.Hash, slot uint64) *big.Int {
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
ret := new(big.Int)
ret.SetBytes(retByte)
return ret
}
func getLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big()
//arrBig = slotKecBig + index * elementSize
arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index*elementSize))
return common.BigToHash(arrBig)
}
func getLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) common.Hash {
slotBig := new(big.Int).SetUint64(slot)
arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
return common.BigToHash(arrBig)
}

282
contracts/test.go Normal file
View file

@ -0,0 +1,282 @@
package contracts
//
//import (
// "fmt"
// "math/big"
// "time"
//
// "github.com/ethereum/go-ethereum/common"
// "github.com/ethereum/go-ethereum/core"
// "github.com/ethereum/go-ethereum/core/state"
// "github.com/ethereum/go-ethereum/crypto"
// "github.com/ethereum/go-ethereum/ethdb"
// "github.com/ethereum/go-ethereum/core/types"
//)
//
//var (
// slotValidatorMapping = map[string]uint64{
// "withdrawsState": 0,
// "validatorsState": 1,
// "voters": 2,
// "candidates": 3,
// "candidateCount": 4,
// "minCandidateCap": 5,
// "minVoterCap": 6,
// "maxValidatorNumber": 7,
// "candidateWithdrawDelay": 8,
// "voterWithdrawDelay": 9,
// }
// slotBlockSignerMapping = map[string]uint64{
// "blockSigners": 0,
// "blocks": 1,
// }
// slotRandomizeMapping = map[string]uint64{
// "randomSecret": 0,
// "randomOpening": 1,
// }
// datadir = "/mnt/sgp1_tuna_chaindata3/data/XDC/chaindata"
// candidate = "0xd6fa3e7a89bf8c84f0ccd204a15c0d259daf2091"
//)
//
//func main() {
// //Init
// chaindb, err := ethdb.NewLDBDatabase(datadir, 0, 0)
// if err != nil || chaindb == nil {
// fmt.Printf("Can't get chaindb: %v", err)
// return
// }
// headHash := core.GetHeadBlockHash(chaindb)
// blockNumber := core.GetBlockNumber(chaindb, headHash)
// block := core.GetBlock(chaindb, headHash, blockNumber)
// if block == nil {
// fmt.Println("Can't get head block")
// return
// }
// database := state.NewDatabase(chaindb)
// headerRootHash := block.Header().Root
// headHeaderHash := core.GetHeadHeaderHash(chaindb)
// statedb, _ := state.New(headHeaderHash, database)
// if statedb == nil {
// headHeaderHash = headerRootHash
// }
// candidateAddress := common.HexToAddress(candidate)
// fmt.Printf("Block head :%d, header root:%v\n", blockNumber, headerRootHash.Hex())
// statedb, _ = state.New(headHeaderHash, database)
// if statedb == nil {
// fmt.Println("Can't get state db")
// return
// }
//
// //GetCandidates
// _ = GetCandidates(statedb)
//
// //GetCandidateOwner
// _ = GetCandidateOwner(statedb, candidateAddress)
//
// //GetCandidateCap
// _ = GetCandidateCap(statedb, candidateAddress)
//
// //GetVoters
// voters := GetVoters(statedb, candidateAddress)
//
// start := time.Now()
// fmt.Printf("--------GetVoterCap---------\n")
// for _, voter := range voters {
// //GetVoterCap
// _ = GetVoterCap(statedb, candidateAddress, voter)
// }
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
//
// //GetSigners
// blockInput := core.GetBlock(chaindb, common.HexToHash("0x632f2403ea19697082d794900275632eb3373f7a9943b1407461995bbbc2816a"), uint64(1800))
// _ = GetSigners(statedb, blockInput)
//
// //GetOpening
// _ = GetOpening(statedb, candidateAddress)
// //GetSecret
// _ = GetSecret(statedb, candidateAddress)
//}
//
//func GetCandidates(statedb *state.StateDB) []common.Address {
// start := time.Now()
// fmt.Printf("--------GetCandidates---------\n")
//
// slot := slotValidatorMapping["candidates"]
// slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
// arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash)
// fmt.Printf("Candidates length: %v\n", arrLength.Hex())
// keys := []common.Hash{}
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
// key := getLocDynamicArrAtElement(slotHash, i, 1)
// keys = append(keys, key)
// }
// rets := []common.Address{}
// for _, key := range keys {
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
// rets = append(rets, common.HexToAddress(ret.Hex()))
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
// }
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
// return rets
//}
//
//func GetCandidateOwner(statedb *state.StateDB, candidate common.Address) common.Address {
// start := time.Now()
// fmt.Printf("--------GetCandidateOwner---------\n")
//
// slot := slotValidatorMapping["validatorsState"]
// // validatorsState[_candidate].owner;
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
// locCandidateOwner := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(0)))
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateOwner))
// fmt.Printf("ret: %v\n", common.HexToAddress(ret.Hex()).Hex())
//
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
// return common.HexToAddress(ret.Hex())
//}
//
//func GetCandidateCap(statedb *state.StateDB, candidate common.Address) string {
// start := time.Now()
// fmt.Printf("--------GetCandidateCap---------\n")
//
// slot := slotValidatorMapping["validatorsState"]
// // validatorsState[_candidate].cap;
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
// locCandidateCap := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(1)))
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateCap))
// fmt.Printf("cap: %v\n", ret.Big().String())
//
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
// return ret.Hex()
//}
//
//func GetVoterCap(state *state.StateDB, candidate, voter common.Address) *big.Int {
// //validatorsState[_candidate].voters[_voter]
// slot := slotValidatorMapping["validatorsState"]
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
// locCandidateVoters := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(2)))
// retByte := crypto.Keccak256(voter.Hash().Bytes(), common.BigToHash(locCandidateVoters).Bytes())
// ret := state.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BytesToHash(retByte))
// fmt.Printf("voter: %v - cap: %v\n", voter.Hex(), ret.Big().String())
// return ret.Big()
//}
//
//func GetVoters(statedb *state.StateDB, candidate common.Address) []common.Address {
// start := time.Now()
// fmt.Printf("--------GetVoters---------\n")
//
// //mapping(address => address[]) voters;
// slot := slotValidatorMapping["voters"]
// locVoters := getLocMappingAtKey(candidate.Hash(), slot)
// arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locVoters))
// fmt.Printf("Voters length: %v\n", arrLength.Hex())
// keys := []common.Hash{}
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
// key := getLocDynamicArrAtElement(common.BigToHash(locVoters), i, 1)
// keys = append(keys, key)
// }
// rets := []common.Address{}
// for _, key := range keys {
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
// rets = append(rets, common.HexToAddress(ret.Hex()))
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
// }
//
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
// return rets
//}
//
//func GetSigners(statedb *state.StateDB, block *types.Block) []common.Address {
// methodName := "getSigners"
// fmt.Printf("---%s---\n", methodName)
// start := time.Now()
// slot := slotBlockSignerMapping["blockSigners"]
// keys := []common.Hash{}
// keyArrSlot := getLocMappingAtKey(block.Hash(), slot)
// arrSlot := statedb.GetState(common.HexToAddress(common.BlockSigners), common.BigToHash(keyArrSlot))
// arrLength := arrSlot.Big().Uint64()
// for i := uint64(0); i < arrLength; i++ {
// key := getLocDynamicArrAtElement(common.BigToHash(keyArrSlot), i, 1)
// keys = append(keys, key)
// }
// rets := []common.Address{}
// for _, key := range keys {
// ret := statedb.GetState(common.HexToAddress(common.BlockSigners), key)
// rets = append(rets, common.HexToAddress(ret.Hex()))
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
// }
//
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
// return rets
//}
//
//func GetSecret(statedb *state.StateDB, address common.Address) [][32]byte {
// start := time.Now()
// fmt.Printf("--------GetSecret---------\n")
//
// slot := slotRandomizeMapping["randomSecret"]
// locSecret := getLocMappingAtKey(address.Hash(), slot)
// arrLength := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locSecret))
// fmt.Printf("Secret length: %v\n", arrLength.Hex())
// keys := []common.Hash{}
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
// key := getLocDynamicArrAtElement(common.BigToHash(locSecret), i, 1)
// keys = append(keys, key)
// }
// rets := [][32]byte{}
// for _, key := range keys {
// ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), key)
// rets = append(rets, ret)
// fmt.Printf("ret hex: %v - ret byte: %v\n", ret.Hex(), ret.Bytes())
// }
// elapsed := time.Since(start)
//
// fmt.Printf("Execution time: %s\n", elapsed)
// return rets
//}
//
//func GetOpening(statedb *state.StateDB, address common.Address) [32]byte {
// start := time.Now()
// fmt.Printf("--------GetOpening---------\n")
//
// slot := slotRandomizeMapping["randomOpening"]
// locOpening := getLocMappingAtKey(address.Hash(), slot)
// ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locOpening))
// fmt.Printf("ret hex: %v - ret byte: %v\n", ret.Hex(), ret.Bytes())
// elapsed := time.Since(start)
// fmt.Printf("Execution time: %s\n", elapsed)
// return ret
//}
//
//
//////////////////////////////////////
///////////// Common lib /////////////
//////////////////////////////////////
//
//func getLocMappingAtKey(key common.Hash, slot uint64) *big.Int {
// slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
// retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
// ret := new(big.Int)
// ret.SetBytes(retByte)
// return ret
//}
//
//func getLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
// slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big()
// //arrBig = slotKecBig + index * elementSize
// arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index*elementSize))
// return common.BigToHash(arrBig)
//}
//
//func getLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) common.Hash {
// slotBig := new(big.Int).SetUint64(slot)
// arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
// return common.BigToHash(arrBig)
//}

View file

@ -38,7 +38,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/XDPoS"
"github.com/ethereum/go-ethereum/contracts/blocksigner/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/state"
"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.
err = pool.AddLocal(txSigned)
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.
@ -114,6 +114,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
err = pool.AddLocal(txSigned)
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)
return err
}
// Put randomize key into chainDb.
@ -125,6 +126,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
if err != nil {
log.Error("Fail to get randomize key from state db.", "error", err)
return err
}
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)
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)
return err
}
// 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.
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)
if err != nil {
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)
return nil, err
}
return addrs, nil
}
@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
intNumber, err := strconv.Atoi(decryptSecret)
if err != nil {
log.Error("Can not convert string to integer", "error", err)
return -1, err
}
random = int64(intNumber)
}
@ -299,23 +307,44 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
}
// 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.
number := header.Number.Uint64()
prevCheckpoint := number - (rCheckpoint * 2)
startBlockNumber := prevCheckpoint + 1
endBlockNumber := startBlockNumber + rCheckpoint - 1
signers := make(map[common.Address]*rewardLog)
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint)
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
mapBlkHash := map[uint64]common.Hash{}
if len(masternodes) > 0 {
for i := startBlockNumber; i <= endBlockNumber; i++ {
block := chain.GetHeaderByNumber(i)
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
if err != nil {
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
return nil, err
data := make(map[common.Hash][]common.Address)
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
header = chain.GetHeader(header.ParentHash, i)
mapBlkHash[i] = header.Hash()
signData, ok := c.BlockSigners.Get(header.Hash())
if !ok {
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.
if len(addrs) > 0 {
addrSigners := make(map[common.Address]bool)
@ -374,46 +403,27 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
}
// Get candidate owner by address.
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
}
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
owner := GetCandidateOwner(state, signerAddr)
return owner
}
// Calculate reward for holders.
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(foudationWalletAddr, signer, calcReward, validator)
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) {
rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward, blockNumber)
if err != nil {
return err, nil
}
if len(rewards) > 0 {
for holder, reward := range rewards {
state.AddBalance(holder, reward)
}
}
return nil, rewards
}
// Get reward balance rates for master node, founder and holders.
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) {
owner := GetCandidatesOwnerBySigner(state, 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.Error("Fail to get voters", "error", err)
return nil, err
}
voters := GetVoters(state, masterAddr)
if len(voters) > 0 {
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.
voterCaps := make(map[common.Address]*big.Int)
for _, voteAddr := range voters {
voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr)
if err != nil {
log.Error("Fail to get vote capacity", "error", err)
return nil, err
if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber {
continue
}
voterCap := GetVoterCap(state, masterAddr, voteAddr)
totalCap.Add(totalCap, 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))
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
balances[foudationWalletAddr] = foudationReward
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
balances[foundationWalletAddr] = foundationReward
jsonHolders, err := json.Marshal(balances)
if err != nil {

View file

@ -1,656 +0,0 @@
[
{
"constant": false,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "propose",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "resign",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_candidate",
"type": "address"
},
{
"name": "_cap",
"type": "uint256"
}
],
"name": "unvote",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "kychash",
"type": "string"
}
],
"name": "uploadKYC",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "vote",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_invalidCandidate",
"type": "address"
}
],
"name": "voteInvalidKYC",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_blockNumber",
"type": "uint256"
},
{
"name": "_index",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"name": "_candidates",
"type": "address[]"
},
{
"name": "_caps",
"type": "uint256[]"
},
{
"name": "_firstOwner",
"type": "address"
},
{
"name": "_minCandidateCap",
"type": "uint256"
},
{
"name": "_minVoterCap",
"type": "uint256"
},
{
"name": "_maxValidatorNumber",
"type": "uint256"
},
{
"name": "_candidateWithdrawDelay",
"type": "uint256"
},
{
"name": "_voterWithdrawDelay",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_voter",
"type": "address"
},
{
"indexed": false,
"name": "_candidate",
"type": "address"
},
{
"indexed": false,
"name": "_cap",
"type": "uint256"
}
],
"name": "Vote",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_voter",
"type": "address"
},
{
"indexed": false,
"name": "_candidate",
"type": "address"
},
{
"indexed": false,
"name": "_cap",
"type": "uint256"
}
],
"name": "Unvote",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_owner",
"type": "address"
},
{
"indexed": false,
"name": "_candidate",
"type": "address"
},
{
"indexed": false,
"name": "_cap",
"type": "uint256"
}
],
"name": "Propose",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_owner",
"type": "address"
},
{
"indexed": false,
"name": "_candidate",
"type": "address"
}
],
"name": "Resign",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_owner",
"type": "address"
},
{
"indexed": false,
"name": "_blockNumber",
"type": "uint256"
},
{
"indexed": false,
"name": "_cap",
"type": "uint256"
}
],
"name": "Withdraw",
"type": "event"
},
{
"constant": true,
"inputs": [],
"name": "candidateCount",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "candidates",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "candidateWithdrawDelay",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "getCandidateCap",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "getCandidateOwner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getCandidates",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_address",
"type": "address"
}
],
"name": "getKYC",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getOwnerCount",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_candidate",
"type": "address"
},
{
"name": "_voter",
"type": "address"
}
],
"name": "getVoterCap",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "getVoters",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getWithdrawBlockNumbers",
"outputs": [
{
"name": "",
"type": "uint256[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_blockNumber",
"type": "uint256"
}
],
"name": "getWithdrawCap",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "address"
}
],
"name": "hasVotedInvalid",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "invalidKYCCount",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_invalidCandidate",
"type": "address"
}
],
"name": "invalidPercent",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_candidate",
"type": "address"
}
],
"name": "isCandidate",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "KYCString",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "maxValidatorNumber",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "minCandidateCap",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "minVoterCap",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "owners",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "uint256"
}
],
"name": "ownerToCandidate",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "voterWithdrawDelay",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]

File diff suppressed because one or more lines are too long

View file

@ -1,54 +1,8 @@
pragma solidity ^0.4.21;
// This contract is under development.
// Refer to readme for further details.
import "./libs/SafeMath.sol";
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract XDCValidator {
contract XDCalidator {
using SafeMath for uint256;
event Vote(address _voter, address _candidate, uint256 _cap);
@ -73,14 +27,6 @@ contract XDCValidator {
mapping(address => ValidatorState) validatorsState;
mapping(address => address[]) voters;
// Mapping structures added for KYC feature.
mapping(address => string) public KYCString;
mapping(address => uint) public invalidKYCCount;
mapping(address => mapping(address => bool)) public hasVotedInvalid;
mapping(address => address[]) public ownerToCandidate;
address[] public owners;
address[] public candidates;
uint256 public candidateCount = 0;
@ -91,26 +37,16 @@ contract XDCValidator {
uint256 public voterWithdrawDelay;
modifier onlyValidCandidateCap {
// anyone can deposit X XDC to become a candidate
// anyone can deposit X XDCto become a candidate
require(msg.value >= minCandidateCap);
_;
}
modifier onlyValidVoterCap {
require(msg.value >= minVoterCap);
_;
}
modifier onlyKYCWhitelisted {
if(bytes(KYCString[msg.sender]).length != 0)
{_;}
else{
if (ownerToCandidate[msg.sender].length > 0)
{_;}
}
}
modifier onlyOwner(address _candidate) {
require(validatorsState[_candidate].owner == msg.sender);
_;
@ -147,7 +83,7 @@ contract XDCValidator {
_;
}
function XDCValidator (
function XDCalidator (
address[] _candidates,
uint256[] _caps,
address _firstOwner,
@ -163,7 +99,7 @@ contract XDCValidator {
candidateWithdrawDelay = _candidateWithdrawDelay;
voterWithdrawDelay = _voterWithdrawDelay;
candidateCount = _candidates.length;
owners.push(_firstOwner);
for (uint256 i = 0; i < _candidates.length; i++) {
candidates.push(_candidates[i]);
validatorsState[_candidates[i]] = ValidatorState({
@ -172,20 +108,11 @@ contract XDCValidator {
cap: _caps[i]
});
voters[_candidates[i]].push(_firstOwner);
ownerToCandidate[_firstOwner].push(_candidates[i]);
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap;
}
}
// uploadKYC : anyone can upload a KYC; its not equivalent to becoming an owner.
function uploadKYC(string kychash) external {
require(bytes(KYCString[msg.sender]).length==0);
KYCString[msg.sender]=kychash;
}
// propose : any non-candidate who has uploaded its KYC can become an owner by proposing a candidate.
function propose(address _candidate) external payable onlyValidCandidateCap onlyKYCWhitelisted onlyNotCandidate(_candidate) {
function propose(address _candidate) external payable onlyValidCandidateCap onlyNotCandidate(_candidate) {
uint256 cap = validatorsState[_candidate].cap.add(msg.value);
candidates.push(_candidate);
validatorsState[_candidate] = ValidatorState({
@ -195,11 +122,6 @@ contract XDCValidator {
});
validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value);
candidateCount = candidateCount.add(1);
if (ownerToCandidate[msg.sender].length ==0){
owners.push(msg.sender);
}
ownerToCandidate[msg.sender].push(_candidate);
voters[_candidate].push(msg.sender);
emit Propose(msg.sender, _candidate, msg.value);
}
@ -276,59 +198,6 @@ contract XDCValidator {
emit Resign(msg.sender, _candidate);
}
// voteInvalidKYC : any candidate can vote for invalid KYC i.e. a particular candidate's owner has uploaded a bad KYC.
// On securing 75% votes against an owner ( not candidate ), owner & all its candidates will lose their funds.
function voteInvalidKYC(address _invalidCandidate) onlyValidCandidate(msg.sender) onlyValidCandidate(_invalidCandidate) public {
address candidateOwner = getCandidateOwner(msg.sender);
address _invalidMasternode = getCandidateOwner(_invalidCandidate);
require(!hasVotedInvalid[candidateOwner][_invalidMasternode]);
hasVotedInvalid[candidateOwner][_invalidMasternode] = true;
invalidKYCCount[_invalidMasternode] += 1;
if( invalidKYCCount[_invalidMasternode]*100/getOwnerCount() >= 75 ){
// 75% owners say that the KYC is invalid
for (uint i=0;i<candidates.length;i++){
if (getCandidateOwner(candidates[i])==_invalidMasternode){
// logic to remove cap.
candidateCount = candidateCount.sub(1);
delete candidates[i];
delete validatorsState[candidates[i]];
delete KYCString[_invalidMasternode];
delete ownerToCandidate[_invalidMasternode];
delete invalidKYCCount[_invalidMasternode];
for(uint k=0;k<owners.length;k++){
if (owners[k]==_invalidMasternode){
delete owners[k];
owners.length--;
break;
}
}
}
}
}
}
// invalidPercent : get votes against an owner in percentage.
function invalidPercent(address _invalidCandidate) onlyValidCandidate(_invalidCandidate) view public returns(uint){
address _invalidMasternode = getCandidateOwner(_invalidCandidate);
return (invalidKYCCount[_invalidMasternode]*100/getOwnerCount());
}
// getOwnerCount : get count of total owners; accounts who own atleast one masternode.
function getOwnerCount() view public returns (uint){
return owners.length;
}
// getKYC : get KYC uploaded of the owner of the given masternode or the owner themselves
function getKYC(address _address) view public returns (string) {
if(isCandidate(_address)){
return KYCString[getCandidateOwner(_address)];
}
else{
return KYCString[_address];
}
}
function withdraw(uint256 _blockNumber, uint _index) public onlyValidWithdraw(_blockNumber, _index) {
uint256 cap = withdrawsState[msg.sender].caps[_blockNumber];
delete withdrawsState[msg.sender].caps[_blockNumber];

File diff suppressed because one or more lines are too long

View file

@ -16,11 +16,10 @@
package validator
import (
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/contracts/validator/contract"
"math/big"
)
type Validator struct {
@ -45,12 +44,12 @@ func NewValidator(transactOpts *bind.TransactOpts, contractAddr common.Address,
func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, validatorAddress []common.Address, caps []*big.Int, ownerAddress common.Address) (common.Address, *Validator, error) {
minDeposit := new(big.Int)
minDeposit.SetString("10000000000000000000000000", 10)
minDeposit.SetString("50000000000000000000000", 10)
minVoterCap := new(big.Int)
minVoterCap.SetString("25000000000000000000000", 10)
// Deposit 10Mil XDC
// Min Voter Cap 25K XDC
// 21 masternodes
minVoterCap.SetString("10000000000000000000", 10)
// Deposit 50K XDC
// Min Voter Cap 10 XDC
// 150 masternodes
// Candidate Delay Withdraw 30 days = 1296000 blocks
// Voter Delay Withdraw 2 days = 86400 blocks
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(150), big.NewInt(1296000), big.NewInt(86400))

View file

@ -17,18 +17,19 @@ package validator
import (
"context"
"encoding/json"
"math/big"
"math/rand"
"testing"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/contracts"
"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/crypto"
"math/rand"
"github.com/ethereum/go-ethereum/log"
)
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))
validatorCap := new(big.Int)
validatorCap.SetString("50000000000000000000000", 10)
validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(
validatorAddr, _, baseValidator, err := contractValidator.DeployXDCValidator(
transactOpts,
contractBackend,
[]common.Address{addr},
@ -144,7 +145,7 @@ func TestRewardBalance(t *testing.T) {
foundationAddr := common.HexToAddress(common.FoudationAddr)
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 {
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
}

View file

@ -0,0 +1,88 @@
package contracts
import (
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
)
var (
slotValidatorMapping = map[string]uint64{
"withdrawsState": 0,
"validatorsState": 1,
"voters": 2,
"candidates": 3,
"candidateCount": 4,
"minCandidateCap": 5,
"minVoterCap": 6,
"maxValidatorNumber": 7,
"candidateWithdrawDelay": 8,
"voterWithdrawDelay": 9,
}
)
func GetCandidates(statedb *state.StateDB) []common.Address {
slot := slotValidatorMapping["candidates"]
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash)
keys := []common.Hash{}
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
key := getLocDynamicArrAtElement(slotHash, i, 1)
keys = append(keys, key)
}
rets := []common.Address{}
for _, key := range keys {
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
rets = append(rets, common.HexToAddress(ret.Hex()))
}
return rets
}
func GetCandidateOwner(statedb *state.StateDB, candidate common.Address) common.Address {
slot := slotValidatorMapping["validatorsState"]
// validatorsState[_candidate].owner;
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
locCandidateOwner := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(0)))
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateOwner))
return common.HexToAddress(ret.Hex())
}
func GetCandidateCap(statedb *state.StateDB, parsed abi.ABI, candidate common.Address) string {
slot := slotValidatorMapping["validatorsState"]
// validatorsState[_candidate].cap;
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
locCandidateCap := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(1)))
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateCap))
return ret.Hex()
}
func GetVoters(statedb *state.StateDB, candidate common.Address) []common.Address {
//mapping(address => address[]) voters;
slot := slotValidatorMapping["voters"]
locVoters := getLocMappingAtKey(candidate.Hash(), slot)
arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locVoters))
keys := []common.Hash{}
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
key := getLocDynamicArrAtElement(common.BigToHash(locVoters), i, 1)
keys = append(keys, key)
}
rets := []common.Address{}
for _, key := range keys {
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
rets = append(rets, common.HexToAddress(ret.Hex()))
}
return rets
}
func GetVoterCap(state *state.StateDB, candidate, voter common.Address) *big.Int {
slot := slotValidatorMapping["validatorsState"]
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
locCandidateVoters := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(2)))
retByte := crypto.Keccak256(voter.Hash().Bytes(), common.BigToHash(locCandidateVoters).Bytes())
ret := state.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BytesToHash(retByte))
return ret.Big()
}