Merge pull request #145 from XinFinOrg/mainnet_test

missing ValidatorMapping update.
This commit is contained in:
Anil Chinchawale 2021-11-16 11:09:20 +05:30 committed by GitHub
commit f9fa3a8a07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 168 additions and 58 deletions

View file

@ -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

View file

@ -24,7 +24,7 @@ const (
MergeSignRange = 15
RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1
IgnoreSignerCheckBlock = uint64(27307800)
OneYear = uint64(365 * 86400)
LiquidateLendingTradeBlock = uint64(100)
)
@ -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
@ -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,

View file

@ -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{}

View file

@ -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

View file

@ -1,7 +1,9 @@
pragma solidity ^0.4.21;
import "./libs/SafeMath.sol";
contract XDCValidator {
using SafeMath for uint256;
@ -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;
@ -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;
@ -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);
_;
@ -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({
@ -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({
@ -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);
}
@ -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];

View file

@ -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 {
@ -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
}

View file

@ -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")
@ -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 {
// return err
// }
// } else {
// candidates = state.GetCandidates(stateDB)
// }
candidates, err := validator.GetCandidates(opts)
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
candidates, err = validator.GetCandidates(opts)
if err != nil {
return err
}
} else {
candidates = state.GetCandidates(stateDB)
}
var ms []utils.Masternode
@ -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)
}

View file

@ -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"
@ -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

View file

@ -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,

View file

@ -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 {

View file

@ -76,8 +76,7 @@ func (b *EthApiBackend) SetHead(number uint64) {
func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
// Pending block is only known by the miner
if blockNr == rpc.PendingBlockNumber {
block := b.eth.miner.PendingBlock()
return block.Header(), nil
blockNr = rpc.LatestBlockNumber
}
// Otherwise resolve and return the block
if blockNr == rpc.LatestBlockNumber {
@ -89,8 +88,7 @@ func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNum
func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
// Pending block is only known by the miner
if blockNr == rpc.PendingBlockNumber {
block := b.eth.miner.PendingBlock()
return block, nil
blockNr = rpc.LatestBlockNumber
}
// Otherwise resolve and return the block
if blockNr == rpc.LatestBlockNumber {
@ -102,8 +100,7 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
// Pending state is only known by the miner
if blockNr == rpc.PendingBlockNumber {
block, state := b.eth.miner.Pending()
return state, block.Header(), nil
blockNr = rpc.LatestBlockNumber
}
// Otherwise resolve the block number and return its state
header, err := b.HeaderByNumber(ctx, blockNr)

View file

@ -21,13 +21,14 @@ import (
"context"
"errors"
"fmt"
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
"io/ioutil"
"math/big"
"runtime"
"sync"
"time"
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
"github.com/XinFinOrg/XDPoSChain/core"
@ -99,7 +100,7 @@ func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.Block
switch start {
case rpc.PendingBlockNumber:
from = api.eth.miner.PendingBlock()
from = api.eth.blockchain.CurrentBlock()
case rpc.LatestBlockNumber:
from = api.eth.blockchain.CurrentBlock()
default:
@ -107,7 +108,7 @@ func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.Block
}
switch end {
case rpc.PendingBlockNumber:
to = api.eth.miner.PendingBlock()
to = api.eth.blockchain.CurrentBlock()
case rpc.LatestBlockNumber:
to = api.eth.blockchain.CurrentBlock()
default:
@ -353,7 +354,7 @@ func (api *PrivateDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.B
switch number {
case rpc.PendingBlockNumber:
block = api.eth.miner.PendingBlock()
block = api.eth.blockchain.CurrentBlock()
case rpc.LatestBlockNumber:
block = api.eth.blockchain.CurrentBlock()
default:
@ -514,7 +515,7 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
break
}
if statedb, err = state.New(block.Root(), database); err == nil {
XDCxState, err = tradingstate.New(block.Root(), tradingstate.NewDatabase(api.eth.XDCX.GetLevelDB()))
XDCxState, err = api.eth.blockchain.OrderStateAt(block)
if err == nil {
break
}

View file

@ -22,9 +22,9 @@ import (
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 3 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release
VersionMeta = "unstable" // Version metadata to append to the version string
VersionMinor = 4 // Minor version component of the current release
VersionPatch = 3 // Patch version component of the current release
VersionMeta = "stable" // Version metadata to append to the version string
)
// Version holds the textual version string.