mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 20:57:59 +00:00
Sync: validate block responses for required data (#5052)
* Less verbose state-db logging * Validate block responses for block bodies * Update client/network/src/protocol.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Added validation test * Disconnect on missing header as well * Typo Co-Authored-By: André Silva <andre.beat@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: André Silva <andre.beat@gmail.com>
This commit is contained in:
@@ -237,7 +237,7 @@ impl<D> Peer<D> {
|
||||
where F: FnMut(BlockBuilder<Block, PeersFullClient, substrate_test_runtime_client::Backend>) -> Block
|
||||
{
|
||||
let best_hash = self.client.info().best_hash;
|
||||
self.generate_blocks_at(BlockId::Hash(best_hash), count, origin, edit_block)
|
||||
self.generate_blocks_at(BlockId::Hash(best_hash), count, origin, edit_block, false)
|
||||
}
|
||||
|
||||
/// Add blocks to the peer -- edit the block before adding. The chain will
|
||||
@@ -247,7 +247,8 @@ impl<D> Peer<D> {
|
||||
at: BlockId<Block>,
|
||||
count: usize,
|
||||
origin: BlockOrigin,
|
||||
mut edit_block: F
|
||||
mut edit_block: F,
|
||||
headers_only: bool,
|
||||
) -> H256 where F: FnMut(BlockBuilder<Block, PeersFullClient, substrate_test_runtime_client::Backend>) -> Block {
|
||||
let full_client = self.client.as_full()
|
||||
.expect("blocks could only be generated by full clients");
|
||||
@@ -272,7 +273,7 @@ impl<D> Peer<D> {
|
||||
origin,
|
||||
header.clone(),
|
||||
None,
|
||||
Some(block.extrinsics)
|
||||
if headers_only { None } else { Some(block.extrinsics) },
|
||||
).unwrap();
|
||||
let cache = if let Some(cache) = cache {
|
||||
cache.into_iter().collect()
|
||||
@@ -294,28 +295,46 @@ impl<D> Peer<D> {
|
||||
self.push_blocks_at(BlockId::Hash(best_hash), count, with_tx)
|
||||
}
|
||||
|
||||
/// Push blocks to the peer (simplified: with or without a TX)
|
||||
pub fn push_headers(&mut self, count: usize) -> H256 {
|
||||
let best_hash = self.client.info().best_hash;
|
||||
self.generate_tx_blocks_at(BlockId::Hash(best_hash), count, false, true)
|
||||
}
|
||||
|
||||
/// Push blocks to the peer (simplified: with or without a TX) starting from
|
||||
/// given hash.
|
||||
pub fn push_blocks_at(&mut self, at: BlockId<Block>, count: usize, with_tx: bool) -> H256 {
|
||||
self.generate_tx_blocks_at(at, count, with_tx, false)
|
||||
}
|
||||
|
||||
/// Push blocks/headers to the peer (simplified: with or without a TX) starting from
|
||||
/// given hash.
|
||||
fn generate_tx_blocks_at(&mut self, at: BlockId<Block>, count: usize, with_tx: bool, headers_only:bool) -> H256 {
|
||||
let mut nonce = 0;
|
||||
if with_tx {
|
||||
self.generate_blocks_at(at, count, BlockOrigin::File, |mut builder| {
|
||||
let transfer = Transfer {
|
||||
from: AccountKeyring::Alice.into(),
|
||||
to: AccountKeyring::Alice.into(),
|
||||
amount: 1,
|
||||
nonce,
|
||||
};
|
||||
builder.push(transfer.into_signed_tx()).unwrap();
|
||||
nonce = nonce + 1;
|
||||
builder.build().unwrap().block
|
||||
})
|
||||
self.generate_blocks_at(
|
||||
at,
|
||||
count,
|
||||
BlockOrigin::File, |mut builder| {
|
||||
let transfer = Transfer {
|
||||
from: AccountKeyring::Alice.into(),
|
||||
to: AccountKeyring::Alice.into(),
|
||||
amount: 1,
|
||||
nonce,
|
||||
};
|
||||
builder.push(transfer.into_signed_tx()).unwrap();
|
||||
nonce = nonce + 1;
|
||||
builder.build().unwrap().block
|
||||
},
|
||||
headers_only
|
||||
)
|
||||
} else {
|
||||
self.generate_blocks_at(
|
||||
at,
|
||||
count,
|
||||
BlockOrigin::File,
|
||||
|builder| builder.build().unwrap().block,
|
||||
headers_only,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -748,6 +767,23 @@ pub trait TestNetFactory: Sized {
|
||||
Async::Ready(())
|
||||
}
|
||||
|
||||
/// Polls the testnet until theres' no activiy of any kind.
|
||||
///
|
||||
/// Must be executed in a task context.
|
||||
fn poll_until_idle(&mut self) -> Async<()> {
|
||||
self.poll();
|
||||
|
||||
for peer in self.peers().iter() {
|
||||
if peer.is_major_syncing() || peer.network.num_queued_blocks() != 0 {
|
||||
return Async::NotReady
|
||||
}
|
||||
if peer.network.num_sync_requests() != 0 {
|
||||
return Async::NotReady
|
||||
}
|
||||
}
|
||||
Async::Ready(())
|
||||
}
|
||||
|
||||
/// Blocks the current thread until we are sync'ed.
|
||||
///
|
||||
/// Calls `poll_until_sync` repeatedly with the runtime passed as parameter.
|
||||
@@ -755,6 +791,13 @@ pub trait TestNetFactory: Sized {
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| Ok(self.poll_until_sync()))).unwrap();
|
||||
}
|
||||
|
||||
/// Blocks the current thread until there are no pending packets.
|
||||
///
|
||||
/// Calls `poll_until_idle` repeatedly with the runtime passed as parameter.
|
||||
fn block_until_idle(&mut self, runtime: &mut tokio::runtime::current_thread::Runtime) {
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| Ok(self.poll_until_idle()))).unwrap();
|
||||
}
|
||||
|
||||
/// Polls the testnet. Processes all the pending actions and returns `NotReady`.
|
||||
fn poll(&mut self) {
|
||||
self.mut_peers(|peers| {
|
||||
|
||||
Reference in New Issue
Block a user