Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Implement PIP messages, request builder, and handlers (#4945)
Browse files Browse the repository at this point in the history
* return errors on database corruption

* fix tests, json tests

* fix remainder of build

* buffer flow -> request credits

* proving state backend

* generate transaction proofs from provider

* network messages for transaction proof

* transaction proof test

* test for transaction proof message

* fix call bug

* request transaction proofs from on_demand

* most of proved_execution rpc

* proved execution future

* initial request definitions

* RLP encoding and decoding for requests

* proofs of non-existance in ProvingBlockChainClient

* new requests in provider.

* encode and decode responses

* complete initial request changes

* handle request packet in LightProtocol

* handle response packets

* implement requesting from

* re-do cost table

* get tests compiling

* fix cost table RLP encoding

* roundtrip tests for request types

* request builder tests

* move request_builder -> request::builder

* get network tests working

* return only complete headers responses

* request builder improvements

* New version of jsonrpc.

* split request filling into fill,complete

* Better invalid encoding messages

* Fixing deprecated methods of tokio_core

* use PIP messages in on_demand, old API

* migrate oneshot::complete to send in on_demand

* get on_demand tests to compile

* port ethsync to PIP messages

* adjust to minor on_demand API changes in RPC

* Using dedicated branch for jsonrpc

* Bump
  • Loading branch information
rphmeier authored and gavofyork committed Mar 23, 2017
1 parent b931a22 commit 64cec5f
Show file tree
Hide file tree
Showing 28 changed files with 2,795 additions and 2,090 deletions.
2 changes: 1 addition & 1 deletion ethcore/light/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
description = "Parity LES primitives"
description = "Parity Light Client Implementation"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore-light"
Expand Down
1 change: 0 additions & 1 deletion ethcore/light/src/client/header_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
//! - It stores only headers (and a pruned subset of them)
//! - To allow for flexibility in the database layout once that's incorporated.
// TODO: use DB instead of memory. DB Layout: just the contents of `candidates`/`headers`
//

use std::collections::{BTreeMap, HashMap};

Expand Down
49 changes: 1 addition & 48 deletions ethcore/light/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use ethcore::service::ClientIoMessage;
use ethcore::encoded;
use io::IoChannel;

use util::{Bytes, DBValue, H256, Mutex, RwLock};
use util::{H256, Mutex, RwLock};

use self::header_chain::{AncestryIter, HeaderChain};

Expand Down Expand Up @@ -315,50 +315,3 @@ impl LightChainClient for Client {
Client::cht_root(self, i)
}
}

// dummy implementation, should be removed when a `TestClient` is added.
impl ::provider::Provider for Client {
fn chain_info(&self) -> BlockChainInfo {
Client::chain_info(self)
}

fn reorg_depth(&self, _a: &H256, _b: &H256) -> Option<u64> {
None
}

fn earliest_state(&self) -> Option<u64> {
None
}

fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
Client::block_header(self, id)
}

fn block_body(&self, _id: BlockId) -> Option<encoded::Body> {
None
}

fn block_receipts(&self, _hash: &H256) -> Option<Bytes> {
None
}

fn state_proof(&self, _req: ::request::StateProof) -> Vec<Bytes> {
Vec::new()
}

fn contract_code(&self, _req: ::request::ContractCode) -> Bytes {
Vec::new()
}

fn header_proof(&self, _req: ::request::HeaderProof) -> Option<(encoded::Header, Vec<Bytes>)> {
None
}

fn transaction_proof(&self, _req: ::request::TransactionProof) -> Option<Vec<DBValue>> {
None
}

fn ready_transactions(&self) -> Vec<::ethcore::transaction::PendingTransaction> {
Vec::new()
}
}
4 changes: 2 additions & 2 deletions ethcore/light/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
//! use-cases like sending transactions from a personal account.
//!
//! The light client performs a header-only sync, doing verification and pruning
//! historical blocks. Upon pruning, batches of 2048 blocks have a number => hash
//! historical blocks. Upon pruning, batches of 2048 blocks have a number => (hash, TD)
//! mapping sealed into "canonical hash tries" which can later be used to verify
//! historical block queries from peers.
Expand Down Expand Up @@ -57,7 +57,7 @@ mod types;

pub use self::provider::Provider;
pub use self::transaction_queue::TransactionQueue;
pub use types::les_request as request;
pub use types::request as request;

#[macro_use]
extern crate log;
Expand Down
35 changes: 14 additions & 21 deletions ethcore/light/src/net/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
// GNU General Public License for more details.

// 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/>.

//! I/O and event context generalizations.
use network::{NetworkContext, PeerId, NodeId};

use super::{Announcement, LightProtocol, ReqId};
use super::error::Error;
use request::{self, Request};
use request::Requests;

/// An I/O context which allows sending and receiving packets as well as
/// disconnecting peers. This is used as a generalization of the portions
Expand Down Expand Up @@ -50,13 +50,13 @@ pub trait IoContext {
impl<'a> IoContext for NetworkContext<'a> {
fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>) {
if let Err(e) = self.send(peer, packet_id, packet_body) {
debug!(target: "les", "Error sending packet to peer {}: {}", peer, e);
debug!(target: "pip", "Error sending packet to peer {}: {}", peer, e);
}
}

fn respond(&self, packet_id: u8, packet_body: Vec<u8>) {
if let Err(e) = self.respond(packet_id, packet_body) {
debug!(target: "les", "Error responding to peer message: {}", e);
debug!(target: "pip", "Error responding to peer message: {}", e);
}
}

Expand All @@ -83,16 +83,17 @@ pub trait BasicContext {
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;

/// Make a request from a peer.
fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error>;
///
/// Fails on: nonexistent peer, network error, peer not server,
/// insufficient credits. Does not check capabilities before sending.
/// On success, returns a request id which can later be coordinated
/// with an event.
fn request_from(&self, peer: PeerId, request: Requests) -> Result<ReqId, Error>;

/// Make an announcement of new capabilities to the rest of the peers.
// TODO: maybe just put this on a timer in LightProtocol?
fn make_announcement(&self, announcement: Announcement);

/// Find the maximum number of requests of a specific type which can be made from
/// supplied peer.
fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize;

/// Disconnect a peer.
fn disconnect_peer(&self, peer: PeerId);

Expand Down Expand Up @@ -123,18 +124,14 @@ impl<'a> BasicContext for TickCtx<'a> {
self.io.persistent_peer_id(id)
}

fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error> {
self.proto.request_from(self.io, &peer, request)
fn request_from(&self, peer: PeerId, requests: Requests) -> Result<ReqId, Error> {
self.proto.request_from(self.io, &peer, requests)
}

fn make_announcement(&self, announcement: Announcement) {
self.proto.make_announcement(self.io, announcement);
}

fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize {
self.proto.max_requests(peer, kind)
}

fn disconnect_peer(&self, peer: PeerId) {
self.io.disconnect_peer(peer);
}
Expand All @@ -160,18 +157,14 @@ impl<'a> BasicContext for Ctx<'a> {
self.io.persistent_peer_id(id)
}

fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error> {
self.proto.request_from(self.io, &peer, request)
fn request_from(&self, peer: PeerId, requests: Requests) -> Result<ReqId, Error> {
self.proto.request_from(self.io, &peer, requests)
}

fn make_announcement(&self, announcement: Announcement) {
self.proto.make_announcement(self.io, announcement);
}

fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize {
self.proto.max_requests(peer, kind)
}

fn disconnect_peer(&self, peer: PeerId) {
self.io.disconnect_peer(peer);
}
Expand Down
4 changes: 4 additions & 0 deletions ethcore/light/src/net/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub enum Error {
UnknownPeer,
/// Unsolicited response.
UnsolicitedResponse,
/// Bad back-reference in request.
BadBackReference,
/// Not a server.
NotServer,
/// Unsupported protocol version.
Expand All @@ -78,6 +80,7 @@ impl Error {
Error::WrongNetwork => Punishment::Disable,
Error::UnknownPeer => Punishment::Disconnect,
Error::UnsolicitedResponse => Punishment::Disable,
Error::BadBackReference => Punishment::Disable,
Error::NotServer => Punishment::Disable,
Error::UnsupportedProtocolVersion(_) => Punishment::Disable,
Error::BadProtocolVersion => Punishment::Disable,
Expand Down Expand Up @@ -109,6 +112,7 @@ impl fmt::Display for Error {
Error::WrongNetwork => write!(f, "Wrong network"),
Error::UnknownPeer => write!(f, "Unknown peer"),
Error::UnsolicitedResponse => write!(f, "Peer provided unsolicited data"),
Error::BadBackReference => write!(f, "Bad back-reference in request."),
Error::NotServer => write!(f, "Peer not a server."),
Error::UnsupportedProtocolVersion(pv) => write!(f, "Unsupported protocol version: {}", pv),
Error::BadProtocolVersion => write!(f, "Bad protocol version in handshake"),
Expand Down
Loading

0 comments on commit 64cec5f

Please sign in to comment.