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/Ethash/Trie: remove level dependency from blockchain #2669

Merged
merged 33 commits into from May 12, 2023

Conversation

gabrocheleau
Copy link
Contributor

No description provided.

@codecov
Copy link

codecov bot commented Apr 27, 2023

Codecov Report

❗ No coverage uploaded for pull request base (develop-v7@ee0d44c). Click here to learn what that means.
The diff coverage is n/a.

Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 90.30% <0.00%> (?)
blockchain 90.55% <0.00%> (?)
client 86.89% <0.00%> (?)
common 96.06% <0.00%> (?)
devp2p 91.84% <0.00%> (?)
ethash ∅ <0.00%> (?)
evm 79.49% <0.00%> (?)
rlp ∅ <0.00%> (?)
statemanager 80.92% <0.00%> (?)
trie 89.90% <0.00%> (?)
tx 95.50% <0.00%> (?)
util 81.32% <0.00%> (?)
vm 81.36% <0.00%> (?)

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

"debug": "^4.3.3",
"ethereum-cryptography": "^1.1.2",
"level": "^8.0.0",
"lru-cache": "^5.1.1",
"memory-level": "^1.0.0"
Copy link
Member

Choose a reason for hiding this comment

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

memory-level also already ready for removal here? Just asking.

@holgerd77
Copy link
Member

Cool 🤩, had some first look over the changes, I would generally say this already very much goes into a good direction! 👍

Copy link
Member

@holgerd77 holgerd77 left a comment

Choose a reason for hiding this comment

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

Great refactor, totally excited about this! 🎉

Some comments, biggest thing likely this encoding thing (can also continue to discuss in the chat).

packages/blockchain/src/consensus/clique.ts Outdated Show resolved Hide resolved
packages/blockchain/src/consensus/clique.ts Outdated Show resolved Hide resolved
@@ -45,7 +44,7 @@ export class EthashConsensus implements Consensus {
public async genesisInit(): Promise<void> {}
public async setup({ blockchain }: ConsensusOptions): Promise<void> {
this.blockchain = blockchain
this._ethash = new Ethash(this.blockchain.db as unknown as EthashCacheDB)
this._ethash = new Ethash(this.blockchain.db as any)
Copy link
Member

Choose a reason for hiding this comment

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

Not for this PR, but should we really take this occasion and loosen the binding between blockchain and the Ethash class/package? So eventually make this an optional dependency? 🤔

I think this is not an easy side-shot though but needs some additional design thoughts, regarding consensus instantiation (eventually) on mainnet, thinks like that.

But at the end should not be that complicated/invasive and I guess it's maybe/likely the time for that.

}
body.push([])
if (body.length !== 3) body.push([])
Copy link
Member

Choose a reason for hiding this comment

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

Not have the complete picture here, is the case at this point that body length might equal 3 sufficiently covered or alternatively not possible to reach due to previous code?

Copy link
Contributor

Choose a reason for hiding this comment

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

I would need @g11tech to validate but I think this should be sufficient.

open() {
return Promise.resolve()
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Is this 1:1 the same as the Trie version?

Wonder if we want to move this to Util as well? (Code) bloat seems limited to me, not such an extensive implementation.

Would this make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like it. I'll move it and adjust the imports accordingly.

value = await this._leveldb.get(key, {
valueEncoding: encoding,
})
if (value === null) return undefined
Copy link
Member

Choose a reason for hiding this comment

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

Ah, this is too hacky here, we need to find another solution for that. 🙂

(so I am getting this right that this would also be the "default" implementation for other Blockchain LevelDB users, right?)

My tendency would be that we make encoding a mandatory method parameter in the DB interface and then just always pass this explicitly in our implementations and one can then decide in the wrapper implementation s (like LevelDB, so this one here) to use this information or not.

Does this make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

We can though I don't know if we should or not. The nicest sort ofd "default" way would be that the DB just takes what we pass in without doing anything to it and returns that same value when we pass in the same key (more or less how our MapDB does). The reason I have to do all this special handling is that level assumes that all data should be a certain datatype and format when you dump it into the DB. I'm not an expert on key/value DBs but if other key/value DBs require encoding details and if the names that specify those encoding types is identical, I think it's fine. If not, I'd prefer to err on the side of not overspecifying what should be in the wrapper.

Copy link
Member

Choose a reason for hiding this comment

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

The wrapper is a code part which is not in our control. People will just copy over this code part if they want to use Blockchain with LevelDB. So this should have a very stable API and be robust and generic in the inside. We do not want to tell people "oh, and please add if (key === NewKeyWeAddedToBlockchain) in line 34 of your wrapper" when we publish an update of our Blockchain library where we add some new functionality. 🙂

@@ -50,7 +51,7 @@ export class VMExecution extends Execution {

if (this.config.vm === undefined) {
const trie = new Trie({
db: new LevelDB(this.stateDB),
db: new LevelDB(this.stateDB) as DB,
Copy link
Member

Choose a reason for hiding this comment

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

Is this casting necessary here?

Copy link
Contributor

Choose a reason for hiding this comment

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

It is in this instance since the client DB allows more key and value types than does the trie.

Copy link
Member

Choose a reason for hiding this comment

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

Can we optimally align this so that we have one single interface for Trie, Blockchain and eventual other usages?

(this goes a bit together with the special-handling topic for the encoding values)

packages/client/lib/sync/fetcher/accountfetcher.ts Outdated Show resolved Hide resolved
packages/ethash/src/level.ts Outdated Show resolved Hide resolved
open() {
return this._leveldb.open()
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Why is LevelDB necessary for VM? Wouldn't MemoryDB do it?

Copy link
Contributor

Choose a reason for hiding this comment

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

I swapped it out for a MapDB borrowed from blockchain and it seems to work fine so will update here.

Copy link
Member

Choose a reason for hiding this comment

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

👍

What is with the version in api/utils.ts? Can we there also use MapDB?

And can we then delete this level.ts file or is it still necessary?

Copy link
Member

@holgerd77 holgerd77 left a comment

Choose a reason for hiding this comment

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

Ok, looks great, I think I will merge this in here now.

Feel free to do continued refinements though.

@holgerd77 holgerd77 merged commit 355b03b into develop-v7 May 12, 2023
39 checks passed
@holgerd77 holgerd77 deleted the blockchain/level-refactor branch May 12, 2023 09:48
@holgerd77 holgerd77 changed the title blockchain: remove level dependency from blockchain Blockchain / Ethash / Trie: remove level dependency from blockchain Jul 6, 2023
@holgerd77 holgerd77 changed the title Blockchain / Ethash / Trie: remove level dependency from blockchain Blockchain/Ethash/Trie: remove level dependency from blockchain Jul 6, 2023
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.

None yet

3 participants