@@ -199,20 +199,23 @@ func BuildTxOpeningRandomize(nonce uint64, randomizeAddr common.Address, randomi
199
199
}
200
200
201
201
// Get signers signed for blockNumber from blockSigner contract.
202
- func GetSignersFromContract (addrBlockSigner common.Address , client bind.ContractBackend , blockHash common.Hash ) ([]common.Address , error ) {
202
+ func GetSignersFromContract (c * posv. Posv , addrBlockSigner common.Address , client bind.ContractBackend , blockHash common.Hash ) ([]common.Address , error ) {
203
203
blockSigner , err := contract .NewBlockSigner (addrBlockSigner , client )
204
204
if err != nil {
205
205
log .Error ("Fail get instance of blockSigner" , "error" , err )
206
206
return nil , err
207
207
}
208
- opts := new (bind.CallOpts )
209
- addrs , err := blockSigner .GetSigners (opts , blockHash )
210
- if err != nil {
211
- log .Error ("Fail get block signers" , "error" , err )
212
- return nil , err
208
+ if caddrs , ok := c .BlockSigners .Get (blockHash ); ! ok || ! c .EnableCache {
209
+ opts := new (bind.CallOpts )
210
+ addrs , err := blockSigner .GetSigners (opts , blockHash )
211
+ if err != nil {
212
+ log .Error ("Fail get block signers" , "error" , err )
213
+ return nil , err
214
+ }
215
+ return addrs , nil
216
+ } else {
217
+ return caddrs .([]common.Address ), nil
213
218
}
214
-
215
- return addrs , nil
216
219
}
217
220
218
221
// Get random from randomize contract.
@@ -307,7 +310,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
307
310
}
308
311
309
312
// Calculate reward for reward checkpoint.
310
- func GetRewardForCheckpoint (chain consensus.ChainReader , blockSignerAddr common.Address , number uint64 , rCheckpoint uint64 , client bind.ContractBackend , totalSigner * uint64 ) (map [common.Address ]* rewardLog , error ) {
313
+ func GetRewardForCheckpoint (c * posv. Posv , chain consensus.ChainReader , blockSignerAddr common.Address , number uint64 , rCheckpoint uint64 , client bind.ContractBackend , totalSigner * uint64 ) (map [common.Address ]* rewardLog , error ) {
311
314
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
312
315
prevCheckpoint := number - (rCheckpoint * 2 )
313
316
startBlockNumber := prevCheckpoint + 1
@@ -317,37 +320,89 @@ func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common.
317
320
masternodes := posv .GetMasternodesFromCheckpointHeader (prevHeaderCheckpoint )
318
321
319
322
if len (masternodes ) > 0 {
320
- for i := startBlockNumber ; i <= endBlockNumber ; i ++ {
321
- block := chain .GetHeaderByNumber (i )
322
- addrs , err := GetSignersFromContract (blockSignerAddr , client , block .Hash ())
323
- if err != nil {
324
- log .Error ("Fail to get signers from smartcontract." , "error" , err , "blockNumber" , i )
325
- return nil , err
326
- }
327
- // Filter duplicate address.
328
- if len (addrs ) > 0 {
329
- addrSigners := make (map [common.Address ]bool )
330
- for _ , masternode := range masternodes {
331
- for _ , addr := range addrs {
332
- if addr == masternode {
333
- if _ , ok := addrSigners [addr ]; ! ok {
334
- addrSigners [addr ] = true
323
+
324
+ if ! c .EnableCache {
325
+ for i := startBlockNumber ; i <= endBlockNumber ; i ++ {
326
+ block := chain .GetHeaderByNumber (i )
327
+ addrs , err := GetSignersFromContract (c , blockSignerAddr , client , block .Hash ())
328
+ if err != nil {
329
+ log .Error ("Fail to get signers from smartcontract." , "error" , err , "blockNumber" , i )
330
+ return nil , err
331
+ }
332
+ // Filter duplicate address.
333
+ if len (addrs ) > 0 {
334
+ addrSigners := make (map [common.Address ]bool )
335
+ for _ , masternode := range masternodes {
336
+ for _ , addr := range addrs {
337
+ if addr == masternode {
338
+ if _ , ok := addrSigners [addr ]; ! ok {
339
+ addrSigners [addr ] = true
340
+ }
341
+ break
335
342
}
336
- break
337
343
}
338
344
}
345
+
346
+ for addr := range addrSigners {
347
+ _ , exist := signers [addr ]
348
+ if exist {
349
+ signers [addr ].Sign ++
350
+ } else {
351
+ signers [addr ] = & rewardLog {1 , new (big.Int )}
352
+ }
353
+ * totalSigner ++
354
+ }
339
355
}
356
+ }
357
+ } else {
358
+ var wg sync.WaitGroup
359
+ squeue := make (chan []common.Address , 1 )
360
+ wg .Add (int (rCheckpoint ))
361
+
362
+ for i := startBlockNumber ; i <= endBlockNumber ; i ++ {
363
+ go func (i uint64 ) {
364
+ block := chain .GetHeaderByNumber (i )
365
+ addrs , err := GetSignersFromContract (c , blockSignerAddr , client , block .Hash ())
366
+ if err != nil {
367
+ log .Crit ("Fail to get signers from smartcontract." , "error" , err , "blockNumber" , i )
368
+ }
369
+ squeue <- addrs
370
+ }(i )
371
+ }
340
372
341
- for addr := range addrSigners {
342
- _ , exist := signers [addr ]
343
- if exist {
344
- signers [addr ].Sign ++
345
- } else {
346
- signers [addr ] = & rewardLog {1 , new (big.Int )}
373
+ fsigner := func () {
374
+ for addrs := range squeue {
375
+ // Filter duplicate address.
376
+ if len (addrs ) > 0 {
377
+ addrSigners := make (map [common.Address ]bool )
378
+ for _ , masternode := range masternodes {
379
+ for _ , addr := range addrs {
380
+ if addr == masternode {
381
+ if _ , ok := addrSigners [addr ]; ! ok {
382
+ addrSigners [addr ] = true
383
+ }
384
+ break
385
+ }
386
+ }
387
+ }
388
+
389
+ for addr := range addrSigners {
390
+ _ , exist := signers [addr ]
391
+ if exist {
392
+ signers [addr ].Sign ++
393
+ } else {
394
+ signers [addr ] = & rewardLog {1 , new (big.Int )}
395
+ }
396
+ * totalSigner ++
397
+ }
347
398
}
348
- * totalSigner ++
399
+ wg . Done ()
349
400
}
350
401
}
402
+
403
+ go fsigner ()
404
+
405
+ wg .Wait ()
351
406
}
352
407
}
353
408
@@ -381,7 +436,6 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
381
436
return resultSigners , nil
382
437
}
383
438
384
- // Get candidate owner by address.
385
439
func GetCandidatesOwnerBySigner (validator * contractValidator.TomoValidator , signerAddr common.Address ) common.Address {
386
440
owner := signerAddr
387
441
opts := new (bind.CallOpts )
@@ -395,8 +449,8 @@ func GetCandidatesOwnerBySigner(validator *contractValidator.TomoValidator, sign
395
449
}
396
450
397
451
// Calculate reward for holders.
398
- func CalculateRewardForHolders (foudationWalletAddr common.Address , validator * contractValidator.TomoValidator , state * state.StateDB , signer common.Address , calcReward * big.Int ) (error , map [common .Address ]* big.Int ) {
399
- rewards , err := GetRewardBalancesRate (foudationWalletAddr , signer , calcReward , validator )
452
+ func CalculateRewardForHolders (c * posv. Posv , foudationWalletAddr common.Address , validator * contractValidator.TomoValidator , state * state.StateDB , signer common.Address , calcReward * big.Int ) (error , map [common .Address ]* big.Int ) {
453
+ rewards , err := GetRewardBalancesRate (c , foudationWalletAddr , signer , calcReward , validator )
400
454
if err != nil {
401
455
return err , nil
402
456
}
@@ -409,7 +463,7 @@ func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *co
409
463
}
410
464
411
465
// Get reward balance rates for master node, founder and holders.
412
- func GetRewardBalancesRate (foudationWalletAddr common.Address , masterAddr common.Address , totalReward * big.Int , validator * contractValidator.TomoValidator ) (map [common.Address ]* big.Int , error ) {
466
+ func GetRewardBalancesRate (c * posv. Posv , foudationWalletAddr common.Address , masterAddr common.Address , totalReward * big.Int , validator * contractValidator.TomoValidator ) (map [common.Address ]* big.Int , error ) {
413
467
owner := GetCandidatesOwnerBySigner (validator , masterAddr )
414
468
balances := make (map [common.Address ]* big.Int )
415
469
rewardMaster := new (big.Int ).Mul (totalReward , new (big.Int ).SetInt64 (common .RewardMasterPercent ))
@@ -419,7 +473,7 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
419
473
opts := new (bind.CallOpts )
420
474
voters , err := validator .GetVoters (opts , masterAddr )
421
475
if err != nil {
422
- log .Error ("Fail to get voters" , "error" , err )
476
+ log .Crit ("Fail to get voters" , "error" , err )
423
477
return nil , err
424
478
}
425
479
@@ -430,10 +484,28 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
430
484
// Get voters capacities.
431
485
voterCaps := make (map [common.Address ]* big.Int )
432
486
for _ , voteAddr := range voters {
433
- voterCap , err := validator .GetVoterCap (opts , masterAddr , voteAddr )
434
- if err != nil {
435
- log .Error ("Fail to get vote capacity" , "error" , err )
436
- return nil , err
487
+ var vote common.Vote
488
+ var voterCap * big.Int
489
+
490
+ vote .Masternode = masterAddr
491
+ vote .Voter = voteAddr
492
+
493
+ if c != nil {
494
+ if vCap , ok := c .Votes .Get (vote ); ok {
495
+ voterCap = vCap .(* big.Int )
496
+ } else {
497
+ voterCap , err = validator .GetVoterCap (opts , masterAddr , voteAddr )
498
+ if err != nil {
499
+ log .Crit ("Fail to get vote capacity" , "error" , err )
500
+ }
501
+ log .Debug ("Add to Votes cache " , "vote.Masternode" , vote .Masternode .String (), "vote.Voter" , vote .Voter .String (), "voterCap" , voterCap .String ())
502
+ c .Votes .Add (vote , voterCap )
503
+ }
504
+ } else {
505
+ voterCap , err = validator .GetVoterCap (opts , masterAddr , voteAddr )
506
+ if err != nil {
507
+ log .Crit ("Fail to get vote capacity" , "error" , err )
508
+ }
437
509
}
438
510
439
511
totalCap .Add (totalCap , voterCap )
0 commit comments