dummy app now uses iavl
This commit is contained in:
parent
5231003bfc
commit
9aff9f94dd
|
@ -4,19 +4,20 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/merkleeyes/iavl"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/iavl"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
type DummyApplication struct {
|
||||
types.BaseApplication
|
||||
|
||||
state merkle.Tree
|
||||
state *iavl.VersionedTree
|
||||
}
|
||||
|
||||
func NewDummyApplication() *DummyApplication {
|
||||
state := iavl.NewIAVLTree(0, nil)
|
||||
state := iavl.NewVersionedTree(0, dbm.NewMemDB())
|
||||
return &DummyApplication{state: state}
|
||||
}
|
||||
|
||||
|
@ -46,22 +47,26 @@ func (app *DummyApplication) Commit() types.Result {
|
|||
|
||||
func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
|
||||
if reqQuery.Prove {
|
||||
value, proof, exists := app.state.Proof(reqQuery.Data)
|
||||
value, proof, err := app.state.GetWithProof(reqQuery.Data)
|
||||
// be stupid here
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resQuery.Index = -1 // TODO make Proof return index
|
||||
resQuery.Key = reqQuery.Data
|
||||
resQuery.Value = value
|
||||
resQuery.Proof = proof
|
||||
if exists {
|
||||
resQuery.Proof = wire.BinaryBytes(proof)
|
||||
if value == nil {
|
||||
resQuery.Log = "exists"
|
||||
} else {
|
||||
resQuery.Log = "does not exist"
|
||||
}
|
||||
return
|
||||
} else {
|
||||
index, value, exists := app.state.Get(reqQuery.Data)
|
||||
index, value := app.state.Get(reqQuery.Data)
|
||||
resQuery.Index = int64(index)
|
||||
resQuery.Value = value
|
||||
if exists {
|
||||
if value != nil {
|
||||
resQuery.Log = "exists"
|
||||
} else {
|
||||
resQuery.Log = "does not exist"
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/merkleeyes/iavl"
|
||||
"github.com/tendermint/iavl"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
)
|
||||
|
@ -39,9 +39,10 @@ func testDummy(t *testing.T, app types.Application, tx []byte, key, value string
|
|||
})
|
||||
require.Equal(t, types.CodeType_OK, resQuery.Code)
|
||||
require.Equal(t, value, string(resQuery.Value))
|
||||
proof, err := iavl.ReadProof(resQuery.Proof)
|
||||
proof, err := iavl.ReadKeyExistsProof(resQuery.Proof)
|
||||
require.Nil(t, err)
|
||||
require.True(t, proof.Verify([]byte(key), resQuery.Value, proof.RootHash)) // NOTE: we have no way to verify the RootHash
|
||||
err = proof.Verify([]byte(key), resQuery.Value, proof.RootHash)
|
||||
require.Nil(t, err, "%+v", err) // NOTE: we have no way to verify the RootHash
|
||||
}
|
||||
|
||||
func TestDummyKV(t *testing.T) {
|
||||
|
@ -309,7 +310,8 @@ func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string)
|
|||
require.Nil(t, err)
|
||||
require.Equal(t, types.CodeType_OK, resQuery.Code)
|
||||
require.Equal(t, value, string(resQuery.Value))
|
||||
proof, err := iavl.ReadProof(resQuery.Proof)
|
||||
proof, err := iavl.ReadKeyExistsProof(resQuery.Proof)
|
||||
require.Nil(t, err)
|
||||
require.True(t, proof.Verify([]byte(key), resQuery.Value, proof.RootHash)) // NOTE: we have no way to verify the RootHash
|
||||
err = proof.Verify([]byte(key), resQuery.Value, proof.RootHash)
|
||||
require.Nil(t, err, "%+v", err) // NOTE: we have no way to verify the RootHash
|
||||
}
|
||||
|
|
|
@ -3,13 +3,12 @@ package dummy
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tendermint/abci/types"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/merkleeyes/iavl"
|
||||
"github.com/tendermint/iavl"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
@ -23,11 +22,11 @@ const (
|
|||
|
||||
type PersistentDummyApplication struct {
|
||||
app *DummyApplication
|
||||
db dbm.DB
|
||||
|
||||
// latest received
|
||||
// TODO: move to merkle tree?
|
||||
blockHeader *types.Header
|
||||
height uint64
|
||||
|
||||
// validator set
|
||||
changes []*types.Validator
|
||||
|
@ -36,17 +35,22 @@ type PersistentDummyApplication struct {
|
|||
}
|
||||
|
||||
func NewPersistentDummyApplication(dbDir string) *PersistentDummyApplication {
|
||||
db := dbm.NewDB("dummy", "leveldb", dbDir)
|
||||
lastBlock := LoadLastBlock(db)
|
||||
name := "dummy"
|
||||
dbPath := path.Join(dbDir, name+".db")
|
||||
empty, _ := cmn.IsDirEmpty(dbPath)
|
||||
|
||||
stateTree := iavl.NewIAVLTree(0, db)
|
||||
stateTree.Load(lastBlock.AppHash)
|
||||
db, err := dbm.NewGoLevelDB(name, dbDir)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// log.Notice("Loaded state", "block", lastBlock.Height, "root", stateTree.Hash())
|
||||
stateTree := iavl.NewVersionedTree(500, db)
|
||||
if !empty {
|
||||
stateTree.Load()
|
||||
}
|
||||
|
||||
return &PersistentDummyApplication{
|
||||
app: &DummyApplication{state: stateTree},
|
||||
db: db,
|
||||
logger: log.NewNopLogger(),
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +61,8 @@ func (app *PersistentDummyApplication) SetLogger(l log.Logger) {
|
|||
|
||||
func (app *PersistentDummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
|
||||
resInfo = app.app.Info(req)
|
||||
lastBlock := LoadLastBlock(app.db)
|
||||
resInfo.LastBlockHeight = lastBlock.Height
|
||||
resInfo.LastBlockAppHash = lastBlock.AppHash
|
||||
resInfo.LastBlockHeight = app.height
|
||||
resInfo.LastBlockAppHash = app.app.state.Hash()
|
||||
return resInfo
|
||||
}
|
||||
|
||||
|
@ -86,18 +89,26 @@ func (app *PersistentDummyApplication) CheckTx(tx []byte) types.Result {
|
|||
}
|
||||
|
||||
func (app *PersistentDummyApplication) Commit() types.Result {
|
||||
// Save
|
||||
appHash := app.app.state.Save()
|
||||
app.logger.Info("Saved state", "root", appHash)
|
||||
app.height = app.blockHeader.Height
|
||||
|
||||
// Save a new version
|
||||
var appHash []byte
|
||||
var err error
|
||||
if app.app.state.Size() > 0 {
|
||||
appHash, err = app.app.state.SaveVersion(app.height)
|
||||
if err != nil {
|
||||
// if this wasn't a dummy app, we'd do something smarter
|
||||
panic(err)
|
||||
}
|
||||
app.logger.Info("Saved state", "root", appHash)
|
||||
}
|
||||
|
||||
lastBlock := LastBlockInfo{
|
||||
Height: app.blockHeader.Height,
|
||||
Height: app.height,
|
||||
AppHash: appHash, // this hash will be in the next block header
|
||||
}
|
||||
|
||||
app.logger.Info("Saving block", "height", lastBlock.Height, "root", lastBlock.AppHash)
|
||||
SaveLastBlock(app.db, lastBlock)
|
||||
|
||||
return types.NewResultOK(appHash, "")
|
||||
}
|
||||
|
||||
|
@ -139,31 +150,6 @@ type LastBlockInfo struct {
|
|||
AppHash []byte
|
||||
}
|
||||
|
||||
// Get the last block from the db
|
||||
func LoadLastBlock(db dbm.DB) (lastBlock LastBlockInfo) {
|
||||
buf := db.Get(lastBlockKey)
|
||||
if len(buf) != 0 {
|
||||
r, n, err := bytes.NewReader(buf), new(int), new(error)
|
||||
wire.ReadBinaryPtr(&lastBlock, r, 0, n, err)
|
||||
if *err != nil {
|
||||
cmn.PanicCrisis(errors.Wrap(*err, "cannot load last block (data has been corrupted or its spec has changed)"))
|
||||
}
|
||||
// TODO: ensure that buf is completely read.
|
||||
}
|
||||
|
||||
return lastBlock
|
||||
}
|
||||
|
||||
func SaveLastBlock(db dbm.DB, lastBlock LastBlockInfo) {
|
||||
buf, n, err := new(bytes.Buffer), new(int), new(error)
|
||||
wire.WriteBinary(lastBlock, buf, n, err)
|
||||
if *err != nil {
|
||||
// TODO
|
||||
cmn.PanicCrisis(errors.Wrap(*err, "cannot save last block"))
|
||||
}
|
||||
db.Set(lastBlockKey, buf.Bytes())
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// update validators
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
hash: f9c2ddad16bf8652076a93bd9f398bb498eefb2f5bd2c89a77d966ebd12feec8
|
||||
updated: 2017-09-22T10:34:17.228026799-04:00
|
||||
hash: 876bc65024f66612325ebafcedeb3e4d5014d46b339cf7583f1c00c6bac6e32c
|
||||
updated: 2017-10-18T11:59:44.724549502+02:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btcd
|
||||
version: b8df516b4b267acf2de46be593a9d948d1d2c420
|
||||
|
@ -57,17 +57,15 @@ imports:
|
|||
- edwards25519
|
||||
- extra25519
|
||||
- name: github.com/tendermint/go-crypto
|
||||
version: e6ea9499ff958479e4a921850d2382eb599f204c
|
||||
version: 8e7f0e7701f92206679ad093d013b9b162427631
|
||||
- name: github.com/tendermint/go-wire
|
||||
version: 5f88da3dbc1a72844e6dfaf274ce87f851d488eb
|
||||
version: 26ee079df7fca1958da8995c727b59759b197534
|
||||
subpackages:
|
||||
- data
|
||||
- name: github.com/tendermint/merkleeyes
|
||||
version: 2f6e5d31e7a35045d8d0a5895cb1fec33dd4d32b
|
||||
subpackages:
|
||||
- iavl
|
||||
- name: github.com/tendermint/iavl
|
||||
version: ff4ffa531df48509d51f0c16c2432f986eed9fcc
|
||||
- name: github.com/tendermint/tmlibs
|
||||
version: bffe6744ec277d60f707ab442e25513617842f8e
|
||||
version: 8e5266a9ef2527e68a1571f932db8228a331b556
|
||||
subpackages:
|
||||
- common
|
||||
- db
|
||||
|
|
|
@ -8,10 +8,8 @@ import:
|
|||
version: develop
|
||||
- package: github.com/tendermint/go-wire
|
||||
version: develop
|
||||
- package: github.com/tendermint/merkleeyes
|
||||
- package: github.com/tendermint/iavl
|
||||
version: develop
|
||||
subpackages:
|
||||
- iavl
|
||||
- package: github.com/tendermint/tmlibs
|
||||
version: develop
|
||||
subpackages:
|
||||
|
|
Loading…
Reference in New Issue