@@ -30,20 +30,28 @@ type XDPoS_v2 struct {
30
30
BFTQueue chan interface {}
31
31
timeoutWorker * countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached
32
32
33
- currentRound utils.Round
33
+ timeoutPool * utils.Pool
34
+ currentRound utils.Round
35
+ highestVotedRound utils.Round
36
+ highestQuorumCert * utils.QuorumCert
37
+ // LockQC in XDPoS Consensus 2.0, used in voting rule
38
+ lockQuorumCert * utils.QuorumCert
39
+ highestTimeoutCert * utils.TimeoutCert
40
+ highestCommitBlock * utils.BlockInfo
34
41
}
35
42
36
43
func New (config * params.XDPoSConfig , db ethdb.Database ) * XDPoS_v2 {
37
44
// Setup Timer
38
45
duration := time .Duration (config .V2 .TimeoutWorkerDuration ) * time .Millisecond
39
46
timer := countdown .NewCountDown (duration )
40
-
47
+ timeoutPool := utils . NewPool ( config . V2 . CertThreshold )
41
48
engine := & XDPoS_v2 {
42
49
config : config ,
43
50
db : db ,
44
51
timeoutWorker : timer ,
45
52
BroadcastCh : make (chan interface {}),
46
53
BFTQueue : make (chan interface {}),
54
+ timeoutPool : timeoutPool ,
47
55
}
48
56
// Add callback to the timer
49
57
timer .OnTimeoutFn = engine .onCountdownTimeout
@@ -62,6 +70,7 @@ func NewFaker(db ethdb.Database, config *params.XDPoSConfig) *XDPoS_v2 {
62
70
// Setup Timer
63
71
duration := time .Duration (config .V2 .TimeoutWorkerDuration ) * time .Millisecond
64
72
timer := countdown .NewCountDown (duration )
73
+ timeoutPool := utils .NewPool (2 )
65
74
66
75
// Allocate the snapshot caches and create the engine
67
76
fakeEngine = & XDPoS_v2 {
@@ -70,6 +79,7 @@ func NewFaker(db ethdb.Database, config *params.XDPoSConfig) *XDPoS_v2 {
70
79
timeoutWorker : timer ,
71
80
BroadcastCh : make (chan interface {}),
72
81
BFTQueue : make (chan interface {}),
82
+ timeoutPool : timeoutPool ,
73
83
}
74
84
// Add callback to the timer
75
85
timer .OnTimeoutFn = fakeEngine .onCountdownTimeout
@@ -171,7 +181,7 @@ func (x *XDPoS_v2) VoteHandler() {
171
181
*/
172
182
func (x * XDPoS_v2 ) VerifyTimeoutMessage (timeoutMsg utils.Timeout ) (bool , error ) {
173
183
// Recover the public key and the Ethereum address
174
- pubkey , err := crypto .Ecrecover (utils .TimeoutSigHash (timeoutMsg .Round ).Bytes (), timeoutMsg .Signature )
184
+ pubkey , err := crypto .Ecrecover (utils .TimeoutSigHash (& timeoutMsg .Round ).Bytes (), timeoutMsg .Signature )
175
185
if err != nil {
176
186
return false , fmt .Errorf ("Error while verifying time out message: %v" , err )
177
187
}
@@ -187,14 +197,20 @@ func (x *XDPoS_v2) VerifyTimeoutMessage(timeoutMsg utils.Timeout) (bool, error)
187
197
return false , fmt .Errorf ("Masternodes does not contain signer address. Master node list %v, Signer address: %v" , masternodes , signerAddress )
188
198
}
189
199
190
- func (x * XDPoS_v2 ) TimeoutHandler () {
191
- /*
192
- 1. checkRoundNumber()
193
- 2. Collect timeout (TODO)
194
- 3. Genrate TC (TODO)
195
- 4. processTC()
196
- 5. generateSyncInfo()
197
- */
200
+ /*
201
+ 1. checkRoundNumber()
202
+ 2. Collect timeout (TODO)
203
+ 3. Genrate TC (TODO)
204
+ 4. processTC()
205
+ 5. generateSyncInfo()
206
+ */
207
+ func (x * XDPoS_v2 ) TimeoutHandler (timeout * utils.Timeout ) {
208
+ // Collect timeout, generate TC
209
+ timeoutCert := x .timeoutPool .Add (timeout )
210
+ // If TC is generated
211
+ if timeoutCert != nil {
212
+ //TODO: processTC(),generateSyncInfo()
213
+ }
198
214
}
199
215
200
216
/*
@@ -245,29 +261,50 @@ func (x *XDPoS_v2) verifyTC(header *types.Header) error {
245
261
}
246
262
247
263
// Update local QC variables including highestQC & lockQC, as well as update commit blockInfo before call
248
- func (x * XDPoS_v2 ) processQC (header * types.Header ) error {
249
- /*
250
- 1. Update HighestQC and LockQC
251
- 2. Update commit block info (TODO)
252
- 3. Check QC round >= node's currentRound. If yes, call setNewRound
253
- */
264
+ /*
265
+ 1. Update HighestQC and LockQC
266
+ 2. Update commit block info (TODO)
267
+ 3. Check QC round >= node's currentRound. If yes, call setNewRound
268
+ */
269
+ func (x * XDPoS_v2 ) processQC (quorumCert * utils.QuorumCert ) error {
270
+ if x .highestQuorumCert == nil || quorumCert .ProposedBlockInfo .Round > x .highestQuorumCert .ProposedBlockInfo .Round {
271
+ x .highestQuorumCert = quorumCert
272
+ //TODO: do I need a clone?
273
+ }
274
+ //TODO: x.blockchain.getBlock(quorumCert.ProposedBlockInfo.Hash) then get the QC inside that block header
275
+ //TODO: update lockQC
276
+ //TODO: find parent and grandparent and grandgrandparent block, check round number, if so, commit grandgrandparent
277
+ if quorumCert .ProposedBlockInfo .Round >= x .currentRound {
278
+ x .setNewRound (quorumCert .ProposedBlockInfo .Round + 1 )
279
+ }
254
280
return nil
255
281
}
256
282
257
- func (x * XDPoS_v2 ) processTC (header * types.Header ) error {
258
- /*
259
- 1. Update highestTC
260
- 2. Check TC round >= node's currentRound. If yes, call setNewRound
261
- */
283
+ /*
284
+ 1. Update highestTC
285
+ 2. Check TC round >= node's currentRound. If yes, call setNewRound
286
+ */
287
+ func (x * XDPoS_v2 ) processTC (timeoutCert * utils.TimeoutCert ) error {
288
+ if x .highestTimeoutCert == nil || timeoutCert .Round > x .highestTimeoutCert .Round {
289
+ x .highestTimeoutCert = timeoutCert
290
+ }
291
+ if timeoutCert .Round >= x .currentRound {
292
+ x .setNewRound (timeoutCert .Round + 1 )
293
+ }
262
294
return nil
263
295
}
264
296
265
- func (x * XDPoS_v2 ) setNewRound () error {
266
- /*
267
- 1. Set currentRound = QC round + 1 (or TC round +1)
268
- 2. Reset timer
269
- 3. Reset vote and timeout Pools
270
- */
297
+ /*
298
+ 1. Set currentRound = QC round + 1 (or TC round +1)
299
+ 2. Reset timer
300
+ 3. Reset vote and timeout Pools
301
+ */
302
+ func (x * XDPoS_v2 ) setNewRound (round utils.Round ) error {
303
+ x .currentRound = round
304
+ //TODO: tell miner now it's a new round and start mine if it's leader
305
+ //TODO: reset timer
306
+ //TODO: vote pools
307
+ x .timeoutPool .Clear ()
271
308
return nil
272
309
}
273
310
@@ -308,7 +345,7 @@ func (x *XDPoS_v2) sendTimeout() error {
308
345
signer , signFn := x .signer , x .signFn
309
346
x .lock .RUnlock ()
310
347
311
- signedHash , err := signFn (accounts.Account {Address : signer }, utils .TimeoutSigHash (x .currentRound ).Bytes ())
348
+ signedHash , err := signFn (accounts.Account {Address : signer }, utils .TimeoutSigHash (& x .currentRound ).Bytes ())
312
349
if err != nil {
313
350
return fmt .Errorf ("Error while signing for timeout message" )
314
351
}
0 commit comments