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: triedb.Config support for arbitrary backend implementations #70

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ARR4N
Copy link
Collaborator

@ARR4N ARR4N commented Nov 13, 2024

Why this should be merged

Allow ava-labs/coreth to use arbitrary triedb database implementations.

How this works

Introduces HashBackend and PathBackend interfaces that triedb.Database type-asserts to instead of hashdb.Database and pathdb.Backend respectively. Other interfaces are introduced to avoid having to modify {hash,path}db.Database.Reader() return values.

The explicit DBOverride field means that we don't have to modify any of the triedb constructor beyond adding a single line immediately before the return. This leaves all modifications of original files entirely mechanistic. This is, however, at the expense of compile-time guarantees of the overriding database being either a HashBackend or a PathBackend.

How this was tested

Unit test demonstrating override + plumbing.

@ARR4N ARR4N marked this pull request as ready for review November 13, 2024 18:32
@@ -36,6 +36,8 @@ type Config struct {
IsVerkle bool // Flag whether the db is holding a verkle tree
HashDB *hashdb.Config // Configs for hash-based scheme
PathDB *pathdb.Config // Configs for experimental path-based scheme

DBOverride BackendConstructor // Injects an arbitrary backend implementation
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: IMO we can call this BackendConstructor as well (or a different name that refers to Backend)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree that they should have the same name. What do you think of these changes?

@@ -119,13 +121,16 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
}
db.backend = hashdb.New(diskdb, config.HashDB, resolver)
}
db.overrideBackend(diskdb, config)
Copy link
Collaborator

Choose a reason for hiding this comment

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

if we handle this here then if config.IsVerkle is set the hashDB path will try to initialize but fail

Copy link
Collaborator

Choose a reason for hiding this comment

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

this is an example (non-recommended) fix ethereum@753d1f5 but probably a different order of checking whether the optional config is specified

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Nice catch, thank you. I was too focussed on mechanistic rules for where changes are made (in this case, "last thing before the return") so we can one day define how to resolve conflicts.

I've moved it to immediately after db is declared and the override now returns a bool that signals an early return. This also removes the smell of having to close a just-opened backend.

// along with the go-ethereum library. If not, see
// <http://www.gnu.org/licenses/>.

package triedb
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: not sure if the triedb/database would be a better package to define this

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I put it here to avoid having to replicate the backend interface anywhere; it also fits nicely with the "accept interfaces" idiom as well as "Go interfaces generally belong in the package that consumes values of the interface type".

Only constructor implementations would need to import them and, since the constructor is injected, there won't be an import loop.

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.

2 participants