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

Add chain data pruning experimental feature #4686

Merged
merged 40 commits into from
Dec 12, 2022

Conversation

wcgcyx
Copy link
Contributor

@wcgcyx wcgcyx commented Nov 16, 2022

PR description

This PR introduces a new feature that allows besu to prune old chain data. Three experimental CLI options are introduced as well: --Xchain-pruning-enabled to turn on/off pruning, --Xchain-pruning-blocks-retained to specify the number of recent blocks to retain and --Xchain-pruning-frequency to specify how often to perform chain data pruning.

Fixed Issue(s)

Linked to #4476

Documentation

  • I thought about documentation and added the doc-change-required label to this PR if
    updates are required.

Changelog

@wcgcyx wcgcyx force-pushed the 4476-chain-data-pruning branch from 04f5c3b to fff4909 Compare November 16, 2022 08:38
@wcgcyx wcgcyx force-pushed the 4476-chain-data-pruning branch from 1fd4fa6 to 0d433a3 Compare November 18, 2022 05:00
@wcgcyx wcgcyx marked this pull request as ready for review November 21, 2022 08:47
CHANGELOG.md Outdated Show resolved Hide resolved
@wcgcyx wcgcyx requested a review from usmansaleem November 22, 2022 03:54
@@ -116,7 +117,8 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
}

// TODO: post-merge cleanup, this should be unnecessary after merge
if (!mergeCoordinator.latestValidAncestorDescendsFromTerminal(newHead.get())) {
if (!mergeCoordinator.latestValidAncestorDescendsFromTerminal(newHead.get())
&& !ChainDataPruner.isPruningEnabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nicer to drive this based on the chain data pruning enabled flag rather than setting and using a static global field

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, I tried that a bit but it seems like that would involve bringing besu command into the protocol context. I consider it to be a temporary solution until #4703 is merged. Then, we could just do a cleanup to get rid of this global field completely.

Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't need to bring the entire Besu command into the protocol context. At most, the chain pruning config values would need to be passed through. A compromise could be to make the ChainPruner a singleton instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, It seems cleaner to add a flag in merge context instead, following what @gfukushima did in #4735

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated to have a temporary flag in protocol context instead. Global variable gets removed.

Comment on lines 2196 to 2200
.isChainDataPruningEnabled(unstableChainDataPruningOptions.getChainDataPruningEnabled())
.chainDataPruningBlocksRetained(
unstableChainDataPruningOptions.getChainDataPruningBlocksRetained())
.chainDataPruningFrequency(
unstableChainDataPruningOptions.getChainDataPruningBlocksFrequency());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can domain object be created instead so that 3 values don't need to passed through

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated

this.blocksToRetain = blocksToRetain;
this.pruningFrequency = pruningFrequency;
this.pruningExecutor =
new ThreadPoolExecutor(
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this instead use the MonitoredExecutors.newFixedThreadPool so we have monitoring

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use monitored executors.

this.blocksToRetain = blocksToRetain;
this.pruningFrequency = pruningFrequency;
this.pruningExecutor =
new ThreadPoolExecutor(
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather the executor was passed in so that this isn't created in the constructor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated

if (blockNumber < pruningMark) {
// Ignore and warn if block number < pruning mark, this normally indicates the
// blocksToRetain
// is too small.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: comment could be moved to previous line // is too small.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated, I've removed unnecessary comments. This comment goes into the logging to show the user that the blocks to retain are too small (probably misconfiguration).


// TODO: cleanup - isChainPruningEnabled will not be required after
// https://github.com/hyperledger/besu/pull/4703 is merged.
public void setIsChainPruningEnabled(final boolean isChainPruningEnabled) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't think this is a good place for the chain pruning enabled flag, it is very high level. Maybe part of the Merge context would be ok, as we only need this check for the Merge RPCs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated. Ended up placing a flag in merge context since it involves very little change.

@wcgcyx wcgcyx requested review from siladu and jframe December 8, 2022 01:38
+ " which normally indicates the blocksToRetain is too small");
return;
}
final KeyValueStorageTransaction tx1 = prunerStorage.startTransaction();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: do we need tx1 and tx2, any reason the same variable can't be reused?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we do need two, then I think a more descriptive name would help readability

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to use one variable actually but tx must be final in the lambda expression so couldn't be reused. Is there a way to get around that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Gotcha, you could probably work around it with a class instead of lambda but it's not worth it for this. Renaming would be an improvement IMO but I wouldn't block the PR on it :)

Signed-off-by: wcgcyx <[email protected]>
@wcgcyx wcgcyx force-pushed the 4476-chain-data-pruning branch from 88d6743 to 2a439f1 Compare December 9, 2022 02:44
Copy link
Contributor

@siladu siladu left a comment

Choose a reason for hiding this comment

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

Approved! Just the tx1, tx2 renaming suggestion but not a blocker for me

CHANGELOG.md Outdated
@@ -10,6 +10,7 @@
- Increase the speed of modexp gas execution and execution. [#4780](https://github.com/hyperledger/besu/pull/4780)
- Added experimental CLI options `--Xeth-capability-max` and `--Xeth-capability-min` to specify a range of capabilities to be supported by the Eth protocol. [#4752](https://github.com/hyperledger/besu/pull/4752)
- Set the default curve in the EVMTool, like is done in production operations [#4790](https://github.com/hyperledger/besu/pull/4790)
- Add chain data pruning feature with three experimental CLI options: `--Xchain-data-pruning-enabled`, `--Xchain-data-pruning-blocks-retained` and `--Xchain-data-pruning-frequency` [#4686](https://github.com/hyperledger/besu/pull/4686)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: remove data from description based previous naming conversation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated


import picocli.CommandLine;

public class ChainDataPruningOptions implements CLIOptions<ChainPrunerConfiguration> {
Copy link
Contributor

Choose a reason for hiding this comment

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

rename to ChainPruningOPtions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

@@ -315,6 +326,30 @@ public BesuController build() {
blockchain, worldStateArchive, protocolSchedule, this::createConsensusContext);
validateContext(protocolContext);

if (chainPrunerConfiguration.getChainPruningEnabled()) {
protocolContext.getConsensusContext(MergeContext.class).setIsChainPruningEnabled(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

If we are not post-merge e.g. using QBFT then the merge context will not be available. You can use the ProtocolContext.safeConsensusContext to handle this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

@@ -56,6 +56,7 @@ dependencies {
implementation 'org.apache.tuweni:tuweni-rlp'
implementation 'org.hyperledger.besu:bls12-381'
implementation 'org.immutables:value-annotations'
implementation 'org.awaitility:awaitility'
Copy link
Contributor

Choose a reason for hiding this comment

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

This should only for testImplementation not implementation it's only needed for tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, that's true, updated.

final KeyValueStorageTransaction pruningTransaction = prunerStorage.startTransaction();
long currentPruningMark = storedPruningMark;
final long newPruningMark = blockNumber - blocksToRetain;
if (event.isNewCanonicalHead()
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this check for pruning frequency could be done before submitting it to the executor so that less work is done in case nothing needs to happen.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need to think about this one.

this.chainPruningBlocksRetained = chainPruningBlocksRetained;
this.chainPruningBlocksFrequency = chainPruningBlocksFrequency;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: chainPruning prefix could removed from the getters and fields are this is all on the ChainPrunerConfiguration class

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

Signed-off-by: wcgcyx <[email protected]>
@macfarla macfarla merged commit 97588ae into hyperledger:main Dec 12, 2022
matkt pushed a commit to matkt/besu that referenced this pull request Dec 17, 2022
* Add chain pruner
* Increase minimum blocks to retain
* Skip ancestor check in pruning mode
* Separate class for pruning storage
* Move pruning to separate thread
* Limit total pruning threads

Signed-off-by: wcgcyx <[email protected]>
Signed-off-by: Zhenyang Shi <[email protected]>
Co-authored-by: Simon Dudley <[email protected]>
Co-authored-by: Jason Frame <[email protected]>
Signed-off-by: Karim TAAM <[email protected]>
ahamlat pushed a commit to ahamlat/besu that referenced this pull request Dec 18, 2022
* Add chain pruner
* Increase minimum blocks to retain
* Skip ancestor check in pruning mode
* Separate class for pruning storage
* Move pruning to separate thread
* Limit total pruning threads

Signed-off-by: wcgcyx <[email protected]>
Signed-off-by: Zhenyang Shi <[email protected]>
Co-authored-by: Simon Dudley <[email protected]>
Co-authored-by: Jason Frame <[email protected]>
Signed-off-by: Ameziane H <[email protected]>
macfarla pushed a commit to macfarla/besu that referenced this pull request Jan 10, 2023
* Add chain pruner
* Increase minimum blocks to retain
* Skip ancestor check in pruning mode
* Separate class for pruning storage
* Move pruning to separate thread
* Limit total pruning threads

Signed-off-by: wcgcyx <[email protected]>
Signed-off-by: Zhenyang Shi <[email protected]>
Co-authored-by: Simon Dudley <[email protected]>
Co-authored-by: Jason Frame <[email protected]>
Signed-off-by: Sally MacFarlane <[email protected]>
eum602 pushed a commit to lacchain/besu that referenced this pull request Nov 3, 2023
* Add chain pruner
* Increase minimum blocks to retain
* Skip ancestor check in pruning mode
* Separate class for pruning storage
* Move pruning to separate thread
* Limit total pruning threads

Signed-off-by: wcgcyx <[email protected]>
Signed-off-by: Zhenyang Shi <[email protected]>
Co-authored-by: Simon Dudley <[email protected]>
Co-authored-by: Jason Frame <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants