Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
polkadot-sdk
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
parity
Mirrored projects
polkadot-sdk
Commits
24c08a78
Commit
24c08a78
authored
5 years ago
by
Pierre Krieger
Committed by
Gavin Wood
5 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Make peerset ban nodes under a reputation (#2667)
parent
ff479c4e
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
substrate/core/peerset/src/lib.rs
+73
-12
73 additions, 12 deletions
substrate/core/peerset/src/lib.rs
with
73 additions
and
12 deletions
substrate/core/peerset/src/lib.rs
+
73
−
12
View file @
24c08a78
...
...
@@ -25,6 +25,8 @@ use libp2p::PeerId;
use
log
::{
debug
,
error
,
trace
};
use
serde_json
::
json
;
/// We don't accept nodes whose reputation is under this value.
const
BANNED_THRESHOLD
:
i32
=
82
*
(
i32
::
min_value
()
/
100
);
/// Reputation change for a node when we get disconnected from it.
const
DISCONNECT_REPUTATION_CHANGE
:
i32
=
-
10
;
...
...
@@ -232,7 +234,13 @@ impl Peerset {
self
.update_time
();
match
self
.data
.peer
(
&
peer_id
)
{
peersstate
::
Peer
::
Connected
(
mut
peer
)
=>
peer
.add_reputation
(
score_diff
),
peersstate
::
Peer
::
Connected
(
mut
peer
)
=>
{
peer
.add_reputation
(
score_diff
);
if
peer
.reputation
()
<
BANNED_THRESHOLD
{
peer
.disconnect
();
self
.message_queue
.push_back
(
Message
::
Drop
(
peer_id
));
}
},
peersstate
::
Peer
::
NotConnected
(
mut
peer
)
=>
peer
.add_reputation
(
score_diff
),
peersstate
::
Peer
::
Unknown
(
peer
)
=>
peer
.discover
()
.add_reputation
(
score_diff
),
}
...
...
@@ -283,22 +291,27 @@ impl Peerset {
fn
alloc_slots
(
&
mut
self
)
{
self
.update_time
();
// Try to grab the next node to attempt to connect to.
while
let
Some
(
next
)
=
self
.data
.reserved_not_connected_peer
()
{
match
next
.try_outgoing
()
{
Ok
(
conn
)
=>
self
.message_queue
.push_back
(
Message
::
Connect
(
conn
.into_peer_id
())),
Err
(
_
)
=>
break
,
// No more slots available.
}
}
loop
{
if
self
.reserved_only
{
break
}
// Try to grab the next node to attempt to connect to.
let
next
=
match
self
.data
.
reserved
_not_connected_peer
()
{
let
next
=
match
self
.data
.
highest
_not_connected_peer
()
{
Some
(
p
)
=>
p
,
None
=>
if
self
.reserved_only
{
break
// No known node to add.
}
else
{
match
self
.data
.highest_not_connected_peer
()
{
Some
(
p
)
=>
p
,
None
=>
break
,
// No known node to add.
}
}
None
=>
break
,
// No known node to add.
};
// Don't connect to nodes with an abysmal reputation.
if
next
.reputation
()
==
i32
::
min_value
()
{
if
next
.reputation
()
<
BANNED_THRESHOLD
{
break
;
}
...
...
@@ -321,6 +334,7 @@ impl Peerset {
// `PeerId` before that message has been read by the user. In this situation we must not answer.
pub
fn
incoming
(
&
mut
self
,
peer_id
:
PeerId
,
index
:
IncomingIndex
)
{
trace!
(
target
:
"peerset"
,
"Incoming {:?}"
,
peer_id
);
self
.update_time
();
let
not_connected
=
match
self
.data
.peer
(
&
peer_id
)
{
// If we're already connected, don't answer, as the docs mention.
...
...
@@ -329,6 +343,11 @@ impl Peerset {
peersstate
::
Peer
::
Unknown
(
entry
)
=>
entry
.discover
(),
};
if
not_connected
.reputation
()
<
BANNED_THRESHOLD
{
self
.message_queue
.push_back
(
Message
::
Reject
(
index
));
return
}
match
not_connected
.try_accept_incoming
()
{
Ok
(
_
)
=>
self
.message_queue
.push_back
(
Message
::
Accept
(
index
)),
Err
(
_
)
=>
self
.message_queue
.push_back
(
Message
::
Reject
(
index
)),
...
...
@@ -430,7 +449,8 @@ impl Stream for Peerset {
mod
tests
{
use
libp2p
::
PeerId
;
use
futures
::
prelude
::
*
;
use
super
::{
PeersetConfig
,
Peerset
,
Message
,
IncomingIndex
};
use
super
::{
PeersetConfig
,
Peerset
,
Message
,
IncomingIndex
,
BANNED_THRESHOLD
};
use
std
::{
thread
,
time
::
Duration
};
fn
assert_messages
(
mut
peerset
:
Peerset
,
messages
:
Vec
<
Message
>
)
->
Peerset
{
for
expected_message
in
messages
{
...
...
@@ -528,4 +548,45 @@ mod tests {
Message
::
Connect
(
discovered
),
]);
}
#[test]
fn
test_peerset_banned
()
{
let
(
mut
peerset
,
handle
)
=
Peerset
::
from_config
(
PeersetConfig
{
in_peers
:
25
,
out_peers
:
25
,
bootnodes
:
vec!
[],
reserved_only
:
false
,
reserved_nodes
:
vec!
[],
});
// We ban a node by setting its reputation under the threshold.
let
peer_id
=
PeerId
::
random
();
handle
.report_peer
(
peer_id
.clone
(),
BANNED_THRESHOLD
-
1
);
let
fut
=
futures
::
future
::
poll_fn
(
move
||
->
Result
<
_
,
()
>
{
// We need one polling for the message to be processed.
assert_eq!
(
peerset
.poll
()
.unwrap
(),
Async
::
NotReady
);
// Check that an incoming connection from that node gets refused.
peerset
.incoming
(
peer_id
.clone
(),
IncomingIndex
(
1
));
if
let
Async
::
Ready
(
msg
)
=
peerset
.poll
()
.unwrap
()
{
assert_eq!
(
msg
.unwrap
(),
Message
::
Reject
(
IncomingIndex
(
1
)));
}
else
{
panic!
()
}
// Wait a bit for the node's reputation to go above the threshold.
thread
::
sleep
(
Duration
::
from_millis
(
1500
));
// Try again. This time the node should be accepted.
peerset
.incoming
(
peer_id
.clone
(),
IncomingIndex
(
2
));
while
let
Async
::
Ready
(
msg
)
=
peerset
.poll
()
.unwrap
()
{
assert_eq!
(
msg
.unwrap
(),
Message
::
Accept
(
IncomingIndex
(
2
)));
}
Ok
(
Async
::
Ready
(()))
});
tokio
::
runtime
::
current_thread
::
Runtime
::
new
()
.unwrap
()
.block_on
(
fut
)
.unwrap
();
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment