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

Commit 2fc1679

Browse files
jimposorpaas
authored andcommitted
Verify block syncing responses against requests (#9670)
* sync: Validate received BlockHeaders packets against stored request. * sync: Validate received BlockBodies and BlockReceipts. * sync: Fix broken tests. * sync: Unit tests for BlockDownloader::import_headers. * sync: Unit tests for import_{bodies,receipts}. * tests: Add missing method doc.
1 parent 7ba5652 commit 2fc1679

File tree

5 files changed

+473
-136
lines changed

5 files changed

+473
-136
lines changed

ethcore/src/client/test_client.rs

Lines changed: 60 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub struct TestBlockChainClient {
118118
}
119119

120120
/// Used for generating test client blocks.
121-
#[derive(Clone)]
121+
#[derive(Clone, Copy)]
122122
pub enum EachBlockWith {
123123
/// Plain block.
124124
Nothing,
@@ -242,69 +242,68 @@ impl TestBlockChainClient {
242242
*self.error_on_logs.write() = val;
243243
}
244244

245-
/// Add blocks to test client.
246-
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
247-
let len = self.numbers.read().len();
248-
for n in len..(len + count) {
249-
let mut header = BlockHeader::new();
250-
header.set_difficulty(From::from(n));
251-
header.set_parent_hash(self.last_hash.read().clone());
252-
header.set_number(n as BlockNumber);
253-
header.set_gas_limit(U256::from(1_000_000));
254-
header.set_extra_data(self.extra_data.clone());
255-
let uncles = match with {
256-
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
257-
let mut uncles = RlpStream::new_list(1);
258-
let mut uncle_header = BlockHeader::new();
259-
uncle_header.set_difficulty(From::from(n));
260-
uncle_header.set_parent_hash(self.last_hash.read().clone());
261-
uncle_header.set_number(n as BlockNumber);
262-
uncles.append(&uncle_header);
263-
header.set_uncles_hash(keccak(uncles.as_raw()));
264-
uncles
265-
},
266-
_ => RlpStream::new_list(0)
267-
};
268-
let txs = match with {
269-
EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => {
270-
let mut txs = RlpStream::new_list(1);
271-
let keypair = Random.generate().unwrap();
272-
// Update nonces value
273-
self.nonces.write().insert(keypair.address(), U256::one());
274-
let tx = Transaction {
275-
action: Action::Create,
276-
value: U256::from(100),
277-
data: "3331600055".from_hex().unwrap(),
278-
gas: U256::from(100_000),
279-
gas_price: U256::from(200_000_000_000u64),
280-
nonce: U256::zero()
281-
};
282-
let signed_tx = tx.sign(keypair.secret(), None);
283-
txs.append(&signed_tx);
284-
txs.out()
285-
},
286-
_ => ::rlp::EMPTY_LIST_RLP.to_vec()
287-
};
288-
289-
let mut rlp = RlpStream::new_list(3);
290-
rlp.append(&header);
291-
rlp.append_raw(&txs, 1);
292-
rlp.append_raw(uncles.as_raw(), 1);
293-
let unverified = Unverified::from_rlp(rlp.out()).unwrap();
294-
self.import_block(unverified).unwrap();
295-
}
296-
}
245+
/// Add a block to test client.
246+
pub fn add_block<F>(&self, with: EachBlockWith, hook: F)
247+
where F: Fn(BlockHeader) -> BlockHeader
248+
{
249+
let n = self.numbers.read().len();
250+
251+
let mut header = BlockHeader::new();
252+
header.set_difficulty(From::from(n));
253+
header.set_parent_hash(self.last_hash.read().clone());
254+
header.set_number(n as BlockNumber);
255+
header.set_gas_limit(U256::from(1_000_000));
256+
header.set_extra_data(self.extra_data.clone());
257+
258+
header = hook(header);
259+
260+
let uncles = match with {
261+
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
262+
let mut uncles = RlpStream::new_list(1);
263+
let mut uncle_header = BlockHeader::new();
264+
uncle_header.set_difficulty(From::from(n));
265+
uncle_header.set_parent_hash(self.last_hash.read().clone());
266+
uncle_header.set_number(n as BlockNumber);
267+
uncles.append(&uncle_header);
268+
header.set_uncles_hash(keccak(uncles.as_raw()));
269+
uncles
270+
},
271+
_ => RlpStream::new_list(0)
272+
};
273+
let txs = match with {
274+
EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => {
275+
let mut txs = RlpStream::new_list(1);
276+
let keypair = Random.generate().unwrap();
277+
// Update nonces value
278+
self.nonces.write().insert(keypair.address(), U256::one());
279+
let tx = Transaction {
280+
action: Action::Create,
281+
value: U256::from(100),
282+
data: "3331600055".from_hex().unwrap(),
283+
gas: U256::from(100_000),
284+
gas_price: U256::from(200_000_000_000u64),
285+
nonce: U256::zero()
286+
};
287+
let signed_tx = tx.sign(keypair.secret(), None);
288+
txs.append(&signed_tx);
289+
txs.out()
290+
},
291+
_ => ::rlp::EMPTY_LIST_RLP.to_vec()
292+
};
297293

298-
/// Make a bad block by setting invalid extra data.
299-
pub fn corrupt_block(&self, n: BlockNumber) {
300-
let hash = self.block_hash(BlockId::Number(n)).unwrap();
301-
let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode().expect("decoding failed");
302-
header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec());
303294
let mut rlp = RlpStream::new_list(3);
304295
rlp.append(&header);
305-
rlp.append_raw(&::rlp::NULL_RLP, 1);
306-
rlp.append_raw(&::rlp::NULL_RLP, 1);
307-
self.blocks.write().insert(hash, rlp.out());
296+
rlp.append_raw(&txs, 1);
297+
rlp.append_raw(uncles.as_raw(), 1);
298+
let unverified = Unverified::from_rlp(rlp.out()).unwrap();
299+
self.import_block(unverified).unwrap();
300+
}
301+
302+
/// Add a sequence of blocks to test client.
303+
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
304+
for _ in 0..count {
305+
self.add_block(with, |header| header);
306+
}
308307
}
309308

310309
/// Make a bad block by setting invalid parent hash.

0 commit comments

Comments
 (0)