Optimization for median raw stake and staking new methods (#2192)

* [chain][network] Factor out block reward from internal chain to proper package

* [network] Fill out record intended for RPC

* [staking][network] NewUtilityMetricSnapshot

* Expose rewards to RPC API

* Change json field

* Fix lint

* Remove marshalling

* Remove import

* Optimize median raw stake, total stake, get stake methods

* Remove unnecessary methods and add thread safety

* Review feedback

* Remove lock/unlock

Co-authored-by: Edgar Aroutiounian <edgar.factorial@gmail.com>
pull/2218/head
flicker-harmony 5 years ago committed by GitHub
parent 801b4b83e2
commit 2de6b0885c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      README.md
  2. 21
      hmy/api_backend.go
  3. 12
      hmy/backend.go

@ -190,6 +190,14 @@ Tx Generator:
./scripts/go_executable_build.sh txgen ./scripts/go_executable_build.sh txgen
``` ```
### Harmony docs and guides
https://docs.harmony.one
### API guides
https://docs.harmony.one/home/developers/api
## Usage ## Usage
You may build the src/harmony.go locally and run local test. You may build the src/harmony.go locally and run local test.

@ -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

@ -2,6 +2,7 @@ package hmy
import ( import (
"math/big" "math/big"
"sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
@ -74,7 +75,16 @@ func New(
networkID: 1, // TODO(ricl): this should be from config networkID: 1, // TODO(ricl): this should be from config
shardID: shardID, shardID: shardID,
} }
hmy.APIBackend = &APIBackend{hmy} hmy.APIBackend = &APIBackend{hmy: hmy,
MedianStakeCache: struct {
sync.Mutex
BlockHeight int64
MedianRawStake *big.Int
}{
BlockHeight: -1,
MedianRawStake: big.NewInt(0),
},
}
return hmy, nil return hmy, nil
} }

Loading…
Cancel
Save