Skip to content

Commit 0ac9bbb

Browse files
zsfelfoldikaralabe
authored andcommitted
les: multiple server bugfixes (#20079)
* les: detailed relative cost metrics * les: filter txpool relative request statistic * les: initialize price factors * les: increased connected bias to lower churn rate * les: fixed clientPool.setLimits * core: do not use mutex in GetAncestor * les: bump factor db version again * les: add metrics * les, light: minor fixes
1 parent d4dce43 commit 0ac9bbb

File tree

8 files changed

+87
-24
lines changed

8 files changed

+87
-24
lines changed

core/blockchain.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,9 +2151,6 @@ func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com
21512151
//
21522152
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
21532153
func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
2154-
bc.chainmu.RLock()
2155-
defer bc.chainmu.RUnlock()
2156-
21572154
return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
21582155
}
21592156

core/headerchain.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,11 @@ func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, ma
349349
}
350350
for ancestor != 0 {
351351
if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {
352-
number -= ancestor
353-
return rawdb.ReadCanonicalHash(hc.chainDb, number), number
352+
ancestorHash := rawdb.ReadCanonicalHash(hc.chainDb, number-ancestor)
353+
if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {
354+
number -= ancestor
355+
return ancestorHash, number
356+
}
354357
}
355358
if *maxNonCanonical == 0 {
356359
return common.Hash{}, 0

les/clientpool.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
const (
3434
negBalanceExpTC = time.Hour // time constant for exponentially reducing negative balance
3535
fixedPointMultiplier = 0x1000000 // constant to convert logarithms to fixed point format
36-
connectedBias = time.Minute // this bias is applied in favor of already connected clients in order to avoid kicking them out very soon
36+
connectedBias = time.Minute * 5 // this bias is applied in favor of already connected clients in order to avoid kicking them out very soon
3737
lazyQueueRefresh = time.Second * 10 // refresh period of the connected queue
3838
)
3939

@@ -366,12 +366,14 @@ func (f *clientPool) setLimits(count int, totalCap uint64) {
366366

367367
f.countLimit = count
368368
f.capacityLimit = totalCap
369-
now := mclock.Now()
370-
f.connectedQueue.MultiPop(func(data interface{}, priority int64) bool {
371-
c := data.(*clientInfo)
372-
f.dropClient(c, now, true)
373-
return f.connectedCapacity > f.capacityLimit || f.connectedQueue.Size() > f.countLimit
374-
})
369+
if f.connectedCapacity > f.capacityLimit || f.connectedQueue.Size() > f.countLimit {
370+
now := mclock.Now()
371+
f.connectedQueue.MultiPop(func(data interface{}, priority int64) bool {
372+
c := data.(*clientInfo)
373+
f.dropClient(c, now, true)
374+
return f.connectedCapacity > f.capacityLimit || f.connectedQueue.Size() > f.countLimit
375+
})
376+
}
375377
}
376378

377379
// requestCost feeds request cost after serving a request from the given peer.

les/costtracker.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/ethereum/go-ethereum/ethdb"
2929
"github.com/ethereum/go-ethereum/les/flowcontrol"
3030
"github.com/ethereum/go-ethereum/log"
31+
"github.com/ethereum/go-ethereum/metrics"
3132
)
3233

3334
const makeCostStats = false // make request cost statistics during operation
@@ -87,7 +88,7 @@ const (
8788
gfUsageTC = time.Second
8889
gfRaiseTC = time.Second * 200
8990
gfDropTC = time.Second * 50
90-
gfDbKey = "_globalCostFactorV3"
91+
gfDbKey = "_globalCostFactorV6"
9192
)
9293

9394
// costTracker is responsible for calculating costs and cost estimates on the
@@ -226,6 +227,9 @@ type reqInfo struct {
226227
// servingTime is the CPU time corresponding to the actual processing of
227228
// the request.
228229
servingTime float64
230+
231+
// msgCode indicates the type of request.
232+
msgCode uint64
229233
}
230234

231235
// gfLoop starts an event loop which updates the global cost factor which is
@@ -269,11 +273,43 @@ func (ct *costTracker) gfLoop() {
269273
for {
270274
select {
271275
case r := <-ct.reqInfoCh:
276+
relCost := int64(factor * r.servingTime * 100 / r.avgTimeCost) // Convert the value to a percentage form
277+
278+
// Record more metrics if we are debugging
279+
if metrics.EnabledExpensive {
280+
switch r.msgCode {
281+
case GetBlockHeadersMsg:
282+
relativeCostHeaderHistogram.Update(relCost)
283+
case GetBlockBodiesMsg:
284+
relativeCostBodyHistogram.Update(relCost)
285+
case GetReceiptsMsg:
286+
relativeCostReceiptHistogram.Update(relCost)
287+
case GetCodeMsg:
288+
relativeCostCodeHistogram.Update(relCost)
289+
case GetProofsV2Msg:
290+
relativeCostProofHistogram.Update(relCost)
291+
case GetHelperTrieProofsMsg:
292+
relativeCostHelperProofHistogram.Update(relCost)
293+
case SendTxV2Msg:
294+
relativeCostSendTxHistogram.Update(relCost)
295+
case GetTxStatusMsg:
296+
relativeCostTxStatusHistogram.Update(relCost)
297+
}
298+
}
299+
// SendTxV2 and GetTxStatus requests are two special cases.
300+
// All other requests will only put pressure on the database, and
301+
// the corresponding delay is relatively stable. While these two
302+
// requests involve txpool query, which is usually unstable.
303+
//
304+
// TODO(rjl493456442) fixes this.
305+
if r.msgCode == SendTxV2Msg || r.msgCode == GetTxStatusMsg {
306+
continue
307+
}
272308
requestServedMeter.Mark(int64(r.servingTime))
273309
requestServedTimer.Update(time.Duration(r.servingTime))
274310
requestEstimatedMeter.Mark(int64(r.avgTimeCost / factor))
275311
requestEstimatedTimer.Update(time.Duration(r.avgTimeCost / factor))
276-
relativeCostHistogram.Update(int64(r.avgTimeCost / factor / r.servingTime))
312+
relativeCostHistogram.Update(relCost)
277313

278314
now := mclock.Now()
279315
dt := float64(now - expUpdate)
@@ -324,6 +360,7 @@ func (ct *costTracker) gfLoop() {
324360
default:
325361
}
326362
}
363+
globalFactorGauge.Update(int64(1000 * factor))
327364
log.Debug("global cost factor updated", "factor", factor)
328365
}
329366
}
@@ -375,7 +412,7 @@ func (ct *costTracker) updateStats(code, amount, servingTime, realCost uint64) {
375412
avg := reqAvgTimeCost[code]
376413
avgTimeCost := avg.baseCost + amount*avg.reqCost
377414
select {
378-
case ct.reqInfoCh <- reqInfo{float64(avgTimeCost), float64(servingTime)}:
415+
case ct.reqInfoCh <- reqInfo{float64(avgTimeCost), float64(servingTime), code}:
379416
default:
380417
}
381418
if makeCostStats {

les/metrics.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ var (
6060
miscOutTxStatusPacketsMeter = metrics.NewRegisteredMeter("les/misc/out/packets/txStatus", nil)
6161
miscOutTxStatusTrafficMeter = metrics.NewRegisteredMeter("les/misc/out/traffic/txStatus", nil)
6262

63+
miscServingTimeHeaderTimer = metrics.NewRegisteredTimer("les/misc/serve/header", nil)
64+
miscServingTimeBodyTimer = metrics.NewRegisteredTimer("les/misc/serve/body", nil)
65+
miscServingTimeCodeTimer = metrics.NewRegisteredTimer("les/misc/serve/code", nil)
66+
miscServingTimeReceiptTimer = metrics.NewRegisteredTimer("les/misc/serve/receipt", nil)
67+
miscServingTimeTrieProofTimer = metrics.NewRegisteredTimer("les/misc/serve/proof", nil)
68+
miscServingTimeHelperTrieTimer = metrics.NewRegisteredTimer("les/misc/serve/helperTrie", nil)
69+
miscServingTimeTxTimer = metrics.NewRegisteredTimer("les/misc/serve/txs", nil)
70+
miscServingTimeTxStatusTimer = metrics.NewRegisteredTimer("les/misc/serve/txStatus", nil)
71+
6372
connectionTimer = metrics.NewRegisteredTimer("les/connection/duration", nil)
6473
serverConnectionGauge = metrics.NewRegisteredGauge("les/connection/server", nil)
6574
clientConnectionGauge = metrics.NewRegisteredGauge("les/connection/client", nil)
@@ -69,12 +78,21 @@ var (
6978
totalConnectedGauge = metrics.NewRegisteredGauge("les/server/totalConnected", nil)
7079
blockProcessingTimer = metrics.NewRegisteredTimer("les/server/blockProcessingTime", nil)
7180

72-
requestServedMeter = metrics.NewRegisteredMeter("les/server/req/avgServedTime", nil)
73-
requestServedTimer = metrics.NewRegisteredTimer("les/server/req/servedTime", nil)
74-
requestEstimatedMeter = metrics.NewRegisteredMeter("les/server/req/avgEstimatedTime", nil)
75-
requestEstimatedTimer = metrics.NewRegisteredTimer("les/server/req/estimatedTime", nil)
76-
relativeCostHistogram = metrics.NewRegisteredHistogram("les/server/req/relative", nil, metrics.NewExpDecaySample(1028, 0.015))
77-
81+
requestServedMeter = metrics.NewRegisteredMeter("les/server/req/avgServedTime", nil)
82+
requestServedTimer = metrics.NewRegisteredTimer("les/server/req/servedTime", nil)
83+
requestEstimatedMeter = metrics.NewRegisteredMeter("les/server/req/avgEstimatedTime", nil)
84+
requestEstimatedTimer = metrics.NewRegisteredTimer("les/server/req/estimatedTime", nil)
85+
relativeCostHistogram = metrics.NewRegisteredHistogram("les/server/req/relative", nil, metrics.NewExpDecaySample(1028, 0.015))
86+
relativeCostHeaderHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/header", nil, metrics.NewExpDecaySample(1028, 0.015))
87+
relativeCostBodyHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/body", nil, metrics.NewExpDecaySample(1028, 0.015))
88+
relativeCostReceiptHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/receipt", nil, metrics.NewExpDecaySample(1028, 0.015))
89+
relativeCostCodeHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/code", nil, metrics.NewExpDecaySample(1028, 0.015))
90+
relativeCostProofHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/proof", nil, metrics.NewExpDecaySample(1028, 0.015))
91+
relativeCostHelperProofHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/helperTrie", nil, metrics.NewExpDecaySample(1028, 0.015))
92+
relativeCostSendTxHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/txs", nil, metrics.NewExpDecaySample(1028, 0.015))
93+
relativeCostTxStatusHistogram = metrics.NewRegisteredHistogram("les/server/req/relative/txStatus", nil, metrics.NewExpDecaySample(1028, 0.015))
94+
95+
globalFactorGauge = metrics.NewRegisteredGauge("les/server/globalFactor", nil)
7896
recentServedGauge = metrics.NewRegisteredGauge("les/server/recentRequestServed", nil)
7997
recentEstimatedGauge = metrics.NewRegisteredGauge("les/server/recentRequestEstimated", nil)
8098
sqServedGauge = metrics.NewRegisteredGauge("les/server/servingQueue/served", nil)

les/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ func NewLesServer(e *eth.Ethereum, config *eth.Config) (*LesServer, error) {
113113
}
114114
srv.fcManager.SetCapacityLimits(srv.freeCapacity, maxCapacity, srv.freeCapacity*2)
115115
srv.clientPool = newClientPool(srv.chainDb, srv.freeCapacity, 10000, mclock.System{}, func(id enode.ID) { go srv.peers.Unregister(peerIdToString(id)) })
116+
srv.clientPool.setPriceFactors(priceFactors{0, 1, 1}, priceFactors{0, 1, 1})
116117

117118
checkpoint := srv.latestLocalCheckpoint()
118119
if !checkpoint.Empty() {

les/server_handler.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
268268
if metrics.EnabledExpensive {
269269
miscInHeaderPacketsMeter.Mark(1)
270270
miscInHeaderTrafficMeter.Mark(int64(msg.Size))
271+
defer func(start time.Time) { miscServingTimeHeaderTimer.UpdateSince(start) }(time.Now())
271272
}
272273
var req struct {
273274
ReqID uint64
@@ -380,6 +381,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
380381
if metrics.EnabledExpensive {
381382
miscInBodyPacketsMeter.Mark(1)
382383
miscInBodyTrafficMeter.Mark(int64(msg.Size))
384+
defer func(start time.Time) { miscServingTimeBodyTimer.UpdateSince(start) }(time.Now())
383385
}
384386
var req struct {
385387
ReqID uint64
@@ -428,6 +430,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
428430
if metrics.EnabledExpensive {
429431
miscInCodePacketsMeter.Mark(1)
430432
miscInCodeTrafficMeter.Mark(int64(msg.Size))
433+
defer func(start time.Time) { miscServingTimeCodeTimer.UpdateSince(start) }(time.Now())
431434
}
432435
var req struct {
433436
ReqID uint64
@@ -499,6 +502,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
499502
if metrics.EnabledExpensive {
500503
miscInReceiptPacketsMeter.Mark(1)
501504
miscInReceiptTrafficMeter.Mark(int64(msg.Size))
505+
defer func(start time.Time) { miscServingTimeReceiptTimer.UpdateSince(start) }(time.Now())
502506
}
503507
var req struct {
504508
ReqID uint64
@@ -555,6 +559,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
555559
if metrics.EnabledExpensive {
556560
miscInTrieProofPacketsMeter.Mark(1)
557561
miscInTrieProofTrafficMeter.Mark(int64(msg.Size))
562+
defer func(start time.Time) { miscServingTimeTrieProofTimer.UpdateSince(start) }(time.Now())
558563
}
559564
var req struct {
560565
ReqID uint64
@@ -657,6 +662,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
657662
if metrics.EnabledExpensive {
658663
miscInHelperTriePacketsMeter.Mark(1)
659664
miscInHelperTrieTrafficMeter.Mark(int64(msg.Size))
665+
defer func(start time.Time) { miscServingTimeHelperTrieTimer.UpdateSince(start) }(time.Now())
660666
}
661667
var req struct {
662668
ReqID uint64
@@ -731,6 +737,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
731737
if metrics.EnabledExpensive {
732738
miscInTxsPacketsMeter.Mark(1)
733739
miscInTxsTrafficMeter.Mark(int64(msg.Size))
740+
defer func(start time.Time) { miscServingTimeTxTimer.UpdateSince(start) }(time.Now())
734741
}
735742
var req struct {
736743
ReqID uint64
@@ -779,6 +786,7 @@ func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
779786
if metrics.EnabledExpensive {
780787
miscInTxStatusPacketsMeter.Mark(1)
781788
miscInTxStatusTrafficMeter.Mark(int64(msg.Size))
789+
defer func(start time.Time) { miscServingTimeTxStatusTimer.UpdateSince(start) }(time.Now())
782790
}
783791
var req struct {
784792
ReqID uint64

light/lightchain.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,6 @@ func (lc *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com
438438
//
439439
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
440440
func (lc *LightChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
441-
lc.chainmu.RLock()
442-
defer lc.chainmu.RUnlock()
443-
444441
return lc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
445442
}
446443

0 commit comments

Comments
 (0)