@ -5,6 +5,7 @@ import (
"errors"
"errors"
"math/big"
"math/big"
"sort"
"sort"
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/common/math"
@ -28,6 +29,11 @@ import (
// APIBackend An implementation of internal/hmyapi/Backend. Full client.
// APIBackend An implementation of internal/hmyapi/Backend. Full client.
type APIBackend struct {
type APIBackend struct {
hmy * Harmony
hmy * Harmony
MedianStakeCache struct {
sync . Mutex
BlockHeight int64
MedianRawStake * big . Int
}
}
}
// ChainDb ...
// ChainDb ...
@ -323,9 +329,16 @@ var (
// GetMedianRawStakeSnapshot ..
// GetMedianRawStakeSnapshot ..
func ( b * APIBackend ) GetMedianRawStakeSnapshot ( ) * big . Int {
func ( b * APIBackend ) GetMedianRawStakeSnapshot ( ) * big . Int {
b . MedianStakeCache . Lock ( )
defer b . MedianStakeCache . Unlock ( )
if b . MedianStakeCache . BlockHeight != - 1 && b . MedianStakeCache . BlockHeight > int64 ( rpc . LatestBlockNumber ) - 20 {
return b . MedianStakeCache . MedianRawStake
}
candidates := b . hmy . BlockChain ( ) . ValidatorCandidates ( )
candidates := b . hmy . BlockChain ( ) . ValidatorCandidates ( )
if len ( candidates ) == 0 {
if len ( candidates ) == 0 {
return big . NewInt ( 0 )
b . MedianStakeCache . Lock ( )
b . MedianStakeCache . MedianRawStake = big . NewInt ( 0 )
return b . MedianStakeCache . MedianRawStake
}
}
stakes := [ ] * big . Int { }
stakes := [ ] * big . Int { }
for i := range candidates {
for i := range candidates {
@ -347,14 +360,16 @@ func (b *APIBackend) GetMedianRawStakeSnapshot() *big.Int {
}
}
const isEven = 0
const isEven = 0
switch l := len ( stakes ) ; l % 2 {
switch l := len ( stakes ) ; l % 2 {
case isEven :
case isEven :
left := stakes [ ( l / 2 ) - 1 ]
left := stakes [ ( l / 2 ) - 1 ]
right := stakes [ l / 2 ]
right := stakes [ l / 2 ]
return new ( big . Int ) . Div ( new ( big . Int ) . Add ( left , right ) , two )
b . MedianStakeCache . MedianRawStake = new ( big . Int ) . Div ( new ( big . Int ) . Add ( left , right ) , two )
default :
default :
return stakes [ l / 2 ]
b . MedianStakeCache . MedianRawStake = stakes [ l / 2 ]
}
}
return b . MedianStakeCache . MedianRawStake
}
}
// GetValidatorStats returns the stats of validator
// GetValidatorStats returns the stats of validator