Skip to content

Commit

Permalink
fix: pov_getRepStats timeout (#1379)
Browse files Browse the repository at this point in the history
  • Loading branch information
zengchen221 authored Apr 19, 2021
1 parent def2d0a commit c9cc39c
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 18 deletions.
122 changes: 105 additions & 17 deletions rpc/api/pov.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"math/big"
"sync"
"time"

rpc "github.com/qlcchain/jsonrpc2"
Expand All @@ -25,13 +26,16 @@ import (
)

type PovApi struct {
cfg *config.Config
l ledger.Store
logger *zap.SugaredLogger
eb event.EventBus
feb *event.FeedEventBus
pubsub *PovSubscription
cc *chainctx.ChainContext
cfg *config.Config
l ledger.Store
logger *zap.SugaredLogger
eb event.EventBus
feb *event.FeedEventBus
pubsub *PovSubscription
cc *chainctx.ChainContext
ctx context.Context
dayIndex uint32
trieMap *sync.Map
}

type PovStatus struct {
Expand Down Expand Up @@ -166,17 +170,82 @@ type PovRepStats struct {

func NewPovApi(ctx context.Context, cfg *config.Config, l ledger.Store, eb event.EventBus, cc *chainctx.ChainContext) *PovApi {
api := &PovApi{
cfg: cfg,
l: l,
eb: eb,
feb: cc.FeedEventBus(),
pubsub: NewPovSubscription(ctx, eb),
logger: log.NewLogger("rpc/pov"),
cc: cc,
}
cfg: cfg,
l: l,
eb: eb,
feb: cc.FeedEventBus(),
pubsub: NewPovSubscription(ctx, eb),
logger: log.NewLogger("rpc/pov"),
cc: cc,
trieMap: new(sync.Map),
dayIndex: 0,
ctx: ctx,
}
go api.initTrieMap()
return api
}

func (api *PovApi) initTrieMap() {
api.initTrie()
vTicker := time.NewTicker(1 * time.Hour)
for {
select {
case <-vTicker.C:
api.initTrie()
case <-api.ctx.Done():
return
}
}
}

func (api *PovApi) initTrie() {
dbDayCnt := 0
lastDayIndex := uint32(0)
if err := api.l.GetAllPovMinerStats(func(stat *types.PovMinerDayStat) error {
dbDayCnt++
if stat.DayIndex > lastDayIndex {
lastDayIndex = stat.DayIndex
}
return nil
}); err != nil {
return
}

if lastDayIndex != api.dayIndex {
api.dayIndex = lastDayIndex
api.trieMap = new(sync.Map)
}

latestHeader, _ := api.l.GetLatestPovHeader()
if latestHeader == nil {
return
}
notStatHeightStart := uint64(0)
if dbDayCnt > 0 {
notStatHeightStart = uint64(lastDayIndex+1)*uint64(common.POVChainBlocksPerDay) + common.DPosOnlinePeriod - 1
}
notStatHeightEnd := latestHeader.GetHeight()
var height uint64
loopCount := 0
simpleTrie := trie.NewSimpleTrieNodePool()
for height = notStatHeightStart; height <= notStatHeightEnd; height += common.DPosOnlinePeriod {
loopCount++
header, _ := api.l.GetPovHeaderByHeight(height)
if header == nil {
break
}

stateHash := header.GetStateHash()
if _, ok := api.trieMap.Load(stateHash); !ok {
stateTrie := trie.NewTrie(api.l.DBStore(), &stateHash, simpleTrie)
if stateTrie != nil {
api.trieMap.Store(stateHash, stateTrie)
}
}
}
return
}

func (api *PovApi) GetPovStatus() (*PovStatus, error) {
apiRsp := new(PovStatus)
apiRsp.PovEnabled = api.cfg.PoV.PovEnabled
Expand Down Expand Up @@ -900,6 +969,23 @@ func (api *PovApi) GetMinerStats(addrs []types.Address) (*PovMinerStats, error)
return apiRsp, nil
}

func (api *PovApi) getPovTrie(stateHash types.Hash) *trie.Trie {
value, ok := api.trieMap.Load(stateHash)
if ok {
if stateTrie, t := value.(*trie.Trie); t {
return stateTrie
}
}

trie := trie.NewTrie(api.l.DBStore(), &stateHash, nil)
if trie == nil {
return nil
}
api.trieMap.Store(stateHash, trie)
return trie

}

func (api *PovApi) GetRepStats(addrs []types.Address) (*PovRepStats, error) {
checkAddrMap := make(map[types.Address]bool)
if len(addrs) > 0 {
Expand Down Expand Up @@ -1632,7 +1718,8 @@ func (api *PovApi) GetAllOnlineRepStates(header *types.PovHeader) []*types.PovRe
minVoteWeight, _ := supply.Div(common.DposVoteDivisor)

stateHash := header.GetStateHash()
stateTrie := trie.NewTrie(api.l.DBStore(), &stateHash, nil)
//stateTrie := trie.NewTrie(api.l.DBStore(), &stateHash, nil)
stateTrie := api.getPovTrie(stateHash)
if stateTrie == nil {
return nil
}
Expand Down Expand Up @@ -1676,7 +1763,8 @@ func (api *PovApi) GetAllOnlineRepStates(header *types.PovHeader) []*types.PovRe

func (api *PovApi) GetRepStatesByHeightAndAccount(header *types.PovHeader, acc types.Address) *types.PovRepState {
stateHash := header.GetStateHash()
stateTrie := trie.NewTrie(api.l.DBStore(), &stateHash, nil)
//stateTrie := trie.NewTrie(api.l.DBStore(), &stateHash, nil)
stateTrie := api.getPovTrie(stateHash)
if stateTrie == nil {
return nil
}
Expand Down
9 changes: 8 additions & 1 deletion rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/url"
"strings"
"sync"
"time"

rpc "github.com/qlcchain/jsonrpc2"
"go.uber.org/zap"
Expand Down Expand Up @@ -239,8 +240,14 @@ func (r *RPC) StartRPC() error {
}

if r.config.RPC.Enable && r.config.RPC.HTTPEnabled {
timeouts := rpc.HTTPTimeouts{
ReadTimeout: 100 * time.Second,
WriteTimeout: 100 * time.Second,
IdleTimeout: 120 * time.Second,
}

apis := r.GetHttpApis(r.config.RPC.PublicModules)
if err := r.startHTTP(r.config.RPC.HTTPEndpoint, apis, nil, r.config.RPC.HTTPCors, r.config.RPC.HttpVirtualHosts, rpc.HTTPTimeouts{}); err != nil {
if err := r.startHTTP(r.config.RPC.HTTPEndpoint, apis, nil, r.config.RPC.HTTPCors, r.config.RPC.HttpVirtualHosts, timeouts); err != nil {
r.logger.Info(err)
r.stopInProcess()
r.stopIPC()
Expand Down

0 comments on commit c9cc39c

Please sign in to comment.