Skip to content

Commit

Permalink
Merge pull request #145 from XinFinOrg/mainnet_test
Browse files Browse the repository at this point in the history
missing ValidatorMapping update.
  • Loading branch information
AnilChinchawale authored Nov 16, 2021
2 parents cbcd635 + 5112dc7 commit f9fa3a8
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 55 deletions.
3 changes: 3 additions & 0 deletions XDCx/XDCx.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,9 @@ func (XDCx *XDCX) GetTradingState(block *types.Block, author common.Address) (*t
}
return tradingstate.New(root, XDCx.StateCache)
}
func (XDCX *XDCX) GetEmptyTradingState() (*tradingstate.TradingStateDB, error) {
return tradingstate.New(tradingstate.EmptyRoot, XDCX.StateCache)
}

func (XDCx *XDCX) GetStateCache() tradingstate.Database {
return XDCx.StateCache
Expand Down
27 changes: 17 additions & 10 deletions common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const (
MergeSignRange = 15
RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1
IgnoreSignerCheckBlock = uint64(27307800)

OneYear = uint64(365 * 86400)
LiquidateLendingTradeBlock = uint64(100)
)
Expand All @@ -36,14 +36,14 @@ var TIPSigning = big.NewInt(3000000)
var TIPRandomize = big.NewInt(3464000)

var TIPIncreaseMasternodes = big.NewInt(5000000) // Upgrade MN Count at Block.
var TIPNoHalvingMNReward = big.NewInt(23779191) // hardfork no halving masternodes reward
var BlackListHFNumber = uint64(23779191)
var TIPXDCX = big.NewInt(23779191)
var TIPXDCXLending = big.NewInt(23779191)
var TIPXDCXCancellationFee = big.NewInt(23779191)
var TIPXDCXCancellationFeeTestnet = big.NewInt(23779191)
var TIPNoHalvingMNReward = big.NewInt(38383838) // hardfork no halving masternodes reward
var BlackListHFNumber = uint64(38383838)
var TIPXDCX = big.NewInt(38383838)
var TIPXDCXLending = big.NewInt(38383838)
var TIPXDCXCancellationFee = big.NewInt(38383838)
var TIPXDCXCancellationFeeTestnet = big.NewInt(38383838)

var TIPXDCXTestnet = big.NewInt(23779191)
var TIPXDCXTestnet = big.NewInt(38383838)
var IsTestnet bool = false
var StoreRewardFolder string
var RollbackHash Hash
Expand Down Expand Up @@ -71,9 +71,16 @@ var TRC21GasPrice = big.NewInt(250000000)
var RateTopUp = big.NewInt(90) // 90%
var BaseTopUp = big.NewInt(100)
var BaseRecall = big.NewInt(100)
var TIPTRC21Fee = big.NewInt(23779191)
var TIPTRC21FeeTestnet = big.NewInt(23779191)
var TIPTRC21Fee = big.NewInt(38383838)
var TIPTRC21FeeTestnet = big.NewInt(38383838)
var LimitTimeFinality = uint64(30) // limit in 30 block

var IgnoreSignerCheckBlockArray = map[uint64]bool{
uint64(1032300): true,
uint64(1033200): true,
uint64(27307800): true,
uint64(28270800): true,
}
var Blacklist = map[Address]bool{
HexToAddress("0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"): true,
HexToAddress("0x5ac26105b35ea8935be382863a70281ec7a985e9"): true,
Expand Down
4 changes: 2 additions & 2 deletions consensus/XDPoS/engines/engine_v1/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ func (x *XDPoS_v1) verifyCascadingFields(chain consensus.ChainReader, header *ty

func (x *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header *types.Header, signers []common.Address) error {
number := header.Number.Uint64()
// ignore signerCheck at checkpoint block 14458500 due to wrong snapshot at gap 14458495
if number == common.IgnoreSignerCheckBlock {
// ignore signerCheck at checkpoint block.
if common.IgnoreSignerCheckBlockArray[number] {
return nil
}
penPenalties := []common.Address{}
Expand Down
1 change: 1 addition & 0 deletions consensus/XDPoS/utils/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Masternode struct {
type TradingService interface {
GetTradingStateRoot(block *types.Block, author common.Address) (common.Hash, error)
GetTradingState(block *types.Block, author common.Address) (*tradingstate.TradingStateDB, error)
GetEmptyTradingState() (*tradingstate.TradingStateDB, error)
HasTradingState(block *types.Block, author common.Address) bool
GetStateCache() tradingstate.Database
GetTriegc() *prque.Prque
Expand Down
99 changes: 97 additions & 2 deletions contracts/validator/contract/XDCValidator.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

pragma solidity ^0.4.21;

import "./libs/SafeMath.sol";


contract XDCValidator {
using SafeMath for uint256;

Expand All @@ -10,6 +12,8 @@ contract XDCValidator {
event Propose(address _owner, address _candidate, uint256 _cap);
event Resign(address _owner, address _candidate);
event Withdraw(address _owner, uint256 _blockNumber, uint256 _cap);
event UploadedKYC(address _owner,string kycHash);
event InvalidatedNode(address _masternodeOwner, address[] _masternodes);

struct ValidatorState {
address owner;
Expand All @@ -27,9 +31,18 @@ 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;
uint256 public ownerCount =0;
uint256 public minCandidateCap;
uint256 public minVoterCap;
uint256 public maxValidatorNumber;
Expand All @@ -43,10 +56,16 @@ contract XDCValidator {
}

modifier onlyValidVoterCap {

require(msg.value >= minVoterCap);
_;
}

modifier onlyKYCWhitelisted {
require(KYCString[msg.sender].length!=0 || ownerToCandidate[msg.sender].length>0);
_;
}

modifier onlyOwner(address _candidate) {
require(validatorsState[_candidate].owner == msg.sender);
_;
Expand Down Expand Up @@ -99,7 +118,8 @@ contract XDCValidator {
candidateWithdrawDelay = _candidateWithdrawDelay;
voterWithdrawDelay = _voterWithdrawDelay;
candidateCount = _candidates.length;

owners.push(_firstOwner);
ownerCount++;
for (uint256 i = 0; i < _candidates.length; i++) {
candidates.push(_candidates[i]);
validatorsState[_candidates[i]] = ValidatorState({
Expand All @@ -108,11 +128,20 @@ contract XDCValidator {
cap: _caps[i]
});
voters[_candidates[i]].push(_firstOwner);
ownerToCandidate[_firstOwner].push(_candidates[i]);
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap;
}
}

function propose(address _candidate) external payable onlyValidCandidateCap onlyNotCandidate(_candidate) {

// uploadKYC : anyone can upload a KYC; its not equivalent to becoming an owner.
function uploadKYC(string kychash) external {
KYCString[msg.sender].push(kychash);
emit UploadedKYC(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) {
uint256 cap = validatorsState[_candidate].cap.add(msg.value);
candidates.push(_candidate);
validatorsState[_candidate] = ValidatorState({
Expand All @@ -122,6 +151,11 @@ 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);
ownerCount++;
}
ownerToCandidate[msg.sender].push(_candidate);
voters[_candidate].push(msg.sender);
emit Propose(msg.sender, _candidate, msg.value);
}
Expand Down Expand Up @@ -198,6 +232,67 @@ 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
address[] memory allMasternodes = new address[](candidates.length-1) ;
uint count=0;
for (uint i=0;i<candidates.length;i++){
if (getCandidateOwner(candidates[i])==_invalidMasternode){
// logic to remove cap.
candidateCount = candidateCount.sub(1);
allMasternodes[count++] = candidates[i];
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];
ownerCount--;
break;
}
}
emit InvalidatedNode(_invalidMasternode,allMasternodes);
}
}

// 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 ownerCount;
}

// getKYC : get KYC uploaded of the owner of the given masternode or the owner themselves
function getLatestKYC(address _address) view public returns (string) {
if(isCandidate(_address)){
return KYCString[getCandidateOwner(_address)][KYCString[getCandidateOwner(_address)].length-1];
}
else{
return KYCString[_address][KYCString[_address].length-1];
}
}

function getHashCount(address _address) view public returns(uint){
return KYCString[_address].length;
}

function withdraw(uint256 _blockNumber, uint _index) public onlyValidWithdraw(_blockNumber, _index) {
uint256 cap = withdrawsState[msg.sender].caps[_blockNumber];
delete withdrawsState[msg.sender].caps[_blockNumber];
Expand Down
7 changes: 4 additions & 3 deletions contracts/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
package validator

import (
"math/big"

"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/contracts/validator/contract"
"math/big"
)

type Validator struct {
Expand Down Expand Up @@ -51,8 +52,8 @@ func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.Contr
// 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))
// Voter Delay Withdraw 10 days = 432000 blocks
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(18), big.NewInt(1296000), big.NewInt(432000))
if err != nil {
return validatorAddr, nil, err
}
Expand Down
36 changes: 19 additions & 17 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,13 @@ func (bc *BlockChain) OrderStateAt(block *types.Block) (*tradingstate.TradingSta
} else {
return nil, err
}
} else {
XDCxState, err := XDCXService.GetEmptyTradingState()
if err == nil {
return XDCxState, nil
} else {
return nil, err
}
}
}
return nil, errors.New("Get XDCx state fail")
Expand Down Expand Up @@ -2428,26 +2435,21 @@ func (bc *BlockChain) UpdateM1() error {
}
opts := new(bind.CallOpts)

// var candidates []common.Address
// // get candidates from slot of stateDB
// // if can't get anything, request from contracts
// stateDB, err := bc.State()
// if err != nil {

// candidates, err = validator.GetCandidates(opts)
// if err != nil {
var candidates []common.Address
// get candidates from slot of stateDB
// if can't get anything, request from contracts
stateDB, err := bc.State()
if err != nil {

// return err
// }
// } else {
candidates, err = validator.GetCandidates(opts)
if err != nil {

// candidates = state.GetCandidates(stateDB)
return err
}
} else {

// }
candidates = state.GetCandidates(stateDB)

candidates, err := validator.GetCandidates(opts)
if err != nil {
return err
}

var ms []utils.Masternode
Expand Down Expand Up @@ -2487,7 +2489,7 @@ func (bc *BlockChain) UpdateM1() error {
maxMasternodes = common.MaxMasternodes
}
if len(ms) > maxMasternodes {
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms[:common.MaxMasternodes])
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms[:maxMasternodes])
} else {
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms)
}
Expand Down
5 changes: 3 additions & 2 deletions core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ package core

import (
"fmt"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"math/rand"
"sync"
"testing"
"time"

"github.com/XinFinOrg/XDPoSChain/core/rawdb"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
"github.com/XinFinOrg/XDPoSChain/core/state"
Expand Down Expand Up @@ -1323,7 +1324,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
}

/*
Collection test for BlochsHashCache
Collection test for BlocksHashCache
cases
1. When init new chain
2. when insertChain
Expand Down
6 changes: 6 additions & 0 deletions core/state/statedb_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,14 @@ var (
"withdrawsState": 0,
"validatorsState": 1,
"voters": 2,
"KYCString": 3,
"invalidKYCCount": 4,
"hasVotedInvalid": 5,
"ownerToCandidate": 6,
"owners": 7,
"candidates": 8,
"candidateCount": 9,
"ownerCount": 10,
"minCandidateCap": 11,
"minVoterCap": 12,
"maxValidatorNumber": 13,
Expand Down
6 changes: 1 addition & 5 deletions eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,7 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI {
// DumpBlock retrieves the entire state of the database at a given block.
func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
if blockNr == rpc.PendingBlockNumber {
// If we're dumping the pending state, we need to request
// both the pending block as well as the pending state from
// the miner and operate on those
_, stateDb := api.eth.miner.Pending()
return stateDb.RawDump(), nil
blockNr = rpc.LatestBlockNumber
}
var block *types.Block
if blockNr == rpc.LatestBlockNumber {
Expand Down
Loading

0 comments on commit f9fa3a8

Please sign in to comment.