Merge branch 'master' into lightsync
This commit is contained in:
@@ -26,6 +26,7 @@ use ethcore::transaction::PendingTransaction;
|
||||
use ethcore::blockchain_info::BlockChainInfo;
|
||||
use ethcore::spec::Spec;
|
||||
use ethcore::service::ClientIoMessage;
|
||||
use ethcore::encoded;
|
||||
use io::IoChannel;
|
||||
|
||||
use util::hash::{H256, H256FastMap};
|
||||
@@ -233,11 +234,11 @@ impl Provider for Client {
|
||||
None
|
||||
}
|
||||
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||
self.chain.get_header(id)
|
||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
|
||||
self.chain.get_header(id).map(encoded::Header::new)
|
||||
}
|
||||
|
||||
fn block_body(&self, _id: BlockId) -> Option<Bytes> {
|
||||
fn block_body(&self, _id: BlockId) -> Option<encoded::Body> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -253,7 +254,7 @@ impl Provider for Client {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn header_proof(&self, _req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)> {
|
||||
fn header_proof(&self, _req: request::HeaderProof) -> Option<(encoded::Header, Vec<Bytes>)> {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
@@ -135,10 +135,10 @@ impl RlpDecodable for CostTable {
|
||||
let mut header_proofs = None;
|
||||
|
||||
for row in rlp.iter() {
|
||||
let msg_id: u8 = try!(row.val_at(0));
|
||||
let msg_id: u8 = row.val_at(0)?;
|
||||
let cost = {
|
||||
let base = try!(row.val_at(1));
|
||||
let per = try!(row.val_at(2));
|
||||
let base = row.val_at(1)?;
|
||||
let per = row.val_at(2)?;
|
||||
|
||||
Cost(base, per)
|
||||
};
|
||||
@@ -155,12 +155,12 @@ impl RlpDecodable for CostTable {
|
||||
}
|
||||
|
||||
Ok(CostTable {
|
||||
headers: try!(headers.ok_or(DecoderError::Custom("No headers cost specified"))),
|
||||
bodies: try!(bodies.ok_or(DecoderError::Custom("No bodies cost specified"))),
|
||||
receipts: try!(receipts.ok_or(DecoderError::Custom("No receipts cost specified"))),
|
||||
state_proofs: try!(state_proofs.ok_or(DecoderError::Custom("No proofs cost specified"))),
|
||||
contract_codes: try!(contract_codes.ok_or(DecoderError::Custom("No contract codes specified"))),
|
||||
header_proofs: try!(header_proofs.ok_or(DecoderError::Custom("No header proofs cost specified"))),
|
||||
headers: headers.ok_or(DecoderError::Custom("No headers cost specified"))?,
|
||||
bodies: bodies.ok_or(DecoderError::Custom("No bodies cost specified"))?,
|
||||
receipts: receipts.ok_or(DecoderError::Custom("No receipts cost specified"))?,
|
||||
state_proofs: state_proofs.ok_or(DecoderError::Custom("No proofs cost specified"))?,
|
||||
contract_codes: contract_codes.ok_or(DecoderError::Custom("No contract codes specified"))?,
|
||||
header_proofs: header_proofs.ok_or(DecoderError::Custom("No header proofs cost specified"))?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ impl Peer {
|
||||
flow_params.recharge(&mut self.local_buffer);
|
||||
|
||||
let max_cost = flow_params.compute_cost(kind, max);
|
||||
try!(self.local_buffer.deduct_cost(max_cost));
|
||||
self.local_buffer.deduct_cost(max_cost)?;
|
||||
Ok(max_cost)
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ impl LightProtocol {
|
||||
/// with an event.
|
||||
pub fn request_from(&self, io: &IoContext, peer_id: &PeerId, request: Request) -> Result<ReqId, Error> {
|
||||
let peers = self.peers.read();
|
||||
let peer = try!(peers.get(peer_id).ok_or_else(|| Error::UnknownPeer));
|
||||
let peer = peers.get(peer_id).ok_or_else(|| Error::UnknownPeer)?;
|
||||
let mut peer = peer.lock();
|
||||
|
||||
if !peer.idle { return Err(Error::Overburdened) }
|
||||
@@ -300,7 +300,7 @@ impl LightProtocol {
|
||||
Some((ref mut buf, ref flow)) => {
|
||||
flow.recharge(buf);
|
||||
let max = flow.compute_cost(request.kind(), request.amount());
|
||||
try!(buf.deduct_cost(max));
|
||||
buf.deduct_cost(max)?;
|
||||
}
|
||||
None => return Err(Error::NotServer),
|
||||
}
|
||||
@@ -407,8 +407,8 @@ impl LightProtocol {
|
||||
// - check whether request was made
|
||||
// - check whether request kinds match
|
||||
fn pre_verify_response(&self, peer: &PeerId, kind: request::Kind, raw: &UntrustedRlp) -> Result<ReqId, Error> {
|
||||
let req_id: usize = try!(raw.val_at(0));
|
||||
let cur_buffer: U256 = try!(raw.val_at(1));
|
||||
let req_id: usize = raw.val_at(0)?;
|
||||
let cur_buffer: U256 = raw.val_at(1)?;
|
||||
|
||||
trace!(target: "les", "pre-verifying response from peer {}, kind={:?}", peer, kind);
|
||||
|
||||
@@ -614,7 +614,7 @@ impl LightProtocol {
|
||||
}
|
||||
};
|
||||
|
||||
let (status, capabilities, flow_params) = try!(status::parse_handshake(data));
|
||||
let (status, capabilities, flow_params) = status::parse_handshake(data)?;
|
||||
|
||||
trace!(target: "les", "Connected peer with chain head {:?}", (status.head_hash, status.head_num));
|
||||
|
||||
@@ -656,7 +656,7 @@ impl LightProtocol {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let announcement = try!(status::parse_announcement(data));
|
||||
let announcement = status::parse_announcement(data)?;
|
||||
|
||||
// scope to ensure locks are dropped before moving into handler-space.
|
||||
{
|
||||
@@ -709,25 +709,25 @@ impl LightProtocol {
|
||||
|
||||
let mut peer = peer.lock();
|
||||
|
||||
let req_id: u64 = try!(data.val_at(0));
|
||||
let data = try!(data.at(1));
|
||||
let req_id: u64 = data.val_at(0)?;
|
||||
let data = data.at(1)?;
|
||||
|
||||
let start_block = {
|
||||
if try!(data.at(0)).size() == 32 {
|
||||
HashOrNumber::Hash(try!(data.val_at(0)))
|
||||
if data.at(0)?.size() == 32 {
|
||||
HashOrNumber::Hash(data.val_at(0)?)
|
||||
} else {
|
||||
HashOrNumber::Number(try!(data.val_at(0)))
|
||||
HashOrNumber::Number(data.val_at(0)?)
|
||||
}
|
||||
};
|
||||
|
||||
let req = request::Headers {
|
||||
start: start_block,
|
||||
max: ::std::cmp::min(MAX_HEADERS, try!(data.val_at(1))),
|
||||
skip: try!(data.val_at(2)),
|
||||
reverse: try!(data.val_at(3)),
|
||||
max: ::std::cmp::min(MAX_HEADERS, data.val_at(1)?),
|
||||
skip: data.val_at(2)?,
|
||||
reverse: data.val_at(3)?,
|
||||
};
|
||||
|
||||
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Headers, req.max));
|
||||
let max_cost = peer.deduct_max(&self.flow_params, request::Kind::Headers, req.max)?;
|
||||
|
||||
let response = self.provider.block_headers(req);
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::Headers, response.len());
|
||||
@@ -739,7 +739,7 @@ impl LightProtocol {
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
|
||||
for header in response {
|
||||
stream.append_raw(&header, 1);
|
||||
stream.append_raw(&header.into_inner(), 1);
|
||||
}
|
||||
|
||||
stream.out()
|
||||
@@ -750,8 +750,8 @@ impl LightProtocol {
|
||||
|
||||
// Receive a response for block headers.
|
||||
fn block_headers(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||
let req_id = try!(self.pre_verify_response(peer, request::Kind::Headers, &raw));
|
||||
let raw_headers: Vec<_> = try!(raw.at(2)).iter().map(|x| x.as_raw().to_owned()).collect();
|
||||
let req_id = self.pre_verify_response(peer, request::Kind::Headers, &raw)?;
|
||||
let raw_headers: Vec<_> = raw.at(2)?.iter().map(|x| x.as_raw().to_owned()).collect();
|
||||
|
||||
for handler in &self.handlers {
|
||||
handler.on_block_headers(&Ctx {
|
||||
@@ -778,16 +778,19 @@ impl LightProtocol {
|
||||
};
|
||||
let mut peer = peer.lock();
|
||||
|
||||
let req_id: u64 = try!(data.val_at(0));
|
||||
let req_id: u64 = data.val_at(0)?;
|
||||
|
||||
let req = request::Bodies {
|
||||
block_hashes: try!(try!(data.at(1)).iter().take(MAX_BODIES).map(|x| x.as_val()).collect())
|
||||
block_hashes: data.at(1)?.iter()
|
||||
.take(MAX_BODIES)
|
||||
.map(|x| x.as_val())
|
||||
.collect::<Result<_, _>>()?
|
||||
};
|
||||
|
||||
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Bodies, req.block_hashes.len()));
|
||||
let max_cost = peer.deduct_max(&self.flow_params, request::Kind::Bodies, req.block_hashes.len())?;
|
||||
|
||||
let response = self.provider.block_bodies(req);
|
||||
let response_len = response.iter().filter(|x| &x[..] != &::rlp::EMPTY_LIST_RLP).count();
|
||||
let response_len = response.iter().filter(|x| x.is_some()).count();
|
||||
let actual_cost = self.flow_params.compute_cost(request::Kind::Bodies, response_len);
|
||||
assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
|
||||
|
||||
@@ -798,7 +801,10 @@ impl LightProtocol {
|
||||
stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
|
||||
|
||||
for body in response {
|
||||
stream.append_raw(&body, 1);
|
||||
match body {
|
||||
Some(body) => stream.append_raw(&body.into_inner(), 1),
|
||||
None => stream.append_empty_data(),
|
||||
};
|
||||
}
|
||||
|
||||
stream.out()
|
||||
@@ -809,8 +815,8 @@ impl LightProtocol {
|
||||
|
||||
// Receive a response for block bodies.
|
||||
fn block_bodies(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||
let req_id = try!(self.pre_verify_response(peer, request::Kind::Bodies, &raw));
|
||||
let raw_bodies: Vec<Bytes> = try!(raw.at(2)).iter().map(|x| x.as_raw().to_owned()).collect();
|
||||
let req_id = self.pre_verify_response(peer, request::Kind::Bodies, &raw)?;
|
||||
let raw_bodies: Vec<Bytes> = raw.at(2)?.iter().map(|x| x.as_raw().to_owned()).collect();
|
||||
|
||||
for handler in &self.handlers {
|
||||
handler.on_block_bodies(&Ctx {
|
||||
@@ -837,13 +843,16 @@ impl LightProtocol {
|
||||
};
|
||||
let mut peer = peer.lock();
|
||||
|
||||
let req_id: u64 = try!(data.val_at(0));
|
||||
let req_id: u64 = data.val_at(0)?;
|
||||
|
||||
let req = request::Receipts {
|
||||
block_hashes: try!(try!(data.at(1)).iter().take(MAX_RECEIPTS).map(|x| x.as_val()).collect())
|
||||
block_hashes: data.at(1)?.iter()
|
||||
.take(MAX_RECEIPTS)
|
||||
.map(|x| x.as_val())
|
||||
.collect::<Result<_,_>>()?
|
||||
};
|
||||
|
||||
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Receipts, req.block_hashes.len()));
|
||||
let max_cost = peer.deduct_max(&self.flow_params, request::Kind::Receipts, req.block_hashes.len())?;
|
||||
|
||||
let response = self.provider.receipts(req);
|
||||
let response_len = response.iter().filter(|x| &x[..] != &::rlp::EMPTY_LIST_RLP).count();
|
||||
@@ -868,11 +877,11 @@ impl LightProtocol {
|
||||
|
||||
// Receive a response for receipts.
|
||||
fn receipts(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||
let req_id = try!(self.pre_verify_response(peer, request::Kind::Receipts, &raw));
|
||||
let raw_receipts: Vec<Vec<Receipt>> = try!(try!(raw.at(2))
|
||||
let req_id = self.pre_verify_response(peer, request::Kind::Receipts, &raw)?;
|
||||
let raw_receipts: Vec<Vec<Receipt>> = raw.at(2)?
|
||||
.iter()
|
||||
.map(|x| x.as_val())
|
||||
.collect());
|
||||
.collect::<Result<_,_>>()?;
|
||||
|
||||
for handler in &self.handlers {
|
||||
handler.on_receipts(&Ctx {
|
||||
@@ -899,24 +908,24 @@ impl LightProtocol {
|
||||
};
|
||||
let mut peer = peer.lock();
|
||||
|
||||
let req_id: u64 = try!(data.val_at(0));
|
||||
let req_id: u64 = data.val_at(0)?;
|
||||
|
||||
let req = {
|
||||
let requests: Result<Vec<_>, Error> = try!(data.at(1)).iter().take(MAX_PROOFS).map(|x| {
|
||||
let requests: Result<Vec<_>, Error> = data.at(1)?.iter().take(MAX_PROOFS).map(|x| {
|
||||
Ok(request::StateProof {
|
||||
block: try!(x.val_at(0)),
|
||||
key1: try!(x.val_at(1)),
|
||||
key2: if try!(x.at(2)).is_empty() { None } else { Some(try!(x.val_at(2))) },
|
||||
from_level: try!(x.val_at(3)),
|
||||
block: x.val_at(0)?,
|
||||
key1: x.val_at(1)?,
|
||||
key2: if x.at(2)?.is_empty() { None } else { Some(x.val_at(2)?) },
|
||||
from_level: x.val_at(3)?,
|
||||
})
|
||||
}).collect();
|
||||
|
||||
request::StateProofs {
|
||||
requests: try!(requests),
|
||||
requests: requests?,
|
||||
}
|
||||
};
|
||||
|
||||
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::StateProofs, req.requests.len()));
|
||||
let max_cost = peer.deduct_max(&self.flow_params, request::Kind::StateProofs, req.requests.len())?;
|
||||
|
||||
let response = self.provider.proofs(req);
|
||||
let response_len = response.iter().filter(|x| &x[..] != &::rlp::EMPTY_LIST_RLP).count();
|
||||
@@ -941,9 +950,9 @@ impl LightProtocol {
|
||||
|
||||
// Receive a response for proofs.
|
||||
fn proofs(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||
let req_id = try!(self.pre_verify_response(peer, request::Kind::StateProofs, &raw));
|
||||
let req_id = self.pre_verify_response(peer, request::Kind::StateProofs, &raw)?;
|
||||
|
||||
let raw_proofs: Vec<Vec<Bytes>> = try!(raw.at(2)).iter()
|
||||
let raw_proofs: Vec<Vec<Bytes>> = raw.at(2)?.iter()
|
||||
.map(|x| x.iter().map(|node| node.as_raw().to_owned()).collect())
|
||||
.collect();
|
||||
|
||||
@@ -972,22 +981,22 @@ impl LightProtocol {
|
||||
};
|
||||
let mut peer = peer.lock();
|
||||
|
||||
let req_id: u64 = try!(data.val_at(0));
|
||||
let req_id: u64 = data.val_at(0)?;
|
||||
|
||||
let req = {
|
||||
let requests: Result<Vec<_>, Error> = try!(data.at(1)).iter().take(MAX_CODES).map(|x| {
|
||||
let requests: Result<Vec<_>, Error> = data.at(1)?.iter().take(MAX_CODES).map(|x| {
|
||||
Ok(request::ContractCode {
|
||||
block_hash: try!(x.val_at(0)),
|
||||
account_key: try!(x.val_at(1)),
|
||||
block_hash: x.val_at(0)?,
|
||||
account_key: x.val_at(1)?,
|
||||
})
|
||||
}).collect();
|
||||
|
||||
request::ContractCodes {
|
||||
code_requests: try!(requests),
|
||||
code_requests: requests?,
|
||||
}
|
||||
};
|
||||
|
||||
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Codes, req.code_requests.len()));
|
||||
let max_cost = peer.deduct_max(&self.flow_params, request::Kind::Codes, req.code_requests.len())?;
|
||||
|
||||
let response = self.provider.contract_codes(req);
|
||||
let response_len = response.iter().filter(|x| !x.is_empty()).count();
|
||||
@@ -1012,9 +1021,11 @@ impl LightProtocol {
|
||||
|
||||
// Receive a response for contract code.
|
||||
fn contract_code(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||
let req_id = try!(self.pre_verify_response(peer, request::Kind::Codes, &raw));
|
||||
let req_id = self.pre_verify_response(peer, request::Kind::Codes, &raw)?;
|
||||
|
||||
let raw_code: Vec<Bytes> = try!(try!(raw.at(2)).iter().map(|x| x.as_val()).collect());
|
||||
let raw_code: Vec<Bytes> = raw.at(2)?.iter()
|
||||
.map(|x| x.as_val())
|
||||
.collect::<Result<_,_>>()?;
|
||||
|
||||
for handler in &self.handlers {
|
||||
handler.on_code(&Ctx {
|
||||
@@ -1041,23 +1052,23 @@ impl LightProtocol {
|
||||
};
|
||||
let mut peer = peer.lock();
|
||||
|
||||
let req_id: u64 = try!(data.val_at(0));
|
||||
let req_id: u64 = data.val_at(0)?;
|
||||
|
||||
let req = {
|
||||
let requests: Result<Vec<_>, Error> = try!(data.at(1)).iter().take(MAX_PROOFS).map(|x| {
|
||||
let requests: Result<Vec<_>, Error> = data.at(1)?.iter().take(MAX_PROOFS).map(|x| {
|
||||
Ok(request::HeaderProof {
|
||||
cht_number: try!(x.val_at(0)),
|
||||
block_number: try!(x.val_at(1)),
|
||||
from_level: try!(x.val_at(2)),
|
||||
cht_number: x.val_at(0)?,
|
||||
block_number: x.val_at(1)?,
|
||||
from_level: x.val_at(2)?,
|
||||
})
|
||||
}).collect();
|
||||
|
||||
request::HeaderProofs {
|
||||
requests: try!(requests),
|
||||
requests: requests?,
|
||||
}
|
||||
};
|
||||
|
||||
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::HeaderProofs, req.requests.len()));
|
||||
let max_cost = peer.deduct_max(&self.flow_params, request::Kind::HeaderProofs, req.requests.len())?;
|
||||
|
||||
let response = self.provider.header_proofs(req);
|
||||
let response_len = response.iter().filter(|x| &x[..] != ::rlp::EMPTY_LIST_RLP).count();
|
||||
@@ -1084,13 +1095,15 @@ impl LightProtocol {
|
||||
fn header_proofs(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||
fn decode_res(raw: UntrustedRlp) -> Result<(Bytes, Vec<Bytes>), ::rlp::DecoderError> {
|
||||
Ok((
|
||||
try!(raw.val_at(0)),
|
||||
try!(raw.at(1)).iter().map(|x| x.as_raw().to_owned()).collect(),
|
||||
raw.val_at(0)?,
|
||||
raw.at(1)?.iter().map(|x| x.as_raw().to_owned()).collect(),
|
||||
))
|
||||
}
|
||||
|
||||
let req_id = try!(self.pre_verify_response(peer, request::Kind::HeaderProofs, &raw));
|
||||
let raw_proofs: Vec<_> = try!(try!(raw.at(2)).iter().map(decode_res).collect());
|
||||
let req_id = self.pre_verify_response(peer, request::Kind::HeaderProofs, &raw)?;
|
||||
let raw_proofs: Vec<_> = raw.at(2)?.iter()
|
||||
.map(decode_res)
|
||||
.collect::<Result<_,_>>()?;
|
||||
|
||||
for handler in &self.handlers {
|
||||
handler.on_header_proofs(&Ctx {
|
||||
@@ -1107,7 +1120,10 @@ impl LightProtocol {
|
||||
fn relay_transactions(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> {
|
||||
const MAX_TRANSACTIONS: usize = 256;
|
||||
|
||||
let txs: Vec<_> = try!(data.iter().take(MAX_TRANSACTIONS).map(|x| x.as_val::<SignedTransaction>()).collect());
|
||||
let txs: Vec<_> = data.iter()
|
||||
.take(MAX_TRANSACTIONS)
|
||||
.map(|x| x.as_val::<SignedTransaction>())
|
||||
.collect::<Result<_,_>>()?;
|
||||
|
||||
debug!(target: "les", "Received {} transactions to relay from peer {}", txs.len(), peer);
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ impl<'a> Parser<'a> {
|
||||
fn expect_raw(&mut self, key: Key) -> Result<UntrustedRlp<'a>, DecoderError> {
|
||||
trace!(target: "les", "Expecting key {}", key.as_str());
|
||||
let pre_pos = self.pos;
|
||||
if let Some((k, val)) = try!(self.get_next()) {
|
||||
if let Some((k, val)) = self.get_next()? {
|
||||
if k == key { return Ok(val) }
|
||||
}
|
||||
|
||||
@@ -111,12 +111,12 @@ impl<'a> Parser<'a> {
|
||||
// get the next key and value RLP.
|
||||
fn get_next(&mut self) -> Result<Option<(Key, UntrustedRlp<'a>)>, DecoderError> {
|
||||
while self.pos < self.rlp.item_count() {
|
||||
let pair = try!(self.rlp.at(self.pos));
|
||||
let k: String = try!(pair.val_at(0));
|
||||
let pair = self.rlp.at(self.pos)?;
|
||||
let k: String = pair.val_at(0)?;
|
||||
|
||||
self.pos += 1;
|
||||
match Key::from_str(&k) {
|
||||
Some(key) => return Ok(Some((key , try!(pair.at(1))))),
|
||||
Some(key) => return Ok(Some((key , pair.at(1)?))),
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
@@ -205,12 +205,12 @@ pub fn parse_handshake(rlp: UntrustedRlp) -> Result<(Status, Capabilities, Optio
|
||||
};
|
||||
|
||||
let status = Status {
|
||||
protocol_version: try!(parser.expect(Key::ProtocolVersion)),
|
||||
network_id: try!(parser.expect(Key::NetworkId)),
|
||||
head_td: try!(parser.expect(Key::HeadTD)),
|
||||
head_hash: try!(parser.expect(Key::HeadHash)),
|
||||
head_num: try!(parser.expect(Key::HeadNum)),
|
||||
genesis_hash: try!(parser.expect(Key::GenesisHash)),
|
||||
protocol_version: parser.expect(Key::ProtocolVersion)?,
|
||||
network_id: parser.expect(Key::NetworkId)?,
|
||||
head_td: parser.expect(Key::HeadTD)?,
|
||||
head_hash: parser.expect(Key::HeadHash)?,
|
||||
head_num: parser.expect(Key::HeadNum)?,
|
||||
genesis_hash: parser.expect(Key::GenesisHash)?,
|
||||
last_head: None,
|
||||
};
|
||||
|
||||
@@ -298,10 +298,10 @@ pub fn parse_announcement(rlp: UntrustedRlp) -> Result<Announcement, DecoderErro
|
||||
let mut last_key = None;
|
||||
|
||||
let mut announcement = Announcement {
|
||||
head_hash: try!(rlp.val_at(0)),
|
||||
head_num: try!(rlp.val_at(1)),
|
||||
head_td: try!(rlp.val_at(2)),
|
||||
reorg_depth: try!(rlp.val_at(3)),
|
||||
head_hash: rlp.val_at(0)?,
|
||||
head_num: rlp.val_at(1)?,
|
||||
head_td: rlp.val_at(2)?,
|
||||
reorg_depth: rlp.val_at(3)?,
|
||||
serve_headers: false,
|
||||
serve_state_since: None,
|
||||
serve_chain_since: None,
|
||||
@@ -313,14 +313,14 @@ pub fn parse_announcement(rlp: UntrustedRlp) -> Result<Announcement, DecoderErro
|
||||
rlp: rlp,
|
||||
};
|
||||
|
||||
while let Some((key, item)) = try!(parser.get_next()) {
|
||||
while let Some((key, item)) = parser.get_next()? {
|
||||
if Some(key) <= last_key { return Err(DecoderError::Custom("Invalid announcement key ordering")) }
|
||||
last_key = Some(key);
|
||||
|
||||
match key {
|
||||
Key::ServeHeaders => announcement.serve_headers = true,
|
||||
Key::ServeStateSince => announcement.serve_state_since = Some(try!(item.as_val())),
|
||||
Key::ServeChainSince => announcement.serve_chain_since = Some(try!(item.as_val())),
|
||||
Key::ServeStateSince => announcement.serve_state_since = Some(item.as_val()?),
|
||||
Key::ServeChainSince => announcement.serve_chain_since = Some(item.as_val()?),
|
||||
Key::TxRelay => announcement.tx_relay = true,
|
||||
_ => return Err(DecoderError::Custom("Nonsensical key in announcement")),
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ use ethcore::blockchain_info::BlockChainInfo;
|
||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::transaction::PendingTransaction;
|
||||
use ethcore::encoded;
|
||||
use network::{PeerId, NodeId};
|
||||
|
||||
use net::buffer_flow::FlowParams;
|
||||
@@ -94,11 +95,11 @@ impl Provider for TestProvider {
|
||||
None
|
||||
}
|
||||
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
|
||||
self.0.client.block_header(id)
|
||||
}
|
||||
|
||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||
fn block_body(&self, id: BlockId) -> Option<encoded::Body> {
|
||||
self.0.client.block_body(id)
|
||||
}
|
||||
|
||||
@@ -122,7 +123,7 @@ impl Provider for TestProvider {
|
||||
req.account_key.iter().chain(req.account_key.iter()).cloned().collect()
|
||||
}
|
||||
|
||||
fn header_proof(&self, _req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)> {
|
||||
fn header_proof(&self, _req: request::HeaderProof) -> Option<(encoded::Header, Vec<Bytes>)> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -273,7 +274,7 @@ fn get_block_headers() {
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(10);
|
||||
for header in headers {
|
||||
response_stream.append_raw(&header, 1);
|
||||
response_stream.append_raw(&header.into_inner(), 1);
|
||||
}
|
||||
|
||||
response_stream.out()
|
||||
@@ -320,7 +321,7 @@ fn get_block_bodies() {
|
||||
|
||||
response_stream.append(&req_id).append(&new_buf).begin_list(10);
|
||||
for body in bodies {
|
||||
response_stream.append_raw(&body, 1);
|
||||
response_stream.append_raw(&body.into_inner(), 1);
|
||||
}
|
||||
|
||||
response_stream.out()
|
||||
|
||||
@@ -21,6 +21,7 @@ use ethcore::blockchain_info::BlockChainInfo;
|
||||
use ethcore::client::{BlockChainClient, ProvingBlockChainClient};
|
||||
use ethcore::transaction::PendingTransaction;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::encoded;
|
||||
|
||||
use util::{Bytes, H256};
|
||||
|
||||
@@ -52,9 +53,8 @@ pub trait Provider: Send + Sync {
|
||||
///
|
||||
/// The returned vector may have any length in the range [0, `max`], but the
|
||||
/// results within must adhere to the `skip` and `reverse` parameters.
|
||||
fn block_headers(&self, req: request::Headers) -> Vec<Bytes> {
|
||||
fn block_headers(&self, req: request::Headers) -> Vec<encoded::Header> {
|
||||
use request::HashOrNumber;
|
||||
use ethcore::views::HeaderView;
|
||||
|
||||
if req.max == 0 { return Vec::new() }
|
||||
|
||||
@@ -67,9 +67,9 @@ pub trait Provider: Send + Sync {
|
||||
return Vec::new();
|
||||
}
|
||||
Some(header) => {
|
||||
let num = HeaderView::new(&header).number();
|
||||
let num = header.number();
|
||||
let canon_hash = self.block_header(BlockId::Number(num))
|
||||
.map(|h| HeaderView::new(&h).hash());
|
||||
.map(|h| h.hash());
|
||||
|
||||
if req.max == 1 || canon_hash != Some(hash) {
|
||||
// Non-canonical header or single header requested.
|
||||
@@ -92,19 +92,18 @@ pub trait Provider: Send + Sync {
|
||||
}
|
||||
|
||||
/// Get a block header by id.
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes>;
|
||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
||||
|
||||
/// Provide as many as possible of the requested blocks (minus the headers) encoded
|
||||
/// in RLP format.
|
||||
fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> {
|
||||
fn block_bodies(&self, req: request::Bodies) -> Vec<Option<encoded::Body>> {
|
||||
req.block_hashes.into_iter()
|
||||
.map(|hash| self.block_body(BlockId::Hash(hash)))
|
||||
.map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get a block body by id.
|
||||
fn block_body(&self, id: BlockId) -> Option<Bytes>;
|
||||
fn block_body(&self, id: BlockId) -> Option<encoded::Body>;
|
||||
|
||||
/// Provide the receipts as many as possible of the requested blocks.
|
||||
/// Returns a vector of RLP-encoded lists of receipts.
|
||||
@@ -169,7 +168,7 @@ pub trait Provider: Send + Sync {
|
||||
None => rlp::EMPTY_LIST_RLP.to_vec(),
|
||||
Some((header, proof)) => {
|
||||
let mut stream = RlpStream::new_list(2);
|
||||
stream.append_raw(&header, 1).begin_list(proof.len());
|
||||
stream.append_raw(&header.into_inner(), 1).begin_list(proof.len());
|
||||
|
||||
for node in proof {
|
||||
stream.append_raw(&node, 1);
|
||||
@@ -184,7 +183,7 @@ pub trait Provider: Send + Sync {
|
||||
/// Provide a header proof from a given Canonical Hash Trie as well as the
|
||||
/// corresponding header. The first element is the block header and the
|
||||
/// second is a merkle proof of the CHT.
|
||||
fn header_proof(&self, req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)>;
|
||||
fn header_proof(&self, req: request::HeaderProof) -> Option<(encoded::Header, Vec<Bytes>)>;
|
||||
|
||||
/// Provide pending transactions.
|
||||
fn ready_transactions(&self) -> Vec<PendingTransaction>;
|
||||
@@ -204,11 +203,11 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
|
||||
Some(self.pruning_info().earliest_state)
|
||||
}
|
||||
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
|
||||
BlockChainClient::block_header(self, id)
|
||||
}
|
||||
|
||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||
fn block_body(&self, id: BlockId) -> Option<encoded::Body> {
|
||||
BlockChainClient::block_body(self, id)
|
||||
}
|
||||
|
||||
@@ -227,7 +226,7 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
|
||||
self.code_by_hash(req.account_key, BlockId::Hash(req.block_hash))
|
||||
}
|
||||
|
||||
fn header_proof(&self, _req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)> {
|
||||
fn header_proof(&self, _req: request::HeaderProof) -> Option<(encoded::Header, Vec<Bytes>)> {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user