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

Blockchain: More Modern and Flexible Consensus Layout / Tree Shaking Optimization #3504

Conversation

holgerd77
Copy link
Member

This PR moves to a more flexible consensus layout for blockchain allowing for an optional consensusDict to be passed in where all consensus objects which should be used for consensus validation must be present.

This basic setup allows for full tree shaking regarding Clique and Etash code and it will - step 2 - also allow to remove the Ethash dependency.

Since we are now in a Proof-of-Stake world where consensus validation is the exception the PR also moves to having consensus validation deactivated by default. Semantics of the consensusValidation flag is "merged" with the consensusDict object ("consensus" and "consensus validation" is basically the same), this allows for a substantial simplification on otherwise useless "combinations" (this and that object passed, but consensusValidation set to false) and also have a lot cleaner deactivated-by-default structure.

Deactivated-by-default also allows for removing a lot of consensusValidation: false passing, which we lately did more and more on tests since we just didn't want to have/do any more.

Consensus transitions - if wished - still fully work, as a side note (even more flexible than before).

WIP, several tests failing. But on the way.

…allowing to pass in different consensus objects
…block header) difficulty equals 0 check from CasperConsensus
…us* and *consensus validation* is basically the same, allowing for more flexible instantiation and optional consensus object usage
…rained settings to use the mechanism (e.g. Clique) but skip the respective validation
…chain without need for ethash passing in) and consensus availability validation (now in the validate() call)
@holgerd77 holgerd77 force-pushed the blockchain-switch-to-a-more-flexible-and-better-tree-shakeable-consensus-layout branch from e775302 to e5c0c0c Compare July 16, 2024 10:15
Copy link

codecov bot commented Jul 16, 2024

Codecov Report

Attention: Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.

Project coverage is 24.24%. Comparing base (ef20930) to head (46df069).
Report is 6 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (ef20930) and HEAD (46df069). Click for more details.

HEAD has 5 uploads less than BASE
Flag BASE (ef20930) HEAD (46df069)
util 1 0
devp2p 1 0
common 1 0
statemanager 1 0
trie 1 0
Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 73.21% <ø> (?)
client 0.00% <0.00%> (?)
common ?
devp2p ?
evm 68.91% <ø> (?)
statemanager ?
trie ?
tx 78.41% <ø> (?)
util ?
vm 58.63% <ø> (?)
wallet 0.00% <ø> (?)

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

@holgerd77
Copy link
Member Author

Ok, I battled a bit more with this than originally anticipated, but I think I've found a good balance now between usage convenience and strictness needs. 🙂 I had some more radical versions in place in between, removing the validateConsensus parameter and the full `CasperConsensus class (literally doing nothing anyhow), but that had too much interference with test runs and existing code execution. So I went back to some more conservative approach, concentrating more on the core task from here (decoupling, tree shaking, dependencies). We can for sure refactor a bit more in the future, if someone has consistent view of where to go and how.

What I did for convenience is set validateConsensus to false by default. We are in a non-validation world anyhow (CL is doing that now) and this makes it more convenient to instantiate a normal mainnet Blockchain (pointing to block 0 for good reasons and there still have an ethash setting in the back).

If you want to fully follow the thought process I went through here it is best to go commit-by-commit and see what I removed (also read commit messages) and then re-introduced later on. 😂

Everything was a bit delicate, so to get to a setting which worked again, just to say.

Just in train of fixing he last remaining tests (if any).

There is one client CLI test which failed on last run, seemed totally unrelated. 🤔

So generally this is ready for review! 🙂

@holgerd77
Copy link
Member Author

Ah, and to say: so this does complete on its goals. So ethash dependency is fully removed from Blockchain (together with its problematic bigint-crypto-utils dependency and tree shaking is done for EthashConsensus and CliqueConsensus.

Before:

grafik

(blockchain size + ethash still present)

After:

grafik

Copy link
Member

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

This looks super clean, some questions though

throw new Error(`${msg} ${header.errorStr()}`)
}
}
public async validateDifficulty(): Promise<void> {}
Copy link
Member

Choose a reason for hiding this comment

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

Where is the difficulty must be 0 check now?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hey there,
thanks a lot for the review, all good points I guess, will address one by one:

So this one originated from a former more radical version, where I fully deleted the CasperConsensus, and as an in-between step deleted this difficulty check. This is not really a consensus check but just a simple format check and is in fact also done in the BlockHeader: https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/block/src/header.ts#L502

I think it is beneficial to remove it here since it otherwise "tricks" us into thinking we would do some kind of consensus validation here for PoS (must be, there is some code! 😋 ), while in reality this is not the case (PoS consensus validation is done on the CL side).

No super strong opinion, but I would tend to keep this removed.

Copy link
Member

Choose a reason for hiding this comment

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

I should have checked upon reviewing because I suspected this check was in our Block Header as well (this would actually be the more logical place!). I agree it should not be in blockchain. This is actually a great change/removal, let's keep it 😄 👍

@@ -390,7 +380,13 @@ export class Blockchain implements BlockchainInterface {
}

if (this._validateConsensus) {
await this.consensus.validateConsensus(block)
if (!(this.common.consensusAlgorithm() in this._consensusDict)) {
Copy link
Member

Choose a reason for hiding this comment

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

For cleani-ness should this not use this.consensus()?

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right, that works as well 🙂, will update!

blockchain.common.consensusAlgorithm = () => 'fibonacci'

try {
await blockchain.checkAndTransitionHardForkByNumber(5n)
Copy link
Member

Choose a reason for hiding this comment

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

This part of the test got deleted, is this correct?

Copy link
Member Author

Choose a reason for hiding this comment

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

Could readd by making the checks more consistent.

{
header: {
number: 16,
difficulty: BigInt(1),
Copy link
Member

Choose a reason for hiding this comment

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

I think this test should still be in, because we test here that we cannot insert PoW blocks (so, blocks with difficulty nonzero)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok.

Needed to think three times (or so 😋) about this.

So this is where this actually interflicts with our removed difficulty check.

So: a PoW block for Londond is created: works. Block is added to Blockchain: now (with removed check) works as well.

I wanted to suggest that we instead do a hardfork check on the Commons (block + blockchain).

This gets hairy quickly though (might still be the better thing to do), since we have this _hardforkByHeadBlockNumber setting in Blockchain and this generally reaches deep into the blockchain update code.

I will capitulate here for now and re-add the difficulty check for now, together with a comment that this is not really a consensus check. That should enable to re-activate the test case.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, works (locally), and I guess for this PR it is ok (maybe: better), since this PR is about something else at the end.

But to admit, this difficulty check is just picking out a very selected case and this problem that it should not be possible to add a non-HF matching block (with eventually different formatting or properties) to a blockchain is a lot broader and should likely be solved on a more generic level.

Copy link
Member

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

LGTM!

@holgerd77 holgerd77 merged commit 03fa912 into master Jul 17, 2024
34 checks passed
@holgerd77 holgerd77 deleted the blockchain-switch-to-a-more-flexible-and-better-tree-shakeable-consensus-layout branch July 17, 2024 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants