Skip to content

Commit

Permalink
Revert "Reduce candidate list storage consumption in DB by storing th…
Browse files Browse the repository at this point in the history
…e list's hash"

This reverts commit e9fb2a2e803bb2563ed9519e86159a5a6f694f6b.
  • Loading branch information
Zhijie Shen authored and zjshen14 committed Aug 29, 2018
1 parent 7e19f58 commit bf59d91
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 49 deletions.
65 changes: 23 additions & 42 deletions state/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ func DefaultTrieOption() FactoryOption {
return func(sf *factory, cfg *config.Config) error {
dbPath := cfg.Chain.TrieDBPath
if len(dbPath) == 0 {
return errors.New("Invalid empty trie DB path")
return errors.New("Invalid empty trie db path")
}
trieDB := db.NewBoltDB(dbPath, nil)
if err := trieDB.Start(context.Background()); err != nil {
return errors.Wrap(err, "failed to start trie DB")
return errors.Wrap(err, "failed to start trie db")
}
// create account trie
accountTrieRoot, err := sf.getRoot(trieDB, trie.AccountKVNameSpace, AccountTrieRootKey)
if err != nil {
return errors.Wrap(err, "failed to get accountTrie's root hash from DB")
return errors.Wrap(err, "failed to get accountTrie's root hash from underlying db")
}
tr, err := trie.NewTrie(trieDB, trie.AccountKVNameSpace, accountTrieRoot)
if err != nil {
Expand All @@ -129,12 +129,12 @@ func InMemTrieOption() FactoryOption {
return func(sf *factory, cfg *config.Config) error {
trieDB := db.NewMemKVStore()
if err := trieDB.Start(context.Background()); err != nil {
return errors.Wrap(err, "failed to start trie DB")
return errors.Wrap(err, "failed to start trie db")
}
// create account trie
accountTrieRoot, err := sf.getRoot(trieDB, trie.AccountKVNameSpace, AccountTrieRootKey)
if err != nil {
return errors.Wrap(err, "failed to get accountTrie's root hash from DB")
return errors.Wrap(err, "failed to get accountTrie's root hash from underlying db")
}
tr, err := trie.NewTrie(trieDB, trie.AccountKVNameSpace, accountTrieRoot)
if err != nil {
Expand Down Expand Up @@ -256,7 +256,7 @@ func (sf *factory) RootHash() hash.Hash32B {
func (sf *factory) Height() (uint64, error) {
height, err := sf.accountTrie.TrieDB().Get(trie.AccountKVNameSpace, []byte(CurrentHeightKey))
if err != nil {
return 0, errors.Wrap(err, "failed to get factory's height from DB")
return 0, errors.Wrap(err, "failed to get factory's height from underlying db")
}
return byteutil.BytesToUint64(height), nil
}
Expand Down Expand Up @@ -337,15 +337,24 @@ func (sf *factory) CommitStateChanges(blockHeight uint64, tsf []*action.Transfer
// Persist accountTrie's root hash
accountRootHash := sf.RootHash()
if err := trieDB.Put(trie.AccountKVNameSpace, []byte(AccountTrieRootKey), accountRootHash[:]); err != nil {
return errors.Wrap(err, "failed to update accountTrie's root hash in DB")
return errors.Wrap(err, "failed to update accountTrie's root hash in underlying db")
}

// Persist new list of candidates to DB
if err := sf.putCandidates(blockHeight); err != nil {
return err
// Persist new list of candidates to underlying db
candidates, err := MapToCandidates(sf.cachedCandidates)
if err != nil {
return errors.Wrap(err, "failed to convert map of cached candidates to candidate list")
}
sort.Sort(candidates)
candidatesBytes, err := Serialize(candidates)
if err != nil {
return errors.Wrap(err, "failed to serialize candidates")
}
if err := trieDB.Put(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(blockHeight), candidatesBytes); err != nil {
return errors.Wrapf(err, "failed to store candidates on height %d into underlying db", blockHeight)
}

// Set current chain height and persist it to DB
// Set current chain height and persist it to db
sf.currentChainHeight = blockHeight
return trieDB.Put(trie.AccountKVNameSpace, []byte(CurrentHeightKey), byteutil.Uint64ToBytes(blockHeight))
}
Expand Down Expand Up @@ -432,7 +441,7 @@ func (sf *factory) Candidates() (uint64, []*Candidate) {

// CandidatesByHeight returns array of candidates in candidate pool of a given height
func (sf *factory) CandidatesByHeight(height uint64) ([]*Candidate, error) {
// Load candidates on the given height from DB
// Load candidates on the given height from underlying db
candidates, err := sf.getCandidates(height)
if err != nil {
return []*Candidate{}, errors.Wrapf(err, "failed to get candidates on height %d", height)
Expand Down Expand Up @@ -521,41 +530,13 @@ func (sf *factory) updateCandidate(pkHash hash.AddrHash, totalWeight *big.Int, b
}

func (sf *factory) getCandidates(height uint64) (CandidateList, error) {
trieDB := sf.accountTrie.TrieDB()
candHash, err := trieDB.Get(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(height))
if err != nil {
return []*Candidate{}, errors.Wrapf(err, "failed to get candidates hash on height %d", height)
}
candidatesBytes, err := trieDB.Get(trie.CandidateKVNameSpace, candHash[:])
candidatesBytes, err := sf.accountTrie.TrieDB().Get(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(height))
if err != nil {
return []*Candidate{}, errors.Wrapf(err, "failed to get candidates on height %d", height)
}
return Deserialize(candidatesBytes)
}

func (sf *factory) putCandidates(height uint64) error {
candidates, err := MapToCandidates(sf.cachedCandidates)
if err != nil {
return errors.Wrap(err, "failed to convert map of cached candidates to candidate list")
}
sort.Sort(candidates)
candidatesBytes, err := Serialize(candidates)
if err != nil {
return errors.Wrap(err, "failed to serialize candidates")
}
trieDB := sf.accountTrie.TrieDB()
h := hash.Hash160b(candidatesBytes)
if err := trieDB.Put(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(height), h[:]); err != nil {
return errors.Wrapf(err, "failed to put candidates hash on height %d", height)
}
if _, err := trieDB.Get(trie.CandidateKVNameSpace, h[:]); err == nil {
// candidate list already exist
return err
}
// store new candidate list into DB
return trieDB.Put(trie.CandidateKVNameSpace, h[:], candidatesBytes)
}

//======================================
// private transfer/vote functions
//======================================
Expand Down Expand Up @@ -685,7 +666,7 @@ func (sf *factory) getRoot(trieDB db.KVStore, nameSpace string, key string) (has
case bolt.ErrBucketNotFound:
trieRoot = trie.EmptyRoot
default:
return hash.ZeroHash32B, errors.Wrap(err, "failed to get trie's root hash from DB")
return hash.ZeroHash32B, errors.Wrap(err, "failed to get trie's root hash from underlying db")
}
return trieRoot, nil
}
9 changes: 2 additions & 7 deletions state/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,7 @@ func TestCandidatesByHeight(t *testing.T) {
candidatesBytes, err := Serialize(candidateList)
require.NoError(t, err)

trieDB := sf.accountTrie.TrieDB()
h := hash.Hash160b(candidatesBytes)
require.Nil(t, trieDB.Put(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(0), h[:]))
require.Nil(t, trieDB.Put(trie.CandidateKVNameSpace, h[:], candidatesBytes))
sf.accountTrie.TrieDB().Put(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(0), candidatesBytes)
candidates, err := sf.CandidatesByHeight(0)
sort.Slice(candidates, func(i, j int) bool {
return strings.Compare(candidates[i].Address, candidates[j].Address) < 0
Expand All @@ -538,9 +535,7 @@ func TestCandidatesByHeight(t *testing.T) {
candidatesBytes, err = Serialize(candidateList)
require.NoError(t, err)

h = hash.Hash160b(candidatesBytes)
require.Nil(t, trieDB.Put(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(1), h[:]))
require.Nil(t, trieDB.Put(trie.CandidateKVNameSpace, h[:], candidatesBytes))
sf.accountTrie.TrieDB().Put(trie.CandidateKVNameSpace, byteutil.Uint64ToBytes(1), candidatesBytes)
candidates, err = sf.CandidatesByHeight(1)
sort.Slice(candidates, func(i, j int) bool {
return strings.Compare(candidates[i].Address, candidates[j].Address) < 0
Expand Down

0 comments on commit bf59d91

Please sign in to comment.