request definitions
This commit is contained in:
parent
1bc124f980
commit
eef9a355af
@ -27,18 +27,19 @@ use block_import_error::BlockImportError;
|
||||
use block_status::BlockStatus;
|
||||
use verification::queue::{Config as QueueConfig, HeaderQueue, QueueInfo, Status};
|
||||
use transaction::SignedTransaction;
|
||||
use types::blockchain_info::BlockChainInfo;
|
||||
|
||||
use super::provider::{CHTProofRequest, Provider, ProofRequest};
|
||||
|
||||
use io::IoChannel;
|
||||
use util::hash::H256;
|
||||
use util::Bytes;
|
||||
use util::{Bytes, Mutex};
|
||||
|
||||
/// Light client implementation.
|
||||
pub struct Client {
|
||||
engine: Arc<Engine>,
|
||||
header_queue: HeaderQueue,
|
||||
message_channel: IoChannel<ClientIoMessage>,
|
||||
message_channel: Mutex<IoChannel<ClientIoMessage>>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
@ -70,11 +71,12 @@ impl Client {
|
||||
}
|
||||
|
||||
/// Get the chain info.
|
||||
pub fn chain_info(&self) -> ChainInfo {
|
||||
|
||||
pub fn chain_info(&self) -> BlockChainInfo {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
// dummy implementation -- may draw from canonical cache further on.
|
||||
impl Provider for Client {
|
||||
fn block_headers(&self, block: H256, skip: usize, max: usize, reverse: bool) -> Vec<Bytes> {
|
||||
Vec::new()
|
||||
|
@ -29,6 +29,10 @@ use parking_lot::{Mutex, RwLock};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use self::request::Request;
|
||||
|
||||
mod request;
|
||||
|
||||
const TIMEOUT: TimerToken = 0;
|
||||
const TIMEOUT_INTERVAL_MS: u64 = 1000;
|
||||
|
||||
@ -87,11 +91,9 @@ mod packet {
|
||||
pub const TRANSACTION_PROOFS: u8 = 0x13;
|
||||
}
|
||||
|
||||
struct Request;
|
||||
|
||||
struct Requested {
|
||||
timestamp: usize,
|
||||
total: Request,
|
||||
req: Request,
|
||||
}
|
||||
|
||||
// data about each peer.
|
||||
@ -172,7 +174,7 @@ impl Chain {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn status(&self, peer: &PeerId, io: &NetworkContext) {
|
||||
fn status(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@ -205,6 +207,16 @@ impl Chain {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Handle a request for receipts.
|
||||
fn get_receipts(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Receive a response for receipts.
|
||||
fn receipts(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Handle a request for proofs.
|
||||
fn get_proofs(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
||||
unimplemented!()
|
||||
@ -284,7 +296,7 @@ impl NetworkProtocolHandler for Chain {
|
||||
packet::BLOCK_BODIES => self.block_bodies(peer, io, rlp),
|
||||
|
||||
packet::GET_RECEIPTS => self.get_receipts(peer, io, rlp),
|
||||
packet::RECEIPTS => self.receipt(peer, io, rlp),
|
||||
packet::RECEIPTS => self.receipts(peer, io, rlp),
|
||||
|
||||
packet::GET_PROOFS => self.get_proofs(peer, io, rlp),
|
||||
packet::PROOFS => self.proofs(peer, io, rlp),
|
||||
@ -311,7 +323,7 @@ impl NetworkProtocolHandler for Chain {
|
||||
}
|
||||
|
||||
fn disconnected(&self, io: &NetworkContext, peer: &PeerId) {
|
||||
self.on_disconnect(peer, io);
|
||||
self.on_disconnect(*peer, io);
|
||||
}
|
||||
|
||||
fn timeout(&self, io: &NetworkContext, timer: TimerToken) {
|
||||
|
@ -14,125 +14,152 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! LES request types.
|
||||
/// LES request types.
|
||||
|
||||
use util::bigint::prelude::*;
|
||||
use rlp::*;
|
||||
use ethcore::transaction::Transaction;
|
||||
use util::{Address, H256};
|
||||
|
||||
/// An LES request. This defines its data format, and the format of its response type.
|
||||
pub trait Request: Sized {
|
||||
/// The response type of this request.
|
||||
type Response: Response;
|
||||
|
||||
/// The error type when decoding a response.
|
||||
type Error;
|
||||
|
||||
/// Whether this request is empty.
|
||||
fn is_empty(&self) -> bool;
|
||||
|
||||
/// The remainder of this request unfulfilled by the response. Required to return
|
||||
/// an equivalent request when provided with an empty response.
|
||||
fn remainder(&self, res: &Self::Response) -> Self;
|
||||
|
||||
/// Attempt to parse raw data into a response object
|
||||
/// or an error. Behavior undefined if the raw data didn't originate from
|
||||
/// this request.
|
||||
fn parse_response(&self, raw: &[u8]) -> Result<Self::Response, Self::Error>;
|
||||
/// A request for block headers.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Headers {
|
||||
/// Block information for the request being made.
|
||||
pub block: (u64, H256),
|
||||
/// The maximum amount of headers which can be returned.
|
||||
pub max: u64,
|
||||
/// The amount of headers to skip between each response entry.
|
||||
pub skip: u64,
|
||||
/// Whether the headers should proceed in falling number from the initial block.
|
||||
pub reverse: bool,
|
||||
}
|
||||
|
||||
/// Request responses. These must have a combination operation used to fill the gaps
|
||||
/// in one response with data from another.
|
||||
pub trait Response: Sized {
|
||||
/// Combine the two responses into one. This can only be relied on to behave correctly
|
||||
/// if `other` is a response to a sub-request of the request this response was
|
||||
/// produced from.
|
||||
fn combine(&mut self, other: Self);
|
||||
/// A request for specific block bodies.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Bodies {
|
||||
/// Hashes which bodies are being requested for.
|
||||
pub block_hashes: Vec<H256>
|
||||
}
|
||||
|
||||
/// A request for block bodies.
|
||||
pub struct BlockBodies {
|
||||
hashes: Vec<H256>,
|
||||
/// A request for transaction receipts.
|
||||
///
|
||||
/// This request is answered with a list of transaction receipts for each block
|
||||
/// requested.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Receipts {
|
||||
/// Block hashes to return receipts for.
|
||||
pub block_hashes: Vec<H256>,
|
||||
}
|
||||
|
||||
/// A response for block bodies.
|
||||
pub struct BlockBodiesResponse {
|
||||
bodies: Vec<(H256, Vec<u8>)>,
|
||||
/// A request for state proofs.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct StateProofs {
|
||||
/// Block hash to query state from.
|
||||
pub block: H256,
|
||||
/// Key of the state trie -- corresponds to account hash.
|
||||
pub key1: H256,
|
||||
/// Key in that account's storage trie; if empty, then the account RLP should be
|
||||
/// returned.
|
||||
pub key2: Option<H256>,
|
||||
/// if greater than zero, trie nodes beyond this level may be omitted.
|
||||
pub from_level: u32, // could even safely be u8; trie w/ 32-byte key can be at most 64-levels deep.
|
||||
}
|
||||
|
||||
impl Request for BlockBodies {
|
||||
type Response = BlockBodiesResponse;
|
||||
type Error = ::rlp::DecoderError;
|
||||
|
||||
fn is_empty(&self) -> bool { self.hashes.is_empty() }
|
||||
|
||||
fn remainder(&self, res: &Self::Response) -> Self {
|
||||
let mut remaining = Vec::new();
|
||||
|
||||
let bodies = res.bodies.iter().map(|&(_, ref b) b).chain(::std::iter::repeat(&Vec::new()));
|
||||
for (hash, body) in self.hashes.iter().zip(bodies) {
|
||||
if body.is_empty() {
|
||||
remaining.push(hash);
|
||||
}
|
||||
}
|
||||
|
||||
BlockBodies {
|
||||
hashes: remaining,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_response(&self, raw: &[u8]) -> Result<Self::Response, Self::Error> {
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use ethcore::header::Header;
|
||||
|
||||
let rlp = UntrustedRlp::new(raw);
|
||||
|
||||
let mut bodies = Vec::with_capacity(self.hashes.len());
|
||||
|
||||
let items = rlp.iter();
|
||||
for hash in self.hashes.iter().cloned() {
|
||||
let res_bytes = match items.next() {
|
||||
Some(rlp) => {
|
||||
// perform basic block verification.
|
||||
// TODO: custom error type?
|
||||
try!(rlp.val_at::<Vec<SignedTransaction>>(0)
|
||||
.and_then(|_| rlp.val_at::<Vec<Header>>(1)));
|
||||
|
||||
try!(rlp.data()).to_owned()
|
||||
}
|
||||
None => Vec::new(),
|
||||
};
|
||||
|
||||
bodies.push((hash, res_bytes));
|
||||
}
|
||||
|
||||
Ok(BlockBodiesResponse {
|
||||
bodies: bodies,
|
||||
})
|
||||
}
|
||||
/// A request for contract code.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ContractCodes {
|
||||
/// Block hash and account key (== sha3(address)) pairs to fetch code for.
|
||||
pub code_requests: Vec<(H256, H256)>,
|
||||
}
|
||||
|
||||
impl Response for BlockBodiesResponse {
|
||||
fn identity() -> Self {
|
||||
BlockBodiesResponse {
|
||||
bodies: Vec::new(),
|
||||
}
|
||||
}
|
||||
/// A request for header proofs from the Canonical Hash Trie.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct HeaderProofs {
|
||||
/// Number of the CHT.
|
||||
pub cht_number: u64,
|
||||
/// Block number requested.
|
||||
pub block_number: u64,
|
||||
/// If greater than zero, trie nodes beyond this level may be omitted.
|
||||
pub from_level: u32,
|
||||
}
|
||||
|
||||
fn combine(&mut self, other: Self) {
|
||||
let other_iter = other.bodies.into_iter();
|
||||
/// A request for block deltas -- merkle proofs of all changed trie nodes and code.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct BlockDeltas {
|
||||
/// Block hashes deltas are being requested for.
|
||||
pub block_hashes: Vec<H256>,
|
||||
}
|
||||
|
||||
'a:
|
||||
for &mut (ref my_hash, ref mut my_body) in self.bodies.iter_mut() {
|
||||
loop {
|
||||
match other_iter.next() {
|
||||
Some((hash, body)) if hash == my_hash && !body.is_empty() => {
|
||||
*my_body = body.to_owned();
|
||||
break
|
||||
}
|
||||
Some(_) => continue,
|
||||
None => break 'a,
|
||||
}
|
||||
}
|
||||
/// A request for a single transaction merkle proof.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TransactionProof {
|
||||
/// The block hash to use the initial state from.
|
||||
pub block_hash: H256,
|
||||
/// The address to treat as the sender of the transaction.
|
||||
pub sender: Address,
|
||||
/// The raw transaction request itself.
|
||||
pub transaction: Transaction,
|
||||
}
|
||||
|
||||
/// A request for transaction merkle proofs.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TransactionProofs {
|
||||
/// Transaction proof requests.
|
||||
pub tx_reqs: Vec<TransactionProof>,
|
||||
}
|
||||
|
||||
/// Kinds of requests.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Kind {
|
||||
/// Requesting headers.
|
||||
Headers,
|
||||
/// Requesting block bodies.
|
||||
Bodies,
|
||||
/// Requesting transaction receipts.
|
||||
Receipts,
|
||||
/// Requesting proofs of state trie nodes.
|
||||
StateProofs,
|
||||
/// Requesting contract code by hash.
|
||||
Codes,
|
||||
/// Requesting header proofs (from the CHT).
|
||||
HeaderProofs,
|
||||
/// Requesting block deltas.
|
||||
Deltas,
|
||||
/// Requesting merkle proofs for transactions.
|
||||
TransactionProofs,
|
||||
}
|
||||
|
||||
/// Encompasses all possible types of requests in a single structure.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Request {
|
||||
/// Requesting headers.
|
||||
Headers(Headers),
|
||||
/// Requesting block bodies.
|
||||
Bodies(Bodies),
|
||||
/// Requesting transaction receipts.
|
||||
Receipts(Receipts),
|
||||
/// Requesting state proofs.
|
||||
StateProofs(StateProofs),
|
||||
/// Requesting contract codes.
|
||||
Codes(ContractCodes),
|
||||
/// Requesting header proofs.
|
||||
HeaderProofs(HeaderProofs),
|
||||
/// Requesting block deltas.
|
||||
Deltas(BlockDeltas),
|
||||
/// Requesting transaction proofs.
|
||||
TransactionProofs(TransactionProofs),
|
||||
}
|
||||
|
||||
impl Request {
|
||||
/// Get the kind of request this is.
|
||||
pub fn kind(&self) -> Kind {
|
||||
match *self {
|
||||
Request::Headers(_) => Kind::Headers,
|
||||
Request::Bodies(_) => Kind::Bodies,
|
||||
Request::Receipts(_) => Kind::Receipts,
|
||||
Request::StateProofs(_) => Kind::StateProofs,
|
||||
Request::Codes(_) => Kind::Codes,
|
||||
Request::HeaderProofs(_) => Kind::HeaderProofs,
|
||||
Request::Deltas(_) => Kind::Deltas,
|
||||
Request::TransactionProofs(_) => Kind::TransactionProofs,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user