From 6283a319ed4ffc33748e36ff50348b4648cde6aa Mon Sep 17 00:00:00 2001 From: frozen <355847+Frozen@users.noreply.github.com> Date: Mon, 5 Sep 2022 19:39:49 +0700 Subject: [PATCH] consensus check is forked --- api/service/explorer/service.go | 6 ++-- consensus/consensus.go | 2 -- consensus/consensus_service.go | 14 -------- consensus/consensus_v2.go | 61 ++++++++++++++++++++++++--------- internal/params/config.go | 11 ++++++ 5 files changed, 58 insertions(+), 36 deletions(-) diff --git a/api/service/explorer/service.go b/api/service/explorer/service.go index d96c1bc56..5887bb3a0 100644 --- a/api/service/explorer/service.go +++ b/api/service/explorer/service.go @@ -223,9 +223,9 @@ func (s *Service) GetBlocks(w http.ResponseWriter, r *http.Request) { for i := cur; i > 0; i-- { block := s.blockchain.GetBlockByNumber(i) - w.Write([]byte(fmt.Sprintf("%d ", i))) - w.Write([]byte(fmt.Sprintf("%s ", block.Header().ViewID().String()))) - w.Write([]byte(fmt.Sprintf("%s ", block.Header().Coinbase().Hash().Hex()))) + w.Write([]byte(fmt.Sprintf("#%d ", i))) + w.Write([]byte(fmt.Sprintf("v%s ", block.Header().ViewID().String()))) + w.Write([]byte(fmt.Sprintf("e%d ", block.Header().Epoch().Uint64()))) w.Write([]byte(fmt.Sprintf("%s\n", block.Header().Coinbase().Hex()))) } } diff --git a/consensus/consensus.go b/consensus/consensus.go index 0c51d648c..e0e096e30 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -73,8 +73,6 @@ type Consensus struct { priKey multibls.PrivateKeys // the publickey of leader LeaderPubKey *bls.PublicKeyWrapper - // index of leader in the list of validators. - LeaderIndex int // blockNum: the next blockNumber that FBFT is going to agree on, // should be equal to the blockNumber of next block blockNum uint64 diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index e646504dd..d26ea8ced 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -474,20 +474,6 @@ func (consensus *Consensus) SetCurBlockViewID(viewID uint64) uint64 { return consensus.current.SetCurBlockViewID(viewID) } -// SetLeaderIndex set the leader index. -func (consensus *Consensus) SetLeaderIndex(f func(int) int) (current int) { - consensus.pubKeyLock.Lock() - defer consensus.pubKeyLock.Unlock() - consensus.LeaderIndex = f(consensus.LeaderIndex) - return consensus.LeaderIndex -} - -func (consensus *Consensus) GetLeaderIndex() int { - consensus.pubKeyLock.Lock() - defer consensus.pubKeyLock.Unlock() - return consensus.LeaderIndex -} - // SetViewChangingID set the current view change ID func (consensus *Consensus) SetViewChangingID(viewID uint64) { consensus.current.SetViewChangingID(viewID) diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index bf042c62d..d92a41783 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -737,25 +737,41 @@ func (consensus *Consensus) SetupForNewConsensus(blk *types.Block, committedMsg atomic.StoreUint64(&consensus.blockNum, blk.NumberU64()+1) curBlockViewID := consensus.SetCurBlockViewID(committedMsg.ViewID + 1) // first view id is going to be 2. prev := consensus.GetLeaderPubKey() - idx := consensus.SetLeaderIndex(func(i int) int { - if curBlockViewID%3 == 0 { - return i + 1 + if consensus.Blockchain.Config().IsLeaderRotation(blk.Epoch()) { + epochBlockViewID, err := consensus.getEpochFirstBlockViewID(blk.Epoch()) + if err != nil { + consensus.getLogger().Error().Err(err).Msgf("[SetupForNewConsensus] Failed to get epoch block viewID for epoch %d", blk.Epoch().Uint64()) + return + } + if epochBlockViewID > curBlockViewID { + consensus.getLogger().Error().Msg("[SetupForNewConsensus] Epoch block viewID is greater than current block viewID") + return } - return i - }) - pps := consensus.Decider.Participants() - consensus.pubKeyLock.Lock() - consensus.LeaderPubKey = &pps[idx%len(pps)] - fmt.Printf("SetupForNewConsensus :%d idx: %d future v%d new: %s prev: %s %q\n", utils.GetPort(), idx, curBlockViewID, consensus.LeaderPubKey.Bytes.Hex(), prev.Bytes.Hex(), consensus.isLeader()) - consensus.pubKeyLock.Unlock() - if consensus.IsLeader() && !consensus.GetLeaderPubKey().Object.IsEqual(prev.Object) { - // leader changed - go func() { - fmt.Printf("ReadySignal :%d for leader %s\n", utils.GetPort(), consensus.GetLeaderPubKey().Bytes.Hex()) - defer fmt.Printf("Defer ReadySignal :%d for leader %s\n", utils.GetPort(), consensus.GetLeaderPubKey().Bytes.Hex()) - consensus.ReadySignal <- SyncProposal - }() + diff := curBlockViewID - epochBlockViewID + + pps := consensus.Decider.Participants() + idx := (int(diff) / 3) % len(pps) + consensus.pubKeyLock.Lock() + fmt.Println("(int(diff)/3)%len(pps) == ", idx) + consensus.LeaderPubKey = &pps[idx] + fmt.Printf("SetupForNewConsensus :%d idx: %d future v%d new: %s prev: %s %v\n", utils.GetPort(), idx, curBlockViewID, consensus.LeaderPubKey.Bytes.Hex(), prev.Bytes.Hex(), consensus.isLeader()) + consensus.pubKeyLock.Unlock() + if consensus.IsLeader() && !consensus.GetLeaderPubKey().Object.IsEqual(prev.Object) { + // leader changed + go func() { + fmt.Printf("ReadySignal :%d for leader %s\n", utils.GetPort(), consensus.GetLeaderPubKey().Bytes.Hex()) + defer fmt.Printf("Defer ReadySignal :%d for leader %s\n", utils.GetPort(), consensus.GetLeaderPubKey().Bytes.Hex()) + consensus.ReadySignal <- SyncProposal + + }() + } + } else { + fmt.Printf("SetupForNewConsensus0 :%d future v%d new: %s prev: %s %v\n", utils.GetPort(), curBlockViewID, consensus.LeaderPubKey.Bytes.Hex(), prev.Bytes.Hex(), consensus.isLeader()) + consensus.pubKeyLock.Lock() + consensus.LeaderPubKey = committedMsg.SenderPubkeys[0] + consensus.pubKeyLock.Unlock() + } } var epoch *big.Int @@ -776,6 +792,17 @@ func (consensus *Consensus) SetupForNewConsensus(blk *types.Block, committedMsg consensus.ResetState() } +func (consensus *Consensus) getEpochFirstBlockViewID(epoch *big.Int) (uint64, error) { + if epoch.Uint64() == 0 { + return 0, nil + } + epochBlock := consensus.Blockchain.GetBlockByNumber(epoch.Uint64() - 1) + if epochBlock == nil { + return 0, errors.Errorf("block not found for number %d", epoch.Uint64()-1) + } + return epochBlock.Header().ViewID().Uint64() + 1, nil +} + func (consensus *Consensus) postCatchup(initBN uint64) { if initBN < consensus.BlockNum() { consensus.getLogger().Info(). diff --git a/internal/params/config.go b/internal/params/config.go index c11daeafb..29af19c74 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -271,6 +271,8 @@ var ( SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 CrossShardXferPrecompileEpoch: big.NewInt(1), AllowlistEpoch: EpochTBD, + LeaderRotationEpoch: big.NewInt(1), + TesnetNinetyPercentEpoch: EpochTBD, FeeCollectEpoch: big.NewInt(5), LeaderRotationEpoch: EpochTBD, LeaderRotationBlocksCount: 5, @@ -315,6 +317,7 @@ var ( big.NewInt(0), // AllowlistEpoch big.NewInt(1), // LeaderRotationEpoch 64, // LeaderRotationBlocksCount + big.NewInt(1), // LeaderRotationEpoch big.NewInt(0), // FeeCollectEpoch } @@ -711,6 +714,14 @@ func (c *ChainConfig) IsLeaderRotation(epoch *big.Int) bool { return isForked(c.LeaderRotationEpoch, epoch) } +func (c *ChainConfig) IsLeaderRotation(epoch *big.Int) bool { + return isForked(c.LeaderRotationEpoch, epoch) +} + +func (c *ChainConfig) IsTestnetNinetyPercent(epoch *big.Int) bool { + return isForked(c.TesnetNinetyPercentEpoch, epoch) && c == TestnetChainConfig +} + // IsFeeCollectEpoch determines whether Txn Fees will be collected into the community-managed account. func (c *ChainConfig) IsFeeCollectEpoch(epoch *big.Int) bool { return isForked(c.FeeCollectEpoch, epoch)