Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
exchain
nebula
Commits
c21b2876
Commit
c21b2876
authored
May 08, 2023
by
Felipe Andrade
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
proxyd: add limit to consensus block lag
parent
fd86a57e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
3 deletions
+63
-3
config.go
proxyd/config.go
+1
-0
consensus_poller.go
proxyd/consensus_poller.go
+18
-3
example.config.toml
proxyd/example.config.toml
+2
-0
consensus_test.go
proxyd/integration_tests/consensus_test.go
+38
-0
consensus.toml
proxyd/integration_tests/testdata/consensus.toml
+1
-0
proxyd.go
proxyd/proxyd.go
+3
-0
No files found.
proxyd/config.go
View file @
c21b2876
...
@@ -105,6 +105,7 @@ type BackendGroupConfig struct {
...
@@ -105,6 +105,7 @@ type BackendGroupConfig struct {
ConsensusBanPeriod
TOMLDuration
`toml:"consensus_ban_period"`
ConsensusBanPeriod
TOMLDuration
`toml:"consensus_ban_period"`
ConsensusMaxUpdateThreshold
TOMLDuration
`toml:"consensus_max_update_threshold"`
ConsensusMaxUpdateThreshold
TOMLDuration
`toml:"consensus_max_update_threshold"`
ConsensusMaxBlockLag
uint64
`toml:"consensus_max_block_lag"`
ConsensusMinPeerCount
int
`toml:"consensus_min_peer_count"`
ConsensusMinPeerCount
int
`toml:"consensus_min_peer_count"`
}
}
...
...
proxyd/consensus_poller.go
View file @
c21b2876
...
@@ -35,6 +35,7 @@ type ConsensusPoller struct {
...
@@ -35,6 +35,7 @@ type ConsensusPoller struct {
banPeriod
time
.
Duration
banPeriod
time
.
Duration
maxUpdateThreshold
time
.
Duration
maxUpdateThreshold
time
.
Duration
maxBlockLag
uint64
}
}
type
backendState
struct
{
type
backendState
struct
{
...
@@ -160,6 +161,12 @@ func WithMaxUpdateThreshold(maxUpdateThreshold time.Duration) ConsensusOpt {
...
@@ -160,6 +161,12 @@ func WithMaxUpdateThreshold(maxUpdateThreshold time.Duration) ConsensusOpt {
}
}
}
}
func
WithMaxBlockLag
(
maxBlockLag
uint64
)
ConsensusOpt
{
return
func
(
cp
*
ConsensusPoller
)
{
cp
.
maxBlockLag
=
maxBlockLag
}
}
func
WithMinPeerCount
(
minPeerCount
uint64
)
ConsensusOpt
{
func
WithMinPeerCount
(
minPeerCount
uint64
)
ConsensusOpt
{
return
func
(
cp
*
ConsensusPoller
)
{
return
func
(
cp
*
ConsensusPoller
)
{
cp
.
minPeerCount
=
minPeerCount
cp
.
minPeerCount
=
minPeerCount
...
@@ -181,6 +188,7 @@ func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller
...
@@ -181,6 +188,7 @@ func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller
banPeriod
:
5
*
time
.
Minute
,
banPeriod
:
5
*
time
.
Minute
,
maxUpdateThreshold
:
30
*
time
.
Second
,
maxUpdateThreshold
:
30
*
time
.
Second
,
maxBlockLag
:
50
,
minPeerCount
:
3
,
minPeerCount
:
3
,
}
}
...
@@ -270,7 +278,12 @@ func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
...
@@ -270,7 +278,12 @@ func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
continue
continue
}
}
if
lowestBlock
==
0
||
backendLatestBlockNumber
<
lowestBlock
{
// find the highest common ancestor, ignoring backends that are too far lagging behind
// when the backend is too far ahead from current lowest, the current lowest is ignored
// when the backend if too far behind, the backend itself is ignored
if
lowestBlock
==
0
||
backendLatestBlockNumber
>
lowestBlock
&&
uint64
(
backendLatestBlockNumber
-
lowestBlock
)
>
cp
.
maxBlockLag
||
backendLatestBlockNumber
<
lowestBlock
&&
uint64
(
lowestBlock
-
backendLatestBlockNumber
)
<
cp
.
maxBlockLag
{
lowestBlock
=
backendLatestBlockNumber
lowestBlock
=
backendLatestBlockNumber
lowestBlockHash
=
backendLatestBlockHash
lowestBlockHash
=
backendLatestBlockHash
}
}
...
@@ -308,12 +321,14 @@ func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
...
@@ -308,12 +321,14 @@ func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
- not banned
- not banned
- with minimum peer count
- with minimum peer count
- updated recently
- updated recently
- not lagging
*/
*/
peerCount
,
_
,
_
,
lastUpdate
,
bannedUntil
:=
cp
.
getBackendState
(
be
)
peerCount
,
latestBlockNumber
,
_
,
lastUpdate
,
bannedUntil
:=
cp
.
getBackendState
(
be
)
notUpdated
:=
lastUpdate
.
Add
(
cp
.
maxUpdateThreshold
)
.
Before
(
time
.
Now
())
notUpdated
:=
lastUpdate
.
Add
(
cp
.
maxUpdateThreshold
)
.
Before
(
time
.
Now
())
isBanned
:=
time
.
Now
()
.
Before
(
bannedUntil
)
isBanned
:=
time
.
Now
()
.
Before
(
bannedUntil
)
notEnoughPeers
:=
!
be
.
skipPeerCountCheck
&&
peerCount
<
cp
.
minPeerCount
notEnoughPeers
:=
!
be
.
skipPeerCountCheck
&&
peerCount
<
cp
.
minPeerCount
if
!
be
.
IsHealthy
()
||
be
.
IsRateLimited
()
||
!
be
.
Online
()
||
notUpdated
||
isBanned
||
notEnoughPeers
{
lagging
:=
(
latestBlockNumber
<
proposedBlock
)
&&
uint64
(
proposedBlock
-
latestBlockNumber
)
>=
cp
.
maxBlockLag
if
!
be
.
IsHealthy
()
||
be
.
IsRateLimited
()
||
!
be
.
Online
()
||
notUpdated
||
isBanned
||
notEnoughPeers
||
lagging
{
filteredBackendsNames
=
append
(
filteredBackendsNames
,
be
.
Name
)
filteredBackendsNames
=
append
(
filteredBackendsNames
,
be
.
Name
)
continue
continue
}
}
...
...
proxyd/example.config.toml
View file @
c21b2876
...
@@ -93,6 +93,8 @@ backends = ["infura"]
...
@@ -93,6 +93,8 @@ backends = ["infura"]
# consensus_ban_period = "1m"
# consensus_ban_period = "1m"
# Maximum delay for update the backend, default 30s
# Maximum delay for update the backend, default 30s
# consensus_max_update_threshold = "20s"
# consensus_max_update_threshold = "20s"
# Maximum block lag, default 50
# consensus_max_block_lag = 10
# Minimum peer count, default 3
# Minimum peer count, default 3
# consensus_min_peer_count = 4
# consensus_min_peer_count = 4
...
...
proxyd/integration_tests/consensus_test.go
View file @
c21b2876
...
@@ -97,6 +97,44 @@ func TestConsensus(t *testing.T) {
...
@@ -97,6 +97,44 @@ func TestConsensus(t *testing.T) {
require
.
Equal
(
t
,
1
,
len
(
consensusGroup
))
require
.
Equal
(
t
,
1
,
len
(
consensusGroup
))
})
})
t
.
Run
(
"prevent using a backend lagging behind"
,
func
(
t
*
testing
.
T
)
{
h1
.
ResetOverrides
()
h2
.
ResetOverrides
()
bg
.
Consensus
.
Unban
()
h1
.
AddOverride
(
&
ms
.
MethodTemplate
{
Method
:
"eth_getBlockByNumber"
,
Block
:
"latest"
,
Response
:
buildGetBlockResponse
(
"0x1"
,
"hash1"
),
})
h2
.
AddOverride
(
&
ms
.
MethodTemplate
{
Method
:
"eth_getBlockByNumber"
,
Block
:
"latest"
,
Response
:
buildGetBlockResponse
(
"0x100"
,
"hash0x100"
),
})
h2
.
AddOverride
(
&
ms
.
MethodTemplate
{
Method
:
"eth_getBlockByNumber"
,
Block
:
"0x100"
,
Response
:
buildGetBlockResponse
(
"0x100"
,
"hash0x100"
),
})
for
_
,
be
:=
range
bg
.
Backends
{
bg
.
Consensus
.
UpdateBackend
(
ctx
,
be
)
}
bg
.
Consensus
.
UpdateBackendGroupConsensus
(
ctx
)
// since we ignored node1, the consensus should be at 0x100
require
.
Equal
(
t
,
"0x100"
,
bg
.
Consensus
.
GetConsensusBlockNumber
()
.
String
())
consensusGroup
:=
bg
.
Consensus
.
GetConsensusGroup
()
be
:=
backend
(
bg
,
"node1"
)
require
.
NotNil
(
t
,
be
)
require
.
NotContains
(
t
,
consensusGroup
,
be
)
require
.
Equal
(
t
,
1
,
len
(
consensusGroup
))
})
t
.
Run
(
"prevent using a backend not in sync"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"prevent using a backend not in sync"
,
func
(
t
*
testing
.
T
)
{
h1
.
ResetOverrides
()
h1
.
ResetOverrides
()
h2
.
ResetOverrides
()
h2
.
ResetOverrides
()
...
...
proxyd/integration_tests/testdata/consensus.toml
View file @
c21b2876
...
@@ -18,6 +18,7 @@ consensus_aware = true
...
@@ -18,6 +18,7 @@ consensus_aware = true
consensus_handler
=
"noop"
# allow more control over the consensus poller for tests
consensus_handler
=
"noop"
# allow more control over the consensus poller for tests
consensus_ban_period
=
"1m"
consensus_ban_period
=
"1m"
consensus_max_update_threshold
=
"2m"
consensus_max_update_threshold
=
"2m"
consensus_max_block_lag
=
50
consensus_min_peer_count
=
4
consensus_min_peer_count
=
4
[rpc_method_mappings]
[rpc_method_mappings]
...
...
proxyd/proxyd.go
View file @
c21b2876
...
@@ -328,6 +328,9 @@ func Start(config *Config) (*Server, func(), error) {
...
@@ -328,6 +328,9 @@ func Start(config *Config) (*Server, func(), error) {
if
bgcfg
.
ConsensusMaxUpdateThreshold
>
0
{
if
bgcfg
.
ConsensusMaxUpdateThreshold
>
0
{
copts
=
append
(
copts
,
WithMaxUpdateThreshold
(
time
.
Duration
(
bgcfg
.
ConsensusMaxUpdateThreshold
)))
copts
=
append
(
copts
,
WithMaxUpdateThreshold
(
time
.
Duration
(
bgcfg
.
ConsensusMaxUpdateThreshold
)))
}
}
if
bgcfg
.
ConsensusMaxBlockLag
>
0
{
copts
=
append
(
copts
,
WithMaxBlockLag
(
bgcfg
.
ConsensusMaxBlockLag
))
}
if
bgcfg
.
ConsensusMinPeerCount
>
0
{
if
bgcfg
.
ConsensusMinPeerCount
>
0
{
copts
=
append
(
copts
,
WithMinPeerCount
(
uint64
(
bgcfg
.
ConsensusMinPeerCount
)))
copts
=
append
(
copts
,
WithMinPeerCount
(
uint64
(
bgcfg
.
ConsensusMinPeerCount
)))
}
}
...
...
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