buffer flow -> request credits
This commit is contained in:
parent
f169c8dbb0
commit
ddbdfafc05
@ -44,8 +44,8 @@ pub enum Error {
|
||||
Rlp(DecoderError),
|
||||
/// A network error.
|
||||
Network(NetworkError),
|
||||
/// Out of buffer.
|
||||
BufferEmpty,
|
||||
/// Out of credits.
|
||||
NoCredits,
|
||||
/// Unrecognized packet code.
|
||||
UnrecognizedPacket(u8),
|
||||
/// Unexpected handshake.
|
||||
@ -72,7 +72,7 @@ impl Error {
|
||||
match *self {
|
||||
Error::Rlp(_) => Punishment::Disable,
|
||||
Error::Network(_) => Punishment::None,
|
||||
Error::BufferEmpty => Punishment::Disable,
|
||||
Error::NoCredits => Punishment::Disable,
|
||||
Error::UnrecognizedPacket(_) => Punishment::Disconnect,
|
||||
Error::UnexpectedHandshake => Punishment::Disconnect,
|
||||
Error::WrongNetwork => Punishment::Disable,
|
||||
@ -103,7 +103,7 @@ impl fmt::Display for Error {
|
||||
match *self {
|
||||
Error::Rlp(ref err) => err.fmt(f),
|
||||
Error::Network(ref err) => err.fmt(f),
|
||||
Error::BufferEmpty => write!(f, "Out of buffer"),
|
||||
Error::NoCredits => write!(f, "Out of request credits"),
|
||||
Error::UnrecognizedPacket(code) => write!(f, "Unrecognized packet: 0x{:x}", code),
|
||||
Error::UnexpectedHandshake => write!(f, "Unexpected handshake"),
|
||||
Error::WrongNetwork => write!(f, "Wrong network"),
|
||||
|
@ -37,7 +37,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use provider::Provider;
|
||||
use request::{self, HashOrNumber, Request};
|
||||
|
||||
use self::buffer_flow::{Buffer, FlowParams};
|
||||
use self::request_credits::{Credits, FlowParams};
|
||||
use self::context::{Ctx, TickCtx};
|
||||
use self::error::Punishment;
|
||||
use self::request_set::RequestSet;
|
||||
@ -51,7 +51,7 @@ mod request_set;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub mod buffer_flow;
|
||||
pub mod request_credits;
|
||||
|
||||
pub use self::error::Error;
|
||||
pub use self::context::{BasicContext, EventContext, IoContext};
|
||||
@ -143,10 +143,10 @@ struct PendingPeer {
|
||||
/// Relevant data to each peer. Not accessible publicly, only `pub` due to
|
||||
/// limitations of the privacy system.
|
||||
pub struct Peer {
|
||||
local_buffer: Buffer, // their buffer relative to us
|
||||
local_credits: Credits, // their credits relative to us
|
||||
status: Status,
|
||||
capabilities: Capabilities,
|
||||
remote_flow: Option<(Buffer, FlowParams)>,
|
||||
remote_flow: Option<(Credits, FlowParams)>,
|
||||
sent_head: H256, // last chain head we've given them.
|
||||
last_update: SteadyTime,
|
||||
pending_requests: RequestSet,
|
||||
@ -155,21 +155,21 @@ pub struct Peer {
|
||||
|
||||
impl Peer {
|
||||
// check the maximum cost of a request, returning an error if there's
|
||||
// not enough buffer left.
|
||||
// not enough credits left.
|
||||
// returns the calculated maximum cost.
|
||||
fn deduct_max(&mut self, flow_params: &FlowParams, kind: request::Kind, max: usize) -> Result<U256, Error> {
|
||||
flow_params.recharge(&mut self.local_buffer);
|
||||
flow_params.recharge(&mut self.local_credits);
|
||||
|
||||
let max_cost = flow_params.compute_cost(kind, max);
|
||||
self.local_buffer.deduct_cost(max_cost)?;
|
||||
self.local_credits.deduct_cost(max_cost)?;
|
||||
Ok(max_cost)
|
||||
}
|
||||
|
||||
// refund buffer for a request. returns new buffer amount.
|
||||
// refund credits for a request. returns new amount of credits.
|
||||
fn refund(&mut self, flow_params: &FlowParams, amount: U256) -> U256 {
|
||||
flow_params.refund(&mut self.local_buffer, amount);
|
||||
flow_params.refund(&mut self.local_credits, amount);
|
||||
|
||||
self.local_buffer.current()
|
||||
self.local_credits.current()
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ pub trait Handler: Send + Sync {
|
||||
pub struct Params {
|
||||
/// Network id.
|
||||
pub network_id: u64,
|
||||
/// Buffer flow parameters.
|
||||
/// Request credits parameters.
|
||||
pub flow_params: FlowParams,
|
||||
/// Initial capabilities.
|
||||
pub capabilities: Capabilities,
|
||||
@ -324,14 +324,14 @@ impl LightProtocol {
|
||||
|
||||
/// Check the maximum amount of requests of a specific type
|
||||
/// which a peer would be able to serve. Returns zero if the
|
||||
/// peer is unknown or has no buffer flow parameters.
|
||||
/// peer is unknown or has no credit parameters.
|
||||
fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize {
|
||||
self.peers.read().get(&peer).and_then(|peer| {
|
||||
let mut peer = peer.lock();
|
||||
match peer.remote_flow {
|
||||
Some((ref mut buf, ref flow)) => {
|
||||
flow.recharge(buf);
|
||||
Some(flow.max_amount(&*buf, kind))
|
||||
Some((ref mut c, ref flow)) => {
|
||||
flow.recharge(c);
|
||||
Some(flow.max_amount(&*c, kind))
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
@ -341,7 +341,7 @@ impl LightProtocol {
|
||||
/// Make a request to a peer.
|
||||
///
|
||||
/// Fails on: nonexistent peer, network error, peer not server,
|
||||
/// insufficient buffer. Does not check capabilities before sending.
|
||||
/// insufficient credits. Does not check capabilities before sending.
|
||||
/// On success, returns a request id which can later be coordinated
|
||||
/// with an event.
|
||||
pub fn request_from(&self, io: &IoContext, peer_id: &PeerId, request: Request) -> Result<ReqId, Error> {
|
||||
@ -350,10 +350,10 @@ impl LightProtocol {
|
||||
let mut peer = peer.lock();
|
||||
|
||||
match peer.remote_flow {
|
||||
Some((ref mut buf, ref flow)) => {
|
||||
flow.recharge(buf);
|
||||
Some((ref mut c, ref flow)) => {
|
||||
flow.recharge(c);
|
||||
let max = flow.compute_cost(request.kind(), request.amount());
|
||||
buf.deduct_cost(max)?;
|
||||
c.deduct_cost(max)?;
|
||||
}
|
||||
None => return Err(Error::NotServer),
|
||||
}
|
||||
@ -454,7 +454,7 @@ impl LightProtocol {
|
||||
// - check whether request kinds match
|
||||
fn pre_verify_response(&self, peer: &PeerId, kind: request::Kind, raw: &UntrustedRlp) -> Result<IdGuard, Error> {
|
||||
let req_id = ReqId(raw.val_at(0)?);
|
||||
let cur_buffer: U256 = raw.val_at(1)?;
|
||||
let cur_credits: U256 = raw.val_at(1)?;
|
||||
|
||||
trace!(target: "les", "pre-verifying response from peer {}, kind={:?}", peer, kind);
|
||||
|
||||
@ -470,9 +470,9 @@ impl LightProtocol {
|
||||
(Some(request), Some(flow_info)) => {
|
||||
had_req = true;
|
||||
|
||||
let &mut (ref mut buf, ref mut flow) = flow_info;
|
||||
let actual_buffer = ::std::cmp::min(cur_buffer, *flow.limit());
|
||||
buf.update_to(actual_buffer);
|
||||
let &mut (ref mut c, ref mut flow) = flow_info;
|
||||
let actual_credits = ::std::cmp::min(cur_credits, *flow.limit());
|
||||
c.update_to(actual_credits);
|
||||
|
||||
if request.kind() != kind {
|
||||
Some(Error::UnsolicitedResponse)
|
||||
@ -675,10 +675,10 @@ impl LightProtocol {
|
||||
return Err(Error::BadProtocolVersion);
|
||||
}
|
||||
|
||||
let remote_flow = flow_params.map(|params| (params.create_buffer(), params));
|
||||
let remote_flow = flow_params.map(|params| (params.create_credits(), params));
|
||||
|
||||
self.peers.write().insert(*peer, Mutex::new(Peer {
|
||||
local_buffer: self.flow_params.create_buffer(),
|
||||
local_credits: self.flow_params.create_credits(),
|
||||
status: status.clone(),
|
||||
capabilities: capabilities.clone(),
|
||||
remote_flow: remote_flow,
|
||||
@ -783,10 +783,10 @@ impl LightProtocol {
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::Headers, response.len());
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
let cur_credits = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
io.respond(packet::BLOCK_HEADERS, {
|
||||
let mut stream = RlpStream::new_list(3);
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||
|
||||
for header in response {
|
||||
stream.append_raw(&header.into_inner(), 1);
|
||||
@ -845,11 +845,11 @@ impl LightProtocol {
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::Bodies, response_len);
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
let cur_credits = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
|
||||
io.respond(packet::BLOCK_BODIES, {
|
||||
let mut stream = RlpStream::new_list(3);
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||
|
||||
for body in response {
|
||||
match body {
|
||||
@ -911,11 +911,11 @@ impl LightProtocol {
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::Receipts, response_len);
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
let cur_credits = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
|
||||
io.respond(packet::RECEIPTS, {
|
||||
let mut stream = RlpStream::new_list(3);
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||
|
||||
for receipts in response {
|
||||
stream.append_raw(&receipts, 1);
|
||||
@ -985,11 +985,11 @@ impl LightProtocol {
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::StateProofs, response_len);
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
let cur_credits = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
|
||||
io.respond(packet::PROOFS, {
|
||||
let mut stream = RlpStream::new_list(3);
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||
|
||||
for proof in response {
|
||||
stream.append_raw(&proof, 1);
|
||||
@ -1057,11 +1057,11 @@ impl LightProtocol {
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::Codes, response_len);
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
let cur_credits = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
|
||||
io.respond(packet::CONTRACT_CODES, {
|
||||
let mut stream = RlpStream::new_list(3);
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||
|
||||
for code in response {
|
||||
stream.append(&code);
|
||||
@ -1130,11 +1130,11 @@ impl LightProtocol {
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::HeaderProofs, response_len);
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
let cur_credits = peer.refund(&self.flow_params, max_cost - actual_cost);
|
||||
|
||||
io.respond(packet::HEADER_PROOFS, {
|
||||
let mut stream = RlpStream::new_list(3);
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||
|
||||
for proof in response {
|
||||
stream.append_raw(&proof, 1);
|
||||
|
@ -14,14 +14,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! LES buffer flow management.
|
||||
//! Request credit management.
|
||||
//!
|
||||
//! Every request in the LES protocol leads to a reduction
|
||||
//! of the requester's buffer value as a rate-limiting mechanism.
|
||||
//! This buffer value will recharge at a set rate.
|
||||
//! Every request in the light protocol leads to a reduction
|
||||
//! of the requester's amount of credits as a rate-limiting mechanism.
|
||||
//! The amount of credits will recharge at a set rate.
|
||||
//!
|
||||
//! This module provides an interface for configuration of buffer
|
||||
//! flow costs and recharge rates.
|
||||
//! This module provides an interface for configuration of
|
||||
//! costs and recharge rates of request credits.
|
||||
//!
|
||||
//! Current default costs are picked completely arbitrarily, not based
|
||||
//! on any empirical timings or mathematical models.
|
||||
@ -38,19 +38,19 @@ use time::{Duration, SteadyTime};
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Cost(pub U256, pub U256);
|
||||
|
||||
/// Buffer value.
|
||||
/// Credits value.
|
||||
///
|
||||
/// Produced and recharged using `FlowParams`.
|
||||
/// Definitive updates can be made as well -- these will reset the recharge
|
||||
/// point to the time of the update.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Buffer {
|
||||
pub struct Credits {
|
||||
estimate: U256,
|
||||
recharge_point: SteadyTime,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
/// Get the current buffer value.
|
||||
impl Credits {
|
||||
/// Get the current amount of credits..
|
||||
pub fn current(&self) -> U256 { self.estimate.clone() }
|
||||
|
||||
/// Make a definitive update.
|
||||
@ -61,7 +61,7 @@ impl Buffer {
|
||||
self.recharge_point = SteadyTime::now();
|
||||
}
|
||||
|
||||
/// Attempt to apply the given cost to the buffer.
|
||||
/// Attempt to apply the given cost to the amount of credits.
|
||||
///
|
||||
/// If successful, the cost will be deducted successfully.
|
||||
///
|
||||
@ -69,7 +69,7 @@ impl Buffer {
|
||||
/// error will be produced.
|
||||
pub fn deduct_cost(&mut self, cost: U256) -> Result<(), Error> {
|
||||
match cost > self.estimate {
|
||||
true => Err(Error::BufferEmpty),
|
||||
true => Err(Error::NoCredits),
|
||||
false => {
|
||||
self.estimate = self.estimate - cost;
|
||||
Ok(())
|
||||
@ -165,7 +165,7 @@ impl RlpDecodable for CostTable {
|
||||
}
|
||||
}
|
||||
|
||||
/// A buffer-flow manager handles costs, recharge, limits
|
||||
/// Handles costs, recharge, limits of request credits.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FlowParams {
|
||||
costs: CostTable,
|
||||
@ -175,7 +175,7 @@ pub struct FlowParams {
|
||||
|
||||
impl FlowParams {
|
||||
/// Create new flow parameters from a request cost table,
|
||||
/// buffer limit, and (minimum) rate of recharge.
|
||||
/// credit limit, and (minimum) rate of recharge.
|
||||
pub fn new(limit: U256, costs: CostTable, recharge: U256) -> Self {
|
||||
FlowParams {
|
||||
costs: costs,
|
||||
@ -201,7 +201,7 @@ impl FlowParams {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the buffer limit.
|
||||
/// Get a reference to the credit limit.
|
||||
pub fn limit(&self) -> &U256 { &self.limit }
|
||||
|
||||
/// Get a reference to the cost table.
|
||||
@ -227,10 +227,10 @@ impl FlowParams {
|
||||
}
|
||||
|
||||
/// Compute the maximum number of costs of a specific kind which can be made
|
||||
/// with the given buffer.
|
||||
/// with the given amount of credits
|
||||
/// Saturates at `usize::max()`. This is not a problem in practice because
|
||||
/// this amount of requests is already prohibitively large.
|
||||
pub fn max_amount(&self, buffer: &Buffer, kind: request::Kind) -> usize {
|
||||
pub fn max_amount(&self, credits: &Credits, kind: request::Kind) -> usize {
|
||||
use util::Uint;
|
||||
use std::usize;
|
||||
|
||||
@ -243,7 +243,7 @@ impl FlowParams {
|
||||
request::Kind::HeaderProofs => &self.costs.header_proofs,
|
||||
};
|
||||
|
||||
let start = buffer.current();
|
||||
let start = credits.current();
|
||||
|
||||
if start <= cost.0 {
|
||||
return 0;
|
||||
@ -259,36 +259,36 @@ impl FlowParams {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create initial buffer parameter.
|
||||
pub fn create_buffer(&self) -> Buffer {
|
||||
Buffer {
|
||||
/// Create initial credits..
|
||||
pub fn create_credits(&self) -> Credits {
|
||||
Credits {
|
||||
estimate: self.limit,
|
||||
recharge_point: SteadyTime::now(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Recharge the buffer based on time passed since last
|
||||
/// Recharge the given credits based on time passed since last
|
||||
/// update.
|
||||
pub fn recharge(&self, buf: &mut Buffer) {
|
||||
pub fn recharge(&self, credits: &mut Credits) {
|
||||
let now = SteadyTime::now();
|
||||
|
||||
// recompute and update only in terms of full seconds elapsed
|
||||
// in order to keep the estimate as an underestimate.
|
||||
let elapsed = (now - buf.recharge_point).num_seconds();
|
||||
buf.recharge_point = buf.recharge_point + Duration::seconds(elapsed);
|
||||
let elapsed = (now - credits.recharge_point).num_seconds();
|
||||
credits.recharge_point = credits.recharge_point + Duration::seconds(elapsed);
|
||||
|
||||
let elapsed: U256 = elapsed.into();
|
||||
|
||||
buf.estimate = ::std::cmp::min(self.limit, buf.estimate + (elapsed * self.recharge));
|
||||
credits.estimate = ::std::cmp::min(self.limit, credits.estimate + (elapsed * self.recharge));
|
||||
}
|
||||
|
||||
/// Refund some buffer which was previously deducted.
|
||||
/// Refund some credits which were previously deducted.
|
||||
/// Does not update the recharge timestamp.
|
||||
pub fn refund(&self, buf: &mut Buffer, refund_amount: U256) {
|
||||
buf.estimate = buf.estimate + refund_amount;
|
||||
pub fn refund(&self, credits: &mut Credits, refund_amount: U256) {
|
||||
credits.estimate = credits.estimate + refund_amount;
|
||||
|
||||
if buf.estimate > self.limit {
|
||||
buf.estimate = self.limit
|
||||
if credits.estimate > self.limit {
|
||||
credits.estimate = self.limit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,20 +318,20 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buffer_mechanism() {
|
||||
fn credits_mechanism() {
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
let flow_params = FlowParams::new(100.into(), Default::default(), 20.into());
|
||||
let mut buffer = flow_params.create_buffer();
|
||||
let mut credits = flow_params.create_credits();
|
||||
|
||||
assert!(buffer.deduct_cost(101.into()).is_err());
|
||||
assert!(buffer.deduct_cost(10.into()).is_ok());
|
||||
assert!(credits.deduct_cost(101.into()).is_err());
|
||||
assert!(credits.deduct_cost(10.into()).is_ok());
|
||||
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
|
||||
flow_params.recharge(&mut buffer);
|
||||
flow_params.recharge(&mut credits);
|
||||
|
||||
assert_eq!(buffer.estimate, 100.into());
|
||||
assert_eq!(credits.estimate, 100.into());
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
use rlp::{DecoderError, RlpDecodable, RlpEncodable, RlpStream, Stream, UntrustedRlp, View};
|
||||
use util::{H256, U256};
|
||||
|
||||
use super::buffer_flow::FlowParams;
|
||||
use super::request_credits::FlowParams;
|
||||
|
||||
// recognized handshake/announcement keys.
|
||||
// unknown keys are to be skipped, known keys have a defined order.
|
||||
@ -207,7 +207,7 @@ impl Capabilities {
|
||||
/// Attempt to parse a handshake message into its three parts:
|
||||
/// - chain status
|
||||
/// - serving capabilities
|
||||
/// - buffer flow parameters
|
||||
/// - request credit parameters
|
||||
pub fn parse_handshake(rlp: UntrustedRlp) -> Result<(Status, Capabilities, Option<FlowParams>), DecoderError> {
|
||||
let mut parser = Parser {
|
||||
pos: 0,
|
||||
@ -300,7 +300,7 @@ pub struct Announcement {
|
||||
pub serve_chain_since: Option<u64>,
|
||||
/// optional new transaction-relay capability. false means "no change"
|
||||
pub tx_relay: bool,
|
||||
// TODO: changes in buffer flow?
|
||||
// TODO: changes in request credits.
|
||||
}
|
||||
|
||||
/// Parse an announcement.
|
||||
@ -372,7 +372,7 @@ pub fn write_announcement(announcement: &Announcement) -> Vec<u8> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::super::buffer_flow::FlowParams;
|
||||
use super::super::request_credits::FlowParams;
|
||||
use util::{U256, H256, FixedHash};
|
||||
use rlp::{RlpStream, Stream ,UntrustedRlp, View};
|
||||
|
||||
|
@ -24,7 +24,7 @@ use ethcore::transaction::PendingTransaction;
|
||||
use ethcore::encoded;
|
||||
use network::{PeerId, NodeId};
|
||||
|
||||
use net::buffer_flow::FlowParams;
|
||||
use net::request_credits::FlowParams;
|
||||
use net::context::IoContext;
|
||||
use net::status::{Capabilities, Status, write_handshake};
|
||||
use net::{encode_request, LightProtocol, Params, packet, Peer};
|
||||
@ -203,7 +203,7 @@ fn genesis_mismatch() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buffer_overflow() {
|
||||
fn credit_overflow() {
|
||||
let flow_params = make_flow_params();
|
||||
let capabilities = capabilities();
|
||||
|
||||
@ -268,11 +268,11 @@ fn get_block_headers() {
|
||||
let headers: Vec<_> = (0..10).map(|i| provider.client.block_header(BlockId::Number(i + 1)).unwrap()).collect();
|
||||
assert_eq!(headers.len(), 10);
|
||||
|
||||
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Headers, 10);
|
||||
let new_creds = *flow_params.limit() - flow_params.compute_cost(request::Kind::Headers, 10);
|
||||
|
||||
let mut response_stream = RlpStream::new_list(3);
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(10);
|
||||
response_stream.append(&req_id).append(&new_creds).begin_list(10);
|
||||
for header in headers {
|
||||
response_stream.append_raw(&header.into_inner(), 1);
|
||||
}
|
||||
@ -317,11 +317,11 @@ fn get_block_bodies() {
|
||||
let bodies: Vec<_> = (0..10).map(|i| provider.client.block_body(BlockId::Number(i + 1)).unwrap()).collect();
|
||||
assert_eq!(bodies.len(), 10);
|
||||
|
||||
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10);
|
||||
let new_creds = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10);
|
||||
|
||||
let mut response_stream = RlpStream::new_list(3);
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(10);
|
||||
response_stream.append(&req_id).append(&new_creds).begin_list(10);
|
||||
for body in bodies {
|
||||
response_stream.append_raw(&body.into_inner(), 1);
|
||||
}
|
||||
@ -371,11 +371,11 @@ fn get_block_receipts() {
|
||||
.map(|hash| provider.client.block_receipts(hash).unwrap())
|
||||
.collect();
|
||||
|
||||
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Receipts, receipts.len());
|
||||
let new_creds = *flow_params.limit() - flow_params.compute_cost(request::Kind::Receipts, receipts.len());
|
||||
|
||||
let mut response_stream = RlpStream::new_list(3);
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(receipts.len());
|
||||
response_stream.append(&req_id).append(&new_creds).begin_list(receipts.len());
|
||||
for block_receipts in receipts {
|
||||
response_stream.append_raw(&block_receipts, 1);
|
||||
}
|
||||
@ -420,11 +420,11 @@ fn get_state_proofs() {
|
||||
vec![::util::sha3::SHA3_NULL_RLP.to_vec()],
|
||||
];
|
||||
|
||||
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2);
|
||||
let new_creds = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2);
|
||||
|
||||
let mut response_stream = RlpStream::new_list(3);
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(2);
|
||||
response_stream.append(&req_id).append(&new_creds).begin_list(2);
|
||||
for proof in proofs {
|
||||
response_stream.begin_list(proof.len());
|
||||
for node in proof {
|
||||
@ -472,11 +472,11 @@ fn get_contract_code() {
|
||||
key2.iter().chain(key2.iter()).cloned().collect(),
|
||||
];
|
||||
|
||||
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Codes, 2);
|
||||
let new_creds = *flow_params.limit() - flow_params.compute_cost(request::Kind::Codes, 2);
|
||||
|
||||
let mut response_stream = RlpStream::new_list(3);
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(2);
|
||||
response_stream.append(&req_id).append(&new_creds).begin_list(2);
|
||||
for code in codes {
|
||||
response_stream.append(&code);
|
||||
}
|
||||
@ -515,10 +515,10 @@ fn id_guard() {
|
||||
pending_requests.insert(req_id_2, req, ::time::SteadyTime::now());
|
||||
|
||||
proto.peers.write().insert(peer_id, ::util::Mutex::new(Peer {
|
||||
local_buffer: flow_params.create_buffer(),
|
||||
local_credits: flow_params.create_credits(),
|
||||
status: status(provider.client.chain_info()),
|
||||
capabilities: capabilities.clone(),
|
||||
remote_flow: Some((flow_params.create_buffer(), flow_params)),
|
||||
remote_flow: Some((flow_params.create_credits(), flow_params)),
|
||||
sent_head: provider.client.chain_info().best_block_hash,
|
||||
last_update: ::time::SteadyTime::now(),
|
||||
pending_requests: pending_requests,
|
||||
|
@ -27,7 +27,7 @@ use ethcore::spec::Spec;
|
||||
use io::IoChannel;
|
||||
use light::client::Client as LightClient;
|
||||
use light::net::{LightProtocol, IoContext, Capabilities, Params as LightParams};
|
||||
use light::net::buffer_flow::FlowParams;
|
||||
use light::net::request_credits::FlowParams;
|
||||
use network::{NodeId, PeerId};
|
||||
use util::RwLock;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user