Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release br v2.4.6 beta1 merge back to dev upgrade #778

Merged
merged 21 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
70a3e88
fix: reduce mine period reset (waiting) time (#735)
wgr523 Nov 19, 2024
5726606
update version
Nov 19, 2024
100ce5c
bug fix for count vote threshold
Nov 22, 2024
2172918
increate timeout to 1 min for testnet
Nov 23, 2024
c26c9aa
Merge pull request #744 from XinFinOrg/increate-timeout-to-1-min-for-…
AnilChinchawale Nov 23, 2024
8556473
feat: reduce wait time when block time already large
wgr523 Dec 3, 2024
1b89654
feat: add a new round chan between consensus and miner
wgr523 Dec 4, 2024
89256cb
Use safe timer reset method (#757)
benjamin202410 Dec 9, 2024
ba5abba
Merge pull request #753 from XinFinOrg/gerui-master-reduce_mine_reset_2
benjamin202410 Dec 13, 2024
383e2d5
Merge branch 'master' into release-br-v2.4.3-beta1
Dec 13, 2024
92d239b
merge from master
Dec 13, 2024
c98f42c
Merge branch 'release-br-v2.4.2-beta1' into release-br-v2.4.3-beta1
Dec 13, 2024
7833117
cherry pick vote test fix
benjamin202410 Nov 29, 2024
e1ab3e0
add buffer channel to unlock deadlock (#766)
benjamin202410 Dec 19, 2024
50f4013
remove normal log
Dec 20, 2024
00785b0
fix tc cross epoch different masternode counts issue
Dec 23, 2024
25462bd
fix tc cross epoch different masternode counts issue
Dec 23, 2024
b2a41af
Merge pull request #770 from XinFinOrg/fix-tc-cross-epoch-different-m…
AnilChinchawale Dec 23, 2024
332380c
fix only timeout round exists in next epoch (#772)
benjamin202410 Dec 24, 2024
c8aae5e
Get right tc epoch (#773)
benjamin202410 Dec 24, 2024
77f9cc5
merge from dev-upgrade
Dec 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ jobs:
script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[d-i].*")
- name: J-N tests
script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[j-n].*")
- name: O-R tests
script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[o-r].*")
- name: S tests
script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/s.*")
- name: O-S tests
script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[o-s].*")
- name: T-Z tests
script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[t-z].*")
steps:
Expand Down
3 changes: 1 addition & 2 deletions consensus/XDPoS/engines/engine_v2/epochSwitch.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
log.Debug("[getEpochSwitchInfo] header doesn't provide, get header by hash", "hash", hash.Hex())
h = chain.GetHeaderByHash(hash)
if h == nil {
log.Warn("[getEpochSwitchInfo] can not find header from db", "hash", hash.Hex())
return nil, fmt.Errorf("[getEpochSwitchInfo] can not find header from db hash %v", hash.Hex())
}
}
Expand Down Expand Up @@ -152,7 +151,7 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {
log.Info("[IsEpochSwitch] true, parent equals V2.SwitchBlock", "round", round, "number", header.Number.Uint64(), "hash", header.Hash())
return true, epochNum, nil
}
log.Debug("[IsEpochSwitch]", "is", parentRound < epochStartRound, "parentRound", parentRound, "round", round, "number", header.Number.Uint64(), "epochNum", epochNum, "hash", header.Hash())
log.Debug("[IsEpochSwitch]", "is", parentRound < epochStartRound, "parentRound", parentRound, "round", round, "number", header.Number.Uint64(), "epochNum", epochNum, "hash", header.Hash().Hex())
// if isEpochSwitch, add to cache
if parentRound < epochStartRound {
x.round2epochBlockInfo.Add(round, &types.BlockInfo{
Expand Down
43 changes: 36 additions & 7 deletions consensus/XDPoS/engines/engine_v2/timeout.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time

snap, err := x.getSnapshot(chain, timeoutCert.GapNumber, true)
if err != nil {
log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "TCGapNumber", timeoutCert.GapNumber)
log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "tcGapNumber", timeoutCert.GapNumber)
return fmt.Errorf("[verifyTC] Unable to get snapshot, %s", err)
}
if snap == nil || len(snap.NextEpochCandidates) == 0 {
Expand All @@ -110,15 +110,42 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time
}
}

epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash())
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, (chain.CurrentHeader()), (chain.CurrentHeader()).Hash())
if err != nil {
log.Error("[verifyTC] Error when getting epoch switch Info", "error", err)
log.Error("[verifyTC] Error when getting epoch switch info", "error", err)
return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err)
}

epochRound := epochSwitchInfo.EpochSwitchBlockInfo.Round
tempTCEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochRound)/x.config.Epoch

epochBlockInfo := &types.BlockInfo{
Hash: epochSwitchInfo.EpochSwitchBlockInfo.Hash,
Round: epochRound,
Number: epochSwitchInfo.EpochSwitchBlockInfo.Number,
}
log.Info("[verifyTC] Init epochInfo", "number", epochBlockInfo.Number, "round", epochRound, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch)
for epochBlockInfo.Round > timeoutCert.Round {
tempTCEpoch--
epochBlockInfo, err = x.GetBlockByEpochNumber(chain, tempTCEpoch)
if err != nil {
log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err)
return fmt.Errorf("fail on verifyTC due to failure in getting epoch block info tc round, %s", err)
}
log.Debug("[verifyTC] Loop to get right epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch)
}
tcEpoch := tempTCEpoch
log.Info("[verifyTC] Final TC epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tcEpoch)

epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash)
if err != nil {
log.Error("[verifyTC] Error when getting epoch switch info", "error", err)
return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err)
}

certThreshold := x.config.V2.Config(uint64(timeoutCert.Round)).CertThreshold
if float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold {
log.Warn("[verifyTC] Invalid TC Signature is nil or empty", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(timeoutCert.Signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold)
log.Warn("[verifyTC] Invalid TC Signature is less or empty", "tcRound", timeoutCert.Round, "tcGapNumber", timeoutCert.GapNumber, "tcSignLen", len(timeoutCert.Signatures), "certThreshold", float64(epochInfo.MasternodesLen)*certThreshold)
return utils.ErrInvalidTCSignatures
}

Expand All @@ -138,14 +165,14 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time
defer wg.Done()
verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochCandidates)
if err != nil || !verified {
log.Error("[verifyTC] Error or verification failure", "Signature", sig, "Error", err)
log.Error("[verifyTC] Error or verification failure", "signature", sig, "error", err)
mutex.Lock() // Lock before accessing haveError
if haveError == nil {
if err != nil {
log.Error("[verifyTC] Error while verfying TC message signatures", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures), "Error", err)
log.Error("[verifyTC] Error while verfying TC message signatures", "tcRound", timeoutCert.Round, "tcGapNumber", timeoutCert.GapNumber, "tcSignLen", len(signatures), "error", err)
haveError = fmt.Errorf("error while verifying TC message signatures, %s", err)
} else {
log.Warn("[verifyTC] Signature not verified doing TC verification", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures))
log.Warn("[verifyTC] Signature not verified doing TC verification", "tcRound", timeoutCert.Round, "tcGapNumber", timeoutCert.GapNumber, "tcSignLen", len(signatures))
haveError = errors.New("fail to verify TC due to signature mis-match")
}
}
Expand Down Expand Up @@ -219,6 +246,8 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error {
Signature: signedHash,
GapNumber: gapNumber,
}

timeoutMsg.SetSigner(x.signer)
log.Warn("[sendTimeout] Timeout message generated, ready to send!", "timeoutMsgRound", timeoutMsg.Round, "timeoutMsgGapNumber", timeoutMsg.GapNumber, "whosTurn", x.whosTurn)
err = x.timeoutHandler(chain, timeoutMsg)
if err != nil {
Expand Down
175 changes: 175 additions & 0 deletions consensus/tests/engine_v2_tests/sync_info_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package engine_v2_tests

import (
"fmt"
"math/big"
"testing"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types"
Expand Down Expand Up @@ -100,3 +102,176 @@ func TestSkipVerifySyncInfoIfBothQcTcNotQualified(t *testing.T) {
assert.False(t, verified)
assert.Nil(t, err)
}

func TestVerifySyncInfoIfTCRoundIsAtNextEpoch(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2

// Make the Highest QC in syncInfo point to an old block to simulate it's no longer qualified
parentBlock := blockchain.GetBlockByNumber(903)
var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField)
if err != nil {
t.Fatal("Fail to decode extra data", err)
}

highestTC := &types.TimeoutCert{
Round: types.Round(899),
Signatures: []types.Signature{},
}

timeoutForSign := &types.TimeoutForSign{
Round: types.Round(900),
GapNumber: 450,
}

// Sign from acc 1, 2, 3 and voter
acc1SignedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(timeoutForSign).Bytes())
acc2SignedHash := SignHashByPK(acc2Key, types.TimeoutSigHash(timeoutForSign).Bytes())
acc3SignedHash := SignHashByPK(acc3Key, types.TimeoutSigHash(timeoutForSign).Bytes())
voterSignedHash := SignHashByPK(voterKey, types.TimeoutSigHash(timeoutForSign).Bytes())

var signatures []types.Signature
signatures = append(signatures, acc1SignedHash, acc2SignedHash, acc3SignedHash, voterSignedHash)

syncInfoTC := &types.TimeoutCert{
Round: timeoutForSign.Round,
Signatures: signatures,
GapNumber: timeoutForSign.GapNumber,
}

syncInfoMsg := &types.SyncInfo{
HighestQuorumCert: extraField.QuorumCert,
HighestTimeoutCert: syncInfoTC,
}

engineV2.SetPropertiesFaker(syncInfoMsg.HighestQuorumCert, highestTC)

verified, err := engineV2.VerifySyncInfoMessage(blockchain, syncInfoMsg)
assert.True(t, verified)
assert.Nil(t, err)
}

func TestVerifySyncInfoIfTcUseDifferentEpoch(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 1349, config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
x := adaptor.EngineV2

// Insert block 1350
t.Logf("Inserting block with propose at 1350...")
blockCoinbaseA := "0xaaa0000000000000000000000000000000001350"
// NOTE: voterAddr never exist in the Masternode list, but all acc1,2,3 already does
tx, err := voteTX(37117, 0, signer.String())
if err != nil {
t.Fatal(err)
}
//Get from block validator error message
merkleRoot := "8a355a8636d1aae24d5a63df0318534e09110891d6ab7bf20587da64725083be"
header := &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(1350)),
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}

header.Extra = generateV2Extra(450, currentBlock, signer, signFn, nil)

parentBlock, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx}, signer, signFn, config)
assert.Nil(t, err)
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)
t.Logf("Inserting block from 1351 to 1799...")
for i := 1351; i <= 1799; i++ {
blockCoinbase := fmt.Sprintf("0xaaa000000000000000000000000000000000%4d", i)
//Get from block validator error message
header = &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(i)),
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbase),
}

header.Extra = generateV2Extra(int64(i)-900, parentBlock, signer, signFn, nil)

block, err := createBlockFromHeader(blockchain, header, nil, signer, signFn, config)
if err != nil {
t.Fatal(err)
}
err = blockchain.InsertBlock(block)
assert.Nil(t, err)
parentBlock = block
}
t.Logf("build epoch block with new set of masternodes")
blockCoinbase := fmt.Sprintf("0xaaa0000000000000000000000000000000001800")
//Get from block validator error message
header = &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(1800)),
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbase),
}

header.Extra = generateV2Extra(900, parentBlock, signer, signFn, nil)
validators := []byte{}

snap, err := x.GetSnapshot(blockchain, parentBlock.Header())
assert.Nil(t, err)

for _, v := range snap.NextEpochCandidates {
validators = append(validators, v[:]...)
}
// set up 1 more masternode to make it difference
validators = append(validators, voterAddr[:]...)
header.Validators = validators
block, err := createBlockFromHeader(blockchain, header, nil, signer, signFn, config)
if err != nil {
t.Fatal(err)
}
err = blockchain.InsertBlock(block)
assert.Nil(t, err)
parentBlock = block

var extraField types.ExtraFields_v2
err = utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField)
if err != nil {
t.Fatal("Fail to decode extra data", err)
}

timeoutForSign := &types.TimeoutForSign{
Round: types.Round(899),
GapNumber: 450,
}

// Sign from acc 1, 2, 3 and voter
acc1SignedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(timeoutForSign).Bytes())
acc2SignedHash := SignHashByPK(acc2Key, types.TimeoutSigHash(timeoutForSign).Bytes())
acc3SignedHash := SignHashByPK(acc3Key, types.TimeoutSigHash(timeoutForSign).Bytes())
voterSignedHash := SignHashByPK(voterKey, types.TimeoutSigHash(timeoutForSign).Bytes())

var signatures []types.Signature
signatures = append(signatures, acc1SignedHash, acc2SignedHash, acc3SignedHash, voterSignedHash)

newTC := &types.TimeoutCert{
Round: timeoutForSign.Round,
Signatures: signatures,
GapNumber: timeoutForSign.GapNumber,
}

syncInfoMsg := &types.SyncInfo{
HighestQuorumCert: extraField.QuorumCert,
HighestTimeoutCert: newTC,
}

x.SetPropertiesFaker(syncInfoMsg.HighestQuorumCert, &types.TimeoutCert{
Round: types.Round(898),
Signatures: []types.Signature{},
})

verified, err := x.VerifySyncInfoMessage(blockchain, syncInfoMsg)
assert.True(t, verified)
assert.Nil(t, err)
}
6 changes: 3 additions & 3 deletions core/types/consensus_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type BlockInfo struct {

// Vote message in XDPoS 2.0
type Vote struct {
signer common.Address //field not exported
signer common.Address //field not exported
ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"`
Signature Signature `json:"signature"`
GapNumber uint64 `json:"gapNumber"`
Expand Down Expand Up @@ -81,9 +81,9 @@ func (s *SyncInfo) Hash() common.Hash {

// Quorum Certificate struct in XDPoS 2.0
type QuorumCert struct {
ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"`
ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"`
Signatures []Signature `json:"signatures"`
GapNumber uint64 `json:"gapNumber"`
GapNumber uint64 `json:"gapNumber"`
}

// Timeout Certificate struct in XDPoS 2.0
Expand Down
4 changes: 2 additions & 2 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ var (
SwitchRound: 0,
CertThreshold: 0.45,
TimeoutSyncThreshold: 3,
TimeoutPeriod: 20,
TimeoutPeriod: 60,
MinePeriod: 2,
},
900000: {
MaxMasternodes: 108,
SwitchRound: 900000,
CertThreshold: 0.667,
TimeoutSyncThreshold: 3,
TimeoutPeriod: 30,
TimeoutPeriod: 60,
MinePeriod: 2,
},
}
Expand Down
8 changes: 4 additions & 4 deletions params/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import (
)

const (
VersionMajor = 2 // Major version component of the current release
VersionMinor = 3 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release
VersionMeta = "stable" // Version metadata to append to the version string
VersionMajor = 2 // Major version component of the current release
VersionMinor = 4 // Minor version component of the current release
VersionPatch = 6 // Patch version component of the current release
VersionMeta = "beta1" // Version metadata to append to the version string
)

// Version holds the textual version string.
Expand Down
Loading