Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
88f174a0
Commit
88f174a0
authored
Jun 01, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth/downloader: adaptive quality of service tuning
parent
780bdb3e
Changes
3
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
235 additions
and
48 deletions
+235
-48
downloader.go
eth/downloader/downloader.go
+119
-25
downloader_test.go
eth/downloader/downloader_test.go
+54
-4
peer.go
eth/downloader/peer.go
+62
-19
No files found.
eth/downloader/downloader.go
View file @
88f174a0
This diff is collapsed.
Click to expand it.
eth/downloader/downloader_test.go
View file @
88f174a0
This diff is collapsed.
Click to expand it.
eth/downloader/peer.go
View file @
88f174a0
...
...
@@ -23,6 +23,8 @@ import (
"errors"
"fmt"
"math"
"sort"
"strings"
"sync"
"sync/atomic"
"time"
...
...
@@ -32,7 +34,7 @@ import (
const
(
maxLackingHashes
=
4096
// Maximum number of entries allowed on the list or lacking items
throughpu
tImpact
=
0.1
// The impact a single measurement has on a peer's final throughput value.
measuremen
tImpact
=
0.1
// The impact a single measurement has on a peer's final throughput value.
)
// Hash and block fetchers belonging to eth/61 and below
...
...
@@ -68,6 +70,8 @@ type peer struct {
receiptThroughput
float64
// Number of receipts measured to be retrievable per second
stateThroughput
float64
// Number of node data pieces measured to be retrievable per second
rtt
time
.
Duration
// Request round trip time to track responsiveness (QoS)
headerStarted
time
.
Time
// Time instance when the last header fetch was started
blockStarted
time
.
Time
// Time instance when the last block (body) fetch was started
receiptStarted
time
.
Time
// Time instance when the last receipt fetch was started
...
...
@@ -290,44 +294,47 @@ func (p *peer) setIdle(started time.Time, delivered int, throughput *float64, id
return
}
// Otherwise update the throughput with a new measurement
measured
:=
float64
(
delivered
)
/
(
float64
(
time
.
Since
(
started
)
+
1
)
/
float64
(
time
.
Second
))
// +1 (ns) to ensure non-zero divisor
*
throughput
=
(
1
-
throughputImpact
)
*
(
*
throughput
)
+
throughputImpact
*
measured
elapsed
:=
time
.
Since
(
started
)
+
1
// +1 (ns) to ensure non-zero divisor
measured
:=
float64
(
delivered
)
/
(
float64
(
elapsed
)
/
float64
(
time
.
Second
))
*
throughput
=
(
1
-
measurementImpact
)
*
(
*
throughput
)
+
measurementImpact
*
measured
p
.
rtt
=
time
.
Duration
((
1
-
measurementImpact
)
*
float64
(
p
.
rtt
)
+
measurementImpact
*
float64
(
elapsed
))
}
// HeaderCapacity retrieves the peers header download allowance based on its
// previously discovered throughput.
func
(
p
*
peer
)
HeaderCapacity
()
int
{
func
(
p
*
peer
)
HeaderCapacity
(
targetRTT
time
.
Duration
)
int
{
p
.
lock
.
RLock
()
defer
p
.
lock
.
RUnlock
()
return
int
(
math
.
M
ax
(
1
,
math
.
Min
(
p
.
headerThroughput
*
float64
(
headerTargetRTT
)
/
float64
(
time
.
Second
),
float64
(
MaxHeaderFetch
)
)))
return
int
(
math
.
M
in
(
1
+
math
.
Max
(
1
,
p
.
headerThroughput
*
float64
(
targetRTT
)
/
float64
(
time
.
Second
)),
float64
(
MaxHeaderFetch
)))
}
// BlockCapacity retrieves the peers block download allowance based on its
// previously discovered throughput.
func
(
p
*
peer
)
BlockCapacity
()
int
{
func
(
p
*
peer
)
BlockCapacity
(
targetRTT
time
.
Duration
)
int
{
p
.
lock
.
RLock
()
defer
p
.
lock
.
RUnlock
()
return
int
(
math
.
M
ax
(
1
,
math
.
Min
(
p
.
blockThroughput
*
float64
(
blockTargetRTT
)
/
float64
(
time
.
Second
),
float64
(
MaxBlockFetch
)
)))
return
int
(
math
.
M
in
(
1
+
math
.
Max
(
1
,
p
.
blockThroughput
*
float64
(
targetRTT
)
/
float64
(
time
.
Second
)),
float64
(
MaxBlockFetch
)))
}
// ReceiptCapacity retrieves the peers receipt download allowance based on its
// previously discovered throughput.
func
(
p
*
peer
)
ReceiptCapacity
()
int
{
func
(
p
*
peer
)
ReceiptCapacity
(
targetRTT
time
.
Duration
)
int
{
p
.
lock
.
RLock
()
defer
p
.
lock
.
RUnlock
()
return
int
(
math
.
M
ax
(
1
,
math
.
Min
(
p
.
receiptThroughput
*
float64
(
receiptTargetRTT
)
/
float64
(
time
.
Second
),
float64
(
MaxReceiptFetch
)
)))
return
int
(
math
.
M
in
(
1
+
math
.
Max
(
1
,
p
.
receiptThroughput
*
float64
(
targetRTT
)
/
float64
(
time
.
Second
)),
float64
(
MaxReceiptFetch
)))
}
// NodeDataCapacity retrieves the peers state download allowance based on its
// previously discovered throughput.
func
(
p
*
peer
)
NodeDataCapacity
()
int
{
func
(
p
*
peer
)
NodeDataCapacity
(
targetRTT
time
.
Duration
)
int
{
p
.
lock
.
RLock
()
defer
p
.
lock
.
RUnlock
()
return
int
(
math
.
M
ax
(
1
,
math
.
Min
(
p
.
stateThroughput
*
float64
(
stateTargetRTT
)
/
float64
(
time
.
Second
),
float64
(
MaxStateFetch
)
)))
return
int
(
math
.
M
in
(
1
+
math
.
Max
(
1
,
p
.
stateThroughput
*
float64
(
targetRTT
)
/
float64
(
time
.
Second
)),
float64
(
MaxStateFetch
)))
}
// MarkLacking appends a new entity to the set of items (blocks, receipts, states)
...
...
@@ -361,13 +368,14 @@ func (p *peer) String() string {
p
.
lock
.
RLock
()
defer
p
.
lock
.
RUnlock
()
return
fmt
.
Sprintf
(
"Peer %s [%s]"
,
p
.
id
,
fmt
.
Sprintf
(
"headers %3.2f/s, "
,
p
.
headerThroughput
)
+
fmt
.
Sprintf
(
"blocks %3.2f/s, "
,
p
.
blockThroughput
)
+
fmt
.
Sprintf
(
"receipts %3.2f/s, "
,
p
.
receiptThroughput
)
+
fmt
.
Sprintf
(
"states %3.2f/s, "
,
p
.
stateThroughput
)
+
fmt
.
Sprintf
(
"lacking %4d"
,
len
(
p
.
lacking
)),
)
return
fmt
.
Sprintf
(
"Peer %s [%s]"
,
p
.
id
,
strings
.
Join
([]
string
{
fmt
.
Sprintf
(
"hs %3.2f/s"
,
p
.
headerThroughput
),
fmt
.
Sprintf
(
"bs %3.2f/s"
,
p
.
blockThroughput
),
fmt
.
Sprintf
(
"rs %3.2f/s"
,
p
.
receiptThroughput
),
fmt
.
Sprintf
(
"ss %3.2f/s"
,
p
.
stateThroughput
),
fmt
.
Sprintf
(
"miss %4d"
,
len
(
p
.
lacking
)),
fmt
.
Sprintf
(
"rtt %v"
,
p
.
rtt
),
},
", "
))
}
// peerSet represents the collection of active peer participating in the chain
...
...
@@ -402,6 +410,10 @@ func (ps *peerSet) Reset() {
// average of all existing peers, to give it a realistic chance of being used
// for data retrievals.
func
(
ps
*
peerSet
)
Register
(
p
*
peer
)
error
{
// Retrieve the current median RTT as a sane default
p
.
rtt
=
ps
.
medianRTT
()
// Register the new peer with some meaningful defaults
ps
.
lock
.
Lock
()
defer
ps
.
lock
.
Unlock
()
...
...
@@ -564,3 +576,34 @@ func (ps *peerSet) idlePeers(minProtocol, maxProtocol int, idleCheck func(*peer)
}
return
idle
,
total
}
// medianRTT returns the median RTT of te peerset, considering only the tuning
// peers if there are more peers available.
func
(
ps
*
peerSet
)
medianRTT
()
time
.
Duration
{
// Gather all the currnetly measured round trip times
ps
.
lock
.
RLock
()
defer
ps
.
lock
.
RUnlock
()
rtts
:=
make
([]
float64
,
0
,
len
(
ps
.
peers
))
for
_
,
p
:=
range
ps
.
peers
{
p
.
lock
.
RLock
()
rtts
=
append
(
rtts
,
float64
(
p
.
rtt
))
p
.
lock
.
RUnlock
()
}
sort
.
Float64s
(
rtts
)
median
:=
rttMaxEstimate
if
qosTuningPeers
<=
len
(
rtts
)
{
median
=
time
.
Duration
(
rtts
[
qosTuningPeers
/
2
])
// Median of our tuning peers
}
else
if
len
(
rtts
)
>
0
{
median
=
time
.
Duration
(
rtts
[
len
(
rtts
)
/
2
])
// Median of our connected peers (maintain even like this some baseline qos)
}
// Restrict the RTT into some QoS defaults, irrelevant of true RTT
if
median
<
rttMinEstimate
{
median
=
rttMinEstimate
}
if
median
>
rttMaxEstimate
{
median
=
rttMaxEstimate
}
return
median
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment