les: always enforce maximum request cost <= minimum buffer limit

This commit is contained in:
Zsolt Felfoldi 2019-05-06 14:12:52 +02:00
parent 82c4b716a8
commit 70ddf60b16

View file

@ -106,6 +106,7 @@ type costTracker struct {
inSizeFactor, outSizeFactor float64 inSizeFactor, outSizeFactor float64
gf, utilTarget float64 gf, utilTarget float64
minBufLimit uint64
gfUpdateCh chan gfUpdate gfUpdateCh chan gfUpdate
gfLock sync.RWMutex gfLock sync.RWMutex
@ -116,7 +117,8 @@ type costTracker struct {
logRecentUsage, logTotalRecharge, logRelCost *csvlogger.Channel logRecentUsage, logTotalRecharge, logRelCost *csvlogger.Channel
} }
// newCostTracker creates a cost tracker and loads the cost factor statistics from the database // newCostTracker creates a cost tracker and loads the cost factor statistics from the database.
// It also returns the minimum capacity that can be assigned to any peer.
func newCostTracker(db ethdb.Database, config *eth.Config, logger *csvlogger.Logger) (*costTracker, uint64) { func newCostTracker(db ethdb.Database, config *eth.Config, logger *csvlogger.Logger) (*costTracker, uint64) {
utilTarget := float64(config.LightServ) * flowcontrol.FixedPointMultiplier / 100 utilTarget := float64(config.LightServ) * flowcontrol.FixedPointMultiplier / 100
ct := &costTracker{ ct := &costTracker{
@ -142,17 +144,15 @@ func newCostTracker(db ethdb.Database, config *eth.Config, logger *csvlogger.Log
} }
ct.gfLoop() ct.gfLoop()
costList := ct.makeCostList(ct.globalFactor() * 1.25) costList := ct.makeCostList(ct.globalFactor() * 1.25)
var minBufLimit uint64
for _, c := range costList { for _, c := range costList {
amount := minBufferReqAmount[c.MsgCode] amount := minBufferReqAmount[c.MsgCode]
cost := c.BaseCost + amount*c.ReqCost cost := c.BaseCost + amount*c.ReqCost
if cost > minBufLimit { if cost > ct.minBufLimit {
minBufLimit = cost ct.minBufLimit = cost
} }
} }
minBufLimit *= uint64(minBufferMultiplier) ct.minBufLimit *= uint64(minBufferMultiplier)
minCapacity := (minBufLimit-1)/bufLimitRatio + 1 return ct, (ct.minBufLimit-1)/bufLimitRatio + 1
return ct, minCapacity
} }
// stop stops the cost tracker and saves the cost factor statistics to the database // stop stops the cost tracker and saves the cost factor statistics to the database
@ -182,10 +182,20 @@ func (ct *costTracker) makeCostList(globalFactor float64) RequestCostList {
} }
var list RequestCostList var list RequestCostList
for code, data := range reqAvgTimeCost { for code, data := range reqAvgTimeCost {
baseCost := maxCost(data.baseCost, reqMaxInSize[code].baseCost, reqMaxOutSize[code].baseCost)
reqCost := maxCost(data.reqCost, reqMaxInSize[code].reqCost, reqMaxOutSize[code].reqCost)
// always enforce maximum request cost <= minimum buffer limit
maxCost := baseCost + reqCost*minBufferReqAmount[code]
if maxCost > ct.minBufLimit {
mul := 0.999 * float64(ct.minBufLimit) / float64(maxCost)
baseCost = uint64(float64(baseCost) * mul)
reqCost = uint64(float64(reqCost) * mul)
}
list = append(list, requestCostListItem{ list = append(list, requestCostListItem{
MsgCode: code, MsgCode: code,
BaseCost: maxCost(data.baseCost, reqMaxInSize[code].baseCost, reqMaxOutSize[code].baseCost), BaseCost: baseCost,
ReqCost: maxCost(data.reqCost, reqMaxInSize[code].reqCost, reqMaxOutSize[code].reqCost), ReqCost: reqCost,
}) })
} }
return list return list