Skip to content

Commit

Permalink
[Storage] Use same storage interface for blockchain and trie storage (#…
Browse files Browse the repository at this point in the history
…193)

# Description

refactoring blocakchain storage interface

# Changes include

- [ ] Bugfix (non-breaking change that solves an issue)
- [ ] Hotfix (change that solves an urgent issue, and requires immediate
attention)
- [x] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (change that is not backwards-compatible and/or
changes current functionality)

# Breaking changes

Please complete this section if any breaking changes have been made,
otherwise delete it

# Checklist

- [x] I have assigned this PR to myself
- [x] I have added at least 1 reviewer
- [x] I have added the relevant labels
- [ ] I have updated the official documentation
- [x] I have added sufficient documentation in code

## Testing

- [x] I have tested this code with the official test suite
- [ ] I have tested this code manually
  • Loading branch information
0xcb9ff9 authored Sep 24, 2022
1 parent d568b65 commit 1f61163
Show file tree
Hide file tree
Showing 22 changed files with 448 additions and 351 deletions.
22 changes: 8 additions & 14 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"sync/atomic"

"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/dogechain-lab/dogechain/blockchain/storage/memory"
"github.com/dogechain-lab/dogechain/chain"
"github.com/dogechain-lab/dogechain/contracts/upgrader"
"github.com/dogechain-lab/dogechain/helper/common"
Expand Down Expand Up @@ -37,6 +36,7 @@ var (
ErrInvalidStateRoot = errors.New("invalid block state root")
ErrInvalidGasUsed = errors.New("invalid block gas used")
ErrInvalidReceiptsRoot = errors.New("invalid block receipts root")
ErrNilStorageBuilder = errors.New("nil storage builder")
ErrClosed = errors.New("blockchain is closed")
)

Expand Down Expand Up @@ -82,10 +82,6 @@ type gasPriceAverage struct {
count *big.Int // Param used in the avg. gas price calculation
}

type StorageBuilder interface {
Build() (storage.Storage, error)
}

type Verifier interface {
VerifyHeader(header *types.Header) error
ProcessHeaders(headers []*types.Header) error
Expand Down Expand Up @@ -186,10 +182,14 @@ func (b *Blockchain) GetAvgGasPrice() *big.Int {
func NewBlockchain(
logger hclog.Logger,
config *chain.Chain,
storageBuilder StorageBuilder,
storageBuilder storage.StorageBuilder,
consensus Verifier,
executor Executor,
) (*Blockchain, error) {
if storageBuilder == nil {
return nil, ErrNilStorageBuilder
}

b := &Blockchain{
logger: logger.Named("blockchain"),
config: config,
Expand All @@ -207,14 +207,8 @@ func NewBlockchain(
err error
)

if storageBuilder == nil {
if db, err = memory.NewMemoryStorage(nil); err != nil {
return nil, err
}
} else {
if db, err = storageBuilder.Build(); err != nil {
return nil, err
}
if db, err = storageBuilder.Build(); err != nil {
return nil, err
}

b.db = db
Expand Down
5 changes: 3 additions & 2 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
"testing"

"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/dogechain-lab/dogechain/blockchain/storage/memory"
"github.com/dogechain-lab/dogechain/blockchain/storage/kvstorage"
"github.com/dogechain-lab/dogechain/chain"
"github.com/dogechain-lab/dogechain/state"
"github.com/dogechain-lab/dogechain/types"
"github.com/hashicorp/go-hclog"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -541,7 +542,7 @@ func TestForkUnknownParents(t *testing.T) {
}

func TestBlockchainWriteBody(t *testing.T) {
storage, err := memory.NewMemoryStorage(nil)
storage, err := kvstorage.NewMemoryStorageBuilder(hclog.NewNullLogger()).Build()
assert.NoError(t, err)

b := &Blockchain{
Expand Down
5 changes: 5 additions & 0 deletions blockchain/storage/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package storage

import "fmt"

var ErrNotFound = fmt.Errorf("not found")
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//nolint:stylecheck
package storage
package kvstorage

import (
"encoding/binary"
"fmt"
"math/big"

"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/dogechain-lab/dogechain/types"
"github.com/dogechain-lab/fastrlp"
"github.com/hashicorp/go-hclog"
Expand Down Expand Up @@ -48,11 +48,10 @@ var (
EMPTY = []byte("empty")
)

// KV is a key value storage interface.
//
// KV = Key-Value
// KV is a generic key-value store, need close it
type KV interface {
Close() error

Set(p []byte, v []byte) error
Get(p []byte) ([]byte, bool, error)
}
Expand All @@ -61,10 +60,9 @@ type KV interface {
type KeyValueStorage struct {
logger hclog.Logger
db KV
Db KV
}

func NewKeyValueStorage(logger hclog.Logger, db KV) Storage {
func newKeyValueStorage(logger hclog.Logger, db KV) storage.Storage {
return &KeyValueStorage{logger: logger, db: db}
}

Expand Down Expand Up @@ -136,14 +134,14 @@ func (s *KeyValueStorage) WriteHeadNumber(n uint64) error {

// WriteForks writes the current forks
func (s *KeyValueStorage) WriteForks(forks []types.Hash) error {
ff := Forks(forks)
ff := storage.Forks(forks)

return s.writeRLP(FORK, EMPTY, &ff)
}

// ReadForks read the current forks
func (s *KeyValueStorage) ReadForks() ([]types.Hash, error) {
forks := &Forks{}
forks := &storage.Forks{}
err := s.readRLP(FORK, EMPTY, forks)

return *forks, err
Expand Down Expand Up @@ -297,8 +295,6 @@ func (s *KeyValueStorage) writeRLP(p, k []byte, raw types.RLPMarshaler) error {
return s.set(p, k, data)
}

var ErrNotFound = fmt.Errorf("not found")

func (s *KeyValueStorage) readRLP(p, k []byte, raw types.RLPUnmarshaler) error {
p = append(p, k...)
data, ok, err := s.db.Get(p)
Expand All @@ -308,7 +304,7 @@ func (s *KeyValueStorage) readRLP(p, k []byte, raw types.RLPUnmarshaler) error {
}

if !ok {
return ErrNotFound
return storage.ErrNotFound
}

if obj, ok := raw.(types.RLPStoreUnmarshaler); ok {
Expand Down
29 changes: 29 additions & 0 deletions blockchain/storage/kvstorage/leveldb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package kvstorage

import (
"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/dogechain-lab/dogechain/helper/kvdb"
"github.com/hashicorp/go-hclog"
)

type leveldbStorageBuilder struct {
logger hclog.Logger
leveldbBuilder kvdb.LevelDBBuilder
}

func (builder *leveldbStorageBuilder) Build() (storage.Storage, error) {
db, err := builder.leveldbBuilder.Build()
if err != nil {
return nil, err
}

return newKeyValueStorage(builder.logger.Named("leveldb"), db), nil
}

// NewLevelDBStorageBuilder creates the new blockchain storage builder
func NewLevelDBStorageBuilder(logger hclog.Logger, leveldbBuilder kvdb.LevelDBBuilder) storage.StorageBuilder {
return &leveldbStorageBuilder{
logger: logger,
leveldbBuilder: leveldbBuilder,
}
}
43 changes: 43 additions & 0 deletions blockchain/storage/kvstorage/leveldb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package kvstorage

import (
"os"
"testing"

"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/dogechain-lab/dogechain/helper/kvdb"
"github.com/hashicorp/go-hclog"
)

func newLevelDBStorage(t *testing.T) (storage.Storage, func()) {
t.Helper()

path, err := os.MkdirTemp("/tmp", "minimal_storage")
if err != nil {
t.Fatal(err)
}

logger := hclog.NewNullLogger()

s, err := NewLevelDBStorageBuilder(
logger, kvdb.NewLevelDBBuilder(logger, path)).Build()
if err != nil {
t.Fatal(err)
}

closeFn := func() {
if err := s.Close(); err != nil {
t.Fatal(err)
}

if err := os.RemoveAll(path); err != nil {
t.Fatal(err)
}
}

return s, closeFn
}

func TestLevelDBStorage(t *testing.T) {
storage.TestStorage(t, newLevelDBStorage)
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package memory
package kvstorage

import (
"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/dogechain-lab/dogechain/helper/hex"
"github.com/hashicorp/go-hclog"
)

// NewMemoryStorage creates the new storage reference with inmemory
func NewMemoryStorage(logger hclog.Logger) (storage.Storage, error) {
type memoryStorageBuilder struct {
logger hclog.Logger
}

func (builder *memoryStorageBuilder) Build() (storage.Storage, error) {
db := &memoryKV{map[string][]byte{}}

return storage.NewKeyValueStorage(logger, db), nil
return newKeyValueStorage(builder.logger, db), nil
}

// NewMemoryStorageBuilder creates the new blockchain storage builder
func NewMemoryStorageBuilder(logger hclog.Logger) storage.StorageBuilder {
return &memoryStorageBuilder{
logger: logger,
}
}

// memoryKV is an in memory implementation of the kv storage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package memory
package kvstorage

import (
"testing"

"github.com/dogechain-lab/dogechain/blockchain/storage"
"github.com/hashicorp/go-hclog"
)

func TestStorage(t *testing.T) {
func TestMemoryStorage(t *testing.T) {
t.Helper()

f := func(t *testing.T) (storage.Storage, func()) {
t.Helper()

s, _ := NewMemoryStorage(nil)
s, _ := NewMemoryStorageBuilder(hclog.NewNullLogger()).Build()

return s, func() {}
}
Expand Down
Loading

0 comments on commit 1f61163

Please sign in to comment.