mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
Make masternode dynamic (#356)
* make masternode dynamic * fix all the tests * remove cmt * fix test again
This commit is contained in:
parent
041b667fb0
commit
c215316744
15 changed files with 160 additions and 97 deletions
|
|
@ -145,8 +145,8 @@ func (w *wizard) makeGenesis() {
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = w.readDefaultInt(3)
|
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = w.readDefaultInt(3)
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %d)\n", common.MaxMasternodesV2/3*2+1)
|
fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %f)\n", 0.666)
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = w.readDefaultInt(common.MaxMasternodesV2)/3*2 + 1
|
genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = w.readDefaultFloat(0.666)
|
||||||
|
|
||||||
genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig
|
genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -772,17 +772,6 @@ func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, block
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *types.QuorumCert, parentHeader *types.Header) error {
|
func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *types.QuorumCert, parentHeader *types.Header) error {
|
||||||
/*
|
|
||||||
1. Check if num of QC signatures is >= x.config.v2.CertThreshold
|
|
||||||
2. Get epoch master node list by hash
|
|
||||||
3. Verify signer signatures: (List of signatures)
|
|
||||||
- Use ecRecover to get the public key
|
|
||||||
- Use the above public key to find out the xdc address
|
|
||||||
- Use the above xdc address to check against the master node list from step 1(For the received QC epoch)
|
|
||||||
4. Verify gapNumber = epochSwitchNumber - epochSwitchNumber%Epoch - Gap
|
|
||||||
5. Verify blockInfo
|
|
||||||
*/
|
|
||||||
|
|
||||||
if quorumCert == nil {
|
if quorumCert == nil {
|
||||||
log.Warn("[verifyQC] QC is Nil")
|
log.Warn("[verifyQC] QC is Nil")
|
||||||
return utils.ErrInvalidQC
|
return utils.ErrInvalidQC
|
||||||
|
|
@ -803,9 +792,9 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
|
||||||
|
|
||||||
qcRound := quorumCert.ProposedBlockInfo.Round
|
qcRound := quorumCert.ProposedBlockInfo.Round
|
||||||
certThreshold := x.config.V2.Config(uint64(qcRound)).CertThreshold
|
certThreshold := x.config.V2.Config(uint64(qcRound)).CertThreshold
|
||||||
if (qcRound > 0) && (signatures == nil || (len(signatures) < certThreshold)) {
|
if (qcRound > 0) && (signatures == nil || float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold) {
|
||||||
//First V2 Block QC, QC Signatures is initial nil
|
//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", certThreshold)
|
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)
|
||||||
return utils.ErrInvalidQCSignatures
|
return utils.ErrInvalidQCSignatures
|
||||||
}
|
}
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
@ -1045,17 +1034,8 @@ func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.In
|
||||||
if len(masternodes) > maxMasternodes {
|
if len(masternodes) > maxMasternodes {
|
||||||
masternodes = masternodes[:maxMasternodes]
|
masternodes = masternodes[:maxMasternodes]
|
||||||
}
|
}
|
||||||
if len(masternodes) < x.config.V2.CurrentConfig.CertThreshold {
|
|
||||||
log.Warn("[calcMasternodes] Current epoch masternodes less than threshold", "number", blockNum, "masternodes", len(masternodes), "threshold", x.config.V2.CurrentConfig.CertThreshold)
|
|
||||||
for i, a := range masternodes {
|
|
||||||
log.Warn("final masternode", "i", i, "addr", a)
|
|
||||||
}
|
|
||||||
for i, a := range penalties {
|
|
||||||
log.Warn("penalty", "i", i, "addr", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return masternodes, penalties, nil
|
|
||||||
|
|
||||||
|
return masternodes, penalties, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given hash, get master node from the epoch switch block of the epoch
|
// Given hash, get master node from the epoch switch block of the epoch
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
|
||||||
Penalties: penalties,
|
Penalties: penalties,
|
||||||
Standbynodes: standbynodes,
|
Standbynodes: standbynodes,
|
||||||
Masternodes: masternodes,
|
Masternodes: masternodes,
|
||||||
|
MasternodesLen: len(masternodes),
|
||||||
EpochSwitchBlockInfo: &types.BlockInfo{
|
EpochSwitchBlockInfo: &types.BlockInfo{
|
||||||
Hash: hash,
|
Hash: hash,
|
||||||
Number: h.Number,
|
Number: h.Number,
|
||||||
|
|
|
||||||
|
|
@ -80,10 +80,10 @@ func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC types.Quo
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Entry point for processing forensics.
|
Entry point for processing forensics.
|
||||||
Triggered once processQC is successfully.
|
Triggered once processQC is successfully.
|
||||||
Forensics runs in a seperate go routine as its no system critical
|
Forensics runs in a seperate go routine as its no system critical
|
||||||
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
|
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
|
||||||
*/
|
*/
|
||||||
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC types.QuorumCert) error {
|
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC types.QuorumCert) error {
|
||||||
log.Debug("Received a QC in forensics", "QC", incomingQC)
|
log.Debug("Received a QC in forensics", "QC", incomingQC)
|
||||||
|
|
@ -387,10 +387,10 @@ func generateVoteEquivocationId(signer common.Address, round1, round2 types.Roun
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Entry point for processing vote equivocation.
|
Entry point for processing vote equivocation.
|
||||||
Triggered once handle vote is successfully.
|
Triggered once handle vote is successfully.
|
||||||
Forensics runs in a seperate go routine as its no system critical
|
Forensics runs in a seperate go routine as its no system critical
|
||||||
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/99516417/Vote+Equivocation+detection+specification
|
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/99516417/Vote+Equivocation+detection+specification
|
||||||
*/
|
*/
|
||||||
func (f *Forensics) ProcessVoteEquivocation(chain consensus.ChainReader, engine *XDPoS_v2, incomingVote *types.Vote) error {
|
func (f *Forensics) ProcessVoteEquivocation(chain consensus.ChainReader, engine *XDPoS_v2, incomingVote *types.Vote) error {
|
||||||
log.Debug("Received a vote in forensics", "vote", incomingVote)
|
log.Debug("Received a vote in forensics", "vote", incomingVote)
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,15 @@ func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeou
|
||||||
numberOfTimeoutsInPool, pooledTimeouts := x.timeoutPool.Add(timeout)
|
numberOfTimeoutsInPool, pooledTimeouts := x.timeoutPool.Add(timeout)
|
||||||
log.Debug("[timeoutHandler] collect timeout", "number", numberOfTimeoutsInPool)
|
log.Debug("[timeoutHandler] collect timeout", "number", numberOfTimeoutsInPool)
|
||||||
|
|
||||||
|
epochInfo, err := x.getEpochSwitchInfo(blockChainReader, blockChainReader.CurrentHeader(), blockChainReader.CurrentHeader().Hash())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[timeoutHandler] Error when getting epoch switch Info", "error", err)
|
||||||
|
return fmt.Errorf("fail on timeoutHandler due to failure in getting epoch switch info, %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Threshold reached
|
// Threshold reached
|
||||||
certThreshold := x.config.V2.Config(uint64(x.currentRound)).CertThreshold
|
certThreshold := x.config.V2.Config(uint64(x.currentRound)).CertThreshold
|
||||||
isThresholdReached := numberOfTimeoutsInPool >= certThreshold
|
isThresholdReached := float64(numberOfTimeoutsInPool) >= float64(epochInfo.MasternodesLen)*certThreshold
|
||||||
if isThresholdReached {
|
if isThresholdReached {
|
||||||
log.Info(fmt.Sprintf("Timeout pool threashold reached: %v, number of items in the pool: %v", isThresholdReached, numberOfTimeoutsInPool))
|
log.Info(fmt.Sprintf("Timeout pool threashold reached: %v, number of items in the pool: %v", isThresholdReached, numberOfTimeoutsInPool))
|
||||||
err := x.onTimeoutPoolThresholdReached(blockChainReader, pooledTimeouts, timeout, timeout.GapNumber)
|
err := x.onTimeoutPoolThresholdReached(blockChainReader, pooledTimeouts, timeout, timeout.GapNumber)
|
||||||
|
|
@ -89,11 +95,11 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time
|
||||||
snap, err := x.getSnapshot(chain, timeoutCert.GapNumber, true)
|
snap, err := x.getSnapshot(chain, timeoutCert.GapNumber, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "TCGapNumber", timeoutCert.GapNumber)
|
log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "TCGapNumber", timeoutCert.GapNumber)
|
||||||
return fmt.Errorf("[verifyTC] Unable to get snapshot")
|
return fmt.Errorf("[verifyTC] Unable to get snapshot, %s", err)
|
||||||
}
|
}
|
||||||
if snap == nil || len(snap.NextEpochMasterNodes) == 0 {
|
if snap == nil || len(snap.NextEpochMasterNodes) == 0 {
|
||||||
log.Error("[verifyTC] Something wrong with the snapshot from gapNumber", "messageGapNumber", timeoutCert.GapNumber, "snapshot", snap)
|
log.Error("[verifyTC] Something wrong with the snapshot from gapNumber", "messageGapNumber", timeoutCert.GapNumber, "snapshot", snap)
|
||||||
return fmt.Errorf("Empty master node lists from snapshot")
|
return fmt.Errorf("empty master node lists from snapshot")
|
||||||
}
|
}
|
||||||
|
|
||||||
signatures, duplicates := UniqueSignatures(timeoutCert.Signatures)
|
signatures, duplicates := UniqueSignatures(timeoutCert.Signatures)
|
||||||
|
|
@ -103,9 +109,15 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[verifyTC] Error when getting epoch switch Info", "error", err)
|
||||||
|
return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
certThreshold := x.config.V2.Config(uint64(timeoutCert.Round)).CertThreshold
|
certThreshold := x.config.V2.Config(uint64(timeoutCert.Round)).CertThreshold
|
||||||
if len(signatures) < certThreshold {
|
if float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold {
|
||||||
log.Warn("[verifyTC] Invalid TC Signature is nil or empty", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(timeoutCert.Signatures), "CertThreshold", certThreshold)
|
log.Warn("[verifyTC] Invalid TC Signature is nil or empty", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(timeoutCert.Signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold)
|
||||||
return utils.ErrInvalidTCSignatures
|
return utils.ErrInvalidTCSignatures
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,12 +136,12 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time
|
||||||
verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochMasterNodes)
|
verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochMasterNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[verifyTC] Error while verfying TC message signatures", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures), "Error", err)
|
log.Error("[verifyTC] Error while verfying TC message signatures", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures), "Error", err)
|
||||||
haveError = fmt.Errorf("Error while verfying TC message signatures")
|
haveError = fmt.Errorf("error while verfying TC message signatures, %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !verified {
|
if !verified {
|
||||||
log.Warn("[verifyTC] Signature not verified doing TC verification", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures))
|
log.Warn("[verifyTC] Signature not verified doing TC verification", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures))
|
||||||
haveError = fmt.Errorf("Fail to verify TC due to signature mis-match")
|
haveError = fmt.Errorf("fail to verify TC due to signature mis-match")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}(signature)
|
}(signature)
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,6 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check its validator
|
|
||||||
verified, validatorAddress, err := x.verifyMsgSignature(sigHash(header), header.Validator, masterNodes)
|
verified, validatorAddress, err := x.verifyMsgSignature(sigHash(header), header.Validator, masterNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for index, mn := range masterNodes {
|
for index, mn := range masterNodes {
|
||||||
|
|
@ -171,11 +170,11 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !verified {
|
if !verified {
|
||||||
log.Warn("[verifyHeader] Fail to verify the block validator as the validator address not within the masternode list", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex())
|
log.Warn("[verifyHeader] Fail to verify the block validator as the validator address not within the masternode list", "BlockNumber", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex())
|
||||||
return utils.ErrValidatorNotWithinMasternodes
|
return utils.ErrValidatorNotWithinMasternodes
|
||||||
}
|
}
|
||||||
if validatorAddress != header.Coinbase {
|
if validatorAddress != header.Coinbase {
|
||||||
log.Warn("[verifyHeader] Header validator and coinbase address not match", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex(), "coinbase", header.Coinbase.Hex())
|
log.Warn("[verifyHeader] Header validator and coinbase address not match", "BlockNumber", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex(), "coinbase", header.Coinbase.Hex())
|
||||||
return utils.ErrCoinbaseAndValidatorMismatch
|
return utils.ErrCoinbaseAndValidatorMismatch
|
||||||
}
|
}
|
||||||
// Check the proposer is the leader
|
// Check the proposer is the leader
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,14 @@ func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *types.Vote)
|
||||||
go x.ForensicsProcessor.DetectEquivocationInVotePool(voteMsg, x.votePool)
|
go x.ForensicsProcessor.DetectEquivocationInVotePool(voteMsg, x.votePool)
|
||||||
go x.ForensicsProcessor.ProcessVoteEquivocation(chain, x, voteMsg)
|
go x.ForensicsProcessor.ProcessVoteEquivocation(chain, x, voteMsg)
|
||||||
|
|
||||||
|
epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[voteHandler] Error when getting epoch switch Info", "error", err)
|
||||||
|
return fmt.Errorf("Fail on voteHandler due to failure in getting epoch switch info")
|
||||||
|
}
|
||||||
|
|
||||||
certThreshold := x.config.V2.Config(uint64(voteMsg.ProposedBlockInfo.Round)).CertThreshold
|
certThreshold := x.config.V2.Config(uint64(voteMsg.ProposedBlockInfo.Round)).CertThreshold
|
||||||
thresholdReached := numberOfVotesInPool >= certThreshold
|
thresholdReached := float64(numberOfVotesInPool) >= float64(epochInfo.MasternodesLen)*certThreshold
|
||||||
if thresholdReached {
|
if thresholdReached {
|
||||||
log.Info(fmt.Sprintf("[voteHandler] Vote pool threashold reached: %v, number of items in the pool: %v", thresholdReached, numberOfVotesInPool))
|
log.Info(fmt.Sprintf("[voteHandler] Vote pool threashold reached: %v, number of items in the pool: %v", thresholdReached, numberOfVotesInPool))
|
||||||
|
|
||||||
|
|
@ -156,9 +162,15 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[voteHandler] Error when getting epoch switch Info", "error", err)
|
||||||
|
return fmt.Errorf("Fail on voteHandler due to failure in getting epoch switch info")
|
||||||
|
}
|
||||||
|
|
||||||
// Skip and wait for the next vote to process again if valid votes is less than what we required
|
// Skip and wait for the next vote to process again if valid votes is less than what we required
|
||||||
certThreshold := x.config.V2.Config(uint64(currentVoteMsg.(*types.Vote).ProposedBlockInfo.Round)).CertThreshold
|
certThreshold := x.config.V2.Config(uint64(currentVoteMsg.(*types.Vote).ProposedBlockInfo.Round)).CertThreshold
|
||||||
if len(validSignatures) < certThreshold {
|
if float64(len(validSignatures)) < float64(epochInfo.MasternodesLen)*certThreshold {
|
||||||
log.Warn("[onVotePoolThresholdReached] Not enough valid signatures to generate QC", "VotesSignaturesAfterFilter", validSignatures, "NumberOfValidVotes", len(validSignatures), "NumberOfVotes", len(pooledVotes))
|
log.Warn("[onVotePoolThresholdReached] Not enough valid signatures to generate QC", "VotesSignaturesAfterFilter", validSignatures, "NumberOfValidVotes", len(validSignatures), "NumberOfVotes", len(pooledVotes))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +180,7 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
|
||||||
Signatures: validSignatures,
|
Signatures: validSignatures,
|
||||||
GapNumber: currentVoteMsg.(*types.Vote).GapNumber,
|
GapNumber: currentVoteMsg.(*types.Vote).GapNumber,
|
||||||
}
|
}
|
||||||
err := x.processQC(chain, quorumCert)
|
err = x.processQC(chain, quorumCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error while processing QC in the Vote handler after reaching pool threshold, ", err)
|
log.Error("Error while processing QC in the Vote handler after reaching pool threshold, ", err)
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,8 @@ var (
|
||||||
ErrInvalidTCSignatures = errors.New("Invalid TC Signatures")
|
ErrInvalidTCSignatures = errors.New("Invalid TC Signatures")
|
||||||
ErrEmptyBlockInfoHash = errors.New("BlockInfo hash is empty")
|
ErrEmptyBlockInfoHash = errors.New("BlockInfo hash is empty")
|
||||||
ErrInvalidFieldInNonEpochSwitch = errors.New("Invalid field exist in a non-epoch swtich block")
|
ErrInvalidFieldInNonEpochSwitch = errors.New("Invalid field exist in a non-epoch swtich block")
|
||||||
ErrValidatorNotWithinMasternodes = errors.New("Validaotor address is not in the master node list")
|
ErrValidatorNotWithinMasternodes = errors.New("Validator address is not in the master node list")
|
||||||
ErrCoinbaseAndValidatorMismatch = errors.New("Validaotor and coinbase address in header does not match")
|
ErrCoinbaseAndValidatorMismatch = errors.New("Validator and coinbase address in header does not match")
|
||||||
ErrNotItsTurn = errors.New("Not validator's turn to mine this block")
|
ErrNotItsTurn = errors.New("Not validator's turn to mine this block")
|
||||||
|
|
||||||
ErrRoundInvalid = errors.New("Invalid Round, it shall be bigger than QC round")
|
ErrRoundInvalid = errors.New("Invalid Round, it shall be bigger than QC round")
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
|
||||||
|
|
||||||
// Set round to 5
|
// Set round to 5
|
||||||
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
||||||
// Create two vote messages which will not reach vote pool threshold
|
// Create three vote messages which will not reach vote pool threshold
|
||||||
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
voteMsg := &types.Vote{
|
voteMsg := &types.Vote{
|
||||||
|
|
@ -42,9 +42,9 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
|
||||||
Signature: signedHash,
|
Signature: signedHash,
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||||
voteMsg = &types.Vote{
|
voteMsg = &types.Vote{
|
||||||
ProposedBlockInfo: blockInfo,
|
ProposedBlockInfo: blockInfo,
|
||||||
|
|
@ -54,6 +54,15 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
|
||||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes())
|
||||||
|
voteMsg = &types.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: signedHash,
|
||||||
|
GapNumber: 450,
|
||||||
|
}
|
||||||
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// Create another vote which is signed by someone not from the master node list
|
// Create another vote which is signed by someone not from the master node list
|
||||||
randomSigner, randomSignFn, err := backends.SimulateWalletAddressAndSignFn()
|
randomSigner, randomSignFn, err := backends.SimulateWalletAddressAndSignFn()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
|
||||||
|
|
@ -140,15 +140,14 @@ func TestTimeoutPeriodAndThreadholdConfigChange(t *testing.T) {
|
||||||
|
|
||||||
// Timeout handler
|
// Timeout handler
|
||||||
func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
||||||
params.TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig = params.UnitTestV2Configs[0]
|
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, nil)
|
|
||||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||||
|
|
||||||
// Set round to 1
|
// Set round to 1
|
||||||
engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
|
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
||||||
// Create two timeout message which will not reach timeout pool threshold
|
// Create two timeout message which will not reach timeout pool threshold
|
||||||
timeoutMsg := &types.Timeout{
|
timeoutMsg := &types.Timeout{
|
||||||
Round: types.Round(1),
|
Round: types.Round(5),
|
||||||
Signature: []byte{1},
|
Signature: []byte{1},
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
|
|
@ -156,32 +155,39 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
||||||
err := engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
err := engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
currentRound, _, _, _, _, _ := engineV2.GetPropertiesFaker()
|
currentRound, _, _, _, _, _ := engineV2.GetPropertiesFaker()
|
||||||
assert.Equal(t, types.Round(1), currentRound)
|
assert.Equal(t, types.Round(5), currentRound)
|
||||||
timeoutMsg = &types.Timeout{
|
timeoutMsg = &types.Timeout{
|
||||||
Round: types.Round(1),
|
Round: types.Round(5),
|
||||||
Signature: []byte{2},
|
Signature: []byte{2},
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
timeoutMsg = &types.Timeout{
|
||||||
|
Round: types.Round(5),
|
||||||
|
Signature: []byte{3},
|
||||||
|
GapNumber: 450,
|
||||||
|
}
|
||||||
|
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||||
assert.Equal(t, types.Round(1), currentRound)
|
assert.Equal(t, types.Round(5), currentRound)
|
||||||
|
|
||||||
// Send a timeout with different gap number, it shall not trigger timeout pool hook
|
// Send a timeout with different gap number, it shall not trigger timeout pool hook
|
||||||
timeoutMsg = &types.Timeout{
|
timeoutMsg = &types.Timeout{
|
||||||
Round: types.Round(1),
|
Round: types.Round(5),
|
||||||
Signature: []byte{3},
|
Signature: []byte{4},
|
||||||
GapNumber: 1350,
|
GapNumber: 1350,
|
||||||
}
|
}
|
||||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||||
assert.Equal(t, types.Round(1), currentRound)
|
assert.Equal(t, types.Round(5), currentRound)
|
||||||
|
|
||||||
// Create a timeout message that should trigger timeout pool hook
|
// Create a timeout message that should trigger timeout pool hook
|
||||||
timeoutMsg = &types.Timeout{
|
timeoutMsg = &types.Timeout{
|
||||||
Round: types.Round(1),
|
Round: types.Round(5),
|
||||||
Signature: []byte{4},
|
Signature: []byte{5},
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,12 +206,12 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
||||||
|
|
||||||
tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
|
tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
|
||||||
assert.NotNil(t, tc)
|
assert.NotNil(t, tc)
|
||||||
assert.Equal(t, tc.Round, types.Round(1))
|
assert.Equal(t, tc.Round, types.Round(5))
|
||||||
assert.Equal(t, uint64(450), tc.GapNumber)
|
assert.Equal(t, uint64(450), tc.GapNumber)
|
||||||
// The signatures shall not include the byte{3} from a different gap number
|
// The signatures shall not include the byte{3} from a different gap number
|
||||||
sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{4}}
|
sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}, []byte{5}}
|
||||||
assert.ElementsMatch(t, tc.Signatures, sigatures)
|
assert.ElementsMatch(t, tc.Signatures, sigatures)
|
||||||
assert.Equal(t, types.Round(2), currentRound)
|
assert.Equal(t, types.Round(6), currentRound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
|
func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,10 @@ func TestConfigSwitchOnDifferentCertThreshold(t *testing.T) {
|
||||||
acc1SignedHash = SignHashByPK(acc1Key, types.VoteSigHash(voteForSign).Bytes())
|
acc1SignedHash = SignHashByPK(acc1Key, types.VoteSigHash(voteForSign).Bytes())
|
||||||
acc2SignedHash = SignHashByPK(acc2Key, types.VoteSigHash(voteForSign).Bytes())
|
acc2SignedHash = SignHashByPK(acc2Key, types.VoteSigHash(voteForSign).Bytes())
|
||||||
acc3SignedHash = SignHashByPK(acc3Key, types.VoteSigHash(voteForSign).Bytes())
|
acc3SignedHash = SignHashByPK(acc3Key, types.VoteSigHash(voteForSign).Bytes())
|
||||||
|
voteSignedHash := SignHashByPK(voterKey, types.VoteSigHash(voteForSign).Bytes())
|
||||||
|
|
||||||
var signaturesThr []types.Signature
|
var signaturesThr []types.Signature
|
||||||
signaturesThr = append(signaturesThr, acc1SignedHash, acc2SignedHash, acc3SignedHash)
|
signaturesThr = append(signaturesThr, acc1SignedHash, acc2SignedHash, acc3SignedHash, voteSignedHash)
|
||||||
quorumCert = &types.QuorumCert{
|
quorumCert = &types.QuorumCert{
|
||||||
ProposedBlockInfo: proposedBlockInfo,
|
ProposedBlockInfo: proposedBlockInfo,
|
||||||
Signatures: signaturesThr,
|
Signatures: signaturesThr,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
|
||||||
|
|
||||||
// Set round to 1
|
// Set round to 1
|
||||||
engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
|
engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
|
||||||
// Create two vote messages which will not reach vote pool threshold
|
// Create three vote messages which will not reach vote pool threshold
|
||||||
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
voteMsg := &types.Vote{
|
voteMsg := &types.Vote{
|
||||||
|
|
@ -52,8 +52,16 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
|
||||||
assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||||
assert.Equal(t, types.Round(1), currentRound)
|
assert.Equal(t, types.Round(1), currentRound)
|
||||||
|
|
||||||
signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes())
|
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||||
|
voteMsg = &types.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: signedHash,
|
||||||
|
GapNumber: 450,
|
||||||
|
}
|
||||||
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes())
|
||||||
voteMsg = &types.Vote{
|
voteMsg = &types.Vote{
|
||||||
ProposedBlockInfo: blockInfo,
|
ProposedBlockInfo: blockInfo,
|
||||||
Signature: signedHash,
|
Signature: signedHash,
|
||||||
|
|
@ -104,7 +112,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
||||||
|
|
||||||
// Set round to 5
|
// Set round to 5
|
||||||
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
||||||
// Create two vote messages which will not reach vote pool threshold
|
// Create three vote messages which will not reach vote pool threshold
|
||||||
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
voteMsg := &types.Vote{
|
voteMsg := &types.Vote{
|
||||||
|
|
@ -128,6 +136,15 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
||||||
}
|
}
|
||||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes())
|
||||||
|
voteMsg = &types.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: signedHash,
|
||||||
|
GapNumber: 450,
|
||||||
|
}
|
||||||
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
||||||
// Still using the initlised value because we did not yet go to the next round
|
// Still using the initlised value because we did not yet go to the next round
|
||||||
assert.Nil(t, lockQuorumCert)
|
assert.Nil(t, lockQuorumCert)
|
||||||
|
|
@ -213,7 +230,7 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
||||||
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||||
|
|
||||||
// Set round to 5
|
// Set round to 5
|
||||||
|
|
@ -230,15 +247,27 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||||
// Create two vote message which will not reach vote pool threshold
|
|
||||||
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
// Create three vote message which will not reach vote pool threshold
|
||||||
|
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||||
|
assert.Nil(t, err)
|
||||||
voteMsg := &types.Vote{
|
voteMsg := &types.Vote{
|
||||||
ProposedBlockInfo: blockInfo,
|
ProposedBlockInfo: blockInfo,
|
||||||
Signature: signedHash,
|
Signature: signedHash,
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := engineV2.VoteHandler(blockchain, voteMsg)
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||||
|
voteMsg = &types.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: signedHash,
|
||||||
|
GapNumber: 450,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||||
// initialised with nil and 0 round
|
// initialised with nil and 0 round
|
||||||
|
|
@ -302,13 +331,19 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
||||||
}
|
}
|
||||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
timeoutMsg = &types.Timeout{
|
||||||
|
Round: types.Round(6),
|
||||||
|
Signature: []byte{3},
|
||||||
|
}
|
||||||
|
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||||
assert.Equal(t, types.Round(6), currentRound)
|
assert.Equal(t, types.Round(6), currentRound)
|
||||||
|
|
||||||
// Create a timeout message that should trigger timeout pool hook
|
// Create a timeout message that should trigger timeout pool hook
|
||||||
timeoutMsg = &types.Timeout{
|
timeoutMsg = &types.Timeout{
|
||||||
Round: types.Round(6),
|
Round: types.Round(6),
|
||||||
Signature: []byte{3},
|
Signature: []byte{4},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||||
|
|
@ -325,7 +360,7 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
||||||
tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
|
tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
|
||||||
assert.NotNil(t, tc)
|
assert.NotNil(t, tc)
|
||||||
assert.Equal(t, types.Round(6), tc.Round)
|
assert.Equal(t, types.Round(6), tc.Round)
|
||||||
sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}}
|
sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}, []byte{4}}
|
||||||
assert.ElementsMatch(t, tc.Signatures, sigatures)
|
assert.ElementsMatch(t, tc.Signatures, sigatures)
|
||||||
// Round shall be +1 now
|
// Round shall be +1 now
|
||||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||||
|
|
@ -430,7 +465,7 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||||
// Create two vote message which will not reach vote pool threshold
|
// Create three vote message which will not reach vote pool threshold
|
||||||
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||||
voteMsg := &types.Vote{
|
voteMsg := &types.Vote{
|
||||||
ProposedBlockInfo: blockInfo,
|
ProposedBlockInfo: blockInfo,
|
||||||
|
|
@ -453,13 +488,20 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
|
||||||
}
|
}
|
||||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
voteMsg = &types.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
|
||||||
|
GapNumber: 450,
|
||||||
|
}
|
||||||
|
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||||
|
assert.Nil(t, err)
|
||||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||||
assert.Equal(t, types.Round(5), currentRound)
|
assert.Equal(t, types.Round(5), currentRound)
|
||||||
|
|
||||||
// Create a vote message that should trigger vote pool hook
|
// Create a vote message that should trigger vote pool hook
|
||||||
voteMsg = &types.Vote{
|
voteMsg = &types.Vote{
|
||||||
ProposedBlockInfo: blockInfo,
|
ProposedBlockInfo: blockInfo,
|
||||||
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
|
Signature: SignHashByPK(voterKey, voteSigningHash.Bytes()),
|
||||||
GapNumber: 450,
|
GapNumber: 450,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ type EpochSwitchInfo struct {
|
||||||
Penalties []common.Address
|
Penalties []common.Address
|
||||||
Standbynodes []common.Address
|
Standbynodes []common.Address
|
||||||
Masternodes []common.Address
|
Masternodes []common.Address
|
||||||
|
MasternodesLen int
|
||||||
EpochSwitchBlockInfo *BlockInfo
|
EpochSwitchBlockInfo *BlockInfo
|
||||||
EpochSwitchParentBlockInfo *BlockInfo
|
EpochSwitchParentBlockInfo *BlockInfo
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ var (
|
||||||
MainnetV2Configs = map[uint64]*V2Config{
|
MainnetV2Configs = map[uint64]*V2Config{
|
||||||
Default: {
|
Default: {
|
||||||
SwitchRound: 0,
|
SwitchRound: 0,
|
||||||
CertThreshold: 73, // based on masternode is 108
|
CertThreshold: 0.667,
|
||||||
TimeoutSyncThreshold: 3,
|
TimeoutSyncThreshold: 3,
|
||||||
TimeoutPeriod: 60,
|
TimeoutPeriod: 60,
|
||||||
MinePeriod: 2,
|
MinePeriod: 2,
|
||||||
|
|
@ -52,7 +52,7 @@ var (
|
||||||
TestnetV2Configs = map[uint64]*V2Config{
|
TestnetV2Configs = map[uint64]*V2Config{
|
||||||
Default: {
|
Default: {
|
||||||
SwitchRound: 0,
|
SwitchRound: 0,
|
||||||
CertThreshold: 7, //based on masternode is 10
|
CertThreshold: 0.667,
|
||||||
TimeoutSyncThreshold: 3,
|
TimeoutSyncThreshold: 3,
|
||||||
TimeoutPeriod: 60,
|
TimeoutPeriod: 60,
|
||||||
MinePeriod: 2,
|
MinePeriod: 2,
|
||||||
|
|
@ -62,7 +62,7 @@ var (
|
||||||
DevnetV2Configs = map[uint64]*V2Config{
|
DevnetV2Configs = map[uint64]*V2Config{
|
||||||
Default: {
|
Default: {
|
||||||
SwitchRound: 0,
|
SwitchRound: 0,
|
||||||
CertThreshold: 73, // based on masternode is 108
|
CertThreshold: 0.667,
|
||||||
TimeoutSyncThreshold: 5,
|
TimeoutSyncThreshold: 5,
|
||||||
TimeoutPeriod: 10,
|
TimeoutPeriod: 10,
|
||||||
MinePeriod: 2,
|
MinePeriod: 2,
|
||||||
|
|
@ -72,21 +72,21 @@ var (
|
||||||
UnitTestV2Configs = map[uint64]*V2Config{
|
UnitTestV2Configs = map[uint64]*V2Config{
|
||||||
Default: {
|
Default: {
|
||||||
SwitchRound: 0,
|
SwitchRound: 0,
|
||||||
CertThreshold: 3,
|
CertThreshold: 0.667,
|
||||||
TimeoutSyncThreshold: 2,
|
TimeoutSyncThreshold: 2,
|
||||||
TimeoutPeriod: 4,
|
TimeoutPeriod: 4,
|
||||||
MinePeriod: 2,
|
MinePeriod: 2,
|
||||||
},
|
},
|
||||||
10: {
|
10: {
|
||||||
SwitchRound: 10,
|
SwitchRound: 10,
|
||||||
CertThreshold: 5,
|
CertThreshold: 1,
|
||||||
TimeoutSyncThreshold: 2,
|
TimeoutSyncThreshold: 2,
|
||||||
TimeoutPeriod: 4,
|
TimeoutPeriod: 4,
|
||||||
MinePeriod: 3,
|
MinePeriod: 3,
|
||||||
},
|
},
|
||||||
899: {
|
899: {
|
||||||
SwitchRound: 899,
|
SwitchRound: 899,
|
||||||
CertThreshold: 5,
|
CertThreshold: 1,
|
||||||
TimeoutSyncThreshold: 4,
|
TimeoutSyncThreshold: 4,
|
||||||
TimeoutPeriod: 5,
|
TimeoutPeriod: 5,
|
||||||
MinePeriod: 2,
|
MinePeriod: 2,
|
||||||
|
|
@ -329,7 +329,7 @@ type V2Config struct {
|
||||||
MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block
|
MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block
|
||||||
TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout
|
TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout
|
||||||
TimeoutPeriod int `json:"timeoutPeriod"` // Duration in ms
|
TimeoutPeriod int `json:"timeoutPeriod"` // Duration in ms
|
||||||
CertThreshold int `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate
|
CertThreshold float64 `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoSConfig) String() string {
|
func (c *XDPoSConfig) String() string {
|
||||||
|
|
|
||||||
|
|
@ -85,11 +85,11 @@ func TestCheckCompatible(t *testing.T) {
|
||||||
func TestUpdateV2Config(t *testing.T) {
|
func TestUpdateV2Config(t *testing.T) {
|
||||||
TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex()
|
TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex()
|
||||||
c := TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
|
c := TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
|
||||||
assert.Equal(t, 3, c.CertThreshold)
|
assert.Equal(t, 0.667, c.CertThreshold)
|
||||||
|
|
||||||
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(10)
|
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(10)
|
||||||
c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
|
c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
|
||||||
assert.Equal(t, 5, c.CertThreshold)
|
assert.Equal(t, float64(1), c.CertThreshold)
|
||||||
|
|
||||||
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(899)
|
TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(899)
|
||||||
c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
|
c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig
|
||||||
|
|
@ -99,16 +99,16 @@ func TestUpdateV2Config(t *testing.T) {
|
||||||
func TestV2Config(t *testing.T) {
|
func TestV2Config(t *testing.T) {
|
||||||
TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex()
|
TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex()
|
||||||
c := TestXDPoSMockChainConfig.XDPoS.V2.Config(1)
|
c := TestXDPoSMockChainConfig.XDPoS.V2.Config(1)
|
||||||
assert.Equal(t, 3, c.CertThreshold)
|
assert.Equal(t, 0.667, c.CertThreshold)
|
||||||
|
|
||||||
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(5)
|
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(5)
|
||||||
assert.Equal(t, 3, c.CertThreshold)
|
assert.Equal(t, 0.667, c.CertThreshold)
|
||||||
|
|
||||||
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(10)
|
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(10)
|
||||||
assert.Equal(t, 3, c.CertThreshold)
|
assert.Equal(t, 0.667, c.CertThreshold)
|
||||||
|
|
||||||
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(11)
|
c = TestXDPoSMockChainConfig.XDPoS.V2.Config(11)
|
||||||
assert.Equal(t, 5, c.CertThreshold)
|
assert.Equal(t, float64(1), c.CertThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildConfigIndex(t *testing.T) {
|
func TestBuildConfigIndex(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue