diff --git a/consensus/consensus.go b/consensus/consensus.go index a6f3eb1d7..914e4d7c5 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -45,6 +45,9 @@ type Consensus struct { // How long to delay sending commit messages. delayCommit time.Duration + // Consensus rounds whose commit phase finished + commitFinishChan chan uint32 + // 2 types of timeouts: normal and viewchange consensusTimeout map[TimeoutType]*utils.Timeout @@ -189,6 +192,12 @@ func (consensus *Consensus) Quorum() int { return len(consensus.PublicKeys)*2/3 + 1 } +// RewardThreshold returns the threshold to stop accepting commit messages +// when leader receives enough signatures for block reward +func (consensus *Consensus) RewardThreshold() int { + return len(consensus.PublicKeys) * 9 / 10 +} + // StakeInfoFinder finds the staking account for the given consensus key. type StakeInfoFinder interface { // FindStakeInfoByNodeKey returns a list of staking information matching @@ -245,6 +254,7 @@ func New(host p2p.Host, ShardID uint32, leader p2p.Peer, blsPriKey *bls.SecretKe consensus.MsgChan = make(chan []byte) consensus.syncReadyChan = make(chan struct{}) + consensus.commitFinishChan = make(chan uint32) consensus.ReadySignal = make(chan struct{}) if nodeconfig.GetDefaultConfig().IsLeader() { diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index ea4ce7767..0af588d37 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -480,11 +480,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) { return } - // already had enough signautres - if len(commitSigs) >= consensus.Quorum() { - consensus.getLogger().Info("received additional commit message", "validatorPubKey", validatorPubKey) - return - } + quorumWasMet := len(commitSigs) >= consensus.Quorum() // Verify the signature on commitPayload is correct var sign bls.Sign @@ -508,9 +504,23 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) { ctxerror.Warn(consensus.getLogger(), err, "commitBitmap.SetKey failed") } - if len(commitSigs) >= consensus.Quorum() { - consensus.getLogger().Info("Enough commits received!", "num", len(commitSigs)) - consensus.finalizeCommits() + quorumIsMet := len(commitSigs) >= consensus.Quorum() + rewardThresholdIsMet := len(commitSigs) >= consensus.RewardThreshold() + + if !quorumWasMet && quorumIsMet { + consensus.getLogger().Info("enough commits received for consensus", "num", len(commitSigs)) + go func(viewID uint32) { + time.Sleep(2 * time.Second) + consensus.getLogger().Debug("Commit grace period ended") + consensus.commitFinishChan <- viewID + }(consensus.viewID) + } + + if rewardThresholdIsMet { + go func(viewID uint32) { + consensus.commitFinishChan <- viewID + consensus.getLogger().Debug("enough commits received for block reward", "num", len(commitSigs)) + }(consensus.viewID) } } @@ -835,6 +845,15 @@ func (consensus *Consensus) Start(blockChannel chan *types.Block, stopChan chan case msg := <-consensus.MsgChan: consensus.handleMessageUpdate(msg) + case viewID := <-consensus.commitFinishChan: + func() { + consensus.mutex.Lock() + defer consensus.mutex.Unlock() + if viewID == consensus.viewID { + consensus.finalizeCommits() + } + }() + case <-stopChan: return } diff --git a/internal/genesis/foundational.go b/internal/genesis/foundational.go index 5c428a6ae..c3ed471db 100644 --- a/internal/genesis/foundational.go +++ b/internal/genesis/foundational.go @@ -137,4 +137,5 @@ var GenesisFNAccounts = [...]DeployAccount{ {Index: "132", Address: "one1t49clgldmutkd6759tyvxje36r4dmq6ukgsdzd", BlsPriKey: "be3e3134482aa89c4e75961c015e9ac3ee564575690117368c653f042804f73d", BlsPublicKey: "940e0941034288dd19b8cb2542fdedeacfe44bdf87c95bdc428350d5f8114d4b", Updated: "from sheet"}, {Index: "133", Address: "one1mtvr4rtt7zwp5xwz65razvy54vzxn57y8wd9um", BlsPriKey: "0d60c1b650d86a835ab555287c5475588a5a729bb57abade10a95c877c82313b", BlsPublicKey: "af4cbb5b185473e667b1004a59aaf265430cd6fc1d2578bf32e88e9c639cd839790f12bf4e58b9f685daf3b9ab3d7001", Updated: "from sheet"}, {Index: "134", Address: "one1ahw70lq9sqqygs8f7zdrvw7zd796w5n48hc5xh", BlsPriKey: "70d73a85dff49f9f0012827aeb61ecdafc19928c642f4532829a963d76b72d24", BlsPublicKey: "f0d6a1d78c4817e451fb242b7501b23a9e9b5214e6ae8695a00e344a2f6662dad96baeb4f983d5613404795fae71e80d", Updated: "from sheet"}, + {Index: "135", Address: "one10ha8a07jpxlla89gcmlu7k9j3ra3sqdyq2c620", BlsPriKey: "f8454288baa18cbbc4b3d6c7e82edc387dff963576d0267ff5d70ee0cb60c420", BlsPublicKey: "03ed4996a4808aa1c9672dcbde4262311fcddd9d291e7f0b96d5fa4968831454479584d0ce0c2471557f506f189cd388", Updated: "from sheet"}, }