Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions db/state_hash_db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package db

import (
"fmt"
"strconv"
"strings"

"github.com/0xsoniclabs/substate/types"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/opt"
)

const StateHashDBPrefix = "dbh" // StateHashDBPrefix + 0x + blockNum(hex) -> StateHash

// StateHashDB is a wrapper around CodeDB. It extends it with Has/Get/Put/DeleteSubstate functions.
//
//go:generate mockgen -source=substate_db.go -destination=./substate_db_mock.go -package=db
type StateHashDB interface {
BaseDB

PutStateHash(blockNumber uint64, stateRoot []byte) error
}

// NewDefaultStateHashDB creates new instance of StateHashDB with default options.
func NewDefaultStateHashDB(path string) (StateHashDB, error) {
return newStateHashDB(path, nil, nil, nil)

Check warning on line 26 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L25-L26

Added lines #L25 - L26 were not covered by tests
}

// NewStateHashDB creates new instance of StateHashDB with customizable options.
// Note: Any of three options is nillable. If that's the case a default value for the option is set.
func NewStateHashDB(path string, o *opt.Options, wo *opt.WriteOptions, ro *opt.ReadOptions) (StateHashDB, error) {
return newStateHashDB(path, o, wo, ro)

Check warning on line 32 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L31-L32

Added lines #L31 - L32 were not covered by tests
}

func MakeDefaultStateHashDB(db *leveldb.DB) StateHashDB {
return &stateHashDB{&baseDB{backend: db}}

Check warning on line 36 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L35-L36

Added lines #L35 - L36 were not covered by tests
}

func MakeDefaultStateHashDBFromBaseDB(db BaseDB) StateHashDB {
return &stateHashDB{&baseDB{backend: db.getBackend()}}

Check warning on line 40 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L39-L40

Added lines #L39 - L40 were not covered by tests
}

// NewReadOnlyStateHashDB creates a new instance of read-only StateHashDB.
func NewReadOnlyStateHashDB(path string) (StateHashDB, error) {
return newStateHashDB(path, &opt.Options{ReadOnly: true}, nil, nil)

Check warning on line 45 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L44-L45

Added lines #L44 - L45 were not covered by tests
}

func MakeStateHashDB(db *leveldb.DB, wo *opt.WriteOptions, ro *opt.ReadOptions) StateHashDB {
return &stateHashDB{&baseDB{backend: db, wo: wo, ro: ro}}

Check warning on line 49 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L48-L49

Added lines #L48 - L49 were not covered by tests
}

func newStateHashDB(path string, o *opt.Options, wo *opt.WriteOptions, ro *opt.ReadOptions) (*stateHashDB, error) {
base, err := newBaseDB(path, o, wo, ro)
if err != nil {
return nil, err
}
return &stateHashDB{base}, nil

Check warning on line 57 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L52-L57

Added lines #L52 - L57 were not covered by tests
}

type stateHashDB struct {
BaseDB
}

func (db *stateHashDB) PutStateHash(blockNumber uint64, stateRoot []byte) error {
hex := strconv.FormatUint(blockNumber, 16)
fullPrefix := StateHashDBPrefix + "0x" + hex
err := db.Put([]byte(fullPrefix), stateRoot)
if err != nil {
return fmt.Errorf("unable to put state hash for block %d: %v", blockNumber, err)
}
return nil

Check warning on line 71 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L64-L71

Added lines #L64 - L71 were not covered by tests
}

func (db *stateHashDB) PutStateHashString(blockNumber string, stateRoot string) error {
fullPrefix := StateHashDBPrefix + blockNumber
err := db.Put([]byte(fullPrefix), types.Hex2Bytes(strings.TrimPrefix(stateRoot, "0x")))
if err != nil {
return fmt.Errorf("unable to put state hash for block %s: %v", blockNumber, err)
}
return nil

Check warning on line 80 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L74-L80

Added lines #L74 - L80 were not covered by tests
}

func (db *stateHashDB) GetStateHash(number int) (types.Hash, error) {
hex := strconv.FormatUint(uint64(number), 16)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This logic is taken over from Aida: block encoding into hex is different from bigEndian encoding we use everywhere else. Maybe we could consider to make a migration to another prefix to unify this.

stateRoot, err := db.Get([]byte(StateHashDBPrefix + "0x" + hex))
if err != nil {
return types.Hash{}, err
}

Check warning on line 88 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L83-L88

Added lines #L83 - L88 were not covered by tests

if stateRoot == nil {
return types.Hash{}, nil
}

Check warning on line 92 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L90-L92

Added lines #L90 - L92 were not covered by tests

return types.Hash(stateRoot), nil

Check warning on line 94 in db/state_hash_db.go

View check run for this annotation

Codecov / codecov/patch

db/state_hash_db.go#L94

Added line #L94 was not covered by tests
}