Skip to content
This repository was archived by the owner on May 23, 2024. It is now read-only.

Commit 607ee0b

Browse files
arkparGuantong
authored andcommitted
Fix block pruning (paritytech#13323)
1 parent 946507b commit 607ee0b

File tree

1 file changed

+65
-19
lines changed

1 file changed

+65
-19
lines changed

client/db/src/lib.rs

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,15 +1709,22 @@ impl<Block: BlockT> Backend<Block> {
17091709
}
17101710

17111711
let new_displaced = self.blockchain.leaves.write().finalize_height(f_num);
1712-
self.prune_blocks(transaction, f_num, &new_displaced)?;
1712+
self.prune_blocks(
1713+
transaction,
1714+
f_num,
1715+
f_hash,
1716+
&new_displaced,
1717+
current_transaction_justifications,
1718+
)?;
17131719

17141720
Ok(())
17151721
}
17161722

17171723
fn prune_blocks(
17181724
&self,
17191725
transaction: &mut Transaction<DbHash>,
1720-
finalized: NumberFor<Block>,
1726+
finalized_number: NumberFor<Block>,
1727+
finalized_hash: Block::Hash,
17211728
displaced: &FinalizationOutcome<Block::Hash, NumberFor<Block>>,
17221729
) -> ClientResult<()> {
17231730
match self.blocks_pruning {
@@ -1729,10 +1736,10 @@ impl<Block: BlockT> Backend<Block> {
17291736
let number = finalized.saturating_sub(keep.into());
17301737
self.prune_block(transaction, BlockId::<Block>::number(number))?;
17311738
}
1732-
self.prune_displaced_branches(transaction, finalized, displaced)?;
1739+
self.prune_displaced_branches(transaction, finalized_hash, displaced)?;
17331740
},
17341741
BlocksPruning::KeepFinalized => {
1735-
self.prune_displaced_branches(transaction, finalized, displaced)?;
1742+
self.prune_displaced_branches(transaction, finalized_hash, displaced)?;
17361743
},
17371744
}
17381745
Ok(())
@@ -1741,26 +1748,21 @@ impl<Block: BlockT> Backend<Block> {
17411748
fn prune_displaced_branches(
17421749
&self,
17431750
transaction: &mut Transaction<DbHash>,
1744-
finalized: NumberFor<Block>,
1751+
finalized: Block::Hash,
17451752
displaced: &FinalizationOutcome<Block::Hash, NumberFor<Block>>,
17461753
) -> ClientResult<()> {
17471754
// Discard all blocks from displaced branches
17481755
for h in displaced.leaves() {
1749-
let mut number = finalized;
1750-
let mut hash = *h;
1751-
// Follow displaced chains back until we reach a finalized block.
1752-
// Since leaves are discarded due to finality, they can't have parents
1753-
// that are canonical, but not yet finalized. So we stop deleting as soon as
1754-
// we reach canonical chain.
1755-
while self.blockchain.hash(number)? != Some(hash) {
1756-
match self.blockchain.header(hash)? {
1757-
Some(header) => {
1758-
self.prune_block(transaction, BlockId::<Block>::hash(hash))?;
1759-
number = header.number().saturating_sub(One::one());
1760-
hash = *header.parent_hash();
1756+
match sp_blockchain::tree_route(&self.blockchain, *h, finalized) {
1757+
Ok(tree_route) =>
1758+
for r in tree_route.retracted() {
1759+
self.blockchain.insert_persisted_body_if_pinned(r.hash)?;
1760+
self.prune_block(transaction, BlockId::<Block>::hash(r.hash))?;
17611761
},
1762-
None => break,
1763-
}
1762+
Err(sp_blockchain::Error::UnknownBlock(_)) => {
1763+
// Sometimes routes can't be calculated. E.g. after warp sync.
1764+
},
1765+
Err(e) => Err(e)?,
17641766
}
17651767
}
17661768
Ok(())
@@ -3407,6 +3409,50 @@ pub(crate) mod tests {
34073409
assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
34083410
}
34093411

3412+
#[test]
3413+
fn prune_blocks_on_finalize_and_reorg() {
3414+
// 0 - 1b
3415+
// \ - 1a - 2a - 3a
3416+
// \ - 2b
3417+
3418+
let backend = Backend::<Block>::new_test_with_tx_storage(BlocksPruning::Some(10), 10);
3419+
3420+
let make_block = |index, parent, val: u64| {
3421+
insert_block(&backend, index, parent, None, H256::random(), vec![val.into()], None)
3422+
.unwrap()
3423+
};
3424+
3425+
let block_0 = make_block(0, Default::default(), 0x00);
3426+
let block_1a = make_block(1, block_0, 0x1a);
3427+
let block_1b = make_block(1, block_0, 0x1b);
3428+
let block_2a = make_block(2, block_1a, 0x2a);
3429+
let block_2b = make_block(2, block_1a, 0x2b);
3430+
let block_3a = make_block(3, block_2a, 0x3a);
3431+
3432+
// Make sure 1b is head
3433+
let mut op = backend.begin_operation().unwrap();
3434+
backend.begin_state_operation(&mut op, block_0).unwrap();
3435+
op.mark_head(block_1b).unwrap();
3436+
backend.commit_operation(op).unwrap();
3437+
3438+
// Finalize 3a
3439+
let mut op = backend.begin_operation().unwrap();
3440+
backend.begin_state_operation(&mut op, block_0).unwrap();
3441+
op.mark_head(block_3a).unwrap();
3442+
op.mark_finalized(block_1a, None).unwrap();
3443+
op.mark_finalized(block_2a, None).unwrap();
3444+
op.mark_finalized(block_3a, None).unwrap();
3445+
backend.commit_operation(op).unwrap();
3446+
3447+
let bc = backend.blockchain();
3448+
assert_eq!(None, bc.body(block_1b).unwrap());
3449+
assert_eq!(None, bc.body(block_2b).unwrap());
3450+
assert_eq!(Some(vec![0x00.into()]), bc.body(block_0).unwrap());
3451+
assert_eq!(Some(vec![0x1a.into()]), bc.body(block_1a).unwrap());
3452+
assert_eq!(Some(vec![0x2a.into()]), bc.body(block_2a).unwrap());
3453+
assert_eq!(Some(vec![0x3a.into()]), bc.body(block_3a).unwrap());
3454+
}
3455+
34103456
#[test]
34113457
fn indexed_data_block_body() {
34123458
let backend = Backend::<Block>::new_test_with_tx_storage(BlocksPruning::Some(1), 10);

0 commit comments

Comments
 (0)