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

Update Database on project #158

Merged
merged 12 commits into from
May 20, 2022
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion pkg/db/abi/manager.go → internal/db/abi/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/NethermindEth/juno/pkg/db"
"github.com/NethermindEth/juno/internal/db"
"math/big"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package abi
import (
"bytes"
"encoding/json"
"github.com/NethermindEth/juno/pkg/db"
"github.com/NethermindEth/juno/internal/db"
"testing"
)

Expand Down Expand Up @@ -41,7 +41,7 @@ type testManagerPutABI struct {

func TestManager(t *testing.T) {
// Init the ABI manager
database := db.New(t.TempDir(), 0)
database := db.NewKeyValueDb(t.TempDir(), 0)
manager := NewABIManager(database)
// Load ABI test files
abis, err := loadABIsFromFiles()
Expand Down Expand Up @@ -76,7 +76,7 @@ func TestManager(t *testing.T) {

func TestManager_GetABI_NotFound(t *testing.T) {
// Init the ABI manager
database := db.New(t.TempDir(), 0)
database := db.NewKeyValueDb(t.TempDir(), 0)
manager := NewABIManager(database)
abi := manager.GetABI("1bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac")
if abi != nil {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestBlockSpecificDatabase_Put(t *testing.T) {
},
}

database := New(t.TempDir(), 0)
database := NewKeyValueDb(t.TempDir(), 0)
db := NewBlockSpecificDatabase(database)

for _, test := range tests {
Expand Down Expand Up @@ -97,7 +97,7 @@ func TestBlockSpecificDatabase_Get(t *testing.T) {
},
}

database := New(t.TempDir(), 0)
database := NewKeyValueDb(t.TempDir(), 0)
db := NewBlockSpecificDatabase(database)

for _, d := range data {
Expand Down
53 changes: 20 additions & 33 deletions pkg/db/db.go → internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ type Databaser interface {
Delete(key []byte) error
// NumberOfItems returns the number of items in the database.
NumberOfItems() (uint64, error)
// Begin starts a new transaction.
Begin()
// Rollback rollsback the database to a previous state.
Rollback()
// Close closes the environment.
Close()
// GetEnv returns the environment of the database
GetEnv() *mdbx.Env
}

// KeyValueDb represents the middleware for an MDBX key-value store.
Expand All @@ -37,35 +35,42 @@ type KeyValueDb struct {
path string
}

// New creates a new key-value database.
func New(path string, flags uint) *KeyValueDb {
log.Default.With("Path", path, "Flags", flags).Info("Creating new database.")
// GetEnv returns the environment of the database
func (d *KeyValueDb) GetEnv() *mdbx.Env {
return d.env
}

// NewKeyValueDbWithEnv creates a new key-value database based on an already created env.
func NewKeyValueDbWithEnv(env *mdbx.Env, path string) *KeyValueDb {
return &KeyValueDb{
env: env,
path: path,
}
}

func NewKeyValueDb(path string, flags uint) *KeyValueDb {
env, err := mdbx.NewEnv()
if err != nil {
// notest
log.Default.With("Error", err).Info("Failed to initialise and allocate new mdbx.Env.")
return nil
}

// Set flags.
// Based on https://github.com/torquem-ch/mdbx-go/blob/96f31f483af593377e52358a079e834256d5af55/mdbx/env_test.go#L495
err = env.SetOption(mdbx.OptMaxDB, 1024)
err = env.SetOption(mdbx.OptMaxDB, 1)
if err != nil {
// notest
log.Default.With("Error", err).Info("Failed to set mdbx.Env options.")
return nil
}
const pageSize = 4096
err = env.SetGeometry(-1, -1, 64*1024*pageSize, -1, -1, pageSize)
err = env.SetGeometry(268435456, 268435456, 25769803776, 268435456, 268435456, pageSize)
if err != nil {
// notest
log.Default.With("Error", err).Info("Failed to set geometry.")
return nil
}
err = env.Open(path, flags, 0664)
err = env.Open(path, flags|mdbx.Exclusive, 0664)
if err != nil {
// notest
log.Default.With("Error", err).Info("Failed to open mdbx.Env.")
return nil
}
return &KeyValueDb{env: env, path: path}
Expand All @@ -76,7 +81,6 @@ func New(path string, flags uint) *KeyValueDb {
func (d *KeyValueDb) Has(key []byte) (has bool, err error) {
val, err := d.getOne(key)
if err != nil {
log.Default.With("Error", err, "Key", string(key)).Info("Key provided does not exist.")
return false, err
}
return val != nil, nil
Expand All @@ -89,17 +93,14 @@ func (d *KeyValueDb) getOne(key []byte) (val []byte, err error) {
if err := d.env.View(func(txn *mdbx.Txn) error {
dbi, err = txn.OpenRoot(mdbx.Create)
if err != nil {
log.Default.With("Error", err).Info("Failed to open database.")
return err
}
val, err = txn.Get(dbi, key)
if err != nil {
if mdbx.IsNotFound(err) {
log.Default.With("Error", err, "Key", string(key)).Info("Failed to get value.")
err = nil
return nil
}
log.Default.With("Error", err, "Key", string(key)).Info("Failed to get value.")
return err
}
return nil
Expand All @@ -113,38 +114,30 @@ func (d *KeyValueDb) getOne(key []byte) (val []byte, err error) {
// Get returns the value associated with the provided key in the
// database or returns an error otherwise.
func (d *KeyValueDb) Get(key []byte) ([]byte, error) {
log.Default.With("Key", key).Info("Getting value using key.")
return d.getOne(key)
}

// Put inserts a key-value pair into the database.
func (d *KeyValueDb) Put(key, value []byte) error {
log.Default.With("Key", string(key)).Info("Putting value at key.")
err := d.env.Update(func(txn *mdbx.Txn) error {
log.Default.Info("Opening the root database.")
dbi, err := txn.OpenRoot(mdbx.Create)
if err != nil {
log.Default.With("Error", err, "Key", string(key)).Info("Unable to open root database.")
return err
}
log.Default.Info("Storing item in database.")
return txn.Put(dbi, key, value, 0)
})
return err
}

// Delete removes a previous inserted key or returns an error otherwise.
func (d *KeyValueDb) Delete(key []byte) error {
log.Default.With("Key", key).Info("Deleting value associated with key.")
err := d.env.Update(func(txn *mdbx.Txn) error {
db, err := txn.OpenRoot(mdbx.Create)
if err != nil {
log.Default.With("Error", err, "Key", string(key)).Info("Unable to open database.")
return err
}
err = txn.Del(db, key, nil)
if mdbx.IsNotFound(err) {
log.Default.With("Error", err, "Key", string(key)).Info("Unable to get value.")
return nil
}
return err
Expand All @@ -154,21 +147,15 @@ func (d *KeyValueDb) Delete(key []byte) error {

// NumberOfItems returns the number of items in the database.
func (d *KeyValueDb) NumberOfItems() (uint64, error) {
log.Default.Info("Getting the number of items in the database.")
stats, err := d.env.Stat()
if err != nil {
// notest
log.Default.With("Error", err).Info("Unable to get stats from env.")
return 0, err
}
return stats.Entries, err
}

// Begin starts a new transaction.
func (d KeyValueDb) Begin() {}

// Rollback rolls back the database to a previous state.
func (d KeyValueDb) Rollback() {}

// Close closes the environment.
func (d *KeyValueDb) Close() {
d.env.Close()
Expand Down
19 changes: 10 additions & 9 deletions pkg/db/db_test.go → internal/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func init() {

// setupDatabaseForTest creates a new KVDatabase for Tests
func setupDatabaseForTest(path string) *KeyValueDb {
return New(path, 0)
return NewKeyValueDb(path, 0)
}

// TestAddKey Check that a single value is inserted without error
Expand Down Expand Up @@ -207,14 +207,6 @@ func TestDelete(t *testing.T) {
}
}

func TestBegin(t *testing.T) {
database := setupDatabaseForTest(t.TempDir())
database.Begin()
}
func TestRollBack(t *testing.T) {
database := setupDatabaseForTest(t.TempDir())
database.Rollback()
}
func TestClose(t *testing.T) {
database := setupDatabaseForTest(t.TempDir())
database.Close()
Expand All @@ -225,6 +217,15 @@ func TestKeyValueDbIsDatabaser(t *testing.T) {
_ = Databaser(a)
}

func TestKeyValueDb_GetEnv(t *testing.T) {
database := setupDatabaseForTest(t.TempDir())
p := NewKeyValueDbWithEnv(database.GetEnv(), t.TempDir())
items, err := p.NumberOfItems()
if err != nil || items != 0 {
return
}
}

// BenchmarkEntriesInDatabase Benchmark the entry of key-value pairs to the db
func BenchmarkEntriesInDatabase(b *testing.B) {
database := setupDatabaseForTest(b.TempDir())
Expand Down
51 changes: 51 additions & 0 deletions internal/db/kv_storer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package db

// KeyValueStore implement the Storer interface that use a Databaser
type KeyValueStore struct {
db Databaser
prefix []byte
}

func NewKeyValueStore(db Databaser, prefix string) KeyValueStore {
return KeyValueStore{
db: db,
prefix: []byte(prefix),
}
}

func (k KeyValueStore) Delete(key []byte) {
err := k.db.Delete(append(k.prefix, key...))
if err != nil {
// notest
return
}
}

func (k KeyValueStore) Get(key []byte) ([]byte, bool) {
get, err := k.db.Get(append(k.prefix, key...))
if err != nil {
// notest
return nil, false
}
return get, get != nil
}

func (k KeyValueStore) Put(key, val []byte) {
err := k.db.Put(append(k.prefix, key...), val)
if err != nil {
// notest
return
}
}

func (k KeyValueStore) Begin() {

}

func (k KeyValueStore) Rollback() {

}

func (k KeyValueStore) Close() {
k.db.Close()
}
38 changes: 38 additions & 0 deletions internal/db/kv_storer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package db

import (
"testing"
)

// setupTransactionDbTest creates a new TransactionDb for Tests
func setupKvStoreTest(database Databaser) KeyValueStore {
return NewKeyValueStore(database, "test")
}

// TestAddKeyToTransaction Check that a single value is stored after made commit
func TestKeyValueStoreNewDbAndCommit(t *testing.T) {
dbKV := NewKeyValueDb(t.TempDir(), 0)
database := setupKvStoreTest(dbKV)
database.Begin()

database.Put([]byte("key"), []byte("value"))

get, has := database.Get([]byte("key"))
if !has || get == nil {
t.Fail()
}

if string(get) != "value" {
t.Fail()
}

database.Delete([]byte("key"))

get, has = database.Get([]byte("key"))
if has || get != nil {
t.Fail()
}
database.Rollback()

database.Close()
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions pkg/db/state/code_test.go → internal/db/state/code_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"embed"
"encoding/json"
"github.com/NethermindEth/juno/pkg/db"
db2 "github.com/NethermindEth/juno/internal/db"
"math/big"
"testing"
)
Expand Down Expand Up @@ -169,8 +169,8 @@ func TestManager_Code(t *testing.T) {
}
tests = append(tests, test)
}
codeDatabase := db.New(t.TempDir(), 0)
storageDatabase := db.NewBlockSpecificDatabase(db.New(t.TempDir(), 0))
codeDatabase := db2.NewKeyValueDb(t.TempDir(), 0)
storageDatabase := db2.NewBlockSpecificDatabase(db2.NewKeyValueDb(t.TempDir(), 0))
manager := NewStateManager(codeDatabase, *storageDatabase)
for _, test := range tests {
var code ContractCode
Expand Down
8 changes: 4 additions & 4 deletions pkg/db/state/state.go → internal/db/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package state

import (
"errors"
"github.com/NethermindEth/juno/pkg/db"
db2 "github.com/NethermindEth/juno/internal/db"
)

var (
Expand All @@ -15,11 +15,11 @@ var (
// Manager is a database manager, with the objective of managing
// the contract codes and contract storages databases.
type Manager struct {
codeDatabase db.Databaser
storageDatabase db.BlockSpecificDatabase
codeDatabase db2.Databaser
storageDatabase db2.BlockSpecificDatabase
}

// NewStateManager returns a new instance of Manager with the given database sources.
func NewStateManager(codeDatabase db.Databaser, storageDatabase db.BlockSpecificDatabase) *Manager {
func NewStateManager(codeDatabase db2.Databaser, storageDatabase db2.BlockSpecificDatabase) *Manager {
return &Manager{codeDatabase, storageDatabase}
}
File renamed without changes.
Loading