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
 | 
			
		||||
	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 {
 | 
			
		||||
@ -76,6 +79,10 @@ impl<T> IoContext for T where T: ?Sized + NetworkContext {
 | 
			
		||||
	fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId> {
 | 
			
		||||
		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.
 | 
			
		||||
 | 
			
		||||
@ -354,6 +354,7 @@ pub struct LightProtocol {
 | 
			
		||||
	peers: RwLock<PeerMap>,
 | 
			
		||||
	capabilities: RwLock<Capabilities>,
 | 
			
		||||
	flow_params: RwLock<Arc<FlowParams>>,
 | 
			
		||||
	free_flow_params: Arc<FlowParams>,
 | 
			
		||||
	handlers: Vec<Arc<Handler>>,
 | 
			
		||||
	req_id: AtomicUsize,
 | 
			
		||||
	sample_store: Box<SampleStore>,
 | 
			
		||||
@ -383,6 +384,7 @@ impl LightProtocol {
 | 
			
		||||
			peers: RwLock::new(HashMap::new()),
 | 
			
		||||
			capabilities: RwLock::new(params.capabilities),
 | 
			
		||||
			flow_params: RwLock::new(Arc::new(flow_params)),
 | 
			
		||||
			free_flow_params: Arc::new(FlowParams::free()),
 | 
			
		||||
			handlers: Vec::new(),
 | 
			
		||||
			req_id: AtomicUsize::new(0),
 | 
			
		||||
			sample_store,
 | 
			
		||||
@ -706,8 +708,13 @@ impl LightProtocol {
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		let capabilities = self.capabilities.read();
 | 
			
		||||
		let local_flow = self.flow_params.read();
 | 
			
		||||
		let status_packet = status::write_handshake(&status, &capabilities, Some(&**local_flow));
 | 
			
		||||
		let cost_local_flow = self.flow_params.read();
 | 
			
		||||
		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 {
 | 
			
		||||
			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 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 {
 | 
			
		||||
			local_credits: local_flow.create_credits(),
 | 
			
		||||
 | 
			
		||||
@ -87,6 +87,10 @@ impl IoContext for Expect {
 | 
			
		||||
	fn persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> {
 | 
			
		||||
		None
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn is_reserved_peer(&self, peer: PeerId) -> bool {
 | 
			
		||||
		peer == 0xff
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
fn setup(capabilities: Capabilities) -> (Arc<TestProviderInner>, LightProtocol) {
 | 
			
		||||
	let provider = Arc::new(TestProviderInner {
 | 
			
		||||
@ -231,6 +239,19 @@ fn handshake_expected() {
 | 
			
		||||
	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]
 | 
			
		||||
#[should_panic]
 | 
			
		||||
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 persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> { unimplemented!() }
 | 
			
		||||
	fn is_reserved_peer(&self, _peer: PeerId) -> bool { false }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// peer-specific data.
 | 
			
		||||
 | 
			
		||||
@ -102,7 +102,7 @@ pub struct NetworkContext<'s> {
 | 
			
		||||
	sessions: Arc<RwLock<Slab<SharedSession>>>,
 | 
			
		||||
	session: Option<SharedSession>,
 | 
			
		||||
	session_id: Option<StreamToken>,
 | 
			
		||||
	_reserved_peers: &'s HashSet<NodeId>,
 | 
			
		||||
	reserved_peers: &'s HashSet<NodeId>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'s> NetworkContext<'s> {
 | 
			
		||||
@ -121,7 +121,7 @@ impl<'s> NetworkContext<'s> {
 | 
			
		||||
			session_id: id,
 | 
			
		||||
			session,
 | 
			
		||||
			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 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
 | 
			
		||||
 | 
			
		||||
@ -285,6 +285,9 @@ pub trait NetworkContext {
 | 
			
		||||
 | 
			
		||||
	/// Returns this object's subprotocol name.
 | 
			
		||||
	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 {
 | 
			
		||||
@ -331,6 +334,10 @@ impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext {
 | 
			
		||||
	fn subprotocol_name(&self) -> ProtocolId {
 | 
			
		||||
		(**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.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user