revise light implementation strategy
This commit is contained in:
parent
90a2c37977
commit
edf17d00c4
@ -69,16 +69,16 @@ impl Client {
|
|||||||
pub fn queue_info(&self) -> QueueInfo {
|
pub fn queue_info(&self) -> QueueInfo {
|
||||||
self.header_queue.queue_info()
|
self.header_queue.queue_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the chain info.
|
|
||||||
pub fn chain_info(&self) -> BlockChainInfo {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dummy implementation -- may draw from canonical cache further on.
|
// dummy implementation -- may draw from canonical cache further on.
|
||||||
impl Provider for Client {
|
impl Provider for Client {
|
||||||
fn block_headers(&self, block: H256, skip: usize, max: usize, reverse: bool) -> Vec<Bytes> {
|
/// Get the chain info.
|
||||||
|
fn chain_info(&self) -> BlockChainInfo {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_headers(&self, block: (u64, H256), skip: usize, max: usize, reverse: bool) -> Vec<Bytes> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
pub use proof_request::{CHTProofRequest, ProofRequest};
|
pub use proof_request::{CHTProofRequest, ProofRequest};
|
||||||
|
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
|
use blockchain_info::BlockChainInfo;
|
||||||
|
|
||||||
use util::Bytes;
|
use util::Bytes;
|
||||||
use util::hash::H256;
|
use util::hash::H256;
|
||||||
@ -30,13 +31,16 @@ use util::hash::H256;
|
|||||||
/// Requests which can't be fulfilled should return an empty RLP list.
|
/// Requests which can't be fulfilled should return an empty RLP list.
|
||||||
///
|
///
|
||||||
/// [1]: https://github.com/ethcore/parity/wiki/Light-Ethereum-Subprotocol-(LES)
|
/// [1]: https://github.com/ethcore/parity/wiki/Light-Ethereum-Subprotocol-(LES)
|
||||||
pub trait Provider {
|
pub trait Provider: Sync {
|
||||||
|
/// Provide current blockchain info.
|
||||||
|
fn chain_info(&self) -> BlockChainInfo;
|
||||||
|
|
||||||
/// Provide a list of headers starting at the requested block,
|
/// Provide a list of headers starting at the requested block,
|
||||||
/// possibly in reverse and skipping `skip` at a time.
|
/// possibly in reverse and skipping `skip` at a time.
|
||||||
///
|
///
|
||||||
/// The returned vector may have any length in the range [0, `max`], but the
|
/// The returned vector may have any length in the range [0, `max`], but the
|
||||||
/// results within must adhere to the `skip` and `reverse` parameters.
|
/// results within must adhere to the `skip` and `reverse` parameters.
|
||||||
fn block_headers(&self, block: H256, skip: usize, max: usize, reverse: bool) -> Vec<Bytes>;
|
fn block_headers(&self, block: (u64, H256), skip: usize, max: usize, reverse: bool) -> Vec<Bytes>;
|
||||||
|
|
||||||
/// Provide as many as possible of the requested blocks (minus the headers) encoded
|
/// Provide as many as possible of the requested blocks (minus the headers) encoded
|
||||||
/// in RLP format.
|
/// in RLP format.
|
||||||
|
@ -91,6 +91,22 @@ mod packet {
|
|||||||
pub const TRANSACTION_PROOFS: u8 = 0x13;
|
pub const TRANSACTION_PROOFS: u8 = 0x13;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper macro for disconnecting peer on error while returning
|
||||||
|
// the value if ok.
|
||||||
|
// requires that error types are debug.
|
||||||
|
macro_rules! try_dc {
|
||||||
|
($io: expr, $peer: expr, $e: expr) => {
|
||||||
|
match $e {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
debug!(target: "les", "disconnecting peer {} due to error {:?}", $peer, e);
|
||||||
|
$io.disconnect_peer($peer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Requested {
|
struct Requested {
|
||||||
timestamp: usize,
|
timestamp: usize,
|
||||||
req: Request,
|
req: Request,
|
||||||
@ -102,9 +118,14 @@ struct Peer {
|
|||||||
current_asking: HashSet<usize>, // pending request ids.
|
current_asking: HashSet<usize>, // pending request ids.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This handles synchronization of the header chain for a light client.
|
/// This is an implementation of the light ethereum network protocol, abstracted
|
||||||
pub struct Chain {
|
/// over a `Provider` of data and a p2p network.
|
||||||
client: Client,
|
///
|
||||||
|
/// This is simply designed for request-response purposes. Higher level uses
|
||||||
|
/// of the protocol, such as synchronization, will function as wrappers around
|
||||||
|
/// this system.
|
||||||
|
pub struct LightProtocol {
|
||||||
|
provider: Box<Provider>,
|
||||||
genesis_hash: H256,
|
genesis_hash: H256,
|
||||||
mainnet: bool,
|
mainnet: bool,
|
||||||
peers: RwLock<HashMap<PeerId, Peer>>,
|
peers: RwLock<HashMap<PeerId, Peer>>,
|
||||||
@ -112,7 +133,7 @@ pub struct Chain {
|
|||||||
req_id: AtomicUsize,
|
req_id: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chain {
|
impl LightProtocol {
|
||||||
// make a request to a given peer.
|
// make a request to a given peer.
|
||||||
fn request_from(&self, peer: &PeerId, req: Request) {
|
fn request_from(&self, peer: &PeerId, req: Request) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
@ -189,6 +210,14 @@ impl Chain {
|
|||||||
fn get_block_headers(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
fn get_block_headers(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
||||||
const MAX_HEADERS: usize = 512;
|
const MAX_HEADERS: usize = 512;
|
||||||
|
|
||||||
|
let req_id: u64 = try_dc!(io, peer, data.val_at(0));
|
||||||
|
let block = try_dc!(io, peer, data.at(1).and_then(|block_list| {
|
||||||
|
(try!(block_list.val_at(0)), try!(block_list.val_at(1))
|
||||||
|
}));
|
||||||
|
let max = ::std::cmp::min(MAX_HEADERS, try_dc!(io, peer, data.val_at(2)));
|
||||||
|
let reverse = try_dc!(io, peer, data.val_at(3));
|
||||||
|
|
||||||
|
let headers = self.provider.block_headers()
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +228,8 @@ impl Chain {
|
|||||||
|
|
||||||
// Handle a request for block bodies.
|
// Handle a request for block bodies.
|
||||||
fn get_block_bodies(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
fn get_block_bodies(&self, peer: &PeerId, io: &NetworkContext, data: UntrustedRlp) {
|
||||||
|
const MAX_BODIES: usize = 512;
|
||||||
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +309,7 @@ impl Chain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkProtocolHandler for Chain {
|
impl NetworkProtocolHandler for LightProtocol {
|
||||||
fn initialize(&self, io: &NetworkContext) {
|
fn initialize(&self, io: &NetworkContext) {
|
||||||
io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS).expect("Error registering sync timer.");
|
io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS).expect("Error registering sync timer.");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user