[Uptime] Compute and return lastest 30 epoch signing information (#3249)

* [Uptime] Compute and return lastest 30 epoch signing information

* subtract previous epoch counters

* caching properly for each validator
pull/3238/head
Ganesha Upadhyaya 4 years ago committed by GitHub
parent 2d6c612cb9
commit 40f407c9b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 62
      hmy/staking.go
  2. 20
      staking/types/validator.go

@ -199,6 +199,52 @@ func (hmy *Harmony) GetAllValidatorAddresses() []common.Address {
return hmy.BlockChain.ValidatorCandidates()
}
var (
epochBlocksMap = map[common.Address]map[uint64]staking.EpochSigningEntry{}
)
func (hmy *Harmony) getEpochSigning(epoch *big.Int, addr common.Address) (staking.EpochSigningEntry, error) {
entry := staking.EpochSigningEntry{}
if validatorMap, ok := epochBlocksMap[addr]; ok {
if val, ok := validatorMap[epoch.Uint64()]; ok {
return val, nil
}
}
snapshot, err := hmy.BlockChain.ReadValidatorSnapshotAtEpoch(epoch, addr)
if err != nil {
return entry, err
}
// the signing information is for the previous epoch
prevEpoch := big.NewInt(0).Sub(epoch, common.Big1)
entry.Epoch = prevEpoch
entry.Blocks = snapshot.Validator.Counters
// subtract previous epoch counters if exists
prevEpochSnap, err := hmy.BlockChain.ReadValidatorSnapshotAtEpoch(prevEpoch, addr)
if err == nil {
entry.Blocks.NumBlocksSigned.Sub(
entry.Blocks.NumBlocksSigned,
prevEpochSnap.Validator.Counters.NumBlocksSigned,
)
entry.Blocks.NumBlocksToSign.Sub(
entry.Blocks.NumBlocksToSign,
prevEpochSnap.Validator.Counters.NumBlocksToSign,
)
}
// update map when adding new entry, also remove an entry beyond last 30
if _, ok := epochBlocksMap[addr]; !ok {
epochBlocksMap[addr] = map[uint64]staking.EpochSigningEntry{}
}
epochBlocksMap[addr][epoch.Uint64()] = entry
epochMinus30 := big.NewInt(0).Sub(epoch, big.NewInt(staking.SigningHistoryLength))
delete(epochBlocksMap[addr], epochMinus30.Uint64())
return entry, nil
}
// GetValidatorInformation returns the information of validator
func (hmy *Harmony) GetValidatorInformation(
addr common.Address, block *types.Block,
@ -320,6 +366,22 @@ func (hmy *Harmony) GetValidatorInformation(
// defaultReply.Lifetime.APR = avgAPR.(numeric.Dec)
// }
epochBlocks := []staking.EpochSigningEntry{}
epochFrom := bc.Config().StakingEpoch
nowMinus := big.NewInt(0).Sub(now, big.NewInt(staking.SigningHistoryLength))
if nowMinus.Cmp(epochFrom) > 0 {
epochFrom = nowMinus
}
for i := now.Int64(); i > epochFrom.Int64(); i-- {
epoch := big.NewInt(i)
entry, err := hmy.getEpochSigning(epoch, addr)
if err != nil {
break
}
epochBlocks = append(epochBlocks, entry)
}
defaultReply.Lifetime.EpochBlocks = epochBlocks
if defaultReply.CurrentlyInCommittee {
defaultReply.ComputedMetrics = stats
defaultReply.EPoSWinningStake = &stats.TotalEffectiveStake

@ -30,6 +30,7 @@ const (
BLSVerificationStr = "harmony-one"
TenThousand = 10000
APRHistoryLength = 30
SigningHistoryLength = 30
)
var (
@ -156,10 +157,11 @@ type ValidatorRPCEnhanced struct {
// AccumulatedOverLifetime ..
type AccumulatedOverLifetime struct {
BlockReward *big.Int `json:"reward-accumulated"`
Signing counters `json:"blocks"`
APR numeric.Dec `json:"apr"`
EpochAPRs []APREntry `json:"epoch-apr"`
BlockReward *big.Int `json:"reward-accumulated"`
Signing counters `json:"blocks"`
APR numeric.Dec `json:"apr"`
EpochAPRs []APREntry `json:"epoch-apr"`
EpochBlocks []EpochSigningEntry `json:"epoch-blocks"`
}
func (w ValidatorWrapper) String() string {
@ -188,8 +190,14 @@ type VoteWithCurrentEpochEarning struct {
// APREntry ..
type APREntry struct {
Epoch *big.Int
Value numeric.Dec
Epoch *big.Int `json:"epoch"`
Value numeric.Dec `json:"apr"`
}
// EpochSigningEntry ..
type EpochSigningEntry struct {
Epoch *big.Int `json:"epoch"`
Blocks counters `json:"blocks"`
}
// ValidatorStats to record validator's performance and history records

Loading…
Cancel
Save