light IPC feature and mock state proofs
This commit is contained in:
parent
8d16f73795
commit
3e8ee9d423
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -462,8 +462,6 @@ version = "1.5.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore 1.5.0",
|
"ethcore 1.5.0",
|
||||||
"ethcore-io 1.5.0",
|
"ethcore-io 1.5.0",
|
||||||
"ethcore-ipc 1.4.0",
|
|
||||||
"ethcore-ipc-codegen 1.4.0",
|
|
||||||
"ethcore-network 1.5.0",
|
"ethcore-network 1.5.0",
|
||||||
"ethcore-util 1.5.0",
|
"ethcore-util 1.5.0",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -8,7 +8,7 @@ authors = ["Ethcore <admin@ethcore.io>"]
|
|||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
"ethcore-ipc-codegen" = { path = "../../ipc/codegen" }
|
"ethcore-ipc-codegen" = { path = "../../ipc/codegen", optional = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
@ -16,6 +16,9 @@ ethcore = { path = "..", features = ["light"] }
|
|||||||
ethcore-util = { path = "../../util" }
|
ethcore-util = { path = "../../util" }
|
||||||
ethcore-network = { path = "../../util/network" }
|
ethcore-network = { path = "../../util/network" }
|
||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
ethcore-ipc = { path = "../../ipc/rpc" }
|
ethcore-ipc = { path = "../../ipc/rpc", optional = true }
|
||||||
rlp = { path = "../../util/rlp" }
|
rlp = { path = "../../util/rlp" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
ipc = ["ethcore/ipc", "ethcore-ipc", "ethcore-ipc-codegen"]
|
@ -14,8 +14,13 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
extern crate ethcore_ipc_codegen;
|
extern crate ethcore_ipc_codegen;
|
||||||
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
fn main() {
|
fn main() {
|
||||||
ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap();
|
ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "ipc"))]
|
||||||
|
fn main() { }
|
@ -47,6 +47,8 @@ extern crate ethcore;
|
|||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate ethcore_network as network;
|
extern crate ethcore_network as network;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate ethcore_ipc as ipc;
|
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
|
extern crate ethcore_ipc as ipc;
|
@ -123,7 +123,19 @@ impl Provider for TestProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> {
|
fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> {
|
||||||
req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
|
req.requests.into_iter()
|
||||||
|
.map(|req| {
|
||||||
|
match req.key2 {
|
||||||
|
Some(key2) => ::util::sha3::SHA3_NULL_RLP.to_owned(),
|
||||||
|
None => {
|
||||||
|
// sort of a leaf node
|
||||||
|
let mut stream = RlpStream::new_list(2);
|
||||||
|
stream.append(&req.key1).append_empty_data();
|
||||||
|
stream.out()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> {
|
fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> {
|
||||||
@ -240,6 +252,9 @@ fn buffer_overflow() {
|
|||||||
proto.handle_packet(&Expect::Punish(1), &1, packet::GET_BLOCK_HEADERS, &request);
|
proto.handle_packet(&Expect::Punish(1), &1, packet::GET_BLOCK_HEADERS, &request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test the basic request types -- these just make sure that requests are parsed
|
||||||
|
// and sent to the provider correctly as well as testing response formatting.
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_block_headers() {
|
fn get_block_headers() {
|
||||||
let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into());
|
let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into());
|
||||||
@ -288,4 +303,151 @@ fn get_block_headers() {
|
|||||||
|
|
||||||
let expected = Expect::Respond(packet::BLOCK_HEADERS, response);
|
let expected = Expect::Respond(packet::BLOCK_HEADERS, response);
|
||||||
proto.handle_packet(&expected, &1, packet::GET_BLOCK_HEADERS, &request_body);
|
proto.handle_packet(&expected, &1, packet::GET_BLOCK_HEADERS, &request_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_block_bodies() {
|
||||||
|
let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into());
|
||||||
|
let capabilities = capabilities();
|
||||||
|
|
||||||
|
let (provider, proto) = setup(flow_params.clone(), capabilities.clone());
|
||||||
|
|
||||||
|
let cur_status = status(provider.client.chain_info());
|
||||||
|
let my_status = write_handshake(&cur_status, &capabilities, &flow_params);
|
||||||
|
|
||||||
|
provider.client.add_blocks(100, EachBlockWith::Nothing);
|
||||||
|
|
||||||
|
let cur_status = status(provider.client.chain_info());
|
||||||
|
|
||||||
|
{
|
||||||
|
let packet_body = write_handshake(&cur_status, &capabilities, &flow_params);
|
||||||
|
proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body));
|
||||||
|
proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = request::Bodies {
|
||||||
|
block_hashes: (0..10).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()).collect(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let req_id = 111;
|
||||||
|
|
||||||
|
let request_body = encode_request(&Request::Bodies(request.clone()), req_id);
|
||||||
|
let response = {
|
||||||
|
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 mut response_stream = RlpStream::new_list(12);
|
||||||
|
|
||||||
|
response_stream.append(&req_id).append(&new_buf);
|
||||||
|
for body in bodies {
|
||||||
|
response_stream.append_raw(&body, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
response_stream.out()
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected = Expect::Respond(packet::BLOCK_BODIES, response);
|
||||||
|
proto.handle_packet(&expected, &1, packet::GET_BLOCK_BODIES, &request_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_block_receipts() {
|
||||||
|
let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into());
|
||||||
|
let capabilities = capabilities();
|
||||||
|
|
||||||
|
let (provider, proto) = setup(flow_params.clone(), capabilities.clone());
|
||||||
|
|
||||||
|
let cur_status = status(provider.client.chain_info());
|
||||||
|
let my_status = write_handshake(&cur_status, &capabilities, &flow_params);
|
||||||
|
|
||||||
|
provider.client.add_blocks(1000, EachBlockWith::Nothing);
|
||||||
|
|
||||||
|
let cur_status = status(provider.client.chain_info());
|
||||||
|
|
||||||
|
{
|
||||||
|
let packet_body = write_handshake(&cur_status, &capabilities, &flow_params);
|
||||||
|
proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body));
|
||||||
|
proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the first 10 block hashes starting with `f` because receipts are only provided
|
||||||
|
// by the test client in that case.
|
||||||
|
let block_hashes: Vec<_> = (0..1000).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap())
|
||||||
|
.filter(|hash| format!("{}", hash).starts_with("f")).take(10).collect();
|
||||||
|
|
||||||
|
let request = request::Receipts {
|
||||||
|
block_hashes: block_hashes.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let req_id = 111;
|
||||||
|
|
||||||
|
let request_body = encode_request(&Request::Receipts(request.clone()), req_id);
|
||||||
|
let response = {
|
||||||
|
let receipts: Vec<_> = block_hashes.iter()
|
||||||
|
.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 mut response_stream = RlpStream::new_list(2 + receipts.len());
|
||||||
|
|
||||||
|
response_stream.append(&req_id).append(&new_buf);
|
||||||
|
for block_receipts in receipts {
|
||||||
|
response_stream.append_raw(&block_receipts, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
response_stream.out()
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected = Expect::Respond(packet::RECEIPTS, response);
|
||||||
|
proto.handle_packet(&expected, &1, packet::GET_RECEIPTS, &request_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_block_bodies() {
|
||||||
|
let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into());
|
||||||
|
let capabilities = capabilities();
|
||||||
|
|
||||||
|
let (provider, proto) = setup(flow_params.clone(), capabilities.clone());
|
||||||
|
|
||||||
|
let cur_status = status(provider.client.chain_info());
|
||||||
|
let my_status = write_handshake(&cur_status, &capabilities, &flow_params);
|
||||||
|
|
||||||
|
provider.client.add_blocks(100, EachBlockWith::Nothing);
|
||||||
|
|
||||||
|
let cur_status = status(provider.client.chain_info());
|
||||||
|
|
||||||
|
{
|
||||||
|
let packet_body = write_handshake(&cur_status, &capabilities, &flow_params);
|
||||||
|
proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body));
|
||||||
|
proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = request::Bodies {
|
||||||
|
block_hashes: (0..10).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()).collect(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let req_id = 111;
|
||||||
|
|
||||||
|
let request_body = encode_request(&Request::Bodies(request.clone()), req_id);
|
||||||
|
let response = {
|
||||||
|
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 mut response_stream = RlpStream::new_list(12);
|
||||||
|
|
||||||
|
response_stream.append(&req_id).append(&new_buf);
|
||||||
|
for body in bodies {
|
||||||
|
response_stream.append_raw(&body, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
response_stream.out()
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected = Expect::Respond(packet::BLOCK_BODIES, response);
|
||||||
|
proto.handle_packet(&expected, &1, packet::GET_BLOCK_BODIES, &request_body);
|
||||||
}
|
}
|
@ -19,7 +19,8 @@
|
|||||||
use util::H256;
|
use util::H256;
|
||||||
|
|
||||||
/// A request for block headers.
|
/// A request for block headers.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct Headers {
|
pub struct Headers {
|
||||||
/// Starting block number
|
/// Starting block number
|
||||||
pub block_num: u64,
|
pub block_num: u64,
|
||||||
@ -35,7 +36,8 @@ pub struct Headers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A request for specific block bodies.
|
/// A request for specific block bodies.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct Bodies {
|
pub struct Bodies {
|
||||||
/// Hashes which bodies are being requested for.
|
/// Hashes which bodies are being requested for.
|
||||||
pub block_hashes: Vec<H256>
|
pub block_hashes: Vec<H256>
|
||||||
@ -45,14 +47,16 @@ pub struct Bodies {
|
|||||||
///
|
///
|
||||||
/// This request is answered with a list of transaction receipts for each block
|
/// This request is answered with a list of transaction receipts for each block
|
||||||
/// requested.
|
/// requested.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct Receipts {
|
pub struct Receipts {
|
||||||
/// Block hashes to return receipts for.
|
/// Block hashes to return receipts for.
|
||||||
pub block_hashes: Vec<H256>,
|
pub block_hashes: Vec<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request for a state proof
|
/// A request for a state proof
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct StateProof {
|
pub struct StateProof {
|
||||||
/// Block hash to query state from.
|
/// Block hash to query state from.
|
||||||
pub block: H256,
|
pub block: H256,
|
||||||
@ -66,14 +70,16 @@ pub struct StateProof {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A request for state proofs.
|
/// A request for state proofs.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct StateProofs {
|
pub struct StateProofs {
|
||||||
/// All the proof requests.
|
/// All the proof requests.
|
||||||
pub requests: Vec<StateProof>,
|
pub requests: Vec<StateProof>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request for contract code.
|
/// A request for contract code.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct ContractCode {
|
pub struct ContractCode {
|
||||||
/// Block hash
|
/// Block hash
|
||||||
pub block_hash: H256,
|
pub block_hash: H256,
|
||||||
@ -82,14 +88,16 @@ pub struct ContractCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A request for contract code.
|
/// A request for contract code.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct ContractCodes {
|
pub struct ContractCodes {
|
||||||
/// Block hash and account key (== sha3(address)) pairs to fetch code for.
|
/// Block hash and account key (== sha3(address)) pairs to fetch code for.
|
||||||
pub code_requests: Vec<ContractCode>,
|
pub code_requests: Vec<ContractCode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request for a header proof from the Canonical Hash Trie.
|
/// A request for a header proof from the Canonical Hash Trie.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct HeaderProof {
|
pub struct HeaderProof {
|
||||||
/// Number of the CHT.
|
/// Number of the CHT.
|
||||||
pub cht_number: u64,
|
pub cht_number: u64,
|
||||||
@ -100,14 +108,16 @@ pub struct HeaderProof {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A request for header proofs from the CHT.
|
/// A request for header proofs from the CHT.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub struct HeaderProofs {
|
pub struct HeaderProofs {
|
||||||
/// All the proof requests.
|
/// All the proof requests.
|
||||||
pub requests: Vec<HeaderProof>,
|
pub requests: Vec<HeaderProof>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kinds of requests.
|
/// Kinds of requests.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub enum Kind {
|
pub enum Kind {
|
||||||
/// Requesting headers.
|
/// Requesting headers.
|
||||||
Headers,
|
Headers,
|
||||||
@ -124,7 +134,8 @@ pub enum Kind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Encompasses all possible types of requests in a single structure.
|
/// Encompasses all possible types of requests in a single structure.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
pub enum Request {
|
pub enum Request {
|
||||||
/// Requesting headers.
|
/// Requesting headers.
|
||||||
Headers(Headers),
|
Headers(Headers),
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Types used in the public (IPC) api which require custom code generation.
|
//! Types used in the public (IPC) api which require custom code generation.
|
||||||
|
#![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues
|
||||||
|
|
||||||
#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
include!(concat!(env!("OUT_DIR"), "/mod.rs.in"));
|
include!(concat!(env!("OUT_DIR"), "/mod.rs.in"));
|
||||||
|
|
||||||
|
#[cfg(not(feature = "ipc"))]
|
||||||
|
include!("mod.rs.in");
|
Loading…
Reference in New Issue
Block a user