Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stages, storage): pruning configuration #3341

Merged
merged 30 commits into from
Jun 29, 2023
Merged

Conversation

shekhirin
Copy link
Collaborator

@shekhirin shekhirin commented Jun 22, 2023

Resolves #3430

PruneMode

There are two modes for pruning, when it's enabled:

  • Full – prune all blocks, used for full node.
  • Distance – prune blocks before the head-N block number. In other words, keep last N blocks.
  • Before – prune blocks before the specified block number. The specified block number is not pruned.

PruneTarget

For convenience, PruneMode can be converted into the PruneTarget which represents either:

  • All variant – prune all blocks, i.e. not save any data. Used for the full node.
  • Block(BlockNumber) variant – prune blocks up to the specified block number, inclusive.

PruneConfig

As per the description in the linked issue: #3430 (comment).

@codecov
Copy link

codecov bot commented Jun 22, 2023

Codecov Report

Merging #3341 (6c7ed6a) into main (0a6b018) will increase coverage by 0.00%.
The diff coverage is 61.36%.

Impacted file tree graph

Impacted Files Coverage Δ
crates/config/src/config.rs 64.40% <0.00%> (-2.85%) ⬇️
crates/primitives/src/lib.rs 100.00% <ø> (ø)
crates/stages/src/stage.rs 85.10% <0.00%> (-11.28%) ⬇️
crates/storage/db/src/tables/codecs/compact.rs 90.62% <ø> (ø)
crates/storage/db/src/tables/models/mod.rs 78.43% <ø> (ø)
crates/primitives/src/prune/mode.rs 95.83% <95.83%> (ø)
crates/primitives/src/prune/checkpoint.rs 100.00% <100.00%> (ø)

... and 18 files with indirect coverage changes

Flag Coverage Δ
integration-tests 16.31% <0.00%> (-0.02%) ⬇️
unit-tests 64.30% <61.36%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
reth binary 23.42% <0.00%> (-0.03%) ⬇️
blockchain tree 81.69% <ø> (+0.32%) ⬆️
pipeline 87.85% <0.00%> (-0.17%) ⬇️
storage (db) 73.99% <ø> (ø)
trie 95.64% <ø> (ø)
txpool 51.37% <ø> (ø)
networking 78.01% <ø> (+0.01%) ⬆️
rpc 58.09% <ø> (-0.01%) ⬇️
consensus/evm 46.81% <ø> (-0.02%) ⬇️
payload builder 6.83% <ø> (ø)
primitives 88.61% <96.42%> (-0.03%) ⬇️

@shekhirin shekhirin force-pushed the alexey/stage-prune branch 2 times, most recently from 8690453 to 503f211 Compare June 23, 2023 13:34
@shekhirin shekhirin changed the title feat(stages, storage): pruning feat(stages, storage): PrunableStage and Pipeline::prune Jun 23, 2023
@shekhirin shekhirin marked this pull request as ready for review June 23, 2023 15:37
Copy link
Member

@rkrasiuk rkrasiuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like a good start! what kind of scope are you planning for this PR? is it in its final form?

crates/config/Cargo.toml Outdated Show resolved Hide resolved
Comment on lines 419 to 422
table!(
/// Stores the highest pruned block number.
( PruneStage ) StageId | BlockNumber
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dream of collapsing SyncStage, SyncStageProgress & PruneStage into a single table

crates/stages/src/pipeline/mod.rs Outdated Show resolved Hide resolved
@rkrasiuk rkrasiuk added C-enhancement New feature or request A-staged-sync Related to staged sync (pipelines and stages) labels Jun 23, 2023
@shekhirin
Copy link
Collaborator Author

seems like a good start! what kind of scope are you planning for this PR? is it in its final form?

This is its final form, plan to implement pruning for stages and trigger pruning in separate PRs

Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
@rkrasiuk
Copy link
Member

what's the plan for pruning outside the pipeline during live sync?

@shekhirin
Copy link
Collaborator Author

what's the plan for pruning outside the pipeline during live sync?

hooking it into the EngineSyncController::poll (or BeaconConsensusEngine::poll, not sure) the same way we're spawning pipeline if the target is set. In case of pruning, we will need to check how many blocks are accumulated since the last pruning, and if it's larger than some threshold, prune. The threshold is needed to not prune after every FCU (see caveat number two in PR description) .

@rkrasiuk
Copy link
Member

will the threshold be present in the pipeline as well? since we don't know how far the target is from the tip

@shekhirin
Copy link
Collaborator Author

will the threshold be present in the pipeline as well? since we don't know how far the target is from the tip

I think it shouldn't be in the pipeline, but rather in the engine. I expect the distance between target block number for pruning and the tip to always be low:

  1. During the live sync, we add blocks one by one, so there's no way we have a large distance
  2. If the engine detects that the block range to fill is large enough to trigger the pipeline (feat: run pipeline only if missing range is large #3059), we should also prune during that pipeline process, which will make the distance low again

@shekhirin shekhirin force-pushed the alexey/stage-prune branch 4 times, most recently from 4fb4ac1 to 6411995 Compare June 27, 2023 16:18
@shekhirin shekhirin marked this pull request as ready for review June 27, 2023 20:21
use reth_codecs::Compact;

#[test]
fn prune_checkpoint_roundtrip() {
Copy link
Collaborator

@joshieDo joshieDo Jun 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary since deriving main_codec automatically adds derive_arbitrary which generates these kind of roundtrip tests for a default of 256 cases. It's mentioned on derive_arbitratry, but not on the main_codec docs, should probably add.

...
running 1 test
test prune::mode::PruneModeTests::proptest ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 283 filtered out; finished in 0.01s
...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, I see:

#[cfg(test)]
mod PruneCheckpointTests {
    use super::Compact;

    #[test]
    fn proptest() {
        let mut config = proptest::prelude::ProptestConfig::with_cases(256i32 as u32);
        {
            let mut config = config.__sugar_to_owned();
            ::proptest::sugar::force_no_fork(&mut config);
            {
                config.source_file = Some(file!( ));
                let mut runner = ::proptest::test_runner::TestRunner::new(config);
                let names = stringify!( field );
                match runner.run(
                    &::proptest::strategy::Strategy::prop_map(
                        ::proptest::arbitrary::any::<super::PruneCheckpoint>(),
                        |values| ::proptest::sugar::NamedArguments(names, values)),
                    |::proptest::sugar::NamedArguments(
                         _, field)|
                        {
                            let _: () = {
                                {
                                    let mut buf = (::alloc::vec::Vec::new());
                                    let len = field.clone().to_compact(&mut buf);
                                    let (decoded, _) = super::PruneCheckpoint::from_compact(&buf, len);
                                    assert!(field == decoded);
                                }
                            };
                            Ok(())
                        })
                {
                    Ok(_) => (),
                    Err(e) => panic!("{}\n{}", e, runner),
                }
            }
        }
    }
}

removed

@joshieDo
Copy link
Collaborator

joshieDo commented Jun 28, 2023

Just giving some context for the change of field order on 506643e

This should have been caught during compilation time (resulting in an error), but a couple weeks ago, this got changed and I missed this PR.

Will follow up with reverting that change, alongside some better docs for main_codec w/ proptest(mentioning the auto round trip test creation) , a way better explanation for the order of fields and a test to catch it in the future

Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serde nits

crates/config/src/config.rs Outdated Show resolved Hide resolved
crates/config/src/config.rs Outdated Show resolved Hide resolved
crates/primitives/src/prune/checkpoint.rs Show resolved Hide resolved
Copy link
Member

@rkrasiuk rkrasiuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@shekhirin shekhirin added this pull request to the merge queue Jun 29, 2023
Merged via the queue into main with commit d3465e2 Jun 29, 2023
@shekhirin shekhirin deleted the alexey/stage-prune branch June 29, 2023 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-staged-sync Related to staged sync (pipelines and stages) C-enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make pruning configurable via reth.toml
6 participants