-
Notifications
You must be signed in to change notification settings - Fork 773
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
Conversation
Codecov Report
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. |
packages/blockchain/package.json
Outdated
"debug": "^4.3.3", | ||
"ethereum-cryptography": "^1.1.2", | ||
"level": "^8.0.0", | ||
"lru-cache": "^5.1.1", | ||
"memory-level": "^1.0.0" |
There was a problem hiding this comment.
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.
Cool 🤩, had some first look over the changes, I would generally say this already very much goes into a good direction! 👍 |
127e6b5
to
89f4741
Compare
Co-authored-by: Gabriel Rocheleau <contact@rockwaterweb.com>
There was a problem hiding this 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).
@@ -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) |
There was a problem hiding this comment.
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([]) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
packages/blockchain/src/db/map.ts
Outdated
open() { | ||
return Promise.resolve() | ||
} | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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)
open() { | ||
return this._leveldb.open() | ||
} | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
…umjs/ethereumjs-monorepo into blockchain/level-refactor
There was a problem hiding this 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.
No description provided.