light: give free credits for reserved peers (#9448)
* light: give free credits for reserved peers * Fix ethcore-light tests * Test free_flow_params
This commit is contained in:
parent
2177a0179e
commit
44531e3009
@ -44,6 +44,9 @@ pub trait IoContext {
|
|||||||
|
|
||||||
/// Persistent peer id
|
/// Persistent peer id
|
||||||
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
|
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
|
||||||
|
|
||||||
|
/// Whether given peer id is reserved peer
|
||||||
|
fn is_reserved_peer(&self, peer: PeerId) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IoContext for T where T: ?Sized + NetworkContext {
|
impl<T> IoContext for T where T: ?Sized + NetworkContext {
|
||||||
@ -76,6 +79,10 @@ impl<T> IoContext for T where T: ?Sized + NetworkContext {
|
|||||||
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId> {
|
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId> {
|
||||||
self.session_info(peer).and_then(|info| info.id)
|
self.session_info(peer).and_then(|info| info.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_reserved_peer(&self, peer: PeerId) -> bool {
|
||||||
|
NetworkContext::is_reserved_peer(self, peer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Basic context for the protocol.
|
/// Basic context for the protocol.
|
||||||
|
@ -354,6 +354,7 @@ pub struct LightProtocol {
|
|||||||
peers: RwLock<PeerMap>,
|
peers: RwLock<PeerMap>,
|
||||||
capabilities: RwLock<Capabilities>,
|
capabilities: RwLock<Capabilities>,
|
||||||
flow_params: RwLock<Arc<FlowParams>>,
|
flow_params: RwLock<Arc<FlowParams>>,
|
||||||
|
free_flow_params: Arc<FlowParams>,
|
||||||
handlers: Vec<Arc<Handler>>,
|
handlers: Vec<Arc<Handler>>,
|
||||||
req_id: AtomicUsize,
|
req_id: AtomicUsize,
|
||||||
sample_store: Box<SampleStore>,
|
sample_store: Box<SampleStore>,
|
||||||
@ -383,6 +384,7 @@ impl LightProtocol {
|
|||||||
peers: RwLock::new(HashMap::new()),
|
peers: RwLock::new(HashMap::new()),
|
||||||
capabilities: RwLock::new(params.capabilities),
|
capabilities: RwLock::new(params.capabilities),
|
||||||
flow_params: RwLock::new(Arc::new(flow_params)),
|
flow_params: RwLock::new(Arc::new(flow_params)),
|
||||||
|
free_flow_params: Arc::new(FlowParams::free()),
|
||||||
handlers: Vec::new(),
|
handlers: Vec::new(),
|
||||||
req_id: AtomicUsize::new(0),
|
req_id: AtomicUsize::new(0),
|
||||||
sample_store,
|
sample_store,
|
||||||
@ -706,8 +708,13 @@ impl LightProtocol {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let capabilities = self.capabilities.read();
|
let capabilities = self.capabilities.read();
|
||||||
let local_flow = self.flow_params.read();
|
let cost_local_flow = self.flow_params.read();
|
||||||
let status_packet = status::write_handshake(&status, &capabilities, Some(&**local_flow));
|
let local_flow = if io.is_reserved_peer(peer) {
|
||||||
|
&*self.free_flow_params
|
||||||
|
} else {
|
||||||
|
&**cost_local_flow
|
||||||
|
};
|
||||||
|
let status_packet = status::write_handshake(&status, &capabilities, Some(local_flow));
|
||||||
|
|
||||||
self.pending_peers.write().insert(peer, PendingPeer {
|
self.pending_peers.write().insert(peer, PendingPeer {
|
||||||
sent_head: chain_info.best_block_hash,
|
sent_head: chain_info.best_block_hash,
|
||||||
@ -818,7 +825,11 @@ impl LightProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let remote_flow = flow_params.map(|params| (params.create_credits(), params));
|
let remote_flow = flow_params.map(|params| (params.create_credits(), params));
|
||||||
let local_flow = self.flow_params.read().clone();
|
let local_flow = if io.is_reserved_peer(peer) {
|
||||||
|
self.free_flow_params.clone()
|
||||||
|
} else {
|
||||||
|
self.flow_params.read().clone()
|
||||||
|
};
|
||||||
|
|
||||||
self.peers.write().insert(peer, Mutex::new(Peer {
|
self.peers.write().insert(peer, Mutex::new(Peer {
|
||||||
local_credits: local_flow.create_credits(),
|
local_credits: local_flow.create_credits(),
|
||||||
|
@ -87,6 +87,10 @@ impl IoContext for Expect {
|
|||||||
fn persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> {
|
fn persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_reserved_peer(&self, peer: PeerId) -> bool {
|
||||||
|
peer == 0xff
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// can't implement directly for Arc due to cross-crate orphan rules.
|
// can't implement directly for Arc due to cross-crate orphan rules.
|
||||||
@ -190,6 +194,10 @@ fn write_handshake(status: &Status, capabilities: &Capabilities, proto: &LightPr
|
|||||||
::net::status::write_handshake(status, capabilities, Some(&*flow_params))
|
::net::status::write_handshake(status, capabilities, Some(&*flow_params))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_free_handshake(status: &Status, capabilities: &Capabilities, proto: &LightProtocol) -> Vec<u8> {
|
||||||
|
::net::status::write_handshake(status, capabilities, Some(&proto.free_flow_params))
|
||||||
|
}
|
||||||
|
|
||||||
// helper for setting up the protocol handler and provider.
|
// helper for setting up the protocol handler and provider.
|
||||||
fn setup(capabilities: Capabilities) -> (Arc<TestProviderInner>, LightProtocol) {
|
fn setup(capabilities: Capabilities) -> (Arc<TestProviderInner>, LightProtocol) {
|
||||||
let provider = Arc::new(TestProviderInner {
|
let provider = Arc::new(TestProviderInner {
|
||||||
@ -231,6 +239,19 @@ fn handshake_expected() {
|
|||||||
proto.on_connect(1, &Expect::Send(1, packet::STATUS, packet_body));
|
proto.on_connect(1, &Expect::Send(1, packet::STATUS, packet_body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserved_handshake_expected() {
|
||||||
|
let capabilities = capabilities();
|
||||||
|
|
||||||
|
let (provider, proto) = setup(capabilities);
|
||||||
|
|
||||||
|
let status = status(provider.client.chain_info());
|
||||||
|
|
||||||
|
let packet_body = write_free_handshake(&status, &capabilities, &proto);
|
||||||
|
|
||||||
|
proto.on_connect(0xff, &Expect::Send(0xff, packet::STATUS, packet_body));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn genesis_mismatch() {
|
fn genesis_mismatch() {
|
||||||
|
@ -68,6 +68,7 @@ impl<'a> IoContext for TestIoContext<'a> {
|
|||||||
fn protocol_version(&self, _peer: PeerId) -> Option<u8> { Some(::light::net::MAX_PROTOCOL_VERSION) }
|
fn protocol_version(&self, _peer: PeerId) -> Option<u8> { Some(::light::net::MAX_PROTOCOL_VERSION) }
|
||||||
|
|
||||||
fn persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> { unimplemented!() }
|
fn persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> { unimplemented!() }
|
||||||
|
fn is_reserved_peer(&self, _peer: PeerId) -> bool { false }
|
||||||
}
|
}
|
||||||
|
|
||||||
// peer-specific data.
|
// peer-specific data.
|
||||||
|
@ -102,7 +102,7 @@ pub struct NetworkContext<'s> {
|
|||||||
sessions: Arc<RwLock<Slab<SharedSession>>>,
|
sessions: Arc<RwLock<Slab<SharedSession>>>,
|
||||||
session: Option<SharedSession>,
|
session: Option<SharedSession>,
|
||||||
session_id: Option<StreamToken>,
|
session_id: Option<StreamToken>,
|
||||||
_reserved_peers: &'s HashSet<NodeId>,
|
reserved_peers: &'s HashSet<NodeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> NetworkContext<'s> {
|
impl<'s> NetworkContext<'s> {
|
||||||
@ -121,7 +121,7 @@ impl<'s> NetworkContext<'s> {
|
|||||||
session_id: id,
|
session_id: id,
|
||||||
session,
|
session,
|
||||||
sessions,
|
sessions,
|
||||||
_reserved_peers: reserved_peers,
|
reserved_peers: reserved_peers,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +190,13 @@ impl<'s> NetworkContextTrait for NetworkContext<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn subprotocol_name(&self) -> ProtocolId { self.protocol }
|
fn subprotocol_name(&self) -> ProtocolId { self.protocol }
|
||||||
|
|
||||||
|
fn is_reserved_peer(&self, peer: PeerId) -> bool {
|
||||||
|
self.session_info(peer)
|
||||||
|
.and_then(|info| info.id)
|
||||||
|
.map(|node| self.reserved_peers.contains(&node))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared host information
|
/// Shared host information
|
||||||
|
@ -285,6 +285,9 @@ pub trait NetworkContext {
|
|||||||
|
|
||||||
/// Returns this object's subprotocol name.
|
/// Returns this object's subprotocol name.
|
||||||
fn subprotocol_name(&self) -> ProtocolId;
|
fn subprotocol_name(&self) -> ProtocolId;
|
||||||
|
|
||||||
|
/// Returns whether the given peer ID is a reserved peer.
|
||||||
|
fn is_reserved_peer(&self, peer: PeerId) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext {
|
impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext {
|
||||||
@ -331,6 +334,10 @@ impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext {
|
|||||||
fn subprotocol_name(&self) -> ProtocolId {
|
fn subprotocol_name(&self) -> ProtocolId {
|
||||||
(**self).subprotocol_name()
|
(**self).subprotocol_name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_reserved_peer(&self, peer: PeerId) -> bool {
|
||||||
|
(**self).is_reserved_peer(peer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Network IO protocol handler. This needs to be implemented for each new subprotocol.
|
/// Network IO protocol handler. This needs to be implemented for each new subprotocol.
|
||||||
|
Loading…
Reference in New Issue
Block a user