add ProcessQC implementation

This commit is contained in:
Jianrong 2021-11-22 20:43:24 +11:00
parent b9068974f5
commit bd60e1b0cf
3 changed files with 36 additions and 26 deletions

View file

@ -35,7 +35,7 @@ type XDPoS_v2 struct {
currentRound utils.Round currentRound utils.Round
highestVotedRound utils.Round highestVotedRound utils.Round
highestQuorumCert *utils.QuorumCert highestQuorumCert *utils.QuorumCert
// LockQC in XDPoS Consensus 2.0, used in voting rule // lockQuorumCert in XDPoS Consensus 2.0, used in voting rule
lockQuorumCert *utils.QuorumCert lockQuorumCert *utils.QuorumCert
highestTimeoutCert *utils.TimeoutCert highestTimeoutCert *utils.TimeoutCert
highestCommitBlock *utils.BlockInfo highestCommitBlock *utils.BlockInfo
@ -79,6 +79,8 @@ func (x *XDPoS_v2) SetNewRoundFaker(newRound utils.Round, resetTimer bool) {
// Utils for test to check currentRound value // Utils for test to check currentRound value
func (x *XDPoS_v2) GetCurrentRound() utils.Round { func (x *XDPoS_v2) GetCurrentRound() utils.Round {
x.lock.Lock()
defer x.lock.Unlock()
return x.currentRound return x.currentRound
} }
@ -307,22 +309,27 @@ func (x *XDPoS_v2) verifyTC(timeoutCert *utils.TimeoutCert) error {
return nil return nil
} }
// Update local QC variables including highestQC & lockQC, as well as update commit blockInfo before call // Update local QC variables including highestQC & lockQuorumCert, as well as update commit blockInfo before call
/* func (x *XDPoS_v2) processQC(blockCahinReader consensus.ChainReader, quorumCert *utils.QuorumCert) error {
1. Update HighestQC and LockQC // 1. Update HighestQC
2. Update commit block info (TODO)
3. Check QC round >= node's currentRound. If yes, call setNewRound
*/
func (x *XDPoS_v2) processQC(quorumCert *utils.QuorumCert) error {
if x.highestQuorumCert == nil || quorumCert.ProposedBlockInfo.Round > x.highestQuorumCert.ProposedBlockInfo.Round { if x.highestQuorumCert == nil || quorumCert.ProposedBlockInfo.Round > x.highestQuorumCert.ProposedBlockInfo.Round {
x.highestQuorumCert = quorumCert
//TODO: do I need a clone? //TODO: do I need a clone?
x.highestQuorumCert = quorumCert
} }
//TODO: x.blockchain.getBlock(quorumCert.ProposedBlockInfo.Hash) then get the QC inside that block header // 2. Get QC from header and update lockQuorumCert
//TODO: update lockQC proposedBlockHeader := blockCahinReader.GetHeaderByHash(quorumCert.ProposedBlockInfo.Hash)
var decodedExtraField utils.ExtraFields_v2
utils.DecodeBytesExtraFields(proposedBlockHeader.Extra, &decodedExtraField)
x.lockQuorumCert = &decodedExtraField.QuorumCert
// 3. Update commit block info
//TODO: find parent and grandparent and grandgrandparent block, check round number, if so, commit grandgrandparent //TODO: find parent and grandparent and grandgrandparent block, check round number, if so, commit grandgrandparent
if quorumCert.ProposedBlockInfo.Round >= x.currentRound { if quorumCert.ProposedBlockInfo.Round >= x.currentRound {
x.setNewRound(quorumCert.ProposedBlockInfo.Round + 1) err := x.setNewRound(quorumCert.ProposedBlockInfo.Round + 1)
if err != nil {
return err
}
} }
return nil return nil
} }
@ -364,8 +371,8 @@ func (x *XDPoS_v2) verifyVotingRule(header *types.Header) error {
Make sure this node has not voted for this round. We can have a variable highestVotedRound, and check currentRound > highestVotedRound. Make sure this node has not voted for this round. We can have a variable highestVotedRound, and check currentRound > highestVotedRound.
HotStuff Voting rule: HotStuff Voting rule:
header's round == local current round, AND (one of the following two:) header's round == local current round, AND (one of the following two:)
header's block extends LockQC's ProposedBlockInfo (we need a isExtending(block_a, block_b) function), OR header's block extends lockQuorumCert's ProposedBlockInfo (we need a isExtending(block_a, block_b) function), OR
header's QC's ProposedBlockInfo.Round > LockQC's ProposedBlockInfo.Round header's QC's ProposedBlockInfo.Round > lockQuorumCert's ProposedBlockInfo.Round
*/ */
return nil return nil
} }

View file

@ -4,6 +4,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
) )
@ -18,10 +19,11 @@ type broadcastTimeoutFn func(*utils.Timeout)
type broadcastSyncInfoFn func(*utils.SyncInfo) type broadcastSyncInfoFn func(*utils.SyncInfo)
type Bfter struct { type Bfter struct {
broadcastCh chan interface{} blockCahinReader *core.BlockChain
quit chan struct{} broadcastCh chan interface{}
consensus ConsensusFns quit chan struct{}
broadcast BroadcastFns consensus ConsensusFns
broadcast BroadcastFns
// Message Cache // Message Cache
knownVotes *lru.ARCCache knownVotes *lru.ARCCache
@ -46,17 +48,18 @@ type BroadcastFns struct {
SyncInfo broadcastSyncInfoFn SyncInfo broadcastSyncInfoFn
} }
func New(broadcasts BroadcastFns) *Bfter { func New(broadcasts BroadcastFns, blockCahinReader *core.BlockChain) *Bfter {
knownVotes, _ := lru.NewARC(messageLimit) knownVotes, _ := lru.NewARC(messageLimit)
knownSyncInfos, _ := lru.NewARC(messageLimit) knownSyncInfos, _ := lru.NewARC(messageLimit)
knownTimeouts, _ := lru.NewARC(messageLimit) knownTimeouts, _ := lru.NewARC(messageLimit)
return &Bfter{ return &Bfter{
quit: make(chan struct{}), quit: make(chan struct{}),
broadcastCh: make(chan interface{}), broadcastCh: make(chan interface{}),
broadcast: broadcasts, broadcast: broadcasts,
knownVotes: knownVotes, knownVotes: knownVotes,
knownSyncInfos: knownSyncInfos, knownSyncInfos: knownSyncInfos,
knownTimeouts: knownTimeouts, knownTimeouts: knownTimeouts,
blockCahinReader: blockCahinReader,
} }
} }

View file

@ -227,7 +227,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
Timeout: manager.BroadcastTimeout, Timeout: manager.BroadcastTimeout,
SyncInfo: manager.BroadcastSyncInfo, SyncInfo: manager.BroadcastSyncInfo,
} }
manager.bfter = bfter.New(broadcasts) manager.bfter = bfter.New(broadcasts, blockchain)
if blockchain.Config().XDPoS != nil { if blockchain.Config().XDPoS != nil {
manager.bfter.SetConsensusFuns(engine) manager.bfter.SetConsensusFuns(engine)
} }