Skip to content

Commit

Permalink
chore(dot/state): create BaseState for accessing non-prefixed db keys (
Browse files Browse the repository at this point in the history
  • Loading branch information
noot committed Apr 28, 2021
1 parent f23a3a3 commit ebe6dec
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 159 deletions.
2 changes: 1 addition & 1 deletion cmd/gossamer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ func updateDotConfigFromGenesisData(ctx *cli.Context, cfg *dot.Config) error {
}

// load genesis data from initialised node database
gen, err := state.LoadGenesisData(db)
gen, err := state.NewBaseState(db).LoadGenesisData()
if err != nil {
return fmt.Errorf("failed to load genesis data: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/gossamer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ func TestUpdateConfigFromGenesisData(t *testing.T) {
gen, err := genesis.NewGenesisFromJSONRaw(genFile.Name())
require.Nil(t, err)

err = state.StoreGenesisData(db, gen.GenesisData())
err = state.NewBaseState(db).StoreGenesisData(gen.GenesisData())
require.Nil(t, err)

err = db.Close()
Expand Down
4 changes: 2 additions & 2 deletions dot/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func NodeInitialized(basepath string, expected bool) bool {
}

// load genesis data from initialised node database
_, err = state.LoadGenesisData(db)
_, err = state.NewBaseState(db).LoadGenesisData()
if err != nil {
logger.Warn(
"node has not been initialised",
Expand Down Expand Up @@ -307,7 +307,7 @@ func NewNode(cfg *Config, ks *keystore.GlobalKeystore, stopFunc func()) (*Node,
publishMetrics(cfg)
}

gd, err := stateSrvc.Storage.GetGenesisData()
gd, err := stateSrvc.Base.LoadGenesisData()
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion dot/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestInitNode_LoadGenesisData(t *testing.T) {
require.NoError(t, err)
}()

gendata, err := state.LoadGenesisData(stateSrvc.DB())
gendata, err := stateSrvc.Base.LoadGenesisData()
require.NoError(t, err)

testGenesis := NewTestGenesis(t)
Expand Down
4 changes: 2 additions & 2 deletions dot/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func createStateService(cfg *Config) (*state.Service, error) {
}

// load most recent state from database
latestState, err := state.LoadLatestStorageHash(stateSrvc.DB())
latestState, err := stateSrvc.Base.LoadLatestStorageHash()
if err != nil {
return nil, fmt.Errorf("failed to load latest state root hash: %s", err)
}
Expand Down Expand Up @@ -327,7 +327,7 @@ func createRPCService(cfg *Config, stateSrvc *state.Service, coreSrvc *core.Serv
// System service
// creates a service for providing system related information
func createSystemService(cfg *types.SystemInfo, stateSrvc *state.Service) (*system.Service, error) {
genesisData, err := stateSrvc.Storage.GetGenesisData()
genesisData, err := stateSrvc.Base.LoadGenesisData()
if err != nil {
return nil, err
}
Expand Down
73 changes: 52 additions & 21 deletions dot/state/db.go → dot/state/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,36 @@
package state

import (
"encoding/binary"
"encoding/json"
"fmt"

"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/genesis"
"github.com/ChainSafe/gossamer/lib/trie"

database "github.com/ChainSafe/chaindb"
"github.com/ChainSafe/chaindb"
)

// BaseState is a wrapper for the chaindb.Database, without any prefixes
type BaseState struct {
db chaindb.Database
}

// NewBaseState returns a new BaseState
func NewBaseState(db chaindb.Database) *BaseState {
return &BaseState{
db: db,
}
}

// StoreBestBlockHash stores the hash at the BestBlockHashKey
func StoreBestBlockHash(db database.Database, hash common.Hash) error {
return db.Put(common.BestBlockHashKey, hash[:])
func (s *BaseState) StoreBestBlockHash(hash common.Hash) error {
return s.db.Put(common.BestBlockHashKey, hash[:])
}

// LoadBestBlockHash loads the hash stored at BestBlockHashKey
func LoadBestBlockHash(db database.Database) (common.Hash, error) {
hash, err := db.Get(common.BestBlockHashKey)
func (s *BaseState) LoadBestBlockHash() (common.Hash, error) {
hash, err := s.db.Get(common.BestBlockHashKey)
if err != nil {
return common.Hash{}, err
}
Expand All @@ -43,18 +55,18 @@ func LoadBestBlockHash(db database.Database) (common.Hash, error) {
}

// StoreGenesisData stores the given genesis data at the known GenesisDataKey.
func StoreGenesisData(db database.Database, gen *genesis.Data) error {
func (s *BaseState) StoreGenesisData(gen *genesis.Data) error {
enc, err := json.Marshal(gen)
if err != nil {
return fmt.Errorf("cannot scale encode genesis data: %s", err)
}

return db.Put(common.GenesisDataKey, enc)
return s.db.Put(common.GenesisDataKey, enc)
}

// LoadGenesisData retrieves the genesis data stored at the known GenesisDataKey.
func LoadGenesisData(db database.Database) (*genesis.Data, error) {
enc, err := db.Get(common.GenesisDataKey)
func (s *BaseState) LoadGenesisData() (*genesis.Data, error) {
enc, err := s.db.Get(common.GenesisDataKey)
if err != nil {
return nil, err
}
Expand All @@ -69,27 +81,46 @@ func LoadGenesisData(db database.Database) (*genesis.Data, error) {
}

// StoreLatestStorageHash stores the current root hash in the database at LatestStorageHashKey
func StoreLatestStorageHash(db database.Database, root common.Hash) error {
return db.Put(common.LatestStorageHashKey, root[:])
func (s *BaseState) StoreLatestStorageHash(root common.Hash) error {
return s.db.Put(common.LatestStorageHashKey, root[:])
}

// LoadLatestStorageHash retrieves the hash stored at LatestStorageHashKey from the DB
func LoadLatestStorageHash(db database.Database) (common.Hash, error) {
hashbytes, err := db.Get(common.LatestStorageHashKey)
func (s *BaseState) LoadLatestStorageHash() (common.Hash, error) {
hashbytes, err := s.db.Get(common.LatestStorageHashKey)
if err != nil {
return common.Hash{}, err
}

return common.NewHash(hashbytes), nil
}

// StoreTrie encodes the entire trie and writes it to the DB
// The key to the DB entry is the root hash of the trie
func StoreTrie(db database.Database, t *trie.Trie) error {
return t.Store(db)
func (s *BaseState) storeSkipToEpoch(epoch uint64) error {
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, epoch)
return s.db.Put(skipToKey, buf)
}

// LoadTrie loads an encoded trie from the DB where the key is `root`
func LoadTrie(db database.Database, t *trie.Trie, root common.Hash) error {
return t.Load(db, root)
func (s *BaseState) loadSkipToEpoch() (uint64, error) {
data, err := s.db.Get(skipToKey)
if err != nil {
return 0, err
}

return binary.LittleEndian.Uint64(data), nil
}

func (s *BaseState) storeFirstSlot(slot uint64) error {
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, slot)
return s.db.Put(firstSlotKey, buf)
}

func (s *BaseState) loadFirstSlot() (uint64, error) {
data, err := s.db.Get(firstSlotKey)
if err != nil {
return 0, err
}

return binary.LittleEndian.Uint64(data), nil
}
64 changes: 22 additions & 42 deletions dot/state/db_test.go → dot/state/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package state

import (
"bytes"
"reflect"
"testing"

"github.com/ChainSafe/gossamer/lib/common"
Expand All @@ -26,7 +25,7 @@ func TestTrie_StoreAndLoadFromDB(t *testing.T) {
}
}

err := StoreTrie(db, tt)
err := tt.Store(db)
require.NoError(t, err)

encroot, err := tt.Hash()
Expand All @@ -35,7 +34,7 @@ func TestTrie_StoreAndLoadFromDB(t *testing.T) {
expected := tt.MustHash()

tt = trie.NewEmptyTrie()
err = LoadTrie(db, tt, encroot)
err = tt.Load(db, encroot)
require.NoError(t, err)
require.Equal(t, expected, tt.MustHash())
}
Expand All @@ -47,6 +46,7 @@ type test struct {

func TestStoreAndLoadLatestStorageHash(t *testing.T) {
db := NewInMemoryDB(t)
base := NewBaseState(db)
tt := trie.NewEmptyTrie()

tests := []test{
Expand All @@ -65,27 +65,19 @@ func TestStoreAndLoadLatestStorageHash(t *testing.T) {
}

expected, err := tt.Hash()
if err != nil {
t.Fatal(err)
}

err = StoreLatestStorageHash(db, expected)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)

hash, err := LoadLatestStorageHash(db)
if err != nil {
t.Fatal(err)
}
err = base.StoreLatestStorageHash(expected)
require.NoError(t, err)

if hash != expected {
t.Fatalf("Fail: got %x expected %x", hash, expected)
}
hash, err := base.LoadLatestStorageHash()
require.NoError(t, err)
require.Equal(t, expected, hash)
}

func TestStoreAndLoadGenesisData(t *testing.T) {
db := NewInMemoryDB(t)
base := NewBaseState(db)

bootnodes := common.StringArrayToBytes([]string{
"/ip4/127.0.0.1/tcp/7001/p2p/12D3KooWHHzSeKaY8xuZVzkLbKFfvNgPPeKhFBGrMbNzbm5akpqu",
Expand All @@ -99,36 +91,24 @@ func TestStoreAndLoadGenesisData(t *testing.T) {
ProtocolID: "/gossamer/test/0",
}

err := StoreGenesisData(db, expected)
if err != nil {
t.Fatal(err)
}

gen, err := LoadGenesisData(db)
if err != nil {
t.Fatal(err)
}
err := base.StoreGenesisData(expected)
require.NoError(t, err)

if !reflect.DeepEqual(gen, expected) {
t.Fatalf("Fail: got %v expected %v", gen, expected)
}
gen, err := base.LoadGenesisData()
require.NoError(t, err)
require.Equal(t, expected, gen)
}

func TestStoreAndLoadBestBlockHash(t *testing.T) {
db := NewInMemoryDB(t)
hash, _ := common.HexToHash("0x3f5a19b9e9507e05276216f3877bb289e47885f8184010c65d0e41580d3663cc")
base := NewBaseState(db)

err := StoreBestBlockHash(db, hash)
if err != nil {
t.Fatal(err)
}
hash, _ := common.HexToHash("0x3f5a19b9e9507e05276216f3877bb289e47885f8184010c65d0e41580d3663cc")

res, err := LoadBestBlockHash(db)
if err != nil {
t.Fatal(err)
}
err := base.StoreBestBlockHash(hash)
require.NoError(t, err)

if !reflect.DeepEqual(res, hash) {
t.Fatalf("Fail: got %x expected %x", res, hash)
}
res, err := base.LoadBestBlockHash()
require.NoError(t, err)
require.Equal(t, hash, res)
}
19 changes: 10 additions & 9 deletions dot/state/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ const pruneKeyBufferSize = 1000

// BlockState defines fields for manipulating the state of blocks, such as BlockTree, BlockDB and Header
type BlockState struct {
bt *blocktree.BlockTree
baseDB chaindb.Database
db chaindb.Database
bt *blocktree.BlockTree
//baseDB chaindb.Database
baseState *BaseState
db chaindb.Database
sync.RWMutex
genesisHash common.Hash

Expand All @@ -61,7 +62,7 @@ func NewBlockState(db chaindb.Database, bt *blocktree.BlockTree) (*BlockState, e

bs := &BlockState{
bt: bt,
baseDB: db,
baseState: NewBaseState(db),
db: chaindb.NewTable(db, blockPrefix),
imported: make(map[byte]chan<- *types.Block),
finalised: make(map[byte]chan<- *types.Header),
Expand All @@ -81,7 +82,7 @@ func NewBlockState(db chaindb.Database, bt *blocktree.BlockTree) (*BlockState, e
func NewBlockStateFromGenesis(db chaindb.Database, header *types.Header) (*BlockState, error) {
bs := &BlockState{
bt: blocktree.NewBlockTreeFromRoot(header, db),
baseDB: db,
baseState: NewBaseState(db),
db: chaindb.NewTable(db, blockPrefix),
imported: make(map[byte]chan<- *types.Block),
finalised: make(map[byte]chan<- *types.Header),
Expand Down Expand Up @@ -548,7 +549,7 @@ func (bs *BlockState) AddBlockWithArrivalTime(block *types.Block, arrivalTime ti
}

go bs.notifyImported(block)
return bs.baseDB.Flush()
return bs.db.Flush()
}

// handleAddedBlock re-sets the canonical number->hash mapping if there was a chain re-org.
Expand Down Expand Up @@ -717,7 +718,7 @@ func (bs *BlockState) BlocktreeAsString() string {
}

func (bs *BlockState) setBestBlockHashKey(hash common.Hash) error {
return StoreBestBlockHash(bs.baseDB, hash)
return bs.baseState.StoreBestBlockHash(hash)
}

// HasArrivalTime returns true if the db contains the block's arrival time
Expand All @@ -727,7 +728,7 @@ func (bs *BlockState) HasArrivalTime(hash common.Hash) (bool, error) {

// GetArrivalTime returns the arrival time in nanoseconds since the Unix epoch of a block given its hash
func (bs *BlockState) GetArrivalTime(hash common.Hash) (time.Time, error) {
arrivalTime, err := bs.baseDB.Get(arrivalTimeKey(hash))
arrivalTime, err := bs.db.Get(arrivalTimeKey(hash))
if err != nil {
return time.Time{}, err
}
Expand All @@ -739,5 +740,5 @@ func (bs *BlockState) GetArrivalTime(hash common.Hash) (time.Time, error) {
func (bs *BlockState) setArrivalTime(hash common.Hash, arrivalTime time.Time) error {
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, uint64(arrivalTime.UnixNano()))
return bs.baseDB.Put(arrivalTimeKey(hash), buf)
return bs.db.Put(arrivalTimeKey(hash), buf)
}
Loading

0 comments on commit ebe6dec

Please sign in to comment.