mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 17:01:02 +00:00
fix: don't unpin blocks that may show up again (#1368)
* backend(fix): Early unpin for pruned blocks with no active `BlockRef` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * backend/tests: Check unpinning only after max_life time Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * backend/tests: Remove unpinning when droped tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * backend/tests: Ensure new blocks are not unpinned Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * backend: Add only pruned blocks to unpin hashset and add a test Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * backend: Introduce the `UnpinPolicy` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update subxt/src/backend/unstable/follow_stream_unpin.rs * backend: Fix clippy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Only unpin blocks that have been pruned by the backend * Fix comments * Mark initialized and finalized blocks as 'can_be_unpinned' too and tests * fmt * tweak a couple more comments * tidy tests and fix undeterministic check * Fix wrong names in comments * tweak another test to focus it a bit more * clippy * wee rename of args in a couple of test helpers * add some logs and simplify submit_transaction in the same way Alex did * ditch logging again and keep to the experiment pr * cargo fmt * reduce CI timeouts to 30mins * Handle Init and Stop events in submit_transaction too, just in case --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
@@ -458,28 +458,13 @@ impl<T: Config + Send + Sync + 'static> Backend<T> for UnstableBackend<T> {
|
||||
extrinsic: &[u8],
|
||||
) -> Result<StreamOfResults<TransactionStatus<T::Hash>>, Error> {
|
||||
// We care about new and finalized block hashes.
|
||||
enum SeenBlock<Ref> {
|
||||
New(Ref),
|
||||
Finalized(Vec<Ref>),
|
||||
}
|
||||
enum SeenBlockMarker {
|
||||
New,
|
||||
Finalized,
|
||||
}
|
||||
|
||||
// First, subscribe to all new and finalized block refs.
|
||||
// - we subscribe to new refs so that when we see `BestChainBlockIncluded`, we
|
||||
// can try to return a block ref for the best block.
|
||||
// - we subscribe to finalized refs so that when we see `Finalized`, we can
|
||||
// guarantee that when we return here, the finalized block we report has been
|
||||
// reported from chainHead_follow already.
|
||||
let mut seen_blocks_sub = self.follow_handle.subscribe().events().filter_map(|ev| {
|
||||
std::future::ready(match ev {
|
||||
FollowEvent::NewBlock(ev) => Some(SeenBlock::New(ev.block_hash)),
|
||||
FollowEvent::Finalized(ev) => Some(SeenBlock::Finalized(ev.finalized_block_hashes)),
|
||||
_ => None,
|
||||
})
|
||||
});
|
||||
// First, subscribe to new blocks.
|
||||
let mut seen_blocks_sub = self.follow_handle.subscribe().events();
|
||||
|
||||
// Then, submit the transaction.
|
||||
let mut tx_progress = self
|
||||
@@ -506,22 +491,39 @@ impl<T: Config + Send + Sync + 'static> Backend<T> for UnstableBackend<T> {
|
||||
// Make a note of new or finalized blocks that have come in since we started the TX.
|
||||
if let Poll::Ready(Some(seen_block)) = seen_blocks_sub.poll_next_unpin(cx) {
|
||||
match seen_block {
|
||||
SeenBlock::New(block_ref) => {
|
||||
FollowEvent::Initialized(ev) => {
|
||||
// Just in case this stream is really slow to start or something..
|
||||
seen_blocks.insert(
|
||||
ev.finalized_block_hash.hash(),
|
||||
(SeenBlockMarker::Finalized, ev.finalized_block_hash),
|
||||
);
|
||||
}
|
||||
FollowEvent::NewBlock(ev) => {
|
||||
// Optimization: once we have a `finalized_hash`, we only care about finalized
|
||||
// block refs now and can avoid bothering to save new blocks.
|
||||
if finalized_hash.is_none() {
|
||||
seen_blocks
|
||||
.insert(block_ref.hash(), (SeenBlockMarker::New, block_ref));
|
||||
seen_blocks.insert(
|
||||
ev.block_hash.hash(),
|
||||
(SeenBlockMarker::New, ev.block_hash),
|
||||
);
|
||||
}
|
||||
}
|
||||
SeenBlock::Finalized(block_refs) => {
|
||||
for block_ref in block_refs {
|
||||
FollowEvent::Finalized(ev) => {
|
||||
for block_ref in ev.finalized_block_hashes {
|
||||
seen_blocks.insert(
|
||||
block_ref.hash(),
|
||||
(SeenBlockMarker::Finalized, block_ref),
|
||||
);
|
||||
}
|
||||
}
|
||||
FollowEvent::Stop => {
|
||||
// If we get this event, we'll lose all of our existing pinned blocks and have a gap
|
||||
// in which we may lose the finaliuzed block that the TX is in. For now, just error if
|
||||
// this happens, to prevent the case in which we never see a finalized block and wait
|
||||
// forever.
|
||||
return Poll::Ready(Some(Err(Error::Other("chainHead_follow emitted 'stop' event during transaction submission".into()))));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -555,7 +557,6 @@ impl<T: Config + Send + Sync + 'static> Backend<T> for UnstableBackend<T> {
|
||||
Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(e))),
|
||||
Poll::Ready(Some(Ok(ev))) => ev,
|
||||
};
|
||||
|
||||
// When we get one, map it to the correct format (or for finalized ev, wait for the pinned block):
|
||||
let ev = match ev {
|
||||
rpc_methods::TransactionStatus::Finalized { block } => {
|
||||
|
||||
Reference in New Issue
Block a user