mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
xin-153 Broadcast syncInfo when consecutive timeouts of same round (#65)
* Broadcast syncInfo when consecutive timeouts of same round * add test * revert test period
This commit is contained in:
parent
e493ddfd6d
commit
d975ba4014
3 changed files with 74 additions and 22 deletions
|
|
@ -45,6 +45,7 @@ type XDPoS_v2 struct {
|
|||
waitPeriodCh chan int
|
||||
|
||||
timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached
|
||||
timeoutCount int // number of timeout being sent
|
||||
|
||||
timeoutPool *utils.Pool
|
||||
votePool *utils.Pool
|
||||
|
|
@ -62,7 +63,7 @@ type XDPoS_v2 struct {
|
|||
|
||||
func New(config *params.XDPoSConfig, db ethdb.Database, waitPeriodCh chan int) *XDPoS_v2 {
|
||||
// Setup Timer
|
||||
duration := time.Duration(config.V2.TimeoutWorkerDuration) * time.Second
|
||||
duration := time.Duration(config.V2.TimeoutPeriod) * time.Second
|
||||
timer := countdown.NewCountDown(duration)
|
||||
timeoutPool := utils.NewPool(config.V2.CertThreshold)
|
||||
|
||||
|
|
@ -162,7 +163,7 @@ func (x *XDPoS_v2) Initial(chain consensus.ChainReader, masternodes []common.Add
|
|||
}
|
||||
|
||||
// Initial timeout
|
||||
log.Info("[Initial] miner wait period", "period", x.config.WaitPeriod)
|
||||
log.Info("[Initial] miner wait period", "period", x.config.V2.WaitPeriod)
|
||||
// avoid deadlock
|
||||
go func() {
|
||||
x.waitPeriodCh <- x.config.V2.WaitPeriod
|
||||
|
|
@ -1184,6 +1185,7 @@ func (x *XDPoS_v2) processTC(blockChainReader consensus.ChainReader, timeoutCert
|
|||
*/
|
||||
func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round utils.Round) error {
|
||||
x.currentRound = round
|
||||
x.timeoutCount = 0
|
||||
//TODO: tell miner now it's a new round and start mine if it's leader
|
||||
x.timeoutWorker.Reset(blockChainReader)
|
||||
//TODO: vote pools
|
||||
|
|
@ -1352,6 +1354,14 @@ func (x *XDPoS_v2) OnCountdownTimeout(time time.Time, chain interface{}) error {
|
|||
log.Error("Error while sending out timeout message at time: ", time)
|
||||
return err
|
||||
}
|
||||
|
||||
x.timeoutCount++
|
||||
if x.timeoutCount%x.config.V2.TimeoutSyncThreshold == 0 {
|
||||
log.Info("[OnCountdownTimeout] timeout sync threadhold reached, send syncInfo message")
|
||||
syncInfo := x.getSyncInfo()
|
||||
x.broadcastToBftChannel(syncInfo)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -19,9 +21,47 @@ func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) {
|
|||
assert.Equal(t, poolSize, 1)
|
||||
assert.NotNil(t, timeoutMsg)
|
||||
assert.Equal(t, uint64(1350), timeoutMsg.(*utils.Timeout).GapNumber)
|
||||
fmt.Println(timeoutMsg.(*utils.Timeout).GapNumber)
|
||||
assert.Equal(t, utils.Round(1), timeoutMsg.(*utils.Timeout).Round)
|
||||
}
|
||||
|
||||
func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
|
||||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 2251, params.TestXDPoSMockChainConfig, 0)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// Because messages are sending async and on random order, so use this way to test
|
||||
var timeoutCounter, syncInfoCounter int
|
||||
for i := 0; i < 3; i++ {
|
||||
obj := <-engineV2.BroadcastCh
|
||||
switch v := obj.(type) {
|
||||
case *utils.Timeout:
|
||||
timeoutCounter++
|
||||
case *utils.SyncInfo:
|
||||
syncInfoCounter++
|
||||
default:
|
||||
log.Error("Unknown message type received", "value", v)
|
||||
}
|
||||
}
|
||||
assert.Equal(t, 2, timeoutCounter)
|
||||
assert.Equal(t, 1, syncInfoCounter)
|
||||
|
||||
t.Log("waiting for another consecutive period")
|
||||
// another consecutive period
|
||||
for i := 0; i < 3; i++ {
|
||||
obj := <-engineV2.BroadcastCh
|
||||
switch v := obj.(type) {
|
||||
case *utils.Timeout:
|
||||
timeoutCounter++
|
||||
case *utils.SyncInfo:
|
||||
syncInfoCounter++
|
||||
default:
|
||||
log.Error("Unknown message type received", "value", v)
|
||||
}
|
||||
}
|
||||
assert.Equal(t, 4, timeoutCounter)
|
||||
assert.Equal(t, 2, syncInfoCounter)
|
||||
}
|
||||
|
||||
// Timeout handler
|
||||
func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
||||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, 0)
|
||||
|
|
|
|||
|
|
@ -36,23 +36,25 @@ var (
|
|||
|
||||
var (
|
||||
XDPoSV2Config = &V2{
|
||||
TimeoutWorkerDuration: 50,
|
||||
CertThreshold: common.MaxMasternodesV2*2/3 + 1,
|
||||
TimeoutPeriod: 50,
|
||||
CertThreshold: common.MaxMasternodesV2*2/3 + 1,
|
||||
}
|
||||
TestXDPoSV2Config = &V2{
|
||||
TimeoutWorkerDuration: 10,
|
||||
CertThreshold: 3,
|
||||
WaitPeriod: 1,
|
||||
MinePeriod: 2,
|
||||
SwitchBlock: big.NewInt(900),
|
||||
SkipV2Validation: true,
|
||||
SwitchBlock: big.NewInt(900),
|
||||
CertThreshold: 3,
|
||||
TimeoutSyncThreshold: 2,
|
||||
TimeoutPeriod: 10,
|
||||
WaitPeriod: 1,
|
||||
MinePeriod: 2,
|
||||
SkipV2Validation: true,
|
||||
}
|
||||
DevnetXDPoSV2Config = &V2{
|
||||
SwitchBlock: big.NewInt(7218000),
|
||||
TimeoutWorkerDuration: 50,
|
||||
CertThreshold: 6,
|
||||
WaitPeriod: 2,
|
||||
MinePeriod: 10,
|
||||
SwitchBlock: big.NewInt(7218000),
|
||||
CertThreshold: 6,
|
||||
TimeoutSyncThreshold: 5,
|
||||
TimeoutPeriod: 50,
|
||||
WaitPeriod: 2,
|
||||
MinePeriod: 10,
|
||||
}
|
||||
|
||||
// XDPoSChain mainnet config
|
||||
|
|
@ -202,18 +204,18 @@ type XDPoSConfig struct {
|
|||
RewardCheckpoint uint64 `json:"rewardCheckpoint"` // Checkpoint block for calculate rewards.
|
||||
Gap uint64 `json:"gap"` // Gap time preparing for the next epoch
|
||||
FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet
|
||||
WaitPeriod int `json:"waitPeriod"` // Miner wait period
|
||||
SkipV1Validation bool //Skip Block Validation for testing purpose, V1 consensus only
|
||||
V2 *V2 `json:"v2"`
|
||||
}
|
||||
|
||||
type V2 struct {
|
||||
WaitPeriod int `json:"waitPeriod"` // Miner wait period to check mine event
|
||||
MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block
|
||||
SwitchBlock *big.Int `json:"switchBlock"` // v1 to v2 switch block number
|
||||
TimeoutWorkerDuration int64 `json:"timeoutWorkerDuration"` // Duration in ms
|
||||
CertThreshold int `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate
|
||||
SkipV2Validation bool //Skip Block Validation for testing purpose, V2 consensus only
|
||||
WaitPeriod int `json:"waitPeriod"` // Miner wait period to check mine event
|
||||
MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block
|
||||
SwitchBlock *big.Int `json:"switchBlock"` // v1 to v2 switch block number
|
||||
TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout
|
||||
TimeoutPeriod int `json:"timeoutPeriod"` // Duration in ms
|
||||
CertThreshold int `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate
|
||||
SkipV2Validation bool //Skip Block Validation for testing purpose, V2 consensus only
|
||||
}
|
||||
|
||||
// String implements the stringer interface, returning the consensus engine details.
|
||||
|
|
|
|||
Loading…
Reference in a new issue