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

Commit 78a38e9

Browse files
authored
ethcore sync decodes rlp less often (#9264)
* deserialize block only once during verification * ethcore-sync uses Unverified * ethcore-sync uses Unverified * fixed build error * removed Block::is_good * applied review suggestions * ethcore-sync deserializes headers and blocks only once
1 parent 712101b commit 78a38e9

File tree

3 files changed

+193
-115
lines changed

3 files changed

+193
-115
lines changed

ethcore/src/verification/queue/kind.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub mod blocks {
113113
}
114114

115115
/// An unverified block.
116+
#[derive(PartialEq, Debug)]
116117
pub struct Unverified {
117118
/// Unverified block header.
118119
pub header: Header,

ethcore/sync/src/block_sync.rs

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ use std::cmp;
2323
use heapsize::HeapSizeOf;
2424
use ethereum_types::H256;
2525
use rlp::{self, Rlp};
26-
use ethcore::header::{BlockNumber, Header as BlockHeader};
26+
use ethcore::header::BlockNumber;
2727
use ethcore::client::{BlockStatus, BlockId, BlockImportError, BlockImportErrorKind};
2828
use ethcore::error::{ImportErrorKind, BlockError};
29-
use ethcore::verification::queue::kind::blocks::Unverified;
3029
use sync_io::SyncIo;
31-
use blocks::BlockCollection;
30+
use blocks::{BlockCollection, SyncBody, SyncHeader};
3231

3332
const MAX_HEADERS_TO_REQUEST: usize = 128;
3433
const MAX_BODIES_TO_REQUEST: usize = 32;
@@ -236,45 +235,39 @@ impl BlockDownloader {
236235
let mut valid_response = item_count == 0; //empty response is valid
237236
let mut any_known = false;
238237
for i in 0..item_count {
239-
let info: BlockHeader = r.val_at(i).map_err(|e| {
240-
trace!(target: "sync", "Error decoding block header RLP: {:?}", e);
241-
BlockDownloaderImportError::Invalid
242-
})?;
243-
let number = BlockNumber::from(info.number());
238+
let info = SyncHeader::from_rlp(r.at(i)?.as_raw().to_vec())?;
239+
let number = BlockNumber::from(info.header.number());
240+
let hash = info.header.hash();
244241
// Check if any of the headers matches the hash we requested
245242
if !valid_response {
246243
if let Some(expected) = expected_hash {
247-
valid_response = expected == info.hash()
244+
valid_response = expected == hash;
248245
}
249246
}
250-
any_known = any_known || self.blocks.contains_head(&info.hash());
251-
if self.blocks.contains(&info.hash()) {
252-
trace!(target: "sync", "Skipping existing block header {} ({:?})", number, info.hash());
247+
any_known = any_known || self.blocks.contains_head(&hash);
248+
if self.blocks.contains(&hash) {
249+
trace!(target: "sync", "Skipping existing block header {} ({:?})", number, hash);
253250
continue;
254251
}
255252

256253
if self.highest_block.as_ref().map_or(true, |n| number > *n) {
257254
self.highest_block = Some(number);
258255
}
259-
let hash = info.hash();
260-
let hdr = r.at(i).map_err(|e| {
261-
trace!(target: "sync", "Error decoding block header RLP: {:?}", e);
262-
BlockDownloaderImportError::Invalid
263-
})?;
256+
264257
match io.chain().block_status(BlockId::Hash(hash.clone())) {
265258
BlockStatus::InChain | BlockStatus::Queued => {
266259
match self.state {
267260
State::Blocks => trace!(target: "sync", "Header already in chain {} ({})", number, hash),
268261
_ => trace!(target: "sync", "Header already in chain {} ({}), state = {:?}", number, hash, self.state),
269262
}
270-
headers.push(hdr.as_raw().to_vec());
263+
headers.push(info);
271264
hashes.push(hash);
272265
},
273266
BlockStatus::Bad => {
274267
return Err(BlockDownloaderImportError::Invalid);
275268
},
276269
BlockStatus::Unknown | BlockStatus::Pending => {
277-
headers.push(hdr.as_raw().to_vec());
270+
headers.push(info);
278271
hashes.push(hash);
279272
}
280273
}
@@ -325,19 +318,15 @@ impl BlockDownloader {
325318
let item_count = r.item_count().unwrap_or(0);
326319
if item_count == 0 {
327320
return Err(BlockDownloaderImportError::Useless);
328-
}
329-
else if self.state != State::Blocks {
321+
} else if self.state != State::Blocks {
330322
trace!(target: "sync", "Ignored unexpected block bodies");
331-
}
332-
else {
323+
} else {
333324
let mut bodies = Vec::with_capacity(item_count);
334325
for i in 0..item_count {
335-
let body = r.at(i).map_err(|e| {
336-
trace!(target: "sync", "Error decoding block boides RLP: {:?}", e);
337-
BlockDownloaderImportError::Invalid
338-
})?;
339-
bodies.push(body.as_raw().to_vec());
326+
let body = SyncBody::from_rlp(r.at(i)?.as_raw())?;
327+
bodies.push(body);
340328
}
329+
341330
if self.blocks.insert_bodies(bodies) != item_count {
342331
trace!(target: "sync", "Deactivating peer for giving invalid block bodies");
343332
return Err(BlockDownloaderImportError::Invalid);
@@ -483,15 +472,6 @@ impl BlockDownloader {
483472
let block = block_and_receipts.block;
484473
let receipts = block_and_receipts.receipts;
485474

486-
let block = match Unverified::from_rlp(block) {
487-
Ok(block) => block,
488-
Err(_) => {
489-
debug!(target: "sync", "Bad block rlp");
490-
bad = true;
491-
break;
492-
}
493-
};
494-
495475
let h = block.header.hash();
496476
let number = block.header.number();
497477
let parent = *block.header.parent_hash();

0 commit comments

Comments
 (0)