[viewchange] only rotate leader among harmony nodes

Signed-off-by: Leo Chen <leo@harmony.one>
pull/3386/head
Leo Chen 4 years ago
parent 45a7823ede
commit e8a8b6f543
  1. 26
      consensus/quorum/quorum.go
  2. 11
      consensus/view_change.go

@ -10,6 +10,7 @@ import (
bls_core "github.com/harmony-one/bls/ffi/go/bls" bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/votepower" "github.com/harmony-one/harmony/consensus/votepower"
bls_cosi "github.com/harmony-one/harmony/crypto/bls" bls_cosi "github.com/harmony-one/harmony/crypto/bls"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
"github.com/harmony-one/harmony/multibls" "github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
@ -73,6 +74,7 @@ type ParticipantTracker interface {
IndexOf(bls.SerializedPublicKey) int IndexOf(bls.SerializedPublicKey) int
ParticipantsCount() int64 ParticipantsCount() int64
NthNext(*bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) NthNext(*bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper)
NthNextHmy(shardingconfig.Instance, *bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper)
UpdateParticipants(pubKeys []bls.PublicKeyWrapper) UpdateParticipants(pubKeys []bls.PublicKeyWrapper)
} }
@ -214,7 +216,29 @@ func (s *cIdentities) NthNext(pubKey *bls.PublicKeyWrapper, next int) (bool, *bl
if idx != -1 { if idx != -1 {
found = true found = true
} }
idx = (idx + next) % int(s.ParticipantsCount()) numNodes := int(s.ParticipantsCount())
// sanity check to avoid out of bound access
if numNodes <= 0 || numNodes > len(s.publicKeys) {
numNodes = len(s.publicKeys)
}
idx = (idx + next) % numNodes
return found, &s.publicKeys[idx]
}
// NthNextHmy return the Nth next pubkey of Harmony nodes, next can be negative number
func (s *cIdentities) NthNextHmy(instance shardingconfig.Instance, pubKey *bls.PublicKeyWrapper, next int) (bool, *bls.PublicKeyWrapper) {
found := false
idx := s.IndexOf(pubKey.Bytes)
if idx != -1 {
found = true
}
numNodes := instance.NumHarmonyOperatedNodesPerShard()
// sanity check to avoid out of bound access
if numNodes <= 0 || numNodes > len(s.publicKeys) {
numNodes = len(s.publicKeys)
}
idx = (idx + next) % numNodes
return found, &s.publicKeys[idx] return found, &s.publicKeys[idx]
} }

@ -1,6 +1,7 @@
package consensus package consensus
import ( import (
"math/big"
"sync" "sync"
"time" "time"
@ -13,6 +14,7 @@ import (
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/shard"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -159,6 +161,7 @@ func (consensus *Consensus) getNextLeaderKey(viewID uint64) *bls.PublicKeyWrappe
} }
var lastLeaderPubKey *bls.PublicKeyWrapper var lastLeaderPubKey *bls.PublicKeyWrapper
var err error var err error
epoch := big.NewInt(0)
if consensus.ChainReader == nil { if consensus.ChainReader == nil {
consensus.getLogger().Error().Msg("[getNextLeaderKey] ChainReader is nil. Use consensus.LeaderPubKey") consensus.getLogger().Error().Msg("[getNextLeaderKey] ChainReader is nil. Use consensus.LeaderPubKey")
lastLeaderPubKey = consensus.LeaderPubKey lastLeaderPubKey = consensus.LeaderPubKey
@ -175,6 +178,7 @@ func (consensus *Consensus) getNextLeaderKey(viewID uint64) *bls.PublicKeyWrappe
Msg("[getNextLeaderKey] Unable to get leaderPubKey from coinbase. Set it to consensus.LeaderPubKey") Msg("[getNextLeaderKey] Unable to get leaderPubKey from coinbase. Set it to consensus.LeaderPubKey")
lastLeaderPubKey = consensus.LeaderPubKey lastLeaderPubKey = consensus.LeaderPubKey
} }
epoch = curHeader.Epoch()
// viewchange happened at the first block of new epoch // viewchange happened at the first block of new epoch
// use the LeaderPubKey as the base of the next leader // use the LeaderPubKey as the base of the next leader
// as we shouldn't use lastLeader from coinbase as the base. // as we shouldn't use lastLeader from coinbase as the base.
@ -192,7 +196,12 @@ func (consensus *Consensus) getNextLeaderKey(viewID uint64) *bls.PublicKeyWrappe
Uint64("newViewID", viewID). Uint64("newViewID", viewID).
Uint64("myCurBlockViewID", consensus.GetCurBlockViewID()). Uint64("myCurBlockViewID", consensus.GetCurBlockViewID()).
Msg("[getNextLeaderKey] got leaderPubKey from coinbase") Msg("[getNextLeaderKey] got leaderPubKey from coinbase")
wasFound, next := consensus.Decider.NthNext(lastLeaderPubKey, gap) // wasFound, next := consensus.Decider.NthNext(lastLeaderPubKey, gap)
// FIXME: rotate leader on harmony nodes only before fully externalization
wasFound, next := consensus.Decider.NthNextHmy(
shard.Schedule.InstanceForEpoch(epoch),
lastLeaderPubKey,
gap)
if !wasFound { if !wasFound {
consensus.getLogger().Warn(). consensus.getLogger().Warn().
Str("key", consensus.LeaderPubKey.Bytes.Hex()). Str("key", consensus.LeaderPubKey.Bytes.Hex()).

Loading…
Cancel
Save