diff --git a/app/store.go b/app/store.go index 87373d705..84092e5db 100644 --- a/app/store.go +++ b/app/store.go @@ -60,7 +60,7 @@ func NewStore(dbName string, cacheSize int, logger log.Logger) (*Store, error) { dbm.NewMemDB(), ) store := &Store{ - State: state.NewState(tree, false), + State: state.NewState(tree, true), height: initialHeight, logger: logger, } @@ -148,7 +148,7 @@ func (s *Store) Commit() abci.Result { Height: s.height, })) - hash, err := s.State.Commit() + hash, err := s.State.Commit(s.height) if err != nil { return abci.NewError(abci.CodeType_InternalError, err.Error()) } @@ -164,25 +164,25 @@ func (s *Store) Commit() abci.Result { // Query implements abci.Application func (s *Store) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { - - if reqQuery.Height != 0 { - // TODO: support older commits - resQuery.Code = abci.CodeType_InternalError - resQuery.Log = "merkleeyes only supports queries on latest commit" - return - } - // set the query response height to current - resQuery.Height = s.height - tree := s.State.Committed() + height := reqQuery.Height + if height == 0 { + if tree.Tree.VersionExists(s.height - 1) { + height = s.height - 1 + } else { + height = s.height + } + } + resQuery.Height = height + switch reqQuery.Path { case "/store", "/key": // Get by key key := reqQuery.Data // Data holds the key bytes resQuery.Key = key if reqQuery.Prove { - value, proof, err := tree.GetWithProof(key) + value, proof, err := tree.GetVersionedWithProof(key, height) if err != nil { resQuery.Log = err.Error() break diff --git a/state/bonsai.go b/state/bonsai.go index 973cd672d..b816c876f 100644 --- a/state/bonsai.go +++ b/state/bonsai.go @@ -54,6 +54,10 @@ func (b *Bonsai) GetWithProof(key []byte) ([]byte, iavl.KeyProof, error) { return b.Tree.GetWithProof(key) } +func (b *Bonsai) GetVersionedWithProof(key []byte, version uint64) ([]byte, iavl.KeyProof, error) { + return b.Tree.GetVersionedWithProof(key, version) +} + func (b *Bonsai) List(start, end []byte, limit int) []Model { res := []Model{} stopAtCount := func(key []byte, value []byte) (stop bool) { diff --git a/state/merkle.go b/state/merkle.go index d232a050d..2add7d2fd 100644 --- a/state/merkle.go +++ b/state/merkle.go @@ -61,7 +61,7 @@ func (s *State) BatchSet(key, value []byte) { } // Commit save persistent nodes to the database and re-copies the trees -func (s *State) Commit() ([]byte, error) { +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 { @@ -70,10 +70,11 @@ func (s *State) Commit() ([]byte, error) { var hash []byte if s.persistent { - nextVersion := s.committed.Tree.LatestVersion() + 1 - hash, err = s.committed.Tree.SaveVersion(nextVersion) - if err != nil { - return nil, err + if s.committed.Tree.Size() > 0 || s.committed.Tree.LatestVersion() > 0 { + hash, err = s.committed.Tree.SaveVersion(version) + if err != nil { + return nil, err + } } } else { hash = s.committed.Tree.Hash()