diff --git a/cmd/gossamer/config.go b/cmd/gossamer/config.go index bc65137174..0131a5a9d9 100644 --- a/cmd/gossamer/config.go +++ b/cmd/gossamer/config.go @@ -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) } diff --git a/cmd/gossamer/config_test.go b/cmd/gossamer/config_test.go index c0485bc8a5..6c87cb8d06 100644 --- a/cmd/gossamer/config_test.go +++ b/cmd/gossamer/config_test.go @@ -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() diff --git a/dot/node.go b/dot/node.go index 86cf10da4e..fc6288b6c3 100644 --- a/dot/node.go +++ b/dot/node.go @@ -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", @@ -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 } diff --git a/dot/node_test.go b/dot/node_test.go index 9afc3175ff..58eb2ea088 100644 --- a/dot/node_test.go +++ b/dot/node_test.go @@ -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) diff --git a/dot/services.go b/dot/services.go index 256f703296..ddfbb28db8 100644 --- a/dot/services.go +++ b/dot/services.go @@ -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) } @@ -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 } diff --git a/dot/state/db.go b/dot/state/base.go similarity index 52% rename from dot/state/db.go rename to dot/state/base.go index 8b88c64deb..32f338d5d3 100644 --- a/dot/state/db.go +++ b/dot/state/base.go @@ -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 } @@ -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 } @@ -69,13 +81,13 @@ 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 } @@ -83,13 +95,32 @@ func LoadLatestStorageHash(db database.Database) (common.Hash, error) { 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 } diff --git a/dot/state/db_test.go b/dot/state/base_test.go similarity index 72% rename from dot/state/db_test.go rename to dot/state/base_test.go index 2a238b8139..a6aee30313 100644 --- a/dot/state/db_test.go +++ b/dot/state/base_test.go @@ -2,7 +2,6 @@ package state import ( "bytes" - "reflect" "testing" "github.com/ChainSafe/gossamer/lib/common" @@ -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() @@ -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()) } @@ -47,6 +46,7 @@ type test struct { func TestStoreAndLoadLatestStorageHash(t *testing.T) { db := NewInMemoryDB(t) + base := NewBaseState(db) tt := trie.NewEmptyTrie() tests := []test{ @@ -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", @@ -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) } diff --git a/dot/state/block.go b/dot/state/block.go index 2ed76e7a87..16406d066e 100644 --- a/dot/state/block.go +++ b/dot/state/block.go @@ -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 @@ -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), @@ -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), @@ -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. @@ -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 @@ -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 } @@ -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) } diff --git a/dot/state/epoch.go b/dot/state/epoch.go index 9afe2cb996..fc45af6d9a 100644 --- a/dot/state/epoch.go +++ b/dot/state/epoch.go @@ -51,8 +51,8 @@ func configDataKey(epoch uint64) []byte { // EpochState tracks information related to each epoch type EpochState struct { - baseDB chaindb.Database db chaindb.Database + baseState *BaseState epochLength uint64 // measured in slots firstSlot uint64 skipToEpoch uint64 @@ -60,7 +60,9 @@ type EpochState struct { // NewEpochStateFromGenesis returns a new EpochState given information for the first epoch, fetched from the runtime func NewEpochStateFromGenesis(db chaindb.Database, genesisConfig *types.BabeConfiguration) (*EpochState, error) { - err := storeFirstSlot(db, 1) // this may change once the first block is imported + baseState := NewBaseState(db) + + err := baseState.storeFirstSlot(1) // this may change once the first block is imported if err != nil { return nil, err } @@ -76,7 +78,7 @@ func NewEpochStateFromGenesis(db chaindb.Database, genesisConfig *types.BabeConf } s := &EpochState{ - baseDB: db, + baseState: NewBaseState(db), db: epochDB, epochLength: genesisConfig.EpochLength, firstSlot: 1, @@ -109,7 +111,7 @@ func NewEpochStateFromGenesis(db chaindb.Database, genesisConfig *types.BabeConf return nil, err } - if err := storeSkipToEpoch(db, 0); err != nil { + if err := s.baseState.storeSkipToEpoch(0); err != nil { return nil, err } @@ -118,23 +120,25 @@ func NewEpochStateFromGenesis(db chaindb.Database, genesisConfig *types.BabeConf // NewEpochState returns a new EpochState func NewEpochState(db chaindb.Database) (*EpochState, error) { + baseState := NewBaseState(db) + epochLength, err := loadEpochLength(db) if err != nil { return nil, err } - firstSlot, err := loadFirstSlot(db) + firstSlot, err := baseState.loadFirstSlot() if err != nil { return nil, err } - skipToEpoch, err := loadSkipToEpoch(db) + skipToEpoch, err := baseState.loadSkipToEpoch() if err != nil { return nil, err } return &EpochState{ - baseDB: db, + baseState: baseState, db: chaindb.NewTable(db, epochPrefix), epochLength: epochLength, firstSlot: firstSlot, @@ -157,21 +161,6 @@ func loadEpochLength(db chaindb.Database) (uint64, error) { return binary.LittleEndian.Uint64(data), nil } -func storeFirstSlot(db chaindb.Database, slot uint64) error { - buf := make([]byte, 8) - binary.LittleEndian.PutUint64(buf, slot) - return db.Put(firstSlotKey, buf) -} - -func loadFirstSlot(db chaindb.Database) (uint64, error) { - data, err := db.Get(firstSlotKey) - if err != nil { - return 0, err - } - - return binary.LittleEndian.Uint64(data), nil -} - // SetCurrentEpoch sets the current epoch func (s *EpochState) SetCurrentEpoch(epoch uint64) error { buf := make([]byte, 8) @@ -301,22 +290,7 @@ func (s *EpochState) GetStartSlotForEpoch(epoch uint64) (uint64, error) { // SetFirstSlot sets the first slot number of the network func (s *EpochState) SetFirstSlot(slot uint64) error { s.firstSlot = slot - return storeFirstSlot(s.baseDB, slot) -} - -func storeSkipToEpoch(db chaindb.Database, epoch uint64) error { - buf := make([]byte, 8) - binary.LittleEndian.PutUint64(buf, epoch) - return db.Put(skipToKey, buf) -} - -func loadSkipToEpoch(db chaindb.Database) (uint64, error) { - data, err := db.Get(skipToKey) - if err != nil { - return 0, err - } - - return binary.LittleEndian.Uint64(data), nil + return s.baseState.storeFirstSlot(slot) } // SkipVerify returns whether verification for the given header should be skipped or not. diff --git a/dot/state/grandpa.go b/dot/state/grandpa.go index 9c8a9e8830..cc159bdf2c 100644 --- a/dot/state/grandpa.go +++ b/dot/state/grandpa.go @@ -39,16 +39,14 @@ var ( // GrandpaState tracks information related to grandpa type GrandpaState struct { - baseDB chaindb.Database - db chaindb.Database + db chaindb.Database } // NewGrandpaStateFromGenesis returns a new GrandpaState given the grandpa genesis authorities func NewGrandpaStateFromGenesis(db chaindb.Database, genesisAuthorities []*types.GrandpaVoter) (*GrandpaState, error) { grandpaDB := chaindb.NewTable(db, grandpaPrefix) s := &GrandpaState{ - baseDB: db, - db: grandpaDB, + db: grandpaDB, } err := s.setCurrentSetID(genesisSetID) @@ -67,8 +65,7 @@ func NewGrandpaStateFromGenesis(db chaindb.Database, genesisAuthorities []*types // NewGrandpaState returns a new GrandpaState func NewGrandpaState(db chaindb.Database) (*GrandpaState, error) { return &GrandpaState{ - baseDB: db, - db: chaindb.NewTable(db, grandpaPrefix), + db: chaindb.NewTable(db, grandpaPrefix), }, nil } diff --git a/dot/state/initialize.go b/dot/state/initialize.go index 8ed36fe2c5..c1e73cedc1 100644 --- a/dot/state/initialize.go +++ b/dot/state/initialize.go @@ -56,6 +56,7 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t *trie if err != nil { return fmt.Errorf("failed to create database: %s", err) } + s.db = db if err = db.ClearAll(); err != nil { return fmt.Errorf("failed to clear database: %s", err) @@ -65,6 +66,8 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t *trie return fmt.Errorf("failed to write genesis trie to database: %w", err) } + s.Base = NewBaseState(db) + rt, err := s.createGenesisRuntime(t, gen) if err != nil { return err @@ -76,7 +79,7 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t *trie } // write initial genesis values to database - if err = s.storeInitialValues(db, gen.GenesisData(), header, t); err != nil { + if err = s.storeInitialValues(gen.GenesisData(), header, t); err != nil { return fmt.Errorf("failed to write genesis values to database: %s", err) } @@ -161,24 +164,24 @@ func loadGrandpaAuthorities(t *trie.Trie) ([]*types.GrandpaVoter, error) { } // storeInitialValues writes initial genesis values to the state database -func (s *Service) storeInitialValues(db chaindb.Database, data *genesis.Data, header *types.Header, t *trie.Trie) error { +func (s *Service) storeInitialValues(data *genesis.Data, header *types.Header, t *trie.Trie) error { // write genesis trie to database - if err := StoreTrie(chaindb.NewTable(db, storagePrefix), t); err != nil { + if err := t.Store(chaindb.NewTable(s.db, storagePrefix)); err != nil { return fmt.Errorf("failed to write trie to database: %s", err) } // write storage hash to database - if err := StoreLatestStorageHash(db, t.MustHash()); err != nil { + if err := s.Base.StoreLatestStorageHash(t.MustHash()); err != nil { return fmt.Errorf("failed to write storage hash to database: %s", err) } // write best block hash to state database - if err := StoreBestBlockHash(db, header.Hash()); err != nil { + if err := s.Base.StoreBestBlockHash(header.Hash()); err != nil { return fmt.Errorf("failed to write best block hash to database: %s", err) } // write genesis data to state database - if err := StoreGenesisData(db, data); err != nil { + if err := s.Base.StoreGenesisData(data); err != nil { return fmt.Errorf("failed to write genesis data to database: %s", err) } diff --git a/dot/state/service.go b/dot/state/service.go index 39be20ce74..7f69cc3d7f 100644 --- a/dot/state/service.go +++ b/dot/state/service.go @@ -39,6 +39,7 @@ type Service struct { logLvl log.Lvl db chaindb.Database isMemDB bool // set to true if using an in-memory database; only used for testing. + Base *BaseState Storage *StorageState Block *BlockState Transaction *TransactionState @@ -104,10 +105,11 @@ func (s *Service) Start() error { } s.db = db + s.Base = NewBaseState(db) } // retrieve latest header - bestHash, err := LoadBestBlockHash(db) + bestHash, err := s.Base.LoadBestBlockHash() if err != nil { return fmt.Errorf("failed to get best block hash: %w", err) } @@ -146,7 +148,7 @@ func (s *Service) Start() error { return fmt.Errorf("failed to create storage state: %w", err) } - stateRoot, err := LoadLatestStorageHash(s.db) + stateRoot, err := s.Base.LoadLatestStorageHash() if err != nil { return fmt.Errorf("cannot load latest storage root: %w", err) } @@ -216,7 +218,7 @@ func (s *Service) Rewind(toBlock int64) error { return err } - return StoreBestBlockHash(s.db, newHead) + return s.Base.StoreBestBlockHash(newHead) } // Stop closes each state database @@ -234,13 +236,13 @@ func (s *Service) Stop() error { return errTrieDoesNotExist(head) } - if err = StoreLatestStorageHash(s.db, head); err != nil { + if err = s.Base.StoreLatestStorageHash(head); err != nil { return err } logger.Debug("storing latest storage trie", "root", head) - if err = StoreTrie(s.Storage.db, t); err != nil { + if err = t.Store(s.Storage.db); err != nil { return err } @@ -249,7 +251,7 @@ func (s *Service) Stop() error { } hash := s.Block.BestBlockHash() - if err = StoreBestBlockHash(s.db, hash); err != nil { + if err = s.Base.StoreBestBlockHash(hash); err != nil { return err } @@ -277,14 +279,13 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e if s.isMemDB { cfg.InMemory = true - } else { - var err error + } - // initialise database using data directory - s.db, err = chaindb.NewBadgerDB(cfg) - if err != nil { - return fmt.Errorf("failed to create database: %s", err) - } + var err error + // initialise database using data directory + s.db, err = chaindb.NewBadgerDB(cfg) + if err != nil { + return fmt.Errorf("failed to create database: %s", err) } block := &BlockState{ @@ -300,8 +301,9 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e return err } - logger.Info("storing first slot...", "slot", firstSlot) - if err = storeFirstSlot(s.db, firstSlot); err != nil { + s.Base = NewBaseState(s.db) + + if err = s.Base.storeFirstSlot(firstSlot); err != nil { return err } @@ -313,7 +315,7 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e skipTo := blockEpoch + 1 - if err := storeSkipToEpoch(s.db, skipTo); err != nil { + if err := s.Base.storeSkipToEpoch(skipTo); err != nil { return err } logger.Debug("skip BABE verification up to epoch", "epoch", skipTo) @@ -327,13 +329,13 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e return fmt.Errorf("trie state root does not equal header state root") } - if err := StoreLatestStorageHash(s.db, root); err != nil { + if err := s.Base.StoreLatestStorageHash(root); err != nil { return err } logger.Info("importing storage trie...", "basepath", s.dbPath, "root", root) - if err := StoreTrie(storage.db, t); err != nil { + if err := t.Store(storage.db); err != nil { return err } @@ -342,7 +344,7 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e return err } - if err := StoreBestBlockHash(s.db, header.Hash()); err != nil { + if err := s.Base.StoreBestBlockHash(header.Hash()); err != nil { return err } diff --git a/dot/state/service_test.go b/dot/state/service_test.go index fff41739f6..72b4c94f7f 100644 --- a/dot/state/service_test.go +++ b/dot/state/service_test.go @@ -248,6 +248,8 @@ func TestService_Import(t *testing.T) { genData, genTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) err := serv.Initialise(genData, genesisHeader, genTrie) require.NoError(t, err) + err = serv.db.Close() + require.NoError(t, err) tr := trie.NewEmptyTrie() var testCases = []string{ diff --git a/dot/state/storage.go b/dot/state/storage.go index e00a2468b0..1aefb4f8ac 100644 --- a/dot/state/storage.go +++ b/dot/state/storage.go @@ -25,7 +25,6 @@ import ( "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/genesis" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/trie" ) @@ -45,9 +44,8 @@ type StorageState struct { blockState *BlockState tries map[common.Hash]*trie.Trie // map of root -> trie - baseDB chaindb.Database - db chaindb.Database - lock sync.RWMutex + db chaindb.Database + lock sync.RWMutex // change notifiers changedLock sync.RWMutex @@ -72,7 +70,6 @@ func NewStorageState(db chaindb.Database, blockState *BlockState, t *trie.Trie) return &StorageState{ blockState: blockState, tries: tries, - baseDB: db, db: chaindb.NewTable(db, storagePrefix), observerList: []Observer{}, }, nil @@ -162,7 +159,7 @@ func (s *StorageState) TrieState(root *common.Hash) (*rtstorage.TrieState, error // LoadFromDB loads an encoded trie from the DB where the key is `root` func (s *StorageState) LoadFromDB(root common.Hash) (*trie.Trie, error) { t := trie.NewEmptyTrie() - err := LoadTrie(s.db, t, root) + err := t.Load(s.db, root) if err != nil { return nil, err } @@ -385,8 +382,3 @@ func (s *StorageState) pruneStorage(closeCh chan interface{}) { } } } - -// GetGenesisData retrieves current genesis data from database -func (s *StorageState) GetGenesisData() (*genesis.Data, error) { - return LoadGenesisData(s.baseDB) -} diff --git a/lib/scale/encode.go b/lib/scale/encode.go index fd54ef0332..bdfc91046a 100644 --- a/lib/scale/encode.go +++ b/lib/scale/encode.go @@ -108,6 +108,7 @@ func (se *Encoder) EncodeCustom(in interface{}) (int, error) { if len(res) == 0 { return 0, fmt.Errorf("method Encode does not have any return values") } + val := res[0].Interface() if len(res) < 2 { return se.Writer.Write(val.([]byte))