@@ -24,14 +24,26 @@ import (
2424 "github.com/ethereum/go-ethereum/consensus/istanbul"
2525)
2626
27- func (c * core ) sendRoundChange () {
27+ // sendNextRoundChange sends the round change message with current round + 1
28+ func (c * core ) sendNextRoundChange () {
29+ cv := c .currentView ()
30+ c .sendRoundChange (new (big.Int ).Add (cv .Round , common .Big1 ))
31+ }
32+
33+ // sendRoundChange sends the round change message with the given round
34+ func (c * core ) sendRoundChange (round * big.Int ) {
2835 logger := c .logger .New ("state" , c .state )
2936 logger .Trace ("sendRoundChange" )
3037
3138 cv := c .currentView ()
39+ if cv .Round .Cmp (round ) >= 0 {
40+ logger .Error ("Cannot send out the round change" , "current round" , cv .Round , "target round" , round )
41+ return
42+ }
43+
3244 c .catchUpRound (& istanbul.View {
3345 // The round number we'd like to transfer to.
34- Round : new (big.Int ).Add ( cv . Round , common . Big1 ),
46+ Round : new (big.Int ).Set ( round ),
3547 Sequence : new (big.Int ).Set (cv .Sequence ),
3648 })
3749
@@ -82,10 +94,7 @@ func (c *core) handleRoundChange(msg *message, src istanbul.Validator) error {
8294
8395 // Add the round change message to its message set and return how many
8496 // messages we've got with the same round number and sequence number.
85- num , err := c .roundChangeSet .Add (& istanbul.View {
86- Round : new (big.Int ).Set (rc .Round ),
87- Sequence : new (big.Int ).Set (rc .Sequence ),
88- }, msg )
97+ num , err := c .roundChangeSet .Add (rc .Round , msg )
8998 if err != nil {
9099 logger .Warn ("Failed to add round change message" , "from" , src , "msg" , msg , "err" , err )
91100 return err
@@ -94,13 +103,9 @@ func (c *core) handleRoundChange(msg *message, src istanbul.Validator) error {
94103 // Once we received f+1 round change messages, those messages form a weak certificate.
95104 // If our round number is smaller than the certificate's round number, we would
96105 // try to catch up the round number.
97- if num == int (c .valSet .F ()+ 1 ) {
106+ if c . waitingForRoundChange && num == int (c .valSet .F ()+ 1 ) {
98107 if cv .Round .Cmp (rc .Round ) < 0 {
99- c .catchUpRound (& istanbul.View {
100- Round : new (big.Int ).Sub (rc .Round , common .Big1 ),
101- Sequence : new (big.Int ).Set (rc .Sequence ),
102- })
103- c .sendRoundChange ()
108+ c .sendRoundChange (rc .Round )
104109 }
105110 }
106111
@@ -120,49 +125,59 @@ func (c *core) handleRoundChange(msg *message, src istanbul.Validator) error {
120125func newRoundChangeSet (valSet istanbul.ValidatorSet ) * roundChangeSet {
121126 return & roundChangeSet {
122127 validatorSet : valSet ,
123- roundChanges : make (map [common. Hash ]* messageSet ),
128+ roundChanges : make (map [uint64 ]* messageSet ),
124129 mu : new (sync.Mutex ),
125130 }
126131}
127132
128133type roundChangeSet struct {
129134 validatorSet istanbul.ValidatorSet
130- roundChanges map [common. Hash ]* messageSet
135+ roundChanges map [uint64 ]* messageSet
131136 mu * sync.Mutex
132137}
133138
134- func (rcs * roundChangeSet ) Add (v * istanbul.View , msg * message ) (int , error ) {
139+ // Add adds the round and message into round change set
140+ func (rcs * roundChangeSet ) Add (r * big.Int , msg * message ) (int , error ) {
135141 rcs .mu .Lock ()
136142 defer rcs .mu .Unlock ()
137143
138- h := istanbul . RLPHash ( v )
139- if rcs .roundChanges [h ] == nil {
140- rcs .roundChanges [h ] = newMessageSet (rcs .validatorSet )
144+ round := r . Uint64 ( )
145+ if rcs .roundChanges [round ] == nil {
146+ rcs .roundChanges [round ] = newMessageSet (rcs .validatorSet )
141147 }
142- err := rcs .roundChanges [h ].Add (msg )
148+ err := rcs .roundChanges [round ].Add (msg )
143149 if err != nil {
144150 return 0 , err
145151 }
146- return rcs .roundChanges [h ].Size (), nil
152+ return rcs .roundChanges [round ].Size (), nil
147153}
148154
149- func (rcs * roundChangeSet ) Clear (v * istanbul.View ) {
155+ // Clear deletes the messages with smaller round
156+ func (rcs * roundChangeSet ) Clear (round * big.Int ) {
150157 rcs .mu .Lock ()
151158 defer rcs .mu .Unlock ()
152159
153160 for k , rms := range rcs .roundChanges {
154- if len (rms .Values ()) == 0 {
161+ if len (rms .Values ()) == 0 || k < round . Uint64 () {
155162 delete (rcs .roundChanges , k )
156163 }
164+ }
165+ }
166+
167+ // MaxRound returns the max round which the number of messages is equal or larger than num
168+ func (rcs * roundChangeSet ) MaxRound (num int ) * big.Int {
169+ rcs .mu .Lock ()
170+ defer rcs .mu .Unlock ()
157171
158- var rc * roundChange
159- if err := rms .Values ()[0 ].Decode (& rc ); err != nil {
172+ var maxRound * big.Int
173+ for k , rms := range rcs .roundChanges {
174+ if rms .Size () < num {
160175 continue
161176 }
162-
163- if rc .Sequence .Cmp (v .Sequence ) < 0 ||
164- (rc .Sequence .Cmp (v .Sequence ) == 0 && rc .Round .Cmp (v .Round ) < 0 ) {
165- delete (rcs .roundChanges , k )
177+ r := big .NewInt (int64 (k ))
178+ if maxRound == nil || maxRound .Cmp (r ) < 0 {
179+ maxRound = r
166180 }
167181 }
182+ return maxRound
168183}
0 commit comments