Merge remote-tracking branch 'origin/master' into bettermining
This commit is contained in:
		
						commit
						fc211f0934
					
				@ -20,5 +20,7 @@
 | 
			
		||||
extern crate rand;
 | 
			
		||||
 | 
			
		||||
pub mod random_path;
 | 
			
		||||
pub mod test_socket;
 | 
			
		||||
 | 
			
		||||
pub use random_path::*;
 | 
			
		||||
pub use test_socket::*;
 | 
			
		||||
 | 
			
		||||
@ -905,7 +905,7 @@ mod tests {
 | 
			
		||||
			gas: U256::from(100_000),
 | 
			
		||||
			gas_price: U256::zero(),
 | 
			
		||||
			nonce: U256::zero()
 | 
			
		||||
		}.fake_sign();
 | 
			
		||||
		}.invalid_sign();
 | 
			
		||||
		let mut state_result = get_temp_state();
 | 
			
		||||
		let mut state = state_result.reference_mut();
 | 
			
		||||
		let mut info = EnvInfo::default();
 | 
			
		||||
 | 
			
		||||
@ -134,7 +134,7 @@ impl Transaction {
 | 
			
		||||
 | 
			
		||||
	/// Useful for test incorrectly signed transactions.
 | 
			
		||||
	#[cfg(test)]
 | 
			
		||||
	pub fn fake_sign(self) -> SignedTransaction {
 | 
			
		||||
	pub fn invalid_sign(self) -> SignedTransaction {
 | 
			
		||||
		SignedTransaction {
 | 
			
		||||
			unsigned: self,
 | 
			
		||||
			r: U256::zero(),
 | 
			
		||||
@ -145,6 +145,18 @@ impl Transaction {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Specify the sender; this won't survive the serialize/deserialize process, but can be cloned.
 | 
			
		||||
	pub fn fake_sign(self, from: Address) -> SignedTransaction {
 | 
			
		||||
		SignedTransaction {
 | 
			
		||||
			unsigned: self,
 | 
			
		||||
			r: U256::zero(),
 | 
			
		||||
			s: U256::zero(),
 | 
			
		||||
			v: 0,
 | 
			
		||||
			hash: Cell::new(None),
 | 
			
		||||
			sender: Cell::new(Some(from)),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Get the transaction cost in gas for the given params.
 | 
			
		||||
	pub fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule) -> u64 {
 | 
			
		||||
		data.iter().fold(
 | 
			
		||||
@ -342,3 +354,19 @@ fn signing() {
 | 
			
		||||
	}.sign(&key.secret());
 | 
			
		||||
	assert_eq!(Address::from(key.public().sha3()), t.sender().unwrap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn fake_signing() {
 | 
			
		||||
	let t = Transaction {
 | 
			
		||||
		action: Action::Create,
 | 
			
		||||
		nonce: U256::from(42),
 | 
			
		||||
		gas_price: U256::from(3000),
 | 
			
		||||
		gas: U256::from(50_000),
 | 
			
		||||
		value: U256::from(1),
 | 
			
		||||
		data: b"Hello!".to_vec()
 | 
			
		||||
	}.fake_sign(Address::from(0x69));
 | 
			
		||||
	assert_eq!(Address::from(0x69), t.sender().unwrap());
 | 
			
		||||
 | 
			
		||||
	let t = t.clone();
 | 
			
		||||
	assert_eq!(Address::from(0x69), t.sender().unwrap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ path = "run.rs"
 | 
			
		||||
"ethcore-ipc" = { path = "../rpc" }
 | 
			
		||||
bincode = "*"
 | 
			
		||||
serde = "0.7.0"
 | 
			
		||||
ethcore-devtools = { path = "../../devtools" }
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
syntex = "0.30.0"
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,9 @@
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
 | 
			
		||||
	use super::super::socket::*;
 | 
			
		||||
	use super::super::service::*;
 | 
			
		||||
	use ipc::*;
 | 
			
		||||
	use devtools::*;
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	fn call_service() {
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@
 | 
			
		||||
extern crate bincode;
 | 
			
		||||
extern crate ethcore_ipc as ipc;
 | 
			
		||||
extern crate serde;
 | 
			
		||||
extern crate ethcore_devtools as devtools;
 | 
			
		||||
 | 
			
		||||
pub mod socket;
 | 
			
		||||
pub mod service;
 | 
			
		||||
mod examples;
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,6 @@ use jsonrpc_core::*;
 | 
			
		||||
use util::numbers::*;
 | 
			
		||||
use util::sha3::*;
 | 
			
		||||
use util::rlp::{encode, UntrustedRlp, View};
 | 
			
		||||
use util::crypto::KeyPair;
 | 
			
		||||
use ethcore::client::*;
 | 
			
		||||
use ethcore::block::IsBlock;
 | 
			
		||||
use ethcore::views::*;
 | 
			
		||||
@ -35,6 +34,7 @@ use v1::traits::{Eth, EthFilter};
 | 
			
		||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt};
 | 
			
		||||
use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner};
 | 
			
		||||
use util::keys::store::AccountProvider;
 | 
			
		||||
use serde;
 | 
			
		||||
 | 
			
		||||
fn default_gas() -> U256 {
 | 
			
		||||
	U256::from(21_000)
 | 
			
		||||
@ -167,38 +167,42 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn sign_call(client: &Arc<C>, accounts: &Arc<A>, request: CallRequest) -> Option<SignedTransaction> {
 | 
			
		||||
		match request.from {
 | 
			
		||||
			Some(ref from) => {
 | 
			
		||||
				let transaction = EthTransaction {
 | 
			
		||||
					nonce: request.nonce.unwrap_or_else(|| client.nonce(from)),
 | 
			
		||||
					action: request.to.map_or(Action::Create, Action::Call),
 | 
			
		||||
					gas: request.gas.unwrap_or_else(default_gas),
 | 
			
		||||
					gas_price: request.gas_price.unwrap_or_else(default_gas_price),
 | 
			
		||||
					value: request.value.unwrap_or_else(U256::zero),
 | 
			
		||||
					data: request.data.map_or_else(Vec::new, |d| d.to_vec())
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				accounts.account_secret(from).ok().map(|secret| transaction.sign(&secret))
 | 
			
		||||
			},
 | 
			
		||||
			None => {
 | 
			
		||||
				let transaction = EthTransaction {
 | 
			
		||||
					nonce: request.nonce.unwrap_or_else(U256::zero),
 | 
			
		||||
					action: request.to.map_or(Action::Create, Action::Call),
 | 
			
		||||
					gas: request.gas.unwrap_or_else(default_gas),
 | 
			
		||||
					gas_price: request.gas_price.unwrap_or_else(default_gas_price),
 | 
			
		||||
					value: request.value.unwrap_or_else(U256::zero),
 | 
			
		||||
					data: request.data.map_or_else(Vec::new, |d| d.to_vec())
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				KeyPair::create().ok().map(|kp| transaction.sign(kp.secret()))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	fn sign_call(client: &Arc<C>, request: CallRequest) -> SignedTransaction {
 | 
			
		||||
		let from = request.from.unwrap_or(Address::zero());
 | 
			
		||||
		EthTransaction {
 | 
			
		||||
			nonce: request.nonce.unwrap_or_else(|| client.nonce(&from)),
 | 
			
		||||
			action: request.to.map_or(Action::Create, Action::Call),
 | 
			
		||||
			gas: request.gas.unwrap_or_else(default_gas),
 | 
			
		||||
			gas_price: request.gas_price.unwrap_or_else(default_gas_price),
 | 
			
		||||
			value: request.value.unwrap_or_else(U256::zero),
 | 
			
		||||
			data: request.data.map_or_else(Vec::new, |d| d.to_vec())
 | 
			
		||||
		}.fake_sign(from)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const MAX_QUEUE_SIZE_TO_MINE_ON: usize = 4;	// because uncles go back 6.
 | 
			
		||||
 | 
			
		||||
fn params_len(params: &Params) -> usize {
 | 
			
		||||
	match params {
 | 
			
		||||
		&Params::Array(ref vec) => vec.len(),
 | 
			
		||||
		_ => 0,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn from_params_discard_second<F>(params: Params) -> Result<(F,), Error> where F: serde::de::Deserialize {
 | 
			
		||||
	match params_len(¶ms) {
 | 
			
		||||
		1 => from_params::<(F, )>(params),
 | 
			
		||||
		_ => from_params::<(F, BlockNumber)>(params).map(|(f, _block_number)| (f, )),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn from_params_discard_third<F1, F2>(params: Params) -> Result<(F1, F2,), Error> where F1: serde::de::Deserialize, F2: serde::de::Deserialize {
 | 
			
		||||
	match params_len(¶ms) {
 | 
			
		||||
		2 => from_params::<(F1, F2, )>(params),
 | 
			
		||||
		_ => from_params::<(F1, F2, BlockNumber)>(params).map(|(f1, f2, _block_number)| (f1, f2, )),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
 | 
			
		||||
	where C: BlockChainClient + 'static,
 | 
			
		||||
		  S: SyncProvider + 'static,
 | 
			
		||||
@ -278,19 +282,18 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn balance(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
		from_params::<(Address, BlockNumber)>(params)
 | 
			
		||||
			.and_then(|(address, _block_number)| to_value(&take_weak!(self.client).balance(&address)))
 | 
			
		||||
		from_params_discard_second(params).and_then(|(address, )|
 | 
			
		||||
			to_value(&take_weak!(self.client).balance(&address)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn storage_at(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
		from_params::<(Address, U256, BlockNumber)>(params)
 | 
			
		||||
			.and_then(|(address, position, _block_number)|
 | 
			
		||||
				to_value(&U256::from(take_weak!(self.client).storage_at(&address, &H256::from(position)))))
 | 
			
		||||
		from_params_discard_third::<Address, U256>(params).and_then(|(address, position, )|
 | 
			
		||||
			to_value(&U256::from(take_weak!(self.client).storage_at(&address, &H256::from(position)))))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn transaction_count(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
		from_params::<(Address, BlockNumber)>(params)
 | 
			
		||||
			.and_then(|(address, _block_number)| to_value(&take_weak!(self.client).nonce(&address)))
 | 
			
		||||
		from_params_discard_second(params).and_then(|(address, )|
 | 
			
		||||
			to_value(&take_weak!(self.client).nonce(&address)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn block_transaction_count_by_hash(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
@ -329,9 +332,8 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
 | 
			
		||||
 | 
			
		||||
	// TODO: do not ignore block number param
 | 
			
		||||
	fn code_at(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
		from_params::<(Address, BlockNumber)>(params)
 | 
			
		||||
			.and_then(|(address, _block_number)|
 | 
			
		||||
				to_value(&take_weak!(self.client).code(&address).map_or_else(Bytes::default, Bytes::new)))
 | 
			
		||||
		from_params_discard_second(params).and_then(|(address, )|
 | 
			
		||||
			to_value(&take_weak!(self.client).code(&address).map_or_else(Bytes::default, Bytes::new)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn block_by_hash(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
@ -506,31 +508,21 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn call(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
		from_params::<(CallRequest, BlockNumber)>(params)
 | 
			
		||||
			.and_then(|(request, _block_number)| {
 | 
			
		||||
				let client = take_weak!(self.client);
 | 
			
		||||
				let accounts = take_weak!(self.accounts);
 | 
			
		||||
				let signed = Self::sign_call(&client, &accounts, request);
 | 
			
		||||
				let output = signed.map(|tx| client.call(&tx)
 | 
			
		||||
					.map(|e| Bytes::new(e.output))
 | 
			
		||||
					.unwrap_or(Bytes::default()));
 | 
			
		||||
 | 
			
		||||
				to_value(&output)
 | 
			
		||||
			})
 | 
			
		||||
		from_params_discard_second(params).and_then(|(request, )| {
 | 
			
		||||
			let client = take_weak!(self.client);
 | 
			
		||||
			let signed = Self::sign_call(&client, request);
 | 
			
		||||
			let output = client.call(&signed).map(|e| Bytes(e.output)).unwrap_or(Bytes::new(vec![]));
 | 
			
		||||
			to_value(&output)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn estimate_gas(&self, params: Params) -> Result<Value, Error> {
 | 
			
		||||
		from_params::<(CallRequest, BlockNumber)>(params)
 | 
			
		||||
			.and_then(|(request, _block_number)| {
 | 
			
		||||
				let client = take_weak!(self.client);
 | 
			
		||||
				let accounts = take_weak!(self.accounts);
 | 
			
		||||
				let signed = Self::sign_call(&client, &accounts, request);
 | 
			
		||||
				let output = signed.map(|tx| client.call(&tx)
 | 
			
		||||
					.map(|e| e.gas_used + e.refunded)
 | 
			
		||||
					.unwrap_or(U256::zero()));
 | 
			
		||||
 | 
			
		||||
				to_value(&output)
 | 
			
		||||
			})
 | 
			
		||||
		from_params_discard_second(params).and_then(|(request, )| {
 | 
			
		||||
			let client = take_weak!(self.client);
 | 
			
		||||
			let signed = Self::sign_call(&client, request);
 | 
			
		||||
			let used = client.call(&signed).map(|res| res.gas_used + res.refunded).unwrap_or(From::from(0));
 | 
			
		||||
			to_value(&used)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -334,6 +334,38 @@ fn rpc_eth_call() {
 | 
			
		||||
	assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn rpc_eth_call_default_block() {
 | 
			
		||||
	let tester = EthTester::default();
 | 
			
		||||
	tester.client.set_execution_result(Executed {
 | 
			
		||||
		gas: U256::zero(),
 | 
			
		||||
		gas_used: U256::from(0xff30),
 | 
			
		||||
		refunded: U256::from(0x5),
 | 
			
		||||
		cumulative_gas_used: U256::zero(),
 | 
			
		||||
		logs: vec![],
 | 
			
		||||
		contracts_created: vec![],
 | 
			
		||||
		output: vec![0x12, 0x34, 0xff],
 | 
			
		||||
		trace: None,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	let request = r#"{
 | 
			
		||||
		"jsonrpc": "2.0",
 | 
			
		||||
		"method": "eth_call",
 | 
			
		||||
		"params": [{
 | 
			
		||||
			"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
 | 
			
		||||
			"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
 | 
			
		||||
			"gas": "0x76c0",
 | 
			
		||||
			"gasPrice": "0x9184e72a000",
 | 
			
		||||
			"value": "0x9184e72a",
 | 
			
		||||
			"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
 | 
			
		||||
		}],
 | 
			
		||||
		"id": 1
 | 
			
		||||
	}"#;
 | 
			
		||||
	let response = r#"{"jsonrpc":"2.0","result":"0x1234ff","id":1}"#;
 | 
			
		||||
 | 
			
		||||
	assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn rpc_eth_estimate_gas() {
 | 
			
		||||
	let tester = EthTester::default();
 | 
			
		||||
@ -367,6 +399,38 @@ fn rpc_eth_estimate_gas() {
 | 
			
		||||
	assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn rpc_eth_estimate_gas_default_block() {
 | 
			
		||||
	let tester = EthTester::default();
 | 
			
		||||
	tester.client.set_execution_result(Executed {
 | 
			
		||||
		gas: U256::zero(),
 | 
			
		||||
		gas_used: U256::from(0xff30),
 | 
			
		||||
		refunded: U256::from(0x5),
 | 
			
		||||
		cumulative_gas_used: U256::zero(),
 | 
			
		||||
		logs: vec![],
 | 
			
		||||
		contracts_created: vec![],
 | 
			
		||||
		output: vec![0x12, 0x34, 0xff],
 | 
			
		||||
		trace: None,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	let request = r#"{
 | 
			
		||||
		"jsonrpc": "2.0",
 | 
			
		||||
		"method": "eth_estimateGas",
 | 
			
		||||
		"params": [{
 | 
			
		||||
			"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
 | 
			
		||||
			"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
 | 
			
		||||
			"gas": "0x76c0",
 | 
			
		||||
			"gasPrice": "0x9184e72a000",
 | 
			
		||||
			"value": "0x9184e72a",
 | 
			
		||||
			"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
 | 
			
		||||
		}],
 | 
			
		||||
		"id": 1
 | 
			
		||||
	}"#;
 | 
			
		||||
	let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
 | 
			
		||||
 | 
			
		||||
	assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
#[ignore]
 | 
			
		||||
fn rpc_eth_send_transaction() {
 | 
			
		||||
@ -476,7 +540,7 @@ fn rpc_eth_compile_serpent() {
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn returns_no_work_if_cant_mine() {
 | 
			
		||||
	let mut eth_tester = EthTester::default();
 | 
			
		||||
	let eth_tester = EthTester::default();
 | 
			
		||||
	eth_tester.client.set_queue_size(10);
 | 
			
		||||
 | 
			
		||||
	let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
 | 
			
		||||
 | 
			
		||||
@ -38,8 +38,6 @@ fn rpc_web3_sha3() {
 | 
			
		||||
	let io = IoHandler::new();
 | 
			
		||||
	io.add_delegate(web3);
 | 
			
		||||
 | 
			
		||||
	let v = version().to_owned().replace("Parity/", "Parity//");
 | 
			
		||||
 | 
			
		||||
	let request = r#"{"jsonrpc": "2.0", "method": "web3_sha3", "params": ["0x00"], "id": 1}"#;
 | 
			
		||||
	let response = r#"{"jsonrpc":"2.0","result":"0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a","id":1}"#;
 | 
			
		||||
 | 
			
		||||
@ -52,8 +50,6 @@ fn rpc_web3_sha3_wiki() {
 | 
			
		||||
	let io = IoHandler::new();
 | 
			
		||||
	io.add_delegate(web3);
 | 
			
		||||
 | 
			
		||||
	let v = version().to_owned().replace("Parity/", "Parity//");
 | 
			
		||||
 | 
			
		||||
	let request = r#"{"jsonrpc": "2.0", "method": "web3_sha3", "params": ["0x68656c6c6f20776f726c64"], "id": 1}"#;
 | 
			
		||||
	let response = r#"{"jsonrpc":"2.0","result":"0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad","id":1}"#;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,9 +35,8 @@ mod tests {
 | 
			
		||||
	use std::str::FromStr;
 | 
			
		||||
	use rustc_serialize::hex::FromHex;
 | 
			
		||||
	use serde_json;
 | 
			
		||||
	use util::numbers::{Uint, U256};
 | 
			
		||||
	use util::numbers::{U256};
 | 
			
		||||
	use util::hash::Address;
 | 
			
		||||
	use ethcore::transaction::{Transaction, Action};
 | 
			
		||||
	use v1::types::Bytes;
 | 
			
		||||
	use super::*;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,9 +35,8 @@ mod tests {
 | 
			
		||||
	use std::str::FromStr;
 | 
			
		||||
	use rustc_serialize::hex::FromHex;
 | 
			
		||||
	use serde_json;
 | 
			
		||||
	use util::numbers::{Uint, U256};
 | 
			
		||||
	use util::numbers::{U256};
 | 
			
		||||
	use util::hash::Address;
 | 
			
		||||
	use ethcore::transaction::{Transaction, Action};
 | 
			
		||||
	use v1::types::Bytes;
 | 
			
		||||
	use super::*;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -501,77 +501,10 @@ mod tests {
 | 
			
		||||
	use std::sync::*;
 | 
			
		||||
	use super::super::stats::*;
 | 
			
		||||
	use std::io::{Read, Write, Error, Cursor, ErrorKind};
 | 
			
		||||
	use std::cmp;
 | 
			
		||||
	use mio::{EventSet};
 | 
			
		||||
	use std::collections::VecDeque;
 | 
			
		||||
	use bytes::*;
 | 
			
		||||
 | 
			
		||||
	struct TestSocket {
 | 
			
		||||
		read_buffer: Vec<u8>,
 | 
			
		||||
		write_buffer: Vec<u8>,
 | 
			
		||||
		cursor: usize,
 | 
			
		||||
		buf_size: usize,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	impl Default for TestSocket {
 | 
			
		||||
		fn default() -> Self {
 | 
			
		||||
			TestSocket::new()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	impl TestSocket {
 | 
			
		||||
		fn new() -> Self {
 | 
			
		||||
			TestSocket {
 | 
			
		||||
				read_buffer: vec![],
 | 
			
		||||
				write_buffer: vec![],
 | 
			
		||||
				cursor: 0,
 | 
			
		||||
				buf_size: 0,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fn new_buf(buf_size: usize) -> TestSocket {
 | 
			
		||||
			TestSocket {
 | 
			
		||||
				read_buffer: vec![],
 | 
			
		||||
				write_buffer: vec![],
 | 
			
		||||
				cursor: 0,
 | 
			
		||||
				buf_size: buf_size,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	impl Read for TestSocket {
 | 
			
		||||
		fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
 | 
			
		||||
			let end_position = cmp::min(self.read_buffer.len(), self.cursor+buf.len());
 | 
			
		||||
			let len = cmp::max(end_position - self.cursor, 0);
 | 
			
		||||
			match len {
 | 
			
		||||
				0 => Ok(0),
 | 
			
		||||
				_ => {
 | 
			
		||||
					for i in self.cursor..end_position {
 | 
			
		||||
						buf[i-self.cursor] = self.read_buffer[i];
 | 
			
		||||
					}
 | 
			
		||||
					self.cursor = self.cursor + buf.len();
 | 
			
		||||
					Ok(len)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	impl Write for TestSocket {
 | 
			
		||||
		fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
 | 
			
		||||
			if self.buf_size == 0 || buf.len() < self.buf_size {
 | 
			
		||||
				self.write_buffer.extend(buf.iter().cloned());
 | 
			
		||||
				Ok(buf.len())
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				self.write_buffer.extend(buf.iter().take(self.buf_size).cloned());
 | 
			
		||||
				Ok(self.buf_size)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fn flush(&mut self) -> Result<(), Error> {
 | 
			
		||||
			unimplemented!();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	use devtools::*;
 | 
			
		||||
 | 
			
		||||
	impl GenericSocket for TestSocket {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user