mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
add ProcessQC implementation
This commit is contained in:
parent
b9068974f5
commit
bd60e1b0cf
3 changed files with 36 additions and 26 deletions
|
|
@ -35,7 +35,7 @@ type XDPoS_v2 struct {
|
|||
currentRound utils.Round
|
||||
highestVotedRound utils.Round
|
||||
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
|
||||
highestTimeoutCert *utils.TimeoutCert
|
||||
highestCommitBlock *utils.BlockInfo
|
||||
|
|
@ -79,6 +79,8 @@ func (x *XDPoS_v2) SetNewRoundFaker(newRound utils.Round, resetTimer bool) {
|
|||
|
||||
// Utils for test to check currentRound value
|
||||
func (x *XDPoS_v2) GetCurrentRound() utils.Round {
|
||||
x.lock.Lock()
|
||||
defer x.lock.Unlock()
|
||||
return x.currentRound
|
||||
}
|
||||
|
||||
|
|
@ -307,22 +309,27 @@ func (x *XDPoS_v2) verifyTC(timeoutCert *utils.TimeoutCert) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Update local QC variables including highestQC & lockQC, as well as update commit blockInfo before call
|
||||
/*
|
||||
1. Update HighestQC and LockQC
|
||||
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 {
|
||||
// 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
|
||||
if x.highestQuorumCert == nil || quorumCert.ProposedBlockInfo.Round > x.highestQuorumCert.ProposedBlockInfo.Round {
|
||||
x.highestQuorumCert = quorumCert
|
||||
//TODO: do I need a clone?
|
||||
x.highestQuorumCert = quorumCert
|
||||
}
|
||||
//TODO: x.blockchain.getBlock(quorumCert.ProposedBlockInfo.Hash) then get the QC inside that block header
|
||||
//TODO: update lockQC
|
||||
// 2. Get QC from header and update lockQuorumCert
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
|
@ -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.
|
||||
HotStuff Voting rule:
|
||||
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 QC's ProposedBlockInfo.Round > LockQC's ProposedBlockInfo.Round
|
||||
header's block extends lockQuorumCert's ProposedBlockInfo (we need a isExtending(block_a, block_b) function), OR
|
||||
header's QC's ProposedBlockInfo.Round > lockQuorumCert's ProposedBlockInfo.Round
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
)
|
||||
|
|
@ -18,10 +19,11 @@ type broadcastTimeoutFn func(*utils.Timeout)
|
|||
type broadcastSyncInfoFn func(*utils.SyncInfo)
|
||||
|
||||
type Bfter struct {
|
||||
broadcastCh chan interface{}
|
||||
quit chan struct{}
|
||||
consensus ConsensusFns
|
||||
broadcast BroadcastFns
|
||||
blockCahinReader *core.BlockChain
|
||||
broadcastCh chan interface{}
|
||||
quit chan struct{}
|
||||
consensus ConsensusFns
|
||||
broadcast BroadcastFns
|
||||
|
||||
// Message Cache
|
||||
knownVotes *lru.ARCCache
|
||||
|
|
@ -46,17 +48,18 @@ type BroadcastFns struct {
|
|||
SyncInfo broadcastSyncInfoFn
|
||||
}
|
||||
|
||||
func New(broadcasts BroadcastFns) *Bfter {
|
||||
func New(broadcasts BroadcastFns, blockCahinReader *core.BlockChain) *Bfter {
|
||||
knownVotes, _ := lru.NewARC(messageLimit)
|
||||
knownSyncInfos, _ := lru.NewARC(messageLimit)
|
||||
knownTimeouts, _ := lru.NewARC(messageLimit)
|
||||
return &Bfter{
|
||||
quit: make(chan struct{}),
|
||||
broadcastCh: make(chan interface{}),
|
||||
broadcast: broadcasts,
|
||||
knownVotes: knownVotes,
|
||||
knownSyncInfos: knownSyncInfos,
|
||||
knownTimeouts: knownTimeouts,
|
||||
quit: make(chan struct{}),
|
||||
broadcastCh: make(chan interface{}),
|
||||
broadcast: broadcasts,
|
||||
knownVotes: knownVotes,
|
||||
knownSyncInfos: knownSyncInfos,
|
||||
knownTimeouts: knownTimeouts,
|
||||
blockCahinReader: blockCahinReader,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
|||
Timeout: manager.BroadcastTimeout,
|
||||
SyncInfo: manager.BroadcastSyncInfo,
|
||||
}
|
||||
manager.bfter = bfter.New(broadcasts)
|
||||
manager.bfter = bfter.New(broadcasts, blockchain)
|
||||
if blockchain.Config().XDPoS != nil {
|
||||
manager.bfter.SetConsensusFuns(engine)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue