cosmos-sdk/state/merkle.go

82 lines
1.8 KiB
Go

package state
import "github.com/tendermint/merkleeyes/iavl"
// State represents the app states, separating the commited state (for queries)
// from the working state (for CheckTx and AppendTx)
type State struct {
committed *Bonsai
deliverTx SimpleDB
checkTx SimpleDB
persistent bool
}
func NewState(tree *iavl.IAVLTree, persistent bool) State {
base := NewBonsai(tree)
return State{
committed: base,
deliverTx: base.Checkpoint(),
checkTx: base.Checkpoint(),
persistent: persistent,
}
}
func (s State) Size() int {
return s.committed.Tree.Size()
}
func (s State) Committed() *Bonsai {
return s.committed
}
func (s State) Append() SimpleDB {
return s.deliverTx
}
func (s State) Check() SimpleDB {
return s.checkTx
}
// Hash applies deliverTx to committed and calculates hash
//
// Note the usage:
// Hash -> gets the calculated hash but doesn't save
// BatchSet -> adds some out-of-bounds data
// Commit -> Save everything to disk and the same hash
func (s *State) Hash() ([]byte, error) {
err := s.committed.Commit(s.deliverTx)
if err != nil {
return nil, err
}
s.deliverTx = s.committed.Checkpoint()
return s.committed.Tree.Hash(), nil
}
// BatchSet is used for some weird magic in storing the new height
func (s *State) BatchSet(key, value []byte) {
if s.persistent {
// This is in the batch with the Save, but not in the tree
s.committed.Tree.BatchSet(key, value)
}
}
// Commit save persistent nodes to the database and re-copies the trees
func (s *State) Commit() ([]byte, error) {
// commit (if we didn't do hash earlier)
err := s.committed.Commit(s.deliverTx)
if err != nil {
return nil, err
}
var hash []byte
if s.persistent {
hash = s.committed.Tree.Save()
} else {
hash = s.committed.Tree.Hash()
}
s.deliverTx = s.committed.Checkpoint()
s.checkTx = s.committed.Checkpoint()
return hash, nil
}