92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
package state
|
|
|
|
import "github.com/tendermint/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
|
|
historySize uint64
|
|
}
|
|
|
|
// NewState wraps a versioned tree and maintains all needed
|
|
// states for the abci app
|
|
func NewState(tree *iavl.VersionedTree, historySize uint64) *State {
|
|
base := NewBonsai(tree)
|
|
return &State{
|
|
committed: base,
|
|
deliverTx: base.Checkpoint(),
|
|
checkTx: base.Checkpoint(),
|
|
historySize: historySize,
|
|
}
|
|
}
|
|
|
|
// Size is the number of nodes in the last commit
|
|
func (s State) Size() int {
|
|
return s.committed.Tree.Size()
|
|
}
|
|
|
|
// IsEmpty is true is no data was ever in the tree
|
|
// (and signals it is unsafe to save)
|
|
func (s State) IsEmpty() bool {
|
|
return s.committed.Tree.IsEmpty()
|
|
}
|
|
|
|
// Committed gives us read-only access to the committed
|
|
// state(s), including historical queries
|
|
func (s State) Committed() *Bonsai {
|
|
return s.committed
|
|
}
|
|
|
|
// Append gives us read-write access to the current working
|
|
// state (to be committed at EndBlock)
|
|
func (s State) Append() SimpleDB {
|
|
return s.deliverTx
|
|
}
|
|
|
|
// Append gives us read-write access to the current scratch
|
|
// state (to be reset at EndBlock)
|
|
func (s State) Check() SimpleDB {
|
|
return s.checkTx
|
|
}
|
|
|
|
// LatestHeight is the last block height we have committed
|
|
func (s State) LatestHeight() uint64 {
|
|
return s.committed.Tree.LatestVersion()
|
|
}
|
|
|
|
// LatestHash is the root hash of the last state we have
|
|
// committed
|
|
func (s State) LatestHash() []byte {
|
|
return s.committed.Tree.Hash()
|
|
}
|
|
|
|
// Commit saves persistent nodes to the database and re-copies the trees
|
|
func (s *State) Commit(version uint64) ([]byte, error) {
|
|
// commit (if we didn't do hash earlier)
|
|
err := s.committed.Commit(s.deliverTx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// store a new version
|
|
var hash []byte
|
|
if !s.IsEmpty() {
|
|
hash, err = s.committed.Tree.SaveVersion(version)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// release an old version
|
|
if version > s.historySize {
|
|
s.committed.Tree.DeleteVersion(version - s.historySize)
|
|
}
|
|
|
|
s.deliverTx = s.committed.Checkpoint()
|
|
s.checkTx = s.committed.Checkpoint()
|
|
return hash, nil
|
|
}
|