Move masternode in v2 config (#372)

* move masternode in v2 config

* update number to meet 7 vote for current setup

* add test

* update all failed test

* fix test

* remove comment

* remove comment

* fix test
This commit is contained in:
Liam 2023-11-29 11:11:58 +11:00 committed by GitHub
parent abb3f5c802
commit 47bfdf7635
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 85 additions and 39 deletions

View file

@ -310,10 +310,10 @@ func (XDCx *XDCX) ConvertXDCToToken(chain consensus.ChainContext, statedb *state
}
// there are 3 tasks need to complete to update data in SDK nodes after matching
// 1. txMatchData.Order: order has been processed. This order should be put to `orders` collection with status sdktypes.OrderStatusOpen
// 2. txMatchData.Trades: includes information of matched orders.
// a. PutObject them to `trades` collection
// b. Update status of regrading orders to sdktypes.OrderStatusFilled
// 1. txMatchData.Order: order has been processed. This order should be put to `orders` collection with status sdktypes.OrderStatusOpen
// 2. txMatchData.Trades: includes information of matched orders.
// a. PutObject them to `trades` collection
// b. Update status of regrading orders to sdktypes.OrderStatusFilled
func (XDCx *XDCX) SyncDataToSDKNode(takerOrderInTx *tradingstate.OrderItem, txHash common.Hash, txMatchTime time.Time, statedb *state.StateDB, trades []map[string]string, rejectedOrders []*tradingstate.OrderItem, dirtyOrderCount *uint64) error {
var (
// originTakerOrder: order get from db, nil if it doesn't exist

View file

@ -15,7 +15,7 @@ const (
EpocBlockOpening = 850
EpocBlockRandomize = 900
MaxMasternodes = 18
MaxMasternodesV2 = 108
MaxMasternodesV2 = 108 // Last v1 masternodes
LimitPenaltyEpoch = 4
LimitPenaltyEpochV2 = 0
BlocksPerYearTest = uint64(200000)

View file

@ -15,7 +15,7 @@ const (
EpocBlockOpening = 850
EpocBlockRandomize = 900
MaxMasternodes = 18
MaxMasternodesV2 = 108
MaxMasternodesV2 = 108 // Last v1 masternodes
LimitPenaltyEpoch = 4
LimitPenaltyEpochV2 = 0
BlocksPerYearTest = uint64(200000)

View file

@ -15,7 +15,7 @@ const (
EpocBlockOpening = 850
EpocBlockRandomize = 900
MaxMasternodes = 18
MaxMasternodesV2 = 15
MaxMasternodesV2 = 15 // Last v1 masternodes
LimitPenaltyEpoch = 4
LimitPenaltyEpochV2 = 0
BlocksPerYearTest = uint64(200000)

View file

@ -264,8 +264,7 @@ func (x *XDPoS_v2) YourTurn(chain consensus.ChainReader, parent *types.Header, s
}
waitedTime := time.Now().Unix() - parent.Time.Int64()
_, parentRound, _, err := x.getExtraFields(parent)
minePeriod := x.config.V2.Config(uint64(parentRound) + 1).MinePeriod // plus 1 means current block
minePeriod := x.config.V2.Config(uint64(x.currentRound)).MinePeriod
if waitedTime < int64(minePeriod) {
log.Trace("[YourTurn] wait after mine period", "minePeriod", minePeriod, "waitedTime", waitedTime)
return false, nil
@ -794,7 +793,7 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
certThreshold := x.config.V2.Config(uint64(qcRound)).CertThreshold
if (qcRound > 0) && (signatures == nil || float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold) {
//First V2 Block QC, QC Signatures is initial nil
log.Warn("[verifyHeader] Invalid QC Signature is nil or less then config", "QC", quorumCert, "QCNumber", quorumCert.ProposedBlockInfo.Number, "Signatures len", len(signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold)
log.Warn("[verifyHeader] Invalid QC Signature is nil or less then config", "QCNumber", quorumCert.ProposedBlockInfo.Number, "LenSignatures", len(signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold)
return utils.ErrInvalidQCSignatures
}
start := time.Now()
@ -1000,8 +999,7 @@ func (x *XDPoS_v2) GetStandbynodes(chain consensus.ChainReader, header *types.He
// Calculate masternodes for a block number and parent hash. In V2, truncating candidates[:MaxMasternodes] is done in this function.
func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.Int, parentHash common.Hash) ([]common.Address, []common.Address, error) {
// using new max masterndoes
maxMasternodes := common.MaxMasternodesV2
maxMasternodes := x.config.V2.Config(uint64(x.currentRound)).MaxMasternodes
snap, err := x.getSnapshot(chain, blockNum.Uint64(), false)
if err != nil {
log.Error("[calcMasternodes] Adaptor v2 getSnapshot has error", "err", err)

View file

@ -40,20 +40,20 @@ func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, pare
return false, errors.New("masternodes not found")
}
curIndex := utils.Position(masterNodes, signer)
if curIndex == -1 {
log.Warn("[yourturn] I am not in masternodes list", "Hash", parent.Hash(), "signer", signer)
return false, nil
}
for i, s := range masterNodes {
log.Debug("[yourturn] Masternode:", "index", i, "address", s.String(), "parentBlockNum", parent.Number)
}
curIndex := utils.Position(masterNodes, signer)
if curIndex == -1 {
log.Warn("[yourturn] I am not in masternodes list", "Hash", parent.Hash().Hex(), "signer", signer.Hex())
return false, nil
}
leaderIndex := uint64(round) % x.config.Epoch % uint64(len(masterNodes))
x.whosTurn = masterNodes[leaderIndex]
if x.whosTurn != signer {
log.Info("[yourturn] Not my turn", "curIndex", curIndex, "leaderIndex", leaderIndex, "Hash", parent.Hash().Hex(), "whosTurn", x.whosTurn, "myaddr", signer)
log.Info("[yourturn] Not my turn", "curIndex", curIndex, "leaderIndex", leaderIndex, "Hash", parent.Hash().Hex(), "whosTurn", x.whosTurn.Hex(), "myaddr", signer.Hex())
return false, nil
}

View file

@ -34,7 +34,7 @@ func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeou
}
// Threshold reached
certThreshold := x.config.V2.Config(uint64(x.currentRound)).CertThreshold
certThreshold := x.config.V2.Config(uint64(timeout.Round)).CertThreshold
isThresholdReached := float64(numberOfTimeoutsInPool) >= float64(epochInfo.MasternodesLen)*certThreshold
if isThresholdReached {
log.Info(fmt.Sprintf("Timeout pool threashold reached: %v, number of items in the pool: %v", isThresholdReached, numberOfTimeoutsInPool))

View file

@ -92,7 +92,7 @@ func TestNotChangeSingerListIfNothingProposedOrVoted(t *testing.T) {
}
}
//Should call updateM1 at gap block, and update the snapshot if there are SM transactions involved
// Should call updateM1 at gap block, and update the snapshot if there are SM transactions involved
func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
blockchain, backend, parentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-2, params.TestXDPoSMockChainConfig)
@ -166,7 +166,7 @@ func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
}
}
//Should call updateM1 before gap block, and update the snapshot if there are SM transactions involved
// Should call updateM1 before gap block, and update the snapshot if there are SM transactions involved
func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
blockchain, backend, currentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)

View file

@ -7,6 +7,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert"
)
@ -95,10 +96,11 @@ func TestIsYourTurnConsensusV2CrossConfig(t *testing.T) {
currentBlockHeader := currentBlock.Header()
currentBlockHeader.Time = big.NewInt(time.Now().Unix())
err := blockchain.InsertBlock(currentBlock)
adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(10), false)
assert.Nil(t, err)
// after first mine period
time.Sleep(time.Duration(firstMinePeriod) * time.Second)
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))
assert.Nil(t, err)
assert.False(t, isYourTurn)
@ -108,7 +110,7 @@ func TestIsYourTurnConsensusV2CrossConfig(t *testing.T) {
secondMinePeriod := blockchain.Config().XDPoS.V2.CurrentConfig.MinePeriod
time.Sleep(time.Duration(secondMinePeriod-firstMinePeriod) * time.Second)
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))
assert.Nil(t, err)
assert.True(t, isYourTurn)
}

View file

@ -223,6 +223,17 @@ func TestPrepareHappyPath(t *testing.T) {
assert.Equal(t, types.Round(0), decodedExtraField.QuorumCert.ProposedBlockInfo.Round)
}
func TestPrepareDifferentMasternode(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1799, config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// trigger initial
adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(919), false)
myturn, err := adaptor.YourTurn(blockchain, currentBlock.Header(), acc1Addr)
assert.Nil(t, err)
assert.True(t, myturn)
}
// test if we have 128 candidates, then snapshot will store all of them, and when preparing (and verifying) candidates is truncated to MaxMasternodes
func TestUpdateMultipleMasterNodes(t *testing.T) {
config := params.TestXDPoSMockChainConfig
@ -279,6 +290,6 @@ func TestUpdateMultipleMasterNodes(t *testing.T) {
adaptor.EngineV2.AuthorizeFaker(voterAddr)
err = adaptor.Prepare(blockchain, header1800)
assert.Nil(t, err)
assert.Equal(t, common.MaxMasternodesV2, len(header1800.Validators)/common.AddressLength) // although 128 masternode candidates, we can only pick MaxMasternodes
assert.Equal(t, blockchain.Config().XDPoS.V2.Config(900).MaxMasternodes, len(header1800.Validators)/common.AddressLength)
assert.Equal(t, 0, len(header1800.Penalties)/common.AddressLength)
}

View file

@ -212,7 +212,7 @@ func TestConfigSwitchOnDifferentCertThreshold(t *testing.T) {
}
extraInBytes, _ := extra.EncodeToBytes()
// after 910 require 5 signs, but we only give 3 signs
// after 910 require 4 signs, but we only give 3 signs
block912 := blockchain.GetBlockByNumber(912).Header()
block912.Extra = extraInBytes
err = adaptor.VerifyHeader(blockchain, block912, true)

View file

@ -767,7 +767,17 @@ func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAd
}
var maxMasternodes int
if s.b.ChainConfig().IsTIPIncreaseMasternodes(block.Number()) {
if header.Number.Cmp(s.b.ChainConfig().XDPoS.V2.SwitchBlock) == 1 {
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
round, err := engine.EngineV2.GetRoundNumber(header)
if err != nil {
return result, err
}
maxMasternodes = s.b.ChainConfig().XDPoS.V2.Config(uint64(round)).MaxMasternodes
} else {
return result, fmt.Errorf("undefined XDPoS consensus engine")
}
} else if s.b.ChainConfig().IsTIPIncreaseMasternodes(block.Number()) {
maxMasternodes = common.MaxMasternodesV2
} else {
maxMasternodes = common.MaxMasternodes
@ -948,7 +958,17 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch
}
var maxMasternodes int
if s.b.ChainConfig().IsTIPIncreaseMasternodes(block.Number()) {
if header.Number.Cmp(s.b.ChainConfig().XDPoS.V2.SwitchBlock) == 1 {
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
round, err := engine.EngineV2.GetRoundNumber(header)
if err != nil {
return result, err
}
maxMasternodes = s.b.ChainConfig().XDPoS.V2.Config(uint64(round)).MaxMasternodes
} else {
return result, fmt.Errorf("undefined XDPoS consensus engine")
}
} else if s.b.ChainConfig().IsTIPIncreaseMasternodes(block.Number()) {
maxMasternodes = common.MaxMasternodesV2
} else {
maxMasternodes = common.MaxMasternodes

View file

@ -41,26 +41,37 @@ var (
var (
MainnetV2Configs = map[uint64]*V2Config{
Default: {
MaxMasternodes: 108,
SwitchRound: 0,
CertThreshold: 0.667,
TimeoutSyncThreshold: 3,
TimeoutPeriod: 60,
TimeoutPeriod: 20,
MinePeriod: 2,
},
}
TestnetV2Configs = map[uint64]*V2Config{
Default: {
MaxMasternodes: 15,
SwitchRound: 0,
CertThreshold: 0.45,
TimeoutSyncThreshold: 3,
TimeoutPeriod: 20,
MinePeriod: 2,
},
900000: {
MaxMasternodes: 108,
SwitchRound: 900000,
CertThreshold: 0.667,
TimeoutSyncThreshold: 3,
TimeoutPeriod: 60,
TimeoutPeriod: 20,
MinePeriod: 2,
},
}
DevnetV2Configs = map[uint64]*V2Config{
Default: {
MaxMasternodes: 108,
SwitchRound: 0,
CertThreshold: 0.667,
TimeoutSyncThreshold: 5,
@ -71,6 +82,7 @@ var (
UnitTestV2Configs = map[uint64]*V2Config{
Default: {
MaxMasternodes: 18,
SwitchRound: 0,
CertThreshold: 0.667,
TimeoutSyncThreshold: 2,
@ -78,15 +90,17 @@ var (
MinePeriod: 2,
},
10: {
MaxMasternodes: 18,
SwitchRound: 10,
CertThreshold: 1,
CertThreshold: 0.667,
TimeoutSyncThreshold: 2,
TimeoutPeriod: 4,
MinePeriod: 3,
},
899: {
SwitchRound: 899,
CertThreshold: 1,
900: {
MaxMasternodes: 20,
SwitchRound: 900,
CertThreshold: 0.667,
TimeoutSyncThreshold: 4,
TimeoutPeriod: 5,
MinePeriod: 2,
@ -325,6 +339,7 @@ type V2 struct {
}
type V2Config struct {
MaxMasternodes int `json:"maxMasternodes"` // v2 max masternodes
SwitchRound uint64 `json:"switchRound"` // v1 to v2 switch block number
MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block
TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout
@ -362,7 +377,7 @@ func (v *V2) UpdateConfig(round uint64) {
}
func (v *V2) Config(round uint64) *V2Config {
configRound := round - 1 //start from next block from SwitchRound number
configRound := round
var index uint64
//find the right config

View file

@ -89,9 +89,9 @@ func TestUpdateV2Config(t *testing.T) {
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(10)
c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
assert.Equal(t, float64(1), c.CertThreshold)
assert.Equal(t, float64(0.667), c.CertThreshold)
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(899)
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(900)
c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
assert.Equal(t, 4, c.TimeoutSyncThreshold)
}
@ -108,12 +108,12 @@ func TestV2Config(t *testing.T) {
assert.Equal(t, 0.667, c.CertThreshold)
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(11)
assert.Equal(t, float64(1), c.CertThreshold)
assert.Equal(t, float64(0.667), c.CertThreshold)
}
func TestBuildConfigIndex(t *testing.T) {
TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex()
index := TestXDPoSMockChainConfig.XDPoS.V2.ConfigIndex()
expected := []uint64{899, 10, 0}
expected := []uint64{900, 10, 0}
assert.Equal(t, expected, index)
}