Skip to content

Commit

Permalink
move config into code (ethereum#54)
Browse files Browse the repository at this point in the history
* move config into code

* set devnet switch block number very high

* increase timeout and certThreshold for devnet config

Co-authored-by: Jianrong <wjrjerome@gmail.com>
  • Loading branch information
Liam and wjrjerome authored Feb 12, 2022
1 parent 76724b0 commit 4424c7d
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 47 deletions.
21 changes: 13 additions & 8 deletions consensus/XDPoS/XDPoS.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,25 @@ type XDPoS struct {
// 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 {
log.Info("[New] initial conensus engines")
// Set any missing consensus parameters to their defaults
conf := *config
if conf.Epoch == 0 {
conf.Epoch = utils.EpochLength
if config.Epoch == 0 {
config.Epoch = utils.EpochLength
}

// TODO: This shall be configurable or replaced
config.V2 = params.DevnetXDPoSV2Config

// Allocate the snapshot caches and create the engine
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)

return &XDPoS{
config: &conf,
config: config,
db: db,

signingTxsCache: signingTxsCache,
EngineV1: engine_v1.New(&conf, db),
EngineV2: engine_v2.New(&conf, db),
EngineV1: engine_v1.New(config, db),
EngineV2: engine_v2.New(config, db),
}
}

Expand Down Expand Up @@ -300,8 +303,10 @@ func (x *XDPoS) GetMasternodesByNumber(chain consensus.ChainReader, blockNumber
}

func (x *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (bool, error) {
if parent.Number.Cmp(x.config.XDPoSV2Block) == 0 {
x.initialV2(chain, parent)
if x.config.V2.SwitchBlock != nil && parent.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
err := x.initialV2(chain, parent)
log.Error("[YourTurn] Error when initialise v2", "Error", err, "ParentBlock", parent)
return false, err
}
switch x.config.BlockConsensusVersion(big.NewInt(parent.Number.Int64() + 1)) {
case params.ConsensusEngineVersion2:
Expand Down
28 changes: 14 additions & 14 deletions consensus/XDPoS/engines/engine_v2/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,18 +340,18 @@ func (x *XDPoS_v2) YourTurn(chain consensus.ChainReader, parent *types.Header, s
}
var masterNodes []common.Address
if isEpochSwitch {
if x.config.XDPoSV2Block.Cmp(parent.Number) == 0 {
snap, err := x.getSnapshot(chain, x.config.XDPoSV2Block.Uint64())
if x.config.V2.SwitchBlock.Cmp(parent.Number) == 0 {
snap, err := x.getSnapshot(chain, x.config.V2.SwitchBlock.Uint64())
if err != nil {
log.Error("[YourTurn] Cannot find snapshot at gap num of last V1", "err", err, "number", x.config.XDPoSV2Block.Uint64())
log.Error("[YourTurn] Cannot find snapshot at gap num of last V1", "err", err, "number", x.config.V2.SwitchBlock.Uint64())
return false, err
}
// the initial snapshot of v1->v2 switch containes penalites node
masterNodes = snap.NextEpochMasterNodes
} else {
snap, err := x.getSnapshot(chain, parent.Number.Uint64()+1)
if err != nil {
log.Error("[YourTurn] Cannot find snapshot at gap block", "err", err, "number", x.config.XDPoSV2Block.Uint64())
log.Error("[YourTurn] Cannot find snapshot at gap block", "err", err, "number", x.config.V2.SwitchBlock.Uint64())
return false, err
}
masterNodes = snap.NextEpochMasterNodes
Expand Down Expand Up @@ -873,7 +873,7 @@ func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, quorumCert
}
// 2. Get QC from header and update lockQuorumCert(lockQuorumCert is the parent of highestQC)
proposedBlockHeader := blockChainReader.GetHeaderByHash(quorumCert.ProposedBlockInfo.Hash)
if proposedBlockHeader.Number.Cmp(x.config.XDPoSV2Block) > 0 {
if proposedBlockHeader.Number.Cmp(x.config.V2.SwitchBlock) > 0 {
// Extra field contain parent information
var decodedExtraField utils.ExtraFields_v2
err := utils.DecodeBytesExtraFields(proposedBlockHeader.Extra, &decodedExtraField)
Expand Down Expand Up @@ -1093,7 +1093,7 @@ func (x *XDPoS_v2) getSyncInfo() *utils.SyncInfo {
//Find parent and grandparent, check round number, if so, commit grandparent(grandGrandParent of currentBlock)
func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposedBlockHeader *types.Header, proposedBlockRound *utils.Round) (bool, error) {
// XDPoS v1.0 switch to v2.0, skip commit
if big.NewInt(0).Sub(proposedBlockHeader.Number, big.NewInt(2)).Cmp(x.config.XDPoSV2Block) <= 0 {
if big.NewInt(0).Sub(proposedBlockHeader.Number, big.NewInt(2)).Cmp(x.config.V2.SwitchBlock) <= 0 {
return false, nil
}
// Find the last two parent block and check their rounds are the continuous
Expand Down Expand Up @@ -1199,7 +1199,7 @@ func (x *XDPoS_v2) GetMasternodesFromEpochSwitchHeader(epochSwitchHeader *types.

func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {
// Return true directly if we are examing the last v1 block. This could happen if the calling function is examing parent block
if header.Number.Cmp(x.config.XDPoSV2Block) == 0 {
if header.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
log.Info("[IsEpochSwitch] examing last v1 block 👯‍♂️")
return true, header.Number.Uint64() / x.config.Epoch, nil
}
Expand All @@ -1213,10 +1213,10 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {
parentRound := decodedExtraField.QuorumCert.ProposedBlockInfo.Round
round := decodedExtraField.Round
epochStartRound := round - round%utils.Round(x.config.Epoch)
epochNum := x.config.XDPoSV2Block.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch
// if parent is last v1 block and this is first v2 block, this is treated as epoch switch
if decodedExtraField.QuorumCert.ProposedBlockInfo.Number.Cmp(x.config.XDPoSV2Block) == 0 {
log.Info("[IsEpochSwitch] true, parent equals XDPoSV2Block", "round", round, "number", header.Number.Uint64(), "hash", header.Hash())
if decodedExtraField.QuorumCert.ProposedBlockInfo.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
log.Info("[IsEpochSwitch] true, parent equals V2.SwitchBlock", "round", round, "number", header.Number.Uint64(), "hash", header.Hash())
return true, epochNum, nil
}
log.Info("[IsEpochSwitch]", "parent round", parentRound, "round", round, "number", header.Number.Uint64(), "hash", header.Hash())
Expand All @@ -1225,9 +1225,9 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {

// IsEpochSwitchAtRound() is used by miner to check whether it mines a block in the same epoch with parent
func (x *XDPoS_v2) IsEpochSwitchAtRound(round utils.Round, parentHeader *types.Header) (bool, uint64, error) {
epochNum := x.config.XDPoSV2Block.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch
// if parent is last v1 block and this is first v2 block, this is treated as epoch switch
if parentHeader.Number.Cmp(x.config.XDPoSV2Block) == 0 {
if parentHeader.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
return true, epochNum, nil
}
var decodedExtraField utils.ExtraFields_v2
Expand Down Expand Up @@ -1263,7 +1263,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
log.Debug("[getEpochSwitchInfo] header is epoch switch", "hash", hash.Hex(), "number", h.Number.Uint64())
var epochSwitchInfo *utils.EpochSwitchInfo
// Special case, in case of last v1 block, we manually build the epoch switch info
if h.Number.Cmp(x.config.XDPoSV2Block) == 0 {
if h.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
masternodes := decodeMasternodesFromHeaderExtra(h)
epochSwitchInfo = &utils.EpochSwitchInfo{
Masternodes: masternodes,
Expand Down Expand Up @@ -1325,6 +1325,6 @@ func (x *XDPoS_v2) GetCurrentEpochSwitchBlock(chain consensus.ChainReader, block
}

currentCheckpointNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()
epochNum := x.config.XDPoSV2Block.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch
return currentCheckpointNumber, epochNum, nil
}
18 changes: 9 additions & 9 deletions consensus/tests/adaptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestAdaptorGetMasternodesFromCheckpointHeader(t *testing.T) {
headerV1.Extra = common.Hex2Bytes("d7830100018358444388676f312e31352e38856c696e757800000000000000000278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758ccef312ee5eea8d7bad5374c6a652150515d744508b61c1a4deb4e4e7bf057e4e3824c11fd2569bcb77a52905cda63b5a58507910bed335e4c9d87ae0ecdfafd400")
masternodesV1 := adaptor.GetMasternodesFromCheckpointHeader(headerV1)
headerV2 := currentBlock.Header()
headerV2.Number.Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(1))
headerV2.Number.Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(1))
headerV2.Validators = common.Hex2Bytes("0278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758c")
masternodesV2 := adaptor.GetMasternodesFromCheckpointHeader(headerV2)
assert.True(t, reflect.DeepEqual(masternodesV1, masternodesV2), "GetMasternodesFromCheckpointHeader in adaptor for v1 v2 not equal", "v1", masternodesV1, "v2", masternodesV2)
Expand All @@ -93,7 +93,7 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
parentBlockInfo := &utils.BlockInfo{
Hash: header.ParentHash,
Round: utils.Round(0),
Number: big.NewInt(0).Set(blockchain.Config().XDPoS.XDPoSV2Block),
Number: big.NewInt(0).Set(blockchain.Config().XDPoS.V2.SwitchBlock),
}
quorumCert := &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Expand All @@ -106,14 +106,14 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
extraBytes, err := extra.EncodeToBytes()
assert.Nil(t, err)
header.Extra = extraBytes
header.Number.Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(1))
header.Number.Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(1))
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err)
assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header)
parentBlockInfo = &utils.BlockInfo{
Hash: header.ParentHash,
Round: utils.Round(1),
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(1)),
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(1)),
}
quorumCert = &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Expand All @@ -126,14 +126,14 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
extraBytes, err = extra.EncodeToBytes()
assert.Nil(t, err)
header.Extra = extraBytes
header.Number.Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(2))
header.Number.Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(2))
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err)
assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header)
parentBlockInfo = &utils.BlockInfo{
Hash: header.ParentHash,
Round: utils.Round(blockchain.Config().XDPoS.Epoch) - 1,
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(100)),
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(100)),
}
quorumCert = &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Expand All @@ -146,14 +146,14 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
extraBytes, err = extra.EncodeToBytes()
assert.Nil(t, err)
header.Extra = extraBytes
header.Number.Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(101))
header.Number.Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(101))
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err)
assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header)
parentBlockInfo = &utils.BlockInfo{
Hash: header.ParentHash,
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 1,
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(100)),
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(100)),
}
quorumCert = &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Expand All @@ -166,7 +166,7 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
extraBytes, err = extra.EncodeToBytes()
assert.Nil(t, err)
header.Extra = extraBytes
header.Number.Add(blockchain.Config().XDPoS.XDPoSV2Block, big.NewInt(101))
header.Number.Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(101))
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err)
assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header)
Expand Down
10 changes: 5 additions & 5 deletions consensus/tests/test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
// Insert initial blocks
for i := 1; i <= numOfBlocks; i++ {
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", i)
roundNumber := int64(i) - chainConfig.XDPoS.XDPoSV2Block.Int64()
roundNumber := int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64()
block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn)

err = blockchain.InsertBlock(block)
Expand Down Expand Up @@ -392,7 +392,7 @@ func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, starti
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
var header *types.Header

if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.XDPoSV2Block) == 1 { // Build engine v2 compatible extra data field
if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.V2.SwitchBlock) == 1 { // Build engine v2 compatible extra data field
var extraField utils.ExtraFields_v2
var round utils.Round
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
Expand Down Expand Up @@ -435,9 +435,9 @@ func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, starti
Extra: extraInBytes,
Validator: signedHash,
}
if int64(blockNumber) == (chainConfig.XDPoS.XDPoSV2Block.Int64() + 1) { // This is the first v2 block, we need to copy the last v1 epoch master node list and inject into v2 validators
if int64(blockNumber) == (chainConfig.XDPoS.V2.SwitchBlock.Int64() + 1) { // This is the first v2 block, we need to copy the last v1 epoch master node list and inject into v2 validators
// Get last master node list from last v1 block
lastv1Block := blockchain.GetBlockByNumber(chainConfig.XDPoS.XDPoSV2Block.Uint64())
lastv1Block := blockchain.GetBlockByNumber(chainConfig.XDPoS.V2.SwitchBlock.Uint64())
masternodesFromV1LastEpoch := decodeMasternodesFromHeaderExtra(lastv1Block.Header())
for _, v := range masternodesFromV1LastEpoch {
header.Validators = append(header.Validators, v[:]...)
Expand All @@ -454,7 +454,7 @@ func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, starti
}

// Inject the hardcoded master node list for the last v1 epoch block
if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.XDPoSV2Block) == 0 {
if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.V2.SwitchBlock) == 0 {
// reset extra
header.Extra = []byte{}
if len(header.Extra) < utils.ExtraVanity {
Expand Down
Loading

0 comments on commit 4424c7d

Please sign in to comment.