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) 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 { func (XDCx *XDCX) GetStateCache() tradingstate.Database {
return XDCx.StateCache return XDCx.StateCache

View file

@ -24,7 +24,7 @@ const (
MergeSignRange = 15 MergeSignRange = 15
RangeReturnSigner = 150 RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1 MinimunMinerBlockPerEpoch = 1
IgnoreSignerCheckBlock = uint64(27307800)
OneYear = uint64(365 * 86400) OneYear = uint64(365 * 86400)
LiquidateLendingTradeBlock = uint64(100) LiquidateLendingTradeBlock = uint64(100)
) )
@ -36,14 +36,14 @@ var TIPSigning = big.NewInt(3000000)
var TIPRandomize = big.NewInt(3464000) var TIPRandomize = big.NewInt(3464000)
var TIPIncreaseMasternodes = big.NewInt(5000000) // Upgrade MN Count at Block. var TIPIncreaseMasternodes = big.NewInt(5000000) // Upgrade MN Count at Block.
var TIPNoHalvingMNReward = big.NewInt(23779191) // hardfork no halving masternodes reward var TIPNoHalvingMNReward = big.NewInt(38383838) // hardfork no halving masternodes reward
var BlackListHFNumber = uint64(23779191) var BlackListHFNumber = uint64(38383838)
var TIPXDCX = big.NewInt(23779191) var TIPXDCX = big.NewInt(38383838)
var TIPXDCXLending = big.NewInt(23779191) var TIPXDCXLending = big.NewInt(38383838)
var TIPXDCXCancellationFee = big.NewInt(23779191) var TIPXDCXCancellationFee = big.NewInt(38383838)
var TIPXDCXCancellationFeeTestnet = big.NewInt(23779191) var TIPXDCXCancellationFeeTestnet = big.NewInt(38383838)
var TIPXDCXTestnet = big.NewInt(23779191) var TIPXDCXTestnet = big.NewInt(38383838)
var IsTestnet bool = false var IsTestnet bool = false
var StoreRewardFolder string var StoreRewardFolder string
var RollbackHash Hash var RollbackHash Hash
@ -71,9 +71,16 @@ var TRC21GasPrice = big.NewInt(250000000)
var RateTopUp = big.NewInt(90) // 90% var RateTopUp = big.NewInt(90) // 90%
var BaseTopUp = big.NewInt(100) var BaseTopUp = big.NewInt(100)
var BaseRecall = big.NewInt(100) var BaseRecall = big.NewInt(100)
var TIPTRC21Fee = big.NewInt(23779191) var TIPTRC21Fee = big.NewInt(38383838)
var TIPTRC21FeeTestnet = big.NewInt(23779191) var TIPTRC21FeeTestnet = big.NewInt(38383838)
var LimitTimeFinality = uint64(30) // limit in 30 block 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{ var Blacklist = map[Address]bool{
HexToAddress("0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"): true, HexToAddress("0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"): true,
HexToAddress("0x5ac26105b35ea8935be382863a70281ec7a985e9"): 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 { func (x *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header *types.Header, signers []common.Address) error {
number := header.Number.Uint64() number := header.Number.Uint64()
// ignore signerCheck at checkpoint block 14458500 due to wrong snapshot at gap 14458495 // ignore signerCheck at checkpoint block.
if number == common.IgnoreSignerCheckBlock { if common.IgnoreSignerCheckBlockArray[number] {
return nil return nil
} }
penPenalties := []common.Address{} penPenalties := []common.Address{}

View file

@ -22,6 +22,7 @@ type Masternode struct {
type TradingService interface { type TradingService interface {
GetTradingStateRoot(block *types.Block, author common.Address) (common.Hash, error) GetTradingStateRoot(block *types.Block, author common.Address) (common.Hash, error)
GetTradingState(block *types.Block, author common.Address) (*tradingstate.TradingStateDB, error) GetTradingState(block *types.Block, author common.Address) (*tradingstate.TradingStateDB, error)
GetEmptyTradingState() (*tradingstate.TradingStateDB, error)
HasTradingState(block *types.Block, author common.Address) bool HasTradingState(block *types.Block, author common.Address) bool
GetStateCache() tradingstate.Database GetStateCache() tradingstate.Database
GetTriegc() *prque.Prque GetTriegc() *prque.Prque

View file

@ -1,7 +1,9 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.21;
import "./libs/SafeMath.sol"; import "./libs/SafeMath.sol";
contract XDCValidator { contract XDCValidator {
using SafeMath for uint256; using SafeMath for uint256;
@ -10,6 +12,8 @@ contract XDCValidator {
event Propose(address _owner, address _candidate, uint256 _cap); event Propose(address _owner, address _candidate, uint256 _cap);
event Resign(address _owner, address _candidate); event Resign(address _owner, address _candidate);
event Withdraw(address _owner, uint256 _blockNumber, uint256 _cap); event Withdraw(address _owner, uint256 _blockNumber, uint256 _cap);
event UploadedKYC(address _owner,string kycHash);
event InvalidatedNode(address _masternodeOwner, address[] _masternodes);
struct ValidatorState { struct ValidatorState {
address owner; address owner;
@ -27,9 +31,18 @@ contract XDCValidator {
mapping(address => ValidatorState) validatorsState; mapping(address => ValidatorState) validatorsState;
mapping(address => address[]) voters; 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; address[] public candidates;
uint256 public candidateCount = 0; uint256 public candidateCount = 0;
uint256 public ownerCount =0;
uint256 public minCandidateCap; uint256 public minCandidateCap;
uint256 public minVoterCap; uint256 public minVoterCap;
uint256 public maxValidatorNumber; uint256 public maxValidatorNumber;
@ -43,10 +56,16 @@ contract XDCValidator {
} }
modifier onlyValidVoterCap { modifier onlyValidVoterCap {
require(msg.value >= minVoterCap); require(msg.value >= minVoterCap);
_; _;
} }
modifier onlyKYCWhitelisted {
require(KYCString[msg.sender].length!=0 || ownerToCandidate[msg.sender].length>0);
_;
}
modifier onlyOwner(address _candidate) { modifier onlyOwner(address _candidate) {
require(validatorsState[_candidate].owner == msg.sender); require(validatorsState[_candidate].owner == msg.sender);
_; _;
@ -99,7 +118,8 @@ contract XDCValidator {
candidateWithdrawDelay = _candidateWithdrawDelay; candidateWithdrawDelay = _candidateWithdrawDelay;
voterWithdrawDelay = _voterWithdrawDelay; voterWithdrawDelay = _voterWithdrawDelay;
candidateCount = _candidates.length; candidateCount = _candidates.length;
owners.push(_firstOwner);
ownerCount++;
for (uint256 i = 0; i < _candidates.length; i++) { for (uint256 i = 0; i < _candidates.length; i++) {
candidates.push(_candidates[i]); candidates.push(_candidates[i]);
validatorsState[_candidates[i]] = ValidatorState({ validatorsState[_candidates[i]] = ValidatorState({
@ -108,11 +128,20 @@ contract XDCValidator {
cap: _caps[i] cap: _caps[i]
}); });
voters[_candidates[i]].push(_firstOwner); voters[_candidates[i]].push(_firstOwner);
ownerToCandidate[_firstOwner].push(_candidates[i]);
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap; 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); uint256 cap = validatorsState[_candidate].cap.add(msg.value);
candidates.push(_candidate); candidates.push(_candidate);
validatorsState[_candidate] = ValidatorState({ validatorsState[_candidate] = ValidatorState({
@ -122,6 +151,11 @@ contract XDCValidator {
}); });
validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value); validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value);
candidateCount = candidateCount.add(1); 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); voters[_candidate].push(msg.sender);
emit Propose(msg.sender, _candidate, msg.value); emit Propose(msg.sender, _candidate, msg.value);
} }
@ -198,6 +232,67 @@ contract XDCValidator {
emit Resign(msg.sender, _candidate); 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) { function withdraw(uint256 _blockNumber, uint _index) public onlyValidWithdraw(_blockNumber, _index) {
uint256 cap = withdrawsState[msg.sender].caps[_blockNumber]; uint256 cap = withdrawsState[msg.sender].caps[_blockNumber];
delete withdrawsState[msg.sender].caps[_blockNumber]; delete withdrawsState[msg.sender].caps[_blockNumber];

View file

@ -16,10 +16,11 @@
package validator package validator
import ( import (
"math/big"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/contracts/validator/contract" "github.com/XinFinOrg/XDPoSChain/contracts/validator/contract"
"math/big"
) )
type Validator struct { type Validator struct {
@ -51,8 +52,8 @@ func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.Contr
// Min Voter Cap 10 XDC // Min Voter Cap 10 XDC
// 150 masternodes // 150 masternodes
// Candidate Delay Withdraw 30 days = 1296000 blocks // Candidate Delay Withdraw 30 days = 1296000 blocks
// Voter Delay Withdraw 2 days = 86400 blocks // Voter Delay Withdraw 10 days = 432000 blocks
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(150), big.NewInt(1296000), big.NewInt(86400)) validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(18), big.NewInt(1296000), big.NewInt(432000))
if err != nil { if err != nil {
return validatorAddr, nil, err return validatorAddr, nil, err
} }

View file

@ -519,6 +519,13 @@ func (bc *BlockChain) OrderStateAt(block *types.Block) (*tradingstate.TradingSta
} else { } else {
return nil, err 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") return nil, errors.New("Get XDCx state fail")
@ -2428,26 +2435,21 @@ func (bc *BlockChain) UpdateM1() error {
} }
opts := new(bind.CallOpts) opts := new(bind.CallOpts)
// var candidates []common.Address var candidates []common.Address
// // get candidates from slot of stateDB // get candidates from slot of stateDB
// // if can't get anything, request from contracts // if can't get anything, request from contracts
// stateDB, err := bc.State() 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)
if err != nil { if err != nil {
return err
candidates, err = validator.GetCandidates(opts)
if err != nil {
return err
}
} else {
candidates = state.GetCandidates(stateDB)
} }
var ms []utils.Masternode var ms []utils.Masternode
@ -2487,7 +2489,7 @@ func (bc *BlockChain) UpdateM1() error {
maxMasternodes = common.MaxMasternodes maxMasternodes = common.MaxMasternodes
} }
if len(ms) > maxMasternodes { if len(ms) > maxMasternodes {
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms[:common.MaxMasternodes]) err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms[:maxMasternodes])
} else { } else {
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms) err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms)
} }

View file

@ -18,13 +18,14 @@ package core
import ( import (
"fmt" "fmt"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big" "math/big"
"math/rand" "math/rand"
"sync" "sync"
"testing" "testing"
"time" "time"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
"github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/state"
@ -1323,7 +1324,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
} }
/* /*
Collection test for BlochsHashCache Collection test for BlocksHashCache
cases cases
1. When init new chain 1. When init new chain
2. when insertChain 2. when insertChain

View file

@ -73,8 +73,14 @@ var (
"withdrawsState": 0, "withdrawsState": 0,
"validatorsState": 1, "validatorsState": 1,
"voters": 2, "voters": 2,
"KYCString": 3,
"invalidKYCCount": 4,
"hasVotedInvalid": 5,
"ownerToCandidate": 6,
"owners": 7,
"candidates": 8, "candidates": 8,
"candidateCount": 9, "candidateCount": 9,
"ownerCount": 10,
"minCandidateCap": 11, "minCandidateCap": 11,
"minVoterCap": 12, "minVoterCap": 12,
"maxValidatorNumber": 13, "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. // DumpBlock retrieves the entire state of the database at a given block.
func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) { func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
// If we're dumping the pending state, we need to request blockNr = rpc.LatestBlockNumber
// 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
} }
var block *types.Block var block *types.Block
if blockNr == rpc.LatestBlockNumber { 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) { func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
// Pending block is only known by the miner // Pending block is only known by the miner
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
block := b.eth.miner.PendingBlock() blockNr = rpc.LatestBlockNumber
return block.Header(), nil
} }
// Otherwise resolve and return the block // Otherwise resolve and return the block
if blockNr == rpc.LatestBlockNumber { 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) { func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
// Pending block is only known by the miner // Pending block is only known by the miner
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
block := b.eth.miner.PendingBlock() blockNr = rpc.LatestBlockNumber
return block, nil
} }
// Otherwise resolve and return the block // Otherwise resolve and return the block
if blockNr == rpc.LatestBlockNumber { 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) { func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
// Pending state is only known by the miner // Pending state is only known by the miner
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
block, state := b.eth.miner.Pending() blockNr = rpc.LatestBlockNumber
return state, block.Header(), nil
} }
// Otherwise resolve the block number and return its state // Otherwise resolve the block number and return its state
header, err := b.HeaderByNumber(ctx, blockNr) header, err := b.HeaderByNumber(ctx, blockNr)

View file

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

View file

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