Implement PIP messages, request builder, and handlers (#4945)

* 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
This commit is contained in:
Robert Habermeier
2017-03-23 13:17:05 +01:00
committed by Gav Wood
parent b931a225ba
commit 64cec5ff7d
28 changed files with 2800 additions and 2095 deletions

View File

@@ -20,13 +20,14 @@ use std::cmp::Ordering;
use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};
use std::fmt;
use ethcore::encoded;
use ethcore::header::Header;
use light::net::ReqId;
use light::request::Headers as HeadersRequest;
use light::request::CompleteHeadersRequest as HeadersRequest;
use network::PeerId;
use util::{Bytes, H256};
use util::H256;
use super::response;
@@ -40,7 +41,7 @@ pub trait ResponseContext {
/// Get the request ID this response corresponds to.
fn req_id(&self) -> &ReqId;
/// Get the (unverified) response data.
fn data(&self) -> &[Bytes];
fn data(&self) -> &[encoded::Header];
/// Punish the responder.
fn punish_responder(&self);
}
@@ -114,7 +115,7 @@ impl Fetcher {
let needed_headers = HeadersRequest {
start: high_rung.parent_hash().clone().into(),
max: diff as usize - 1,
max: diff - 1,
skip: 0,
reverse: true,
};
@@ -190,7 +191,7 @@ impl Fetcher {
return SyncRound::Fetch(self);
}
match response::decode_and_verify(headers, &request.headers_request) {
match response::verify(headers, &request.headers_request) {
Err(e) => {
trace!(target: "sync", "Punishing peer {} for invalid response ({})", ctx.responder(), e);
ctx.punish_responder();
@@ -286,21 +287,21 @@ impl Fetcher {
}
// Compute scaffold parameters from non-zero distance between start and target block: (skip, pivots).
fn scaffold_params(diff: u64) -> (u64, usize) {
fn scaffold_params(diff: u64) -> (u64, u64) {
// default parameters.
// amount of blocks between each scaffold pivot.
const ROUND_SKIP: u64 = 255;
// amount of scaffold pivots: these are the Xs in "X___X___X"
const ROUND_PIVOTS: usize = 256;
const ROUND_PIVOTS: u64 = 256;
let rem = diff % (ROUND_SKIP + 1);
if diff <= ROUND_SKIP {
// just request headers from the start to the target.
(0, rem as usize)
(0, rem)
} else {
// the number of pivots necessary to exactly hit or overshoot the target.
let pivots_to_target = (diff / (ROUND_SKIP + 1)) + if rem == 0 { 0 } else { 1 };
let num_pivots = ::std::cmp::min(pivots_to_target, ROUND_PIVOTS as u64) as usize;
let num_pivots = ::std::cmp::min(pivots_to_target, ROUND_PIVOTS);
(ROUND_SKIP, num_pivots)
}
}
@@ -319,7 +320,7 @@ pub struct RoundStart {
contributors: HashSet<PeerId>,
attempt: usize,
skip: u64,
pivots: usize,
pivots: u64,
}
impl RoundStart {
@@ -372,7 +373,7 @@ impl RoundStart {
}
};
match response::decode_and_verify(ctx.data(), &req) {
match response::verify(ctx.data(), &req) {
Ok(headers) => {
if self.sparse_headers.len() == 0
&& headers.get(0).map_or(false, |x| x.parent_hash() != &self.start_block.1) {
@@ -383,7 +384,7 @@ impl RoundStart {
self.contributors.insert(ctx.responder());
self.sparse_headers.extend(headers);
if self.sparse_headers.len() == self.pivots {
if self.sparse_headers.len() as u64 == self.pivots {
return if self.skip == 0 {
SyncRound::abort(AbortReason::TargetReached, self.sparse_headers.into())
} else {
@@ -429,7 +430,7 @@ impl RoundStart {
let start = (self.start_block.0 + 1)
+ self.sparse_headers.len() as u64 * (self.skip + 1);
let max = self.pivots - self.sparse_headers.len();
let max = self.pivots - self.sparse_headers.len() as u64;
let headers_request = HeadersRequest {
start: start.into(),