diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 179d351404..8356f52b28 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1248,7 +1248,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai } var engine consensus.Engine if config.XDPoS != nil { - engine = XDPoS.New(config.XDPoS, chainDb) + engine = XDPoS.New(config, chainDb) } else { engine = ethash.NewFaker() if !ctx.GlobalBool(FakePoWFlag.Name) { diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index 869d0199d6..b6ff00490c 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -78,8 +78,9 @@ func (x *XDPoS) SubscribeForensicsEvent(ch chan<- types.ForensicsEvent) event.Su // New creates a XDPoS delegated-proof-of-stake consensus engine with the initial // signers set to the ones provided by the user. -func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS { +func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { log.Info("[New] initialise consensus engines") + config := chainConfig.XDPoS // Set any missing consensus parameters to their defaults if config.Epoch == 0 { config.Epoch = utils.EpochLength @@ -108,8 +109,8 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS { WaitPeriodCh: waitPeriodCh, signingTxsCache: signingTxsCache, - EngineV1: engine_v1.New(config, db), - EngineV2: engine_v2.New(config, db, waitPeriodCh), + EngineV1: engine_v1.New(chainConfig, db), + EngineV2: engine_v2.New(chainConfig, db, waitPeriodCh), } } @@ -138,8 +139,8 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS { GetLendingService: func() utils.LendingService { return nil }, signingTxsCache: signingTxsCache, - EngineV1: engine_v1.NewFaker(db, conf), - EngineV2: engine_v2.New(conf, db, waitPeriodCh), + EngineV1: engine_v1.NewFaker(db, chainConfig), + EngineV2: engine_v2.New(chainConfig, db, waitPeriodCh), } return fakeEngine } diff --git a/consensus/XDPoS/XDPoS_test.go b/consensus/XDPoS/XDPoS_test.go index 0d36c8a05b..c4c555d494 100644 --- a/consensus/XDPoS/XDPoS_test.go +++ b/consensus/XDPoS/XDPoS_test.go @@ -10,7 +10,7 @@ import ( func TestAdaptorShouldShareDbWithV1Engine(t *testing.T) { database := rawdb.NewMemoryDatabase() - config := params.TestXDPoSMockChainConfig.XDPoS + config := params.TestXDPoSMockChainConfig engine := New(config, database) assert := assert.New(t) diff --git a/consensus/XDPoS/engines/engine_v1/engine.go b/consensus/XDPoS/engines/engine_v1/engine.go index c6e9c0053c..98b38607f0 100644 --- a/consensus/XDPoS/engines/engine_v1/engine.go +++ b/consensus/XDPoS/engines/engine_v1/engine.go @@ -38,6 +38,8 @@ const ( // XDPoS is the delegated-proof-of-stake consensus engine proposed to support the // Ethereum testnet following the Ropsten attacks. type XDPoS_v1 struct { + chainConfig *params.ChainConfig // Chain & network configuration + config *params.XDPoSConfig // Consensus engine configuration parameters db ethdb.Database // Database to store and retrieve snapshot checkpoints @@ -79,7 +81,8 @@ func (x *XDPoS_v1) SigHash(header *types.Header) (hash common.Hash) { // New creates a XDPoS delegated-proof-of-stake consensus engine with the initial // signers set to the ones provided by the user. -func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS_v1 { +func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS_v1 { + config := chainConfig.XDPoS // Set any missing consensus parameters to their defaults conf := *config if conf.Epoch == 0 { @@ -91,6 +94,8 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS_v1 { validatorSignatures, _ := lru.NewARC(utils.InmemorySnapshots) verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots) return &XDPoS_v1{ + chainConfig: chainConfig, + config: &conf, db: db, @@ -778,7 +783,20 @@ func (x *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er return nil } +// Update masternodes into snapshot. In V1, truncating ms[:MaxMasternodes] is done in this function. func (x *XDPoS_v1) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error { + var maxMasternodes int + // check if block number is increase ms checkpoint + if x.chainConfig.IsTIPIncreaseMasternodes(header.Number) || (x.config.V2.SwitchBlock != nil && header.Number.Cmp(x.config.V2.SwitchBlock) == 1) { + // using new masterndoes + maxMasternodes = common.MaxMasternodesV2 + } else { + // using old masterndoes + maxMasternodes = common.MaxMasternodes + } + if len(ms) > maxMasternodes { + ms = ms[:maxMasternodes] + } number := header.Number.Uint64() log.Trace("take snapshot", "number", number, "hash", header.Hash()) // get snapshot @@ -1007,10 +1025,10 @@ func (x *XDPoS_v1) getSignersFromContract(chain consensus.ChainReader, checkpoin return signers, nil } -func NewFaker(db ethdb.Database, config *params.XDPoSConfig) *XDPoS_v1 { +func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS_v1 { var fakeEngine *XDPoS_v1 // Set any missing consensus parameters to their defaults - conf := config + conf := chainConfig.XDPoS // Allocate the snapshot caches and create the engine recents, _ := lru.NewARC(utils.InmemorySnapshots) @@ -1018,6 +1036,8 @@ func NewFaker(db ethdb.Database, config *params.XDPoSConfig) *XDPoS_v1 { validatorSignatures, _ := lru.NewARC(utils.InmemorySnapshots) verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots) fakeEngine = &XDPoS_v1{ + chainConfig: chainConfig, + config: conf, db: db, recents: recents, diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index c71e41c72f..0ff6aa9c18 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -24,6 +24,8 @@ import ( ) type XDPoS_v2 struct { + chainConfig *params.ChainConfig // Chain & network configuration + config *params.XDPoSConfig // Consensus engine configuration parameters db ethdb.Database // Database to store and retrieve snapshot checkpoints isInitilised bool // status of v2 variables @@ -64,7 +66,8 @@ type XDPoS_v2 struct { votePoolCollectionTime time.Time } -func New(config *params.XDPoSConfig, db ethdb.Database, waitPeriodCh chan int) *XDPoS_v2 { +func New(chainConfig *params.ChainConfig, db ethdb.Database, waitPeriodCh chan int) *XDPoS_v2 { + config := chainConfig.XDPoS // Setup timeoutTimer duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second timeoutTimer := countdown.NewCountDown(duration) @@ -77,6 +80,8 @@ func New(config *params.XDPoSConfig, db ethdb.Database, waitPeriodCh chan int) * timeoutPool := utils.NewPool() votePool := utils.NewPool() engine := &XDPoS_v2{ + chainConfig: chainConfig, + config: config, db: db, isInitilised: false, @@ -988,7 +993,11 @@ func (x *XDPoS_v2) GetPenalties(chain consensus.ChainReader, header *types.Heade return epochSwitchInfo.Penalties } +// Calculate masternodes for a block number and parent hash. In V2, truncating candidates[:MaxMasternodes] is done in this function. func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.Int, parentHash common.Hash) ([]common.Address, []common.Address, error) { + // using new max masterndoes + maxMasternodes := common.MaxMasternodesV2 + snap, err := x.getSnapshot(chain, blockNum.Uint64(), false) if err != nil { log.Error("[calcMasternodes] Adaptor v2 getSnapshot has error", "err", err) @@ -998,11 +1007,17 @@ func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.In if blockNum.Uint64() == x.config.V2.SwitchBlock.Uint64()+1 { log.Info("[calcMasternodes] examing first v2 block") + if len(candidates) > maxMasternodes { + candidates = candidates[:maxMasternodes] + } return candidates, []common.Address{}, nil } if x.HookPenalty == nil { log.Info("[calcMasternodes] no hook penalty defined") + if len(candidates) > maxMasternodes { + candidates = candidates[:maxMasternodes] + } return candidates, []common.Address{}, nil } @@ -1012,6 +1027,18 @@ func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.In return nil, nil, err } masternodes := common.RemoveItemFromArray(candidates, penalties) + if len(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 } diff --git a/consensus/tests/engine_v1_tests/block_signer_test.go b/consensus/tests/engine_v1_tests/block_signer_test.go index df176d8114..673c23b1bc 100644 --- a/consensus/tests/engine_v1_tests/block_signer_test.go +++ b/consensus/tests/engine_v1_tests/block_signer_test.go @@ -154,6 +154,7 @@ func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) { if err != nil { t.Fatalf("Failed while trying to get signers") } + assert.Equal(t, common.MaxMasternodes, len(signers)) // Now, we voted acc 1 to be in the signerList, which will kick out acc3 because it has less funds if signers[acc3Addr.Hex()] == true { debugMessage(backend, signers, t) @@ -195,6 +196,7 @@ func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc1Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 1 should sit in the signer list") @@ -244,6 +246,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc1Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 1 should sit in the signer list") @@ -279,6 +282,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) // Should not run the `updateM1` for forked chain, hence account3 still exit if signers[acc3Addr.Hex()] != true { debugMessage(backend, signers, t) @@ -312,6 +316,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc2Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 2 should sit in the signer list") @@ -325,6 +330,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc2Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 2 should sit in the signer list") @@ -338,6 +344,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc2Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("acc2Addr should sit in the signer list") @@ -404,6 +411,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc1Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 1 should sit in the signer list") @@ -445,6 +453,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) // Should not run the `updateM1` for forked chain, hence account3 still exit if signers[acc3Addr.Hex()] != true { debugMessage(backend, signers, t) @@ -473,6 +482,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc2Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 2 should sit in the signer list") @@ -482,6 +492,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc2Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("account 2 should sit in the signer list") @@ -491,6 +502,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc2Addr.Hex()] != true { debugMessage(backend, signers, t) t.Fatalf("acc2Addr should sit in the signer list") @@ -564,6 +576,7 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) if signers[acc1Addr.Hex()] == true { debugMessage(backend, signers, t) t.Fatalf("account 1 should NOT sit in the signer list") @@ -623,6 +636,7 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) { if err != nil { t.Fatal(err) } + assert.Equal(t, common.MaxMasternodes, len(signers)) // Should run the `updateM1` for forked chain, but it should not be affected by the voted block 451A which is not on the mainchain anymore if signers[acc3Addr.Hex()] != true { @@ -630,63 +644,3 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) { t.Fatalf("account 3 should sit in the signer list as previos block result") } } - -/* - V2 Consensus -*/ -/* -// Pending for creating cross version blocks -func TestV2UpdateSignerListIfVotedBeforeGap(t *testing.T) { - config := params.TestXDPoSMockChainConfig - blockchain, backend, parentBlock, signer, signFn := PrepareXDCTestBlockChain(t, int(config.XDPoS.Epoch)+GAP-2, config) - // Insert first Block 1349 - t.Logf("Inserting block with propose at 1349...") - blockCoinbaseA := "0xaaa0000000000000000000000000000000001349" - tx, err := voteTX(37117, 0, acc1Addr.String()) - if err != nil { - t.Fatal(err) - } - - //Get from block validator error message - merkleRoot := "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772" - header := &types.Header{ - Root: common.HexToHash(merkleRoot), - Number: big.NewInt(int64(1349)), - ParentHash: parentBlock.Hash(), - Coinbase: common.HexToAddress(blockCoinbaseA), - } - block1349, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx}, signer, signFn, blockchain.Config()) - if err != nil { - t.Fatal(err) - } - parentBlock = block1349 - - // Now, let's mine another block to trigger the GAP block signerList update - block1350CoinbaseAddress := "0xaaa0000000000000000000000000000000001350" - merkleRoot = "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772" - header = &types.Header{ - Root: common.HexToHash(merkleRoot), - Number: big.NewInt(int64(1350)), - ParentHash: parentBlock.Hash(), - Coinbase: common.HexToAddress(block1350CoinbaseAddress), - } - block1350, err := insertBlock(blockchain, header) - if err != nil { - t.Fatal(err) - } - - signers, err := GetSnapshotSigner(blockchain, block1350.Header()) - if err != nil { - t.Fatalf("Failed while trying to get signers") - } - // Now, we voted acc 1 to be in the signerList, which will kick out acc3 because it has less funds - if signers[acc3Addr.Hex()] == true { - debugMessage(backend, signers, t) - t.Fatalf("account 3 should NOT sit in the signer list") - } - if signers[acc1Addr.Hex()] != true { - debugMessage(backend, signers, t) - t.Fatalf("account 1 should sit in the signer list") - } -} -*/ diff --git a/consensus/tests/engine_v2_tests/adaptor_test.go b/consensus/tests/engine_v2_tests/adaptor_test.go index 6eb2ff65e1..564a16f585 100644 --- a/consensus/tests/engine_v2_tests/adaptor_test.go +++ b/consensus/tests/engine_v2_tests/adaptor_test.go @@ -180,7 +180,7 @@ func TestAdaptorGetMasternodesV2(t *testing.T) { adaptor := blockchain.Engine().(*XDPoS.XDPoS) blockNum := 901 blockCoinBase := "0x111000000000000000000000000000000123" - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "") // block 901 is the first v2 block, and is treated as epoch switch block err := blockchain.InsertBlock(currentBlock) @@ -190,7 +190,7 @@ func TestAdaptorGetMasternodesV2(t *testing.T) { masternodes1ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64()) assert.True(t, reflect.DeepEqual(masternodes1, masternodes1ByNumber), "at block number", blockNum) for blockNum = 902; blockNum < 915; blockNum++ { - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(currentBlock) assert.Nil(t, err) masternodes2 := adaptor.GetMasternodes(blockchain, currentBlock.Header()) @@ -213,7 +213,7 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) { // V2 blockNum := 901 blockCoinBase := "0x111000000000000000000000000000000123" - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(currentBlock) assert.Nil(t, err) currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number()) @@ -222,7 +222,7 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) { assert.Equal(t, uint64(1), epochNum) for blockNum = 902; blockNum < 915; blockNum++ { - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(currentBlock) assert.Nil(t, err) @@ -248,13 +248,13 @@ func TestGetParentBlock(t *testing.T) { // V2 blockNum := 901 blockCoinBase := "0x111000000000000000000000000000000123" - block901 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block900, blockNum, 1, blockCoinBase, signer, signFn, nil, nil) + block901 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block900, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block901) assert.Nil(t, err) // let's inject another one, but the highestedQC has not been updated, so it shall still point to 900 blockNum = 902 - block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil, nil) + block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block902) assert.Nil(t, err) block = adaptor.FindParentBlockToAssign(blockchain, block902) diff --git a/consensus/tests/engine_v2_tests/authorised_masternode_test.go b/consensus/tests/engine_v2_tests/authorised_masternode_test.go index d93a5747f1..adf0e38b97 100644 --- a/consensus/tests/engine_v2_tests/authorised_masternode_test.go +++ b/consensus/tests/engine_v2_tests/authorised_masternode_test.go @@ -17,7 +17,7 @@ func TestIsAuthorisedMNForConsensusV2(t *testing.T) { adaptor := blockchain.Engine().(*XDPoS.XDPoS) blockNum := 902 blockCoinBase := "0x111000000000000000000000000000000123" - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil, "") err := blockchain.InsertBlock(currentBlock) assert.Nil(t, err) // As long as the address is in the master node list, they are all valid @@ -38,7 +38,7 @@ func TestIsYourTurnConsensusV2(t *testing.T) { adaptor := blockchain.Engine().(*XDPoS.XDPoS) blockNum := 901 blockCoinBase := "0x111000000000000000000000000000000123" - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "") currentBlockHeader := currentBlock.Header() currentBlockHeader.Time = big.NewInt(time.Now().Unix()) err := blockchain.InsertBlock(currentBlock) @@ -64,7 +64,7 @@ func TestIsYourTurnConsensusV2(t *testing.T) { // We continue to grow the chain which will increase the round number blockNum = 902 - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(currentBlock) assert.Nil(t, err) time.Sleep(time.Duration(minePeriod) * time.Second) @@ -89,7 +89,7 @@ func TestIsYourTurnConsensusV2CrossConfig(t *testing.T) { adaptor := blockchain.Engine().(*XDPoS.XDPoS) blockNum := 910 // 910 is new config switch block blockCoinBase := "0x111000000000000000000000000000000123" - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 10, blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 10, blockCoinBase, signer, signFn, nil, nil, "") currentBlockHeader := currentBlock.Header() currentBlockHeader.Time = big.NewInt(time.Now().Unix()) err := blockchain.InsertBlock(currentBlock) diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index 648de3a373..854eebd124 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -30,6 +30,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rlp" + "github.com/stretchr/testify/assert" ) type masterNodes map[string]big.Int @@ -199,6 +200,90 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.S return contractBackend2 } +func getMultiCandidatesBackend(t *testing.T, chainConfig *params.ChainConfig, n int) *backends.SimulatedBackend { + assert.GreaterOrEqual(t, n, 4) + // initial helper backend, give a very large gas limit + contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, + }, 1000000000, chainConfig) + + transactOpts := bind.NewKeyedTransactor(voterKey) + + var candidates []common.Address + var caps []*big.Int + defalutCap := new(big.Int) + defalutCap.SetString("1000000000", 10) + + for i := 1; i <= n-4; i++ { + addr := fmt.Sprintf("%04d", i) + candidates = append(candidates, common.StringToAddress(addr)) + caps = append(caps, defalutCap) + } + + acc1Cap, acc2Cap, acc3Cap, voterCap := new(big.Int), new(big.Int), new(big.Int), new(big.Int) + + acc1Cap.SetString("10000001", 10) + acc2Cap.SetString("10000002", 10) + acc3Cap.SetString("10000003", 10) + voterCap.SetString("2000000000", 10) // give voter the highest cap to make it win the masternode selection + + caps = append(caps, voterCap, acc1Cap, acc2Cap, acc3Cap) + candidates = append(candidates, voterAddr, acc1Addr, acc2Addr, acc3Addr) + + // create validator smart contract + validatorSCAddr, _, _, err := contractValidator.DeployXDCValidator( + transactOpts, + contractBackendForSC, + candidates, + caps, + voterAddr, // first owner, not used + big.NewInt(50000), + big.NewInt(1), + big.NewInt(99), + big.NewInt(100), + big.NewInt(100), + ) + if err != nil { + t.Fatalf("can't deploy root registry: %v", err) + } + + contractBackendForSC.Commit() // Write into database(state) + + // Prepare Code and Storage + d := time.Now().Add(3000 * time.Millisecond) + ctx, cancel := context.WithDeadline(context.Background(), d) + defer cancel() + + code, _ := contractBackendForSC.CodeAt(ctx, validatorSCAddr, nil) + storage := make(map[common.Hash]common.Hash) + f := func(key, val common.Hash) bool { + decode := []byte{} + trim := bytes.TrimLeft(val.Bytes(), "\x00") + err := rlp.DecodeBytes(trim, &decode) + if err != nil { + t.Fatalf("Failed while decode byte") + } + storage[key] = common.BytesToHash(decode) + log.Info("DecodeBytes", "value", val.String(), "decode", storage[key].String()) + return true + } + err = contractBackendForSC.ForEachStorageAt(ctx, validatorSCAddr, nil, f) + if err != nil { + t.Fatalf("Failed while trying to read all keys from SC") + } + + // create test backend with smart contract in it + contractBackend2 := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + acc1Addr: {Balance: new(big.Int).SetUint64(10000000000)}, + acc2Addr: {Balance: new(big.Int).SetUint64(10000000000)}, + acc3Addr: {Balance: new(big.Int).SetUint64(10000000000)}, + voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, + common.HexToAddress(common.MasternodeVotingSMC): {Balance: new(big.Int).SetUint64(1), Code: code, Storage: storage}, // Binding the MasternodeVotingSMC with newly created 'code' for SC execution + }, 10000000, chainConfig) + + return contractBackend2 +} + func signingTxWithKey(header *types.Header, nonce uint64, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { tx := contracts.CreateTxSign(header.Number, header.Hash(), nonce, common.HexToAddress(common.BlockSigners)) s := types.NewEIP155Signer(big.NewInt(chainID)) @@ -316,7 +401,7 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon blockCoinBase = signer.Hex() } roundNumber := int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64() - block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, nil, nil) + block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block) if err != nil { @@ -338,7 +423,7 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon forkedBlockRoundNumber = roundNumber + int64(*forkedBlockOptions.numOfForkedBlocks) } - forkedBlock := CreateBlock(blockchain, chainConfig, currentForkBlock, i, forkedBlockRoundNumber, forkedBlockCoinBase, signer, signFn, nil, forkedBlockOptions.signersKey) + forkedBlock := CreateBlock(blockchain, chainConfig, currentForkBlock, i, forkedBlockRoundNumber, forkedBlockCoinBase, signer, signFn, nil, forkedBlockOptions.signersKey, "") err = blockchain.InsertBlock(forkedBlock) if err != nil { @@ -403,7 +488,7 @@ func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks in } roundNumber := int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64() // use signer itself as penalty - block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, signer[:], nil) + block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, signer[:], nil, "") err = blockchain.InsertBlock(block) if err != nil { @@ -421,9 +506,62 @@ func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks in return blockchain, backend, currentBlock, signer, signFn } -func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumber int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), penalties []byte, signersKey []*ecdsa.PrivateKey) *types.Block { +// V2 concensus engine, compared to PrepareXDCTestBlockChainForV2Engine: (1) no forking (2) 128 masternode candidates +func PrepareXDCTestBlockChainWith128Candidates(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig) (*BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error)) { + // Preparation + var err error + signer, signFn, err := backends.SimulateWalletAddressAndSignFn() + if err != nil { + t.Fatal("Error while creating simulated wallet for generating singer address and signer fn: ", err) + } + backend := getMultiCandidatesBackend(t, chainConfig, 128) + blockchain := backend.GetBlockChain() + blockchain.Client = backend + + engine := blockchain.Engine().(*XDPoS.XDPoS) + + // Authorise + engine.Authorize(signer, signFn) + + currentBlock := blockchain.Genesis() + + go func() { + for range core.CheckpointCh { + checkpointChanMsg := <-core.CheckpointCh + log.Info("[V2] Got a message from core CheckpointChan!", "msg", checkpointChanMsg) + } + }() + + // Insert initial blocks + for i := 1; i <= numOfBlocks; i++ { + blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", i) + // for v2 blocks, fill in correct coinbase + if int64(i) > chainConfig.XDPoS.V2.SwitchBlock.Int64() { + blockCoinBase = signer.Hex() + } + roundNumber := int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64() + block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, nil, nil, "b345a8560bd51926803dd17677c9f0751193914a851a4ec13063d6bf50220b53") + err = blockchain.InsertBlock(block) + if err != nil { + t.Fatal(err) + } + currentBlock = block + } + + // Update Signer as there is no previous signer assigned + err = UpdateSigner(blockchain) + if err != nil { + t.Fatal(err) + } + + return blockchain, backend, currentBlock, signer, signFn +} + +func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumber int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), penalties []byte, signersKey []*ecdsa.PrivateKey, merkleRoot string) *types.Block { currentBlock := startingBlock - merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930" + if len(merkleRoot) == 0 { + merkleRoot = "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930" + } var header *types.Header if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.V2.SwitchBlock) == 1 { // Build engine v2 compatible extra data field diff --git a/consensus/tests/engine_v2_tests/initial_test.go b/consensus/tests/engine_v2_tests/initial_test.go index 09446171d4..438fdf8b76 100644 --- a/consensus/tests/engine_v2_tests/initial_test.go +++ b/consensus/tests/engine_v2_tests/initial_test.go @@ -59,7 +59,7 @@ func TestInitialOtherV2Block(t *testing.T) { blockCoinBase := "0x111000000000000000000000000000000123" for blockNum := 901; blockNum <= 910; blockNum++ { - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil, "") err := blockchain.InsertBlock(currentBlock) assert.Nil(t, err) } diff --git a/consensus/tests/engine_v2_tests/mine_test.go b/consensus/tests/engine_v2_tests/mine_test.go index a56658e1e8..4ed5bd2c96 100644 --- a/consensus/tests/engine_v2_tests/mine_test.go +++ b/consensus/tests/engine_v2_tests/mine_test.go @@ -222,3 +222,63 @@ func TestPrepareHappyPath(t *testing.T) { assert.Equal(t, types.Round(4), decodedExtraField.Round) assert.Equal(t, types.Round(0), decodedExtraField.QuorumCert.ProposedBlockInfo.Round) } + +// test if we have 128 candidates, then snapshot will store all of them, and when preparing (and verifying) candidates is truncated to MaxMasternodes +func TestUpdateMultipleMasterNodes(t *testing.T) { + config := params.TestXDPoSMockChainConfig + blockchain, _, currentBlock, signer, signFn := PrepareXDCTestBlockChainWith128Candidates(t, int(config.XDPoS.Epoch+config.XDPoS.Gap)-1, config) + adaptor := blockchain.Engine().(*XDPoS.XDPoS) + x := adaptor.EngineV2 + // Insert block 1350 + t.Logf("Inserting block with propose at 1350...") + blockCoinbaseA := "0xaaa0000000000000000000000000000000001350" + //Get from block validator error message + merkleRoot := "b345a8560bd51926803dd17677c9f0751193914a851a4ec13063d6bf50220b53" + parentBlock := CreateBlock(blockchain, config, currentBlock, 1350, 450, blockCoinbaseA, signer, signFn, nil, nil, merkleRoot) + err := blockchain.InsertBlock(parentBlock) + assert.Nil(t, err) + // 1350 is a gap block, need to update the snapshot + err = blockchain.UpdateM1() + assert.Nil(t, err) + // but we wait until 1800 to test the snapshot + + t.Logf("Inserting block from 1351 to 1800...") + for i := 1351; i <= 1800; i++ { + blockCoinbase := fmt.Sprintf("0xaaa000000000000000000000000000000000%4d", i) + block := CreateBlock(blockchain, config, parentBlock, i, int64(i-900), blockCoinbase, signer, signFn, nil, nil, merkleRoot) + err = blockchain.InsertBlock(block) + assert.Nil(t, err) + if i < 1800 { + parentBlock = block + } + if i == 1800 { + snap, err := x.GetSnapshot(blockchain, block.Header()) + + assert.Nil(t, err) + assert.Equal(t, 1350, int(snap.Number)) + assert.Equal(t, 128, len(snap.NextEpochMasterNodes)) // 128 is all masternode candidates, not limited by MaxMasternodes + } + } + + tstamp := time.Now().Unix() + + header1800 := &types.Header{ + ParentHash: parentBlock.Hash(), + Number: big.NewInt(int64(1800)), + GasLimit: params.TargetGasLimit, + Time: big.NewInt(tstamp), + Coinbase: voterAddr, + } + + adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(900), false) + blockInfo := &types.BlockInfo{Hash: parentBlock.Hash(), Round: types.Round(900 - 1), Number: parentBlock.Number()} + signature := []byte{1, 2, 3, 4, 5, 6, 7, 8} + signatures := []types.Signature{signature} + quorumCert := &types.QuorumCert{ProposedBlockInfo: blockInfo, Signatures: signatures, GapNumber: 1350} + adaptor.EngineV2.ProcessQCFaker(blockchain, quorumCert) + adaptor.EngineV2.AuthorizeFaker(voterAddr) + err = adaptor.Prepare(blockchain, header1800) + assert.Nil(t, err) + assert.Equal(t, common.MaxMasternodesV2, len(header1800.Validators)/common.AddressLength) // although 128 masternode candidates, we can only pick MaxMasternodes + assert.Equal(t, 0, len(header1800.Penalties)/common.AddressLength) +} diff --git a/consensus/tests/engine_v2_tests/proposed_block_test.go b/consensus/tests/engine_v2_tests/proposed_block_test.go index db7485911b..3f39a24a66 100644 --- a/consensus/tests/engine_v2_tests/proposed_block_test.go +++ b/consensus/tests/engine_v2_tests/proposed_block_test.go @@ -45,7 +45,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) { // Insert another Block, but it won't trigger commit blockNum := 902 blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil) + block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block902) assert.Nil(t, err) err = engineV2.ProposedBlockHandler(blockchain, block902.Header()) @@ -63,7 +63,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) { // Insert one more Block, but still won't trigger commit blockNum = 903 blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block903 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block902, blockNum, 3, blockCoinBase, signer, signFn, nil, nil) + block903 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block902, blockNum, 3, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block903) assert.Nil(t, err) err = engineV2.ProposedBlockHandler(blockchain, block903.Header()) @@ -82,7 +82,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) { // Insert one more Block, this time will trigger commit blockNum = 904 blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block904 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block903, blockNum, 4, blockCoinBase, signer, signFn, nil, nil) + block904 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block903, blockNum, 4, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block904) assert.Nil(t, err) err = engineV2.ProposedBlockHandler(blockchain, block904.Header()) @@ -134,7 +134,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) { // Injecting new block which have gaps in the round number (Round 7 instead of 6) blockNum := 906 blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block906 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 7, blockCoinBase, signer, signFn, nil, nil) + block906 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 7, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block906) assert.Nil(t, err) err = engineV2.ProposedBlockHandler(blockchain, block906.Header()) @@ -156,7 +156,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) { blockNum = 907 blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block907 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block906, blockNum, 8, blockCoinBase, signer, signFn, nil, nil) + block907 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block906, blockNum, 8, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block907) assert.Nil(t, err) err = engineV2.ProposedBlockHandler(blockchain, block907.Header()) diff --git a/consensus/tests/engine_v2_tests/timeout_test.go b/consensus/tests/engine_v2_tests/timeout_test.go index 0199249d16..c1c9709d5c 100644 --- a/consensus/tests/engine_v2_tests/timeout_test.go +++ b/consensus/tests/engine_v2_tests/timeout_test.go @@ -109,7 +109,7 @@ func TestTimeoutPeriodAndThreadholdConfigChange(t *testing.T) { // Create another block to trigger update parameters blockNum := 1800 blockCoinBase := "0x111000000000000000000000000000000123" - currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 900, blockCoinBase, signer, signFn, nil, nil) + currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 900, blockCoinBase, signer, signFn, nil, nil, "") currentBlockHeader := currentBlock.Header() currentBlockHeader.Time = big.NewInt(time.Now().Unix()) err := blockchain.InsertBlock(currentBlock) diff --git a/consensus/tests/engine_v2_tests/verify_blockinfo_test.go b/consensus/tests/engine_v2_tests/verify_blockinfo_test.go index 68778d899d..5bc5a8c45f 100644 --- a/consensus/tests/engine_v2_tests/verify_blockinfo_test.go +++ b/consensus/tests/engine_v2_tests/verify_blockinfo_test.go @@ -26,7 +26,7 @@ func TestShouldVerifyBlockInfo(t *testing.T) { // Insert another Block, but it won't trigger commit blockNum := 902 blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil) + block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil, "") err = blockchain.InsertBlock(block902) assert.Nil(t, err) diff --git a/consensus/tests/engine_v2_tests/verify_header_test.go b/consensus/tests/engine_v2_tests/verify_header_test.go index 11bb9c1fd3..4e1cb8b7e3 100644 --- a/consensus/tests/engine_v2_tests/verify_header_test.go +++ b/consensus/tests/engine_v2_tests/verify_header_test.go @@ -421,12 +421,12 @@ func TestShouldVerifyHeadersEvenIfParentsNotYetWrittenIntoDB(t *testing.T) { // Create block 911 but don't write into DB blockNumber := 911 roundNumber := int64(blockNumber) - config.XDPoS.V2.SwitchBlock.Int64() - block911 := CreateBlock(blockchain, &config, block910, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil, nil) + block911 := CreateBlock(blockchain, &config, block910, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil, nil, "") // Create block 912 and not write into DB as well blockNumber = 912 roundNumber = int64(blockNumber) - config.XDPoS.V2.SwitchBlock.Int64() - block912 := CreateBlock(blockchain, &config, block911, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil, nil) + block912 := CreateBlock(blockchain, &config, block911, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil, nil, "") headersTobeVerified = append(headersTobeVerified, block910.Header(), block911.Header(), block912.Header()) // Randomly set full verify diff --git a/consensus/tests/engine_v2_tests/vote_test.go b/consensus/tests/engine_v2_tests/vote_test.go index e9a1041e8a..311e0488eb 100644 --- a/consensus/tests/engine_v2_tests/vote_test.go +++ b/consensus/tests/engine_v2_tests/vote_test.go @@ -339,7 +339,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) { // Create a new block but don't inject it into the chain yet blockNum := 906 blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) - block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil, nil) + block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil, nil, "") blockInfo := &types.BlockInfo{ Hash: block.Header().Hash(), diff --git a/core/blockchain.go b/core/blockchain.go index 927a3ba4df..0de36014ae 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2550,20 +2550,7 @@ func (bc *BlockChain) UpdateM1() error { log.Info("Updating new set of masternodes") // get block header header := bc.CurrentHeader() - var maxMasternodes int - // check if block number is increase ms checkpoint - if bc.chainConfig.IsTIPIncreaseMasternodes(header.Number) || (bc.chainConfig.XDPoS.V2.SwitchBlock != nil && header.Number.Cmp(bc.chainConfig.XDPoS.V2.SwitchBlock) == 1) { - // using new masterndoes - maxMasternodes = common.MaxMasternodesV2 - } else { - // using old masterndoes - maxMasternodes = common.MaxMasternodes - } - if len(ms) > maxMasternodes { - err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms[:maxMasternodes]) - } else { - err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms) - } + err = engine.UpdateMasternodes(bc, header, ms) if err != nil { return err } diff --git a/eth/backend.go b/eth/backend.go index a3f09ccac0..91c60d40d9 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -338,7 +338,7 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine { // If delegated-proof-of-stake is requested, set it up if chainConfig.XDPoS != nil { - return XDPoS.New(chainConfig.XDPoS, db) + return XDPoS.New(chainConfig, db) } // Otherwise assume proof-of-work