mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-16 18:00:46 +00:00
resolve sync issue by passing right round number (#384)
This commit is contained in:
parent
e30d909643
commit
c7a42fd7c9
7 changed files with 54 additions and 9 deletions
|
|
@ -336,7 +336,7 @@ func (x *XDPoS_v2) Prepare(chain consensus.ChainReader, header *types.Header) er
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if isEpochSwitchBlock {
|
if isEpochSwitchBlock {
|
||||||
masterNodes, penalties, err := x.calcMasternodes(chain, header.Number, header.ParentHash)
|
masterNodes, penalties, err := x.calcMasternodes(chain, header.Number, header.ParentHash, currentRound)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -997,9 +997,9 @@ 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.
|
// 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) {
|
func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.Int, parentHash common.Hash, round types.Round) ([]common.Address, []common.Address, error) {
|
||||||
// using new max masterndoes
|
// using new max masterndoes
|
||||||
maxMasternodes := x.config.V2.Config(uint64(x.currentRound)).MaxMasternodes
|
maxMasternodes := x.config.V2.Config(uint64(round)).MaxMasternodes
|
||||||
snap, err := x.getSnapshot(chain, blockNum.Uint64(), false)
|
snap, err := x.getSnapshot(chain, blockNum.Uint64(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[calcMasternodes] Adaptor v2 getSnapshot has error", "err", err)
|
log.Error("[calcMasternodes] Adaptor v2 getSnapshot has error", "err", err)
|
||||||
|
|
@ -1081,7 +1081,7 @@ func (x *XDPoS_v2) allowedToSend(chain consensus.ChainReader, blockHeader *types
|
||||||
for _, mn := range masterNodes {
|
for _, mn := range masterNodes {
|
||||||
log.Debug("[allowedToSend] Master node list", "masterNodeAddress", mn.Hash())
|
log.Debug("[allowedToSend] Master node list", "masterNodeAddress", mn.Hash())
|
||||||
}
|
}
|
||||||
log.Info("[allowedToSend] Not in the Masternode list, not suppose to send message", "sendType", sendType, "MyAddress", signer.Hex())
|
log.Debug("[allowedToSend] Not in the Masternode list, not suppose to send message", "sendType", sendType, "MyAddress", signer.Hex())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, pare
|
||||||
}
|
}
|
||||||
var masterNodes []common.Address
|
var masterNodes []common.Address
|
||||||
if isEpochSwitch {
|
if isEpochSwitch {
|
||||||
masterNodes, _, err = x.calcMasternodes(chain, big.NewInt(0).Add(parent.Number, big.NewInt(1)), parent.Hash())
|
masterNodes, _, err = x.calcMasternodes(chain, big.NewInt(0).Add(parent.Number, big.NewInt(1)), parent.Hash(), round)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[yourturn] Cannot calcMasternodes at gap num ", "err", err, "parent number", parent.Number)
|
log.Error("[yourturn] Cannot calcMasternodes at gap num ", "err", err, "parent number", parent.Number)
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
return utils.ErrInvalidCheckpointSigners
|
return utils.ErrInvalidCheckpointSigners
|
||||||
}
|
}
|
||||||
|
|
||||||
localMasterNodes, localPenalties, err := x.calcMasternodes(chain, header.Number, header.ParentHash)
|
localMasterNodes, localPenalties, err := x.calcMasternodes(chain, header.Number, header.ParentHash, round)
|
||||||
masterNodes = localMasterNodes
|
masterNodes = localMasterNodes
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[verifyHeader] Fail to calculate master nodes list with penalty", "Number", header.Number, "Hash", header.Hash())
|
log.Error("[verifyHeader] Fail to calculate master nodes list with penalty", "Number", header.Number, "Hash", header.Hash())
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,50 @@ func TestConfigSwitchOnDifferentCertThreshold(t *testing.T) {
|
||||||
assert.Equal(t, utils.ErrValidatorNotWithinMasternodes, err)
|
assert.Equal(t, utils.ErrValidatorNotWithinMasternodes, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Insert 20 masternode before gap block
|
||||||
|
2. Prepare 20 masternode block header with round 9000
|
||||||
|
3. verify this header while node is on round 899,
|
||||||
|
This is to simulate node is syncing from remote during config switch
|
||||||
|
*/
|
||||||
|
func TestConfigSwitchOnDifferentMasternodeCount(t *testing.T) {
|
||||||
|
b, err := json.Marshal(params.TestXDPoSMockChainConfig)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
configString := string(b)
|
||||||
|
|
||||||
|
var config params.ChainConfig
|
||||||
|
err = json.Unmarshal([]byte(configString), &config)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
// Enable verify
|
||||||
|
config.XDPoS.V2.SkipV2Validation = false
|
||||||
|
// Block 901 is the first v2 block with round of 1
|
||||||
|
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*2, &config, nil)
|
||||||
|
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||||
|
x := adaptor.EngineV2
|
||||||
|
|
||||||
|
// Generate round 900 header, num 1800
|
||||||
|
header1800 := blockchain.GetBlockByNumber(1800).Header()
|
||||||
|
|
||||||
|
snap, err := x.GetSnapshot(blockchain, currentBlock.Header())
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, len(snap.NextEpochMasterNodes), 20)
|
||||||
|
header1800.Validators = []byte{}
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
header1800.Validators = append(header1800.Validators, snap.NextEpochMasterNodes[i].Bytes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
round, err := x.GetRoundNumber(header1800)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, round, types.Round(900))
|
||||||
|
|
||||||
|
adaptor.EngineV2.SetNewRoundFaker(blockchain, 899, false)
|
||||||
|
|
||||||
|
err = adaptor.VerifyHeader(blockchain, header1800, true)
|
||||||
|
|
||||||
|
// error ErrValidatorNotWithinMasternodes means verifyQC is passed and move to next verification process
|
||||||
|
assert.Equal(t, utils.ErrValidatorNotWithinMasternodes, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigSwitchOnDifferentMindPeriod(t *testing.T) {
|
func TestConfigSwitchOnDifferentMindPeriod(t *testing.T) {
|
||||||
b, err := json.Marshal(params.TestXDPoSMockChainConfig)
|
b, err := json.Marshal(params.TestXDPoSMockChainConfig)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,7 @@ func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common
|
||||||
// If we're the first to request this task, initialise the result container
|
// If we're the first to request this task, initialise the result container
|
||||||
index := int(header.Number.Int64() - int64(q.resultOffset))
|
index := int(header.Number.Int64() - int64(q.resultOffset))
|
||||||
if index >= len(q.resultCache) || index < 0 {
|
if index >= len(q.resultCache) || index < 0 {
|
||||||
|
log.Error("index allocation went beyond available resultCache space", "index", index, "len.resultCache", len(q.resultCache), "blockNum", header.Number.Int64(), "resultOffset", q.resultOffset)
|
||||||
common.Report("index allocation went beyond available resultCache space")
|
common.Report("index allocation went beyond available resultCache space")
|
||||||
return nil, false, errInvalidChain
|
return nil, false, errInvalidChain
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,9 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Info("[V2 Hook Penalty] parentHeader is nil, wait block to be writen in disk", "parentNumber", parentNumber)
|
log.Info("[V2 Hook Penalty] parentHeader is nil, wait block to be writen in disk", "parentNumber", parentNumber)
|
||||||
time.Sleep(200 * time.Millisecond) // 0.2s
|
time.Sleep(time.Second) // 1s
|
||||||
|
|
||||||
if timeout > 50 { // wait over 10s
|
if timeout > 30 { // wait over 30s
|
||||||
log.Error("[V2 Hook Penalty] parentHeader is nil, wait too long not writen in to disk", "parentNumber", parentNumber)
|
log.Error("[V2 Hook Penalty] parentHeader is nil, wait too long not writen in to disk", "parentNumber", parentNumber)
|
||||||
return []common.Address{}, fmt.Errorf("parentHeader is nil")
|
return []common.Address{}, fmt.Errorf("parentHeader is nil")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 2 // Major version component of the current release
|
VersionMajor = 2 // Major version component of the current release
|
||||||
VersionMinor = 0 // Minor version component of the current release
|
VersionMinor = 0 // Minor version component of the current release
|
||||||
VersionPatch = 0 // Patch version component of the current release
|
VersionPatch = 1 // Patch version component of the current release
|
||||||
VersionMeta = "beta1" // Version metadata to append to the version string
|
VersionMeta = "beta1" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue