Xin-124 Deal with Block Time mine time (#55)

* add wait v2 period in miner

* add perido initial

* add mine and wait time

* update todo

* merge all xdc test config into 1
This commit is contained in:
Liam 2022-02-13 03:40:47 +03:00 committed by GitHub
parent 4424c7d01e
commit 5a3acd173d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 187 additions and 130 deletions

View file

@ -53,6 +53,9 @@ type XDPoS struct {
// Transaction cache, only make sense for adaptor level // Transaction cache, only make sense for adaptor level
signingTxsCache *lru.Cache signingTxsCache *lru.Cache
// Share Channel
WaitPeriodCh chan int // Miner wait Period Channel
// Trading and lending service // Trading and lending service
GetXDCXService func() utils.TradingService GetXDCXService func() utils.TradingService
GetLendingService func() utils.LendingService GetLendingService func() utils.LendingService
@ -71,6 +74,7 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS {
config.Epoch = utils.EpochLength config.Epoch = utils.EpochLength
} }
waitPeriodCh := make(chan int)
// TODO: This shall be configurable or replaced // TODO: This shall be configurable or replaced
config.V2 = params.DevnetXDPoSV2Config config.V2 = params.DevnetXDPoSV2Config
@ -81,9 +85,11 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS {
config: config, config: config,
db: db, db: db,
WaitPeriodCh: waitPeriodCh,
signingTxsCache: signingTxsCache, signingTxsCache: signingTxsCache,
EngineV1: engine_v1.New(config, db), EngineV1: engine_v1.New(config, db),
EngineV2: engine_v2.New(config, db), EngineV2: engine_v2.New(config, db, waitPeriodCh),
} }
} }
@ -97,18 +103,23 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS {
conf = chainConfig.XDPoS conf = chainConfig.XDPoS
} }
waitPeriodCh := make(chan int)
// Allocate the snapshot caches and create the engine // Allocate the snapshot caches and create the engine
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
fakeEngine = &XDPoS{ fakeEngine = &XDPoS{
config: conf, config: conf,
db: db, db: db,
WaitPeriodCh: waitPeriodCh,
GetXDCXService: func() utils.TradingService { return nil }, GetXDCXService: func() utils.TradingService { return nil },
GetLendingService: func() utils.LendingService { return nil }, GetLendingService: func() utils.LendingService { return nil },
signingTxsCache: signingTxsCache, signingTxsCache: signingTxsCache,
EngineV1: engine_v1.NewFaker(db, conf), EngineV1: engine_v1.NewFaker(db, conf),
EngineV2: engine_v2.New(conf, db), EngineV2: engine_v2.New(conf, db, waitPeriodCh),
} }
return fakeEngine return fakeEngine
} }
@ -305,8 +316,10 @@ func (x *XDPoS) GetMasternodesByNumber(chain consensus.ChainReader, blockNumber
func (x *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (bool, error) { func (x *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (bool, error) {
if x.config.V2.SwitchBlock != nil && parent.Number.Cmp(x.config.V2.SwitchBlock) == 0 { if x.config.V2.SwitchBlock != nil && parent.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
err := x.initialV2(chain, parent) err := x.initialV2(chain, parent)
log.Error("[YourTurn] Error when initialise v2", "Error", err, "ParentBlock", parent) if err != nil {
return false, err log.Error("[YourTurn] Error when initialise v2", "Error", err, "ParentBlock", parent)
return false, err
}
} }
switch x.config.BlockConsensusVersion(big.NewInt(parent.Number.Int64() + 1)) { switch x.config.BlockConsensusVersion(big.NewInt(parent.Number.Int64() + 1)) {
case params.ConsensusEngineVersion2: case params.ConsensusEngineVersion2:

View file

@ -38,7 +38,9 @@ type XDPoS_v2 struct {
lock sync.RWMutex // Protects the signer fields lock sync.RWMutex // Protects the signer fields
signLock sync.RWMutex // Protects the signer fields signLock sync.RWMutex // Protects the signer fields
BroadcastCh chan interface{} BroadcastCh chan interface{}
waitPeriodCh chan int
timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached
timeoutPool *utils.Pool timeoutPool *utils.Pool
@ -54,7 +56,7 @@ type XDPoS_v2 struct {
HookReward func(chain consensus.ChainReader, state *state.StateDB, parentState *state.StateDB, header *types.Header) (error, map[string]interface{}) HookReward func(chain consensus.ChainReader, state *state.StateDB, parentState *state.StateDB, header *types.Header) (error, map[string]interface{})
} }
func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS_v2 { func New(config *params.XDPoSConfig, db ethdb.Database, waitPeriodCh chan int) *XDPoS_v2 {
// Setup Timer // Setup Timer
duration := time.Duration(config.V2.TimeoutWorkerDuration) * time.Second duration := time.Duration(config.V2.TimeoutWorkerDuration) * time.Second
timer := countdown.NewCountDown(duration) timer := countdown.NewCountDown(duration)
@ -74,8 +76,10 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS_v2 {
epochSwitches: epochSwitches, epochSwitches: epochSwitches,
timeoutWorker: timer, timeoutWorker: timer,
BroadcastCh: make(chan interface{}), BroadcastCh: make(chan interface{}),
timeoutPool: timeoutPool, waitPeriodCh: waitPeriodCh,
votePool: votePool,
timeoutPool: timeoutPool,
votePool: votePool,
highestTimeoutCert: &utils.TimeoutCert{ highestTimeoutCert: &utils.TimeoutCert{
Round: utils.Round(0), Round: utils.Round(0),
@ -144,6 +148,16 @@ func (x *XDPoS_v2) Initial(chain consensus.ChainReader, header *types.Header, ma
snap := newSnapshot(lastGapNum, lastGapHeader.Hash(), x.currentRound, x.highestQuorumCert, masternodes) snap := newSnapshot(lastGapNum, lastGapHeader.Hash(), x.currentRound, x.highestQuorumCert, masternodes)
x.snapshots.Add(snap.Hash, snap) x.snapshots.Add(snap.Hash, snap)
storeSnapshot(snap, x.db) storeSnapshot(snap, x.db)
// Initial timeout
log.Info("[Initial] miner wait period", "period", x.config.WaitPeriod)
// avoid deadlock
go func() {
x.waitPeriodCh <- x.config.V2.WaitPeriod
}()
log.Info("[Initial] finish initialisation")
return nil return nil
} }
@ -332,6 +346,12 @@ func (x *XDPoS_v2) YourTurn(chain consensus.ChainReader, parent *types.Header, s
x.lock.RLock() x.lock.RLock()
defer x.lock.RUnlock() defer x.lock.RUnlock()
waitedTime := time.Now().Unix() - parent.Time.Int64()
if waitedTime < int64(x.config.V2.MinePeriod) {
log.Trace("[YourTurn] wait after mine period", "minePeriod", x.config.V2.MinePeriod, "waitedTime", waitedTime)
return false, nil
}
round := x.currentRound round := x.currentRound
isEpochSwitch, _, err := x.IsEpochSwitchAtRound(round, parent) isEpochSwitch, _, err := x.IsEpochSwitchAtRound(round, parent)
if err != nil { if err != nil {

View file

@ -15,7 +15,7 @@ import (
) )
func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) { func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
blockchain, backend, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 10, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, backend, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
addressFromAdaptor, errorAdaptor := adaptor.Author(currentBlock.Header()) addressFromAdaptor, errorAdaptor := adaptor.Author(currentBlock.Header())
@ -30,13 +30,13 @@ func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
assert.Equal(t, addressFromAdaptor, addressFromV1Engine) assert.Equal(t, addressFromAdaptor, addressFromV1Engine)
// Insert one more block to make it above 10, which means now we are on v2 of consensus engine // Insert one more block to make it above 10, which means now we are on v2 of consensus engine
// Insert block 11 // Insert block 901
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", 11) blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", 901)
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930" merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
header := &types.Header{ header := &types.Header{
Root: common.HexToHash(merkleRoot), Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(11)), Number: big.NewInt(int64(901)),
ParentHash: currentBlock.Hash(), ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase), Coinbase: common.HexToAddress(blockCoinBase),
} }
@ -44,17 +44,17 @@ func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
block11, err := createBlockFromHeader(blockchain, header, nil) block901, err := createBlockFromHeader(blockchain, header, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
blockchain.InsertBlock(block11) blockchain.InsertBlock(block901)
addressFromAdaptor, errorAdaptor = adaptor.Author(block11.Header()) addressFromAdaptor, errorAdaptor = adaptor.Author(block901.Header())
if errorAdaptor != nil { if errorAdaptor != nil {
t.Fatalf("Failed while trying to get Author from adaptor") t.Fatalf("Failed while trying to get Author from adaptor")
} }
addressFromV2Engine, errV2 := adaptor.EngineV2.Author(block11.Header()) addressFromV2Engine, errV2 := adaptor.EngineV2.Author(block901.Header())
if errV2 != nil { if errV2 != nil {
t.Fatalf("Failed while trying to get Author from engine v2") t.Fatalf("Failed while trying to get Author from engine v2")
} }
@ -63,7 +63,7 @@ func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
} }
func TestAdaptorGetMasternodesFromCheckpointHeader(t *testing.T) { func TestAdaptorGetMasternodesFromCheckpointHeader(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
headerV1 := currentBlock.Header() headerV1 := currentBlock.Header()
headerV1.Extra = common.Hex2Bytes("d7830100018358444388676f312e31352e38856c696e757800000000000000000278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758ccef312ee5eea8d7bad5374c6a652150515d744508b61c1a4deb4e4e7bf057e4e3824c11fd2569bcb77a52905cda63b5a58507910bed335e4c9d87ae0ecdfafd400") headerV1.Extra = common.Hex2Bytes("d7830100018358444388676f312e31352e38856c696e757800000000000000000278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758ccef312ee5eea8d7bad5374c6a652150515d744508b61c1a4deb4e4e7bf057e4e3824c11fd2569bcb77a52905cda63b5a58507910bed335e4c9d87ae0ecdfafd400")
@ -75,7 +75,7 @@ func TestAdaptorGetMasternodesFromCheckpointHeader(t *testing.T) {
assert.True(t, reflect.DeepEqual(masternodesV1, masternodesV2), "GetMasternodesFromCheckpointHeader in adaptor for v1 v2 not equal", "v1", masternodesV1, "v2", masternodesV2) assert.True(t, reflect.DeepEqual(masternodesV1, masternodesV2), "GetMasternodesFromCheckpointHeader in adaptor for v1 v2 not equal", "v1", masternodesV1, "v2", masternodesV2)
} }
func TestAdaptorIsEpochSwitch(t *testing.T) { func TestAdaptorIsEpochSwitch(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
header := currentBlock.Header() header := currentBlock.Header()
// v1 // v1
@ -174,20 +174,20 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
func TestAdaptorGetMasternodesV2(t *testing.T) { func TestAdaptorGetMasternodesV2(t *testing.T) {
// we skip test for v1 since it's hard to make a real genesis block // we skip test for v1 since it's hard to make a real genesis block
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 10, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 11 blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123" blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
// block 11 is the first v2 block, and is treated as epoch switch block // block 901 is the first v2 block, and is treated as epoch switch block
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
masternodes1 := adaptor.GetMasternodes(blockchain, currentBlock.Header()) masternodes1 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
assert.Equal(t, 4, len(masternodes1)) assert.Equal(t, 4, len(masternodes1))
masternodes1ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64()) masternodes1ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64())
assert.True(t, reflect.DeepEqual(masternodes1, masternodes1ByNumber), "at block number", blockNum) assert.True(t, reflect.DeepEqual(masternodes1, masternodes1ByNumber), "at block number", blockNum)
for blockNum = 12; blockNum < 15; blockNum++ { for blockNum = 902; blockNum < 915; blockNum++ {
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
masternodes2 := adaptor.GetMasternodes(blockchain, currentBlock.Header()) masternodes2 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
assert.True(t, reflect.DeepEqual(masternodes1, masternodes2), "at block number", blockNum) assert.True(t, reflect.DeepEqual(masternodes1, masternodes2), "at block number", blockNum)
@ -197,32 +197,32 @@ func TestAdaptorGetMasternodesV2(t *testing.T) {
} }
func TestGetCurrentEpochSwitchBlock(t *testing.T) { func TestGetCurrentEpochSwitchBlock(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 10, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// V1 // V1
currentCheckpointNumber, epochNum, err := adaptor.GetCurrentEpochSwitchBlock(blockchain, big.NewInt(9)) currentCheckpointNumber, epochNum, err := adaptor.GetCurrentEpochSwitchBlock(blockchain, big.NewInt(900))
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint64(0), currentCheckpointNumber) assert.Equal(t, uint64(900), currentCheckpointNumber)
assert.Equal(t, uint64(0), epochNum) assert.Equal(t, uint64(1), epochNum)
// V2 // V2
blockNum := 11 blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123" blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number()) currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint64(11), currentCheckpointNumber) assert.Equal(t, uint64(901), currentCheckpointNumber)
assert.Equal(t, uint64(0), epochNum) assert.Equal(t, uint64(1), epochNum)
for blockNum = 12; blockNum < 15; blockNum++ { for blockNum = 902; blockNum < 915; blockNum++ {
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
currentCheckpointNumber, epochNum, err := adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number()) currentCheckpointNumber, epochNum, err := adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint64(11), currentCheckpointNumber) assert.Equal(t, uint64(901), currentCheckpointNumber)
assert.Equal(t, uint64(0), epochNum) assert.Equal(t, uint64(1), epochNum)
} }
} }

View file

@ -3,6 +3,7 @@ package tests
import ( import (
"math/big" "math/big"
"testing" "testing"
"time"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
@ -73,11 +74,11 @@ func TestIsAuthorisedMNForConsensusV1(t *testing.T) {
func TestIsAuthorisedMNForConsensusV2(t *testing.T) { func TestIsAuthorisedMNForConsensusV2(t *testing.T) {
// we skip test for v1 since it's hard to make a real genesis block // we skip test for v1 since it's hard to make a real genesis block
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 10, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 11 blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123" blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
// As long as the address is in the master node list, they are all valid // As long as the address is in the master node list, they are all valid
@ -93,17 +94,23 @@ func TestIsAuthorisedMNForConsensusV2(t *testing.T) {
func TestIsYourTurnConsensusV2(t *testing.T) { func TestIsYourTurnConsensusV2(t *testing.T) {
// we skip test for v1 since it's hard to make a real genesis block // we skip test for v1 since it's hard to make a real genesis block
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 10, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
minePeriod := params.TestXDPoSV2Config.MinePeriod
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 11 blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123" blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
// The first address is valid // Less then Mine Period
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7")) isYourTurn, err := adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))
assert.Nil(t, err) assert.Nil(t, err)
assert.False(t, isYourTurn)
time.Sleep(time.Duration(minePeriod) * time.Second)
// The first address is valid
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))
assert.Nil(t, err)
assert.True(t, isYourTurn) assert.True(t, isYourTurn)
// The second and third address are not valid // The second and third address are not valid
@ -115,9 +122,10 @@ func TestIsYourTurnConsensusV2(t *testing.T) {
assert.False(t, isYourTurn) assert.False(t, isYourTurn)
// We continue to grow the chain which will increase the round number // We continue to grow the chain which will increase the round number
blockNum = 12 blockNum = 902
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn) currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock) blockchain.InsertBlock(currentBlock)
time.Sleep(time.Duration(minePeriod) * time.Second)
adaptor.EngineV2.SetNewRoundFaker(1, false) adaptor.EngineV2.SetNewRoundFaker(1, false)
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7")) isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))

View file

@ -625,7 +625,7 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
/* /*
// Pending for creating cross version blocks // Pending for creating cross version blocks
func TestV2UpdateSignerListIfVotedBeforeGap(t *testing.T) { func TestV2UpdateSignerListIfVotedBeforeGap(t *testing.T) {
config := params.TestXDPoSMockChainConfigWithV2EngineEpochSwitch config := params.TestXDPoSMockChainConfig
blockchain, backend, parentBlock, _ := PrepareXDCTestBlockChain(t, int(config.XDPoS.Epoch)+GAP-2, config) blockchain, backend, parentBlock, _ := PrepareXDCTestBlockChain(t, int(config.XDPoS.Epoch)+GAP-2, config)
// Insert first Block 1349 // Insert first Block 1349
t.Logf("Inserting block with propose at 1349...") t.Logf("Inserting block with propose at 1349...")

View file

@ -10,7 +10,7 @@ import (
) )
func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) { func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
engineV2.SetNewRoundFaker(utils.Round(1), true) engineV2.SetNewRoundFaker(utils.Round(1), true)

View file

@ -15,8 +15,9 @@ import (
) )
func TestYourTurnInitialV2(t *testing.T) { func TestYourTurnInitialV2(t *testing.T) {
config := params.TestXDPoSMockChainConfigWithV2EngineEpochSwitch config := params.TestXDPoSMockChainConfig
blockchain, _, parentBlock, _ := PrepareXDCTestBlockChain(t, int(config.XDPoS.Epoch)-1, config) blockchain, _, parentBlock, _ := PrepareXDCTestBlockChain(t, int(config.XDPoS.Epoch)-1, config)
minePeriod := config.XDPoS.V2.MinePeriod
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// Insert block 900 // Insert block 900
@ -36,6 +37,7 @@ func TestYourTurnInitialV2(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
blockchain.InsertBlock(block900) blockchain.InsertBlock(block900)
time.Sleep(time.Duration(minePeriod) * time.Second)
// YourTurn is called before mine first v2 block // YourTurn is called before mine first v2 block
b, err := adaptor.YourTurn(blockchain, block900.Header(), common.HexToAddress("xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1")) b, err := adaptor.YourTurn(blockchain, block900.Header(), common.HexToAddress("xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1"))
@ -57,7 +59,7 @@ func TestYourTurnInitialV2(t *testing.T) {
} }
func TestUpdateMasterNodes(t *testing.T) { func TestUpdateMasterNodes(t *testing.T) {
config := params.TestXDPoSMockChainConfigWithV2EngineEpochSwitch config := params.TestXDPoSMockChainConfig
blockchain, backend, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch+config.XDPoS.Gap)-1, config, 0) blockchain, backend, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch+config.XDPoS.Gap)-1, config, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
x := adaptor.EngineV2 x := adaptor.EngineV2
@ -121,7 +123,7 @@ func TestUpdateMasterNodes(t *testing.T) {
} }
func TestPrepare(t *testing.T) { func TestPrepare(t *testing.T) {
config := params.TestXDPoSMockChainConfigWithV2EngineEpochSwitch config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch), config, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch), config, 0)
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)

View file

@ -12,8 +12,8 @@ import (
) )
func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) { func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Block 11 is the first v2 block with round of 1 // Block 901 is the first v2 block with round of 1
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField utils.ExtraFields_v2
@ -41,11 +41,11 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
assert.Equal(t, utils.Round(0), highestQC.ProposedBlockInfo.Round) assert.Equal(t, utils.Round(0), highestQC.ProposedBlockInfo.Round)
// Insert another Block, but it won't trigger commit // Insert another Block, but it won't trigger commit
blockNum := 12 blockNum := 902
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block12 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 2, blockCoinBase, signer, signFn) block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block12) blockchain.InsertBlock(block902)
err = engineV2.ProposedBlockHandler(blockchain, block12.Header()) err = engineV2.ProposedBlockHandler(blockchain, block902.Header())
if err != nil { if err != nil {
t.Fatal("Fail propose proposedBlock handler", err) t.Fatal("Fail propose proposedBlock handler", err)
} }
@ -58,11 +58,11 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
assert.Equal(t, utils.Round(1), highestQC.ProposedBlockInfo.Round) assert.Equal(t, utils.Round(1), highestQC.ProposedBlockInfo.Round)
// Insert one more Block, but still won't trigger commit // Insert one more Block, but still won't trigger commit
blockNum = 13 blockNum = 903
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block13 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, block12, blockNum, 3, blockCoinBase, signer, signFn) block903 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block902, blockNum, 3, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block13) blockchain.InsertBlock(block903)
err = engineV2.ProposedBlockHandler(blockchain, block13.Header()) err = engineV2.ProposedBlockHandler(blockchain, block903.Header())
if err != nil { if err != nil {
t.Fatal("Fail propose proposedBlock handler", err) t.Fatal("Fail propose proposedBlock handler", err)
} }
@ -76,11 +76,11 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
assert.Nil(t, highestCommitBlock) assert.Nil(t, highestCommitBlock)
// Insert one more Block, this time will trigger commit // Insert one more Block, this time will trigger commit
blockNum = 14 blockNum = 904
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block14 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, block13, blockNum, 4, blockCoinBase, signer, signFn) block904 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block903, blockNum, 4, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block14) blockchain.InsertBlock(block904)
err = engineV2.ProposedBlockHandler(blockchain, block14.Header()) err = engineV2.ProposedBlockHandler(blockchain, block904.Header())
if err != nil { if err != nil {
t.Fatal("Fail propose proposedBlock handler", err) t.Fatal("Fail propose proposedBlock handler", err)
} }
@ -97,8 +97,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
} }
func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) { func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
// Block 11 is the first v2 block with round of 1 // Block 901 is the first v2 block with round of 1
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField utils.ExtraFields_v2
@ -118,7 +118,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
round, _, highestQC, _, highestCommitBlock := engineV2.GetProperties() round, _, highestQC, _, highestCommitBlock := engineV2.GetProperties()
grandGrandParentBlock := blockchain.GetBlockByNumber(12) grandGrandParentBlock := blockchain.GetBlockByNumber(902)
// Shoud trigger setNewRound // Shoud trigger setNewRound
assert.Equal(t, utils.Round(5), round) assert.Equal(t, utils.Round(5), round)
assert.Equal(t, utils.Round(4), highestQC.ProposedBlockInfo.Round) assert.Equal(t, utils.Round(4), highestQC.ProposedBlockInfo.Round)
@ -127,11 +127,11 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
assert.Equal(t, utils.Round(2), highestCommitBlock.Round) assert.Equal(t, utils.Round(2), highestCommitBlock.Round)
// Injecting new block which have gaps in the round number (Round 7 instead of 6) // Injecting new block which have gaps in the round number (Round 7 instead of 6)
blockNum := 16 blockNum := 906
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block16 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 7, blockCoinBase, signer, signFn) block906 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 7, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block16) blockchain.InsertBlock(block906)
err = engineV2.ProposedBlockHandler(blockchain, block16.Header()) err = engineV2.ProposedBlockHandler(blockchain, block906.Header())
if err != nil { if err != nil {
t.Fatal("Fail propose proposedBlock handler", err) t.Fatal("Fail propose proposedBlock handler", err)
} }
@ -139,7 +139,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
voteMsg = <-engineV2.BroadcastCh voteMsg = <-engineV2.BroadcastCh
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
round, _, highestQC, _, highestCommitBlock = engineV2.GetProperties() round, _, highestQC, _, highestCommitBlock = engineV2.GetProperties()
grandGrandParentBlock = blockchain.GetBlockByNumber(13) grandGrandParentBlock = blockchain.GetBlockByNumber(903)
assert.Equal(t, utils.Round(6), round) assert.Equal(t, utils.Round(6), round)
assert.Equal(t, utils.Round(5), highestQC.ProposedBlockInfo.Round) assert.Equal(t, utils.Round(5), highestQC.ProposedBlockInfo.Round)
@ -148,11 +148,11 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number) assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number)
assert.Equal(t, utils.Round(3), highestCommitBlock.Round) assert.Equal(t, utils.Round(3), highestCommitBlock.Round)
blockNum = 17 blockNum = 907
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block17 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, block16, blockNum, 8, blockCoinBase, signer, signFn) block907 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block906, blockNum, 8, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block17) blockchain.InsertBlock(block907)
err = engineV2.ProposedBlockHandler(blockchain, block17.Header()) err = engineV2.ProposedBlockHandler(blockchain, block907.Header())
if err != nil { if err != nil {
t.Fatal("Fail propose proposedBlock handler", err) t.Fatal("Fail propose proposedBlock handler", err)
} }
@ -163,7 +163,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
assert.Equal(t, utils.Round(8), round) assert.Equal(t, utils.Round(8), round)
assert.Equal(t, utils.Round(7), highestQC.ProposedBlockInfo.Round) assert.Equal(t, utils.Round(7), highestQC.ProposedBlockInfo.Round)
// Should NOT commit, the `grandGrandParentBlock` is still on blockNum 13 // Should NOT commit, the `grandGrandParentBlock` is still on blockNum 903
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash) assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number) assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number)
assert.Equal(t, utils.Round(3), highestCommitBlock.Round) assert.Equal(t, utils.Round(3), highestCommitBlock.Round)
@ -171,7 +171,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
} }
func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) { func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 16, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 5 // Set current round to 5
@ -201,7 +201,7 @@ func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
// Should not set new round if proposedBlockInfo round is less than currentRound. // Should not set new round if proposedBlockInfo round is less than currentRound.
// NOTE: This shall not even happen because we have `verifyQC` before being passed into ProposedBlockHandler // NOTE: This shall not even happen because we have `verifyQC` before being passed into ProposedBlockHandler
func TestShouldNotSetNewRound(t *testing.T) { func TestShouldNotSetNewRound(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 16, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 6 // Set current round to 6
@ -225,7 +225,7 @@ func TestShouldNotSetNewRound(t *testing.T) {
} }
func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) { func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 16, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 5 // Set current round to 5
@ -263,7 +263,7 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
} }
func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T) { func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 16, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 8 // Set current round to 8
@ -296,8 +296,8 @@ func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T)
\ 14'(7) \ 14'(7)
*/ */
func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) { func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
// Block number 15, 16 have forks and forkedBlock is the 16th // Block number 905, 906 have forks and forkedBlock is the 906th
blockchain, _, currentBlock, _, _, forkedBlock := PrepareXDCTestBlockChainForV2Engine(t, 16, params.TestXDPoSMockChainConfigWithV2Engine, 3) blockchain, _, currentBlock, _, _, forkedBlock := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 3)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField utils.ExtraFields_v2
@ -306,7 +306,7 @@ func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
} }
assert.Equal(t, utils.Round(9), extraField.Round) assert.Equal(t, utils.Round(9), extraField.Round)
// Set the lockQC and other pre-requist properties by block 16 // Set the lockQC and other pre-requist properties by block 906
err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header()) err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header())
if err != nil { if err != nil {
t.Fatal("Error while handling block 16", err) t.Fatal("Error while handling block 16", err)
@ -334,18 +334,18 @@ func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
func TestShouldSendVoteMsg(t *testing.T) { func TestShouldSendVoteMsg(t *testing.T) {
// Block number 15, 16 have forks and forkedBlock is the 16th // Block number 15, 16 have forks and forkedBlock is the 16th
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 13, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 903, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Block 11 is first v2 block // Block 901 is first v2 block
for i := 11; i < 14; i++ { for i := 901; i < 904; i++ {
blockHeader := blockchain.GetBlockByNumber(uint64(i)).Header() blockHeader := blockchain.GetBlockByNumber(uint64(i)).Header()
err := engineV2.ProposedBlockHandler(blockchain, blockHeader) err := engineV2.ProposedBlockHandler(blockchain, blockHeader)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
round, _, _, _, _ := engineV2.GetProperties() round, _, _, _, _ := engineV2.GetProperties()
assert.Equal(t, utils.Round(i-10), round) assert.Equal(t, utils.Round(i-900), round)
vote := <-engineV2.BroadcastCh vote := <-engineV2.BroadcastCh
assert.Equal(t, round, vote.(*utils.Vote).ProposedBlockInfo.Round) assert.Equal(t, round, vote.(*utils.Vote).ProposedBlockInfo.Round)
} }

View file

@ -11,8 +11,8 @@ import (
) )
func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) { func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
// Block 11 is the first v2 block with starting round of 0 // Block 901 is the first v2 block with starting round of 0
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField utils.ExtraFields_v2
@ -38,12 +38,12 @@ func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
assert.Equal(t, utils.Round(5), round) assert.Equal(t, utils.Round(5), round)
assert.Equal(t, extraField.QuorumCert, highestQuorumCert) assert.Equal(t, extraField.QuorumCert, highestQuorumCert)
assert.Equal(t, utils.Round(2), highestCommitBlock.Round) assert.Equal(t, utils.Round(2), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(12), highestCommitBlock.Number) assert.Equal(t, big.NewInt(902), highestCommitBlock.Number)
} }
func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) { func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) {
// Block 11 is the first v2 block with starting round of 0 // Block 901 is the first v2 block with starting round of 0
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField utils.ExtraFields_v2

View file

@ -527,7 +527,7 @@ func createBlockFromHeader(bc *BlockChain, customHeader *types.Header, txs []*ty
Difficulty: difficulty, Difficulty: difficulty,
Number: customHeader.Number, Number: customHeader.Number,
GasLimit: 1200000000, GasLimit: 1200000000,
Time: big.NewInt(customHeader.Number.Int64() * 10), Time: big.NewInt(time.Now().Unix()),
Extra: customHeader.Extra, Extra: customHeader.Extra,
Validator: customHeader.Validator, Validator: customHeader.Validator,
Validators: customHeader.Validators, Validators: customHeader.Validators,

View file

@ -11,7 +11,7 @@ import (
// Timeout handler // Timeout handler
func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) { func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 1 // Set round to 1
@ -62,7 +62,7 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
} }
func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) { func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 3 // Set round to 3

View file

@ -16,7 +16,7 @@ import (
// VoteHandler // VoteHandler
func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *testing.T) { func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &utils.BlockInfo{
@ -78,13 +78,13 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
} }
func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) { func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &utils.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: utils.Round(5),
Number: big.NewInt(15), Number: big.NewInt(905),
} }
voteSigningHash := utils.VoteSigHash(blockInfo) voteSigningHash := utils.VoteSigHash(blockInfo)
@ -152,13 +152,13 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo) assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
// Check round has now changed from 5 to 6 // Check round has now changed from 5 to 6
assert.Equal(t, utils.Round(6), currentRound) assert.Equal(t, utils.Round(6), currentRound)
// Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 13 with round 3 // Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 903 with round 3
assert.Equal(t, utils.Round(3), highestCommitBlock.Round) assert.Equal(t, utils.Round(3), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(13), highestCommitBlock.Number) assert.Equal(t, big.NewInt(903), highestCommitBlock.Number)
} }
func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testing.T) { func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &utils.BlockInfo{
@ -192,7 +192,7 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi
} }
func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) { func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5 // Set round to 5
@ -202,7 +202,7 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
blockInfo := &utils.BlockInfo{ blockInfo := &utils.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: utils.Round(5),
Number: big.NewInt(11), Number: big.NewInt(901),
} }
voteSigningHash := utils.VoteSigHash(blockInfo) voteSigningHash := utils.VoteSigHash(blockInfo)
// Create two vote message which will not reach vote pool threshold // Create two vote message which will not reach vote pool threshold
@ -305,18 +305,18 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
} }
func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) { func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Create a new block but don't inject it into the chain yet // Create a new block but don't inject it into the chain yet
blockNum := 16 blockNum := 906
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 6, blockCoinBase, signer, signFn) block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn)
blockInfo := &utils.BlockInfo{ blockInfo := &utils.BlockInfo{
Hash: block.Header().Hash(), Hash: block.Header().Hash(),
Round: utils.Round(6), Round: utils.Round(6),
Number: big.NewInt(16), Number: big.NewInt(906),
} }
voteSigningHash := utils.VoteSigHash(blockInfo) voteSigningHash := utils.VoteSigHash(blockInfo)
@ -370,7 +370,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
// The highestQC proposedBlockInfo shall be the same as the one from its votes // The highestQC proposedBlockInfo shall be the same as the one from its votes
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo) assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
assert.Equal(t, utils.Round(7), currentRound) assert.Equal(t, utils.Round(7), currentRound)
// Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 14 with round 4 // Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 904 with round 4
assert.Equal(t, utils.Round(4), highestCommitBlock.Round) assert.Equal(t, utils.Round(4), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(14), highestCommitBlock.Number) assert.Equal(t, big.NewInt(904), highestCommitBlock.Number)
} }

View file

@ -58,10 +58,6 @@ const (
chainHeadChanSize = 10 chainHeadChanSize = 10
// chainSideChanSize is the size of channel listening to ChainSideEvent. // chainSideChanSize is the size of channel listening to ChainSideEvent.
chainSideChanSize = 10 chainSideChanSize = 10
// timeout waiting for M1
waitPeriod = 10
// timeout for checkpoint.
waitPeriodCheckpoint = 20
txMatchGasLimit = 40000000 txMatchGasLimit = 40000000
) )
@ -269,7 +265,14 @@ func (self *worker) update() {
} }
defer self.chainHeadSub.Unsubscribe() defer self.chainHeadSub.Unsubscribe()
defer self.chainSideSub.Unsubscribe() defer self.chainSideSub.Unsubscribe()
timeout := time.NewTimer(waitPeriod * time.Second)
// timeout waiting for v1 inital value
// TODO: Read value from config after we decide where is the config
waitPeriod := 10
WaitPeriodCh := self.engine.(*XDPoS.XDPoS).WaitPeriodCh
defer close(WaitPeriodCh)
timeout := time.NewTimer(time.Duration(waitPeriod) * time.Second)
c := make(chan struct{}) c := make(chan struct{})
finish := make(chan struct{}) finish := make(chan struct{})
defer close(finish) defer close(finish)
@ -288,24 +291,31 @@ func (self *worker) update() {
for { for {
// A real event arrived, process interesting content // A real event arrived, process interesting content
select { select {
case v := <-WaitPeriodCh:
log.Info("[worker] update mine period", "period", v)
waitPeriod = v
timeout.Reset(time.Duration(waitPeriod) * time.Second)
case <-c: case <-c:
if atomic.LoadInt32(&self.mining) == 1 { if atomic.LoadInt32(&self.mining) == 1 {
self.commitNewWork() self.commitNewWork()
} }
timeout.Reset(waitPeriod * time.Second) timeout.Reset(time.Duration(waitPeriod) * time.Second)
// Handle ChainHeadEvent
// Handle ChainHeadEvent
case <-self.chainHeadCh: case <-self.chainHeadCh:
self.commitNewWork() self.commitNewWork()
timeout.Reset(waitPeriod * time.Second) timeout.Reset(time.Duration(waitPeriod) * time.Second)
// Handle ChainSideEvent // Handle ChainSideEvent
case ev := <-self.chainSideCh: case ev := <-self.chainSideCh:
if self.config.XDPoS == nil { if self.config.XDPoS == nil {
self.uncleMu.Lock() self.uncleMu.Lock()
self.possibleUncles[ev.Block.Hash()] = ev.Block self.possibleUncles[ev.Block.Hash()] = ev.Block
self.uncleMu.Unlock() self.uncleMu.Unlock()
} }
// Handle TxPreEvent
// Handle TxPreEvent
case ev := <-self.txCh: case ev := <-self.txCh:
// Apply transaction to the pending state if we're not mining // Apply transaction to the pending state if we're not mining
if atomic.LoadInt32(&self.mining) == 0 { if atomic.LoadInt32(&self.mining) == 0 {
@ -322,8 +332,10 @@ func (self *worker) update() {
self.commitNewWork() self.commitNewWork()
} }
} }
case <-self.chainHeadSub.Err(): case <-self.chainHeadSub.Err():
return return
case <-self.chainSideSub.Err(): case <-self.chainSideSub.Err():
return return
} }

View file

@ -42,12 +42,16 @@ var (
TestXDPoSV2Config = &V2{ TestXDPoSV2Config = &V2{
TimeoutWorkerDuration: 10, TimeoutWorkerDuration: 10,
CertThreshold: 3, CertThreshold: 3,
SwitchBlock: big.NewInt(10), WaitPeriod: 1,
MinePeriod: 2,
SwitchBlock: big.NewInt(900),
} }
DevnetXDPoSV2Config = &V2{ DevnetXDPoSV2Config = &V2{
SwitchBlock: big.NewInt(9999999), // Temporary set it to very high SwitchBlock: big.NewInt(9999999), // Temporary set it to very high
TimeoutWorkerDuration: 50, TimeoutWorkerDuration: 50,
CertThreshold: 6, CertThreshold: 6,
WaitPeriod: 2,
MinePeriod: 10,
} }
// XDPoSChain mainnet config // XDPoSChain mainnet config
@ -134,13 +138,8 @@ var (
AllXDPoSProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 0, Epoch: 30000}} AllXDPoSProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 0, Epoch: 30000}}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
TestXDPoSChanConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 2, Epoch: 900, Reward: 250, RewardCheckpoint: 900, Gap: 890, FoudationWalletAddr: common.HexToAddress("0x0000000000000000000000000000000000000068"), V2: XDPoSV2Config}}
// XDPoS config in use for v1 engine only
TestXDPoSMockChainConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true, V2: &V2{CertThreshold: 3, TimeoutWorkerDuration: 10}}}
// XDPoS config with v2 engine after block 10
TestXDPoSMockChainConfigWithV2Engine = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true, V2: TestXDPoSV2Config}}
// XDPoS config with v2 engine after block 901 // XDPoS config with v2 engine after block 901
TestXDPoSMockChainConfigWithV2EngineEpochSwitch = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true, V2: &V2{CertThreshold: 3, TimeoutWorkerDuration: 10, SwitchBlock: big.NewInt(900)}}} TestXDPoSMockChainConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true, V2: TestXDPoSV2Config}}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil} TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int)) TestRules = TestChainConfig.Rules(new(big.Int))
@ -202,11 +201,14 @@ type XDPoSConfig struct {
RewardCheckpoint uint64 `json:"rewardCheckpoint"` // Checkpoint block for calculate rewards. RewardCheckpoint uint64 `json:"rewardCheckpoint"` // Checkpoint block for calculate rewards.
Gap uint64 `json:"gap"` // Gap time preparing for the next epoch Gap uint64 `json:"gap"` // Gap time preparing for the next epoch
FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet
WaitPeriod int `json:"waitPeriod"` // Miner wait period
SkipValidation bool //Skip Block Validation for testing purpose SkipValidation bool //Skip Block Validation for testing purpose
V2 *V2 `json:"v2"` V2 *V2 `json:"v2"`
} }
type V2 struct { 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 SwitchBlock *big.Int `json:"switchBlock"` // v1 to v2 switch block number
TimeoutWorkerDuration int64 `json:"timeoutWorkerDuration"` // Duration in ms TimeoutWorkerDuration int64 `json:"timeoutWorkerDuration"` // Duration in ms
CertThreshold int `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate CertThreshold int `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate