2018-02-19 20:34:51 +00:00
|
|
|
package kvstore
|
2016-11-21 23:42:42 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2018-08-10 00:25:57 -05:00
|
|
|
"fmt"
|
2016-11-21 23:42:42 -05:00
|
|
|
"io/ioutil"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
|
|
|
|
2017-01-10 18:12:20 +01:00
|
|
|
"github.com/stretchr/testify/require"
|
2017-11-30 15:37:31 -05:00
|
|
|
|
2018-07-01 22:36:49 -04:00
|
|
|
cmn "github.com/tendermint/tendermint/libs/common"
|
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
2017-11-30 15:37:31 -05:00
|
|
|
|
2018-06-22 06:59:02 +02:00
|
|
|
abcicli "github.com/tendermint/tendermint/abci/client"
|
|
|
|
"github.com/tendermint/tendermint/abci/example/code"
|
|
|
|
abciserver "github.com/tendermint/tendermint/abci/server"
|
|
|
|
"github.com/tendermint/tendermint/abci/types"
|
2016-11-21 23:42:42 -05:00
|
|
|
)
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) {
|
2019-06-21 01:56:27 -04:00
|
|
|
req := types.RequestDeliverTx{Tx: tx}
|
|
|
|
ar := app.DeliverTx(req)
|
2017-01-10 18:12:20 +01:00
|
|
|
require.False(t, ar.IsErr(), ar)
|
|
|
|
// repeating tx doesn't raise error
|
2019-06-21 01:56:27 -04:00
|
|
|
ar = app.DeliverTx(req)
|
2017-01-10 18:12:20 +01:00
|
|
|
require.False(t, ar.IsErr(), ar)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2017-01-10 18:12:20 +01:00
|
|
|
// make sure query is fine
|
2018-05-31 21:45:14 -04:00
|
|
|
resQuery := app.Query(types.RequestQuery{
|
2017-01-23 23:42:09 -08:00
|
|
|
Path: "/store",
|
|
|
|
Data: []byte(key),
|
|
|
|
})
|
2017-11-30 15:37:31 -05:00
|
|
|
require.Equal(t, code.CodeTypeOK, resQuery.Code)
|
2017-01-23 23:42:09 -08:00
|
|
|
require.Equal(t, value, string(resQuery.Value))
|
2017-01-10 17:06:51 +01:00
|
|
|
|
2017-01-10 18:12:20 +01:00
|
|
|
// make sure proof is fine
|
2018-05-31 21:45:14 -04:00
|
|
|
resQuery = app.Query(types.RequestQuery{
|
2017-01-23 23:42:09 -08:00
|
|
|
Path: "/store",
|
|
|
|
Data: []byte(key),
|
|
|
|
Prove: true,
|
|
|
|
})
|
2017-11-30 15:37:31 -05:00
|
|
|
require.EqualValues(t, code.CodeTypeOK, resQuery.Code)
|
2017-01-23 23:42:09 -08:00
|
|
|
require.Equal(t, value, string(resQuery.Value))
|
2016-11-21 23:42:42 -05:00
|
|
|
}
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
func TestKVStoreKV(t *testing.T) {
|
|
|
|
kvstore := NewKVStoreApplication()
|
2016-11-21 23:42:42 -05:00
|
|
|
key := "abc"
|
|
|
|
value := key
|
|
|
|
tx := []byte(key)
|
2018-02-19 20:34:51 +00:00
|
|
|
testKVStore(t, kvstore, tx, key, value)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
|
|
|
value = "def"
|
|
|
|
tx = []byte(key + "=" + value)
|
2018-02-19 20:34:51 +00:00
|
|
|
testKVStore(t, kvstore, tx, key, value)
|
2016-11-21 23:42:42 -05:00
|
|
|
}
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
func TestPersistentKVStoreKV(t *testing.T) {
|
|
|
|
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
|
2016-11-21 23:42:42 -05:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore := NewPersistentKVStoreApplication(dir)
|
2016-11-21 23:42:42 -05:00
|
|
|
key := "abc"
|
|
|
|
value := key
|
|
|
|
tx := []byte(key)
|
2018-02-19 20:34:51 +00:00
|
|
|
testKVStore(t, kvstore, tx, key, value)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
|
|
|
value = "def"
|
|
|
|
tx = []byte(key + "=" + value)
|
2018-02-19 20:34:51 +00:00
|
|
|
testKVStore(t, kvstore, tx, key, value)
|
2016-11-21 23:42:42 -05:00
|
|
|
}
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
func TestPersistentKVStoreInfo(t *testing.T) {
|
|
|
|
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
|
2016-11-21 23:42:42 -05:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore := NewPersistentKVStoreApplication(dir)
|
|
|
|
InitKVStore(kvstore)
|
2017-12-01 00:41:07 -05:00
|
|
|
height := int64(0)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2018-05-31 21:45:14 -04:00
|
|
|
resInfo := kvstore.Info(types.RequestInfo{})
|
2016-12-26 17:44:36 -08:00
|
|
|
if resInfo.LastBlockHeight != height {
|
|
|
|
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
|
2016-11-21 23:42:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// make and apply block
|
2017-12-01 00:41:07 -05:00
|
|
|
height = int64(1)
|
2016-11-21 23:42:42 -05:00
|
|
|
hash := []byte("foo")
|
2017-12-22 19:41:19 -08:00
|
|
|
header := types.Header{
|
2017-12-01 00:41:07 -05:00
|
|
|
Height: int64(height),
|
2016-11-21 23:42:42 -05:00
|
|
|
}
|
2018-07-27 06:23:19 +04:00
|
|
|
kvstore.BeginBlock(types.RequestBeginBlock{Hash: hash, Header: header})
|
|
|
|
kvstore.EndBlock(types.RequestEndBlock{Height: header.Height})
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore.Commit()
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2018-05-31 21:45:14 -04:00
|
|
|
resInfo = kvstore.Info(types.RequestInfo{})
|
2016-12-26 17:44:36 -08:00
|
|
|
if resInfo.LastBlockHeight != height {
|
|
|
|
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
|
2016-11-21 23:42:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// add a validator, remove a validator, update a validator
|
2017-12-20 00:02:41 -08:00
|
|
|
func TestValUpdates(t *testing.T) {
|
2018-02-19 20:34:51 +00:00
|
|
|
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
|
2016-11-21 23:42:42 -05:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore := NewPersistentKVStoreApplication(dir)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
|
|
|
// init with some validators
|
|
|
|
total := 10
|
|
|
|
nInit := 5
|
2017-10-23 14:20:15 +02:00
|
|
|
vals := RandVals(total)
|
2016-11-21 23:42:42 -05:00
|
|
|
// iniitalize with the first nInit
|
2018-05-31 21:45:14 -04:00
|
|
|
kvstore.InitChain(types.RequestInitChain{
|
2018-02-16 19:49:33 -05:00
|
|
|
Validators: vals[:nInit],
|
|
|
|
})
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
vals1, vals2 := vals[:nInit], kvstore.Validators()
|
2016-11-21 23:42:42 -05:00
|
|
|
valsEqual(t, vals1, vals2)
|
|
|
|
|
2018-08-06 00:18:24 -04:00
|
|
|
var v1, v2, v3 types.ValidatorUpdate
|
2016-11-21 23:42:42 -05:00
|
|
|
|
|
|
|
// add some validators
|
|
|
|
v1, v2 = vals[nInit], vals[nInit+1]
|
2018-08-06 00:18:24 -04:00
|
|
|
diff := []types.ValidatorUpdate{v1, v2}
|
2016-11-21 23:42:42 -05:00
|
|
|
tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
|
|
|
|
tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
makeApplyBlock(t, kvstore, 1, diff, tx1, tx2)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
vals1, vals2 = vals[:nInit+2], kvstore.Validators()
|
2016-11-21 23:42:42 -05:00
|
|
|
valsEqual(t, vals1, vals2)
|
|
|
|
|
|
|
|
// remove some validators
|
|
|
|
v1, v2, v3 = vals[nInit-2], vals[nInit-1], vals[nInit]
|
|
|
|
v1.Power = 0
|
|
|
|
v2.Power = 0
|
|
|
|
v3.Power = 0
|
2018-08-06 00:18:24 -04:00
|
|
|
diff = []types.ValidatorUpdate{v1, v2, v3}
|
2016-11-21 23:42:42 -05:00
|
|
|
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
|
|
|
|
tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
|
|
|
|
tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2019-08-02 08:53:52 +02:00
|
|
|
vals1 = append(vals[:nInit-2], vals[nInit+1]) // nolint: gocritic
|
2018-02-19 20:34:51 +00:00
|
|
|
vals2 = kvstore.Validators()
|
2016-11-21 23:42:42 -05:00
|
|
|
valsEqual(t, vals1, vals2)
|
|
|
|
|
|
|
|
// update some validators
|
|
|
|
v1 = vals[0]
|
|
|
|
if v1.Power == 5 {
|
|
|
|
v1.Power = 6
|
|
|
|
} else {
|
|
|
|
v1.Power = 5
|
|
|
|
}
|
2018-08-06 00:18:24 -04:00
|
|
|
diff = []types.ValidatorUpdate{v1}
|
2016-11-21 23:42:42 -05:00
|
|
|
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
|
|
|
|
|
2018-02-19 20:34:51 +00:00
|
|
|
makeApplyBlock(t, kvstore, 3, diff, tx1)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2018-08-06 00:18:24 -04:00
|
|
|
vals1 = append([]types.ValidatorUpdate{v1}, vals1[1:]...)
|
2018-02-19 20:34:51 +00:00
|
|
|
vals2 = kvstore.Validators()
|
2016-11-21 23:42:42 -05:00
|
|
|
valsEqual(t, vals1, vals2)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-08-06 00:18:24 -04:00
|
|
|
func makeApplyBlock(t *testing.T, kvstore types.Application, heightInt int, diff []types.ValidatorUpdate, txs ...[]byte) {
|
2016-11-21 23:42:42 -05:00
|
|
|
// make and apply block
|
2017-12-01 00:41:07 -05:00
|
|
|
height := int64(heightInt)
|
2016-11-21 23:42:42 -05:00
|
|
|
hash := []byte("foo")
|
2017-12-22 19:41:19 -08:00
|
|
|
header := types.Header{
|
2016-11-21 23:42:42 -05:00
|
|
|
Height: height,
|
|
|
|
}
|
|
|
|
|
2018-07-27 06:23:19 +04:00
|
|
|
kvstore.BeginBlock(types.RequestBeginBlock{Hash: hash, Header: header})
|
2016-11-21 23:42:42 -05:00
|
|
|
for _, tx := range txs {
|
2019-06-21 01:56:27 -04:00
|
|
|
if r := kvstore.DeliverTx(types.RequestDeliverTx{Tx: tx}); r.IsErr() {
|
2016-11-21 23:42:42 -05:00
|
|
|
t.Fatal(r)
|
|
|
|
}
|
|
|
|
}
|
2018-07-27 06:23:19 +04:00
|
|
|
resEndBlock := kvstore.EndBlock(types.RequestEndBlock{Height: header.Height})
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore.Commit()
|
2016-11-21 23:42:42 -05:00
|
|
|
|
2017-12-20 00:02:41 -08:00
|
|
|
valsEqual(t, diff, resEndBlock.ValidatorUpdates)
|
2016-11-21 23:42:42 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// order doesn't matter
|
2018-08-06 00:18:24 -04:00
|
|
|
func valsEqual(t *testing.T, vals1, vals2 []types.ValidatorUpdate) {
|
2016-11-21 23:42:42 -05:00
|
|
|
if len(vals1) != len(vals2) {
|
|
|
|
t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
|
|
|
|
}
|
2018-08-06 00:18:24 -04:00
|
|
|
sort.Sort(types.ValidatorUpdates(vals1))
|
|
|
|
sort.Sort(types.ValidatorUpdates(vals2))
|
2016-11-21 23:42:42 -05:00
|
|
|
for i, v1 := range vals1 {
|
|
|
|
v2 := vals2[i]
|
2018-05-23 22:20:35 -04:00
|
|
|
if !bytes.Equal(v1.PubKey.Data, v2.PubKey.Data) ||
|
2016-11-21 23:42:42 -05:00
|
|
|
v1.Power != v2.Power {
|
|
|
|
t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-10 18:12:20 +01:00
|
|
|
|
2017-01-27 22:27:32 -08:00
|
|
|
func makeSocketClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
|
2017-01-10 18:12:20 +01:00
|
|
|
// Start the listener
|
2018-08-10 00:25:57 -05:00
|
|
|
socket := fmt.Sprintf("unix://%s.sock", name)
|
2017-05-04 22:43:54 +04:00
|
|
|
logger := log.TestingLogger()
|
2017-04-28 00:37:18 +04:00
|
|
|
|
2017-11-08 17:29:15 -05:00
|
|
|
server := abciserver.NewSocketServer(socket, app)
|
2017-05-15 12:51:24 -04:00
|
|
|
server.SetLogger(logger.With("module", "abci-server"))
|
2018-01-05 22:19:37 -05:00
|
|
|
if err := server.Start(); err != nil {
|
2017-01-10 18:12:20 +01:00
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Connect to the socket
|
2017-05-15 11:29:34 -04:00
|
|
|
client := abcicli.NewSocketClient(socket, false)
|
2017-05-15 12:51:24 -04:00
|
|
|
client.SetLogger(logger.With("module", "abci-client"))
|
2018-01-05 22:19:37 -05:00
|
|
|
if err := client.Start(); err != nil {
|
2017-01-10 18:12:20 +01:00
|
|
|
server.Stop()
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
2017-05-15 12:51:24 -04:00
|
|
|
return client, server, nil
|
2017-01-10 18:12:20 +01:00
|
|
|
}
|
|
|
|
|
2017-01-27 22:27:32 -08:00
|
|
|
func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
|
2017-01-10 18:12:20 +01:00
|
|
|
// Start the listener
|
2018-08-10 00:25:57 -05:00
|
|
|
socket := fmt.Sprintf("unix://%s.sock", name)
|
2017-05-04 22:43:54 +04:00
|
|
|
logger := log.TestingLogger()
|
2017-01-10 18:12:20 +01:00
|
|
|
|
|
|
|
gapp := types.NewGRPCApplication(app)
|
2017-11-08 17:29:15 -05:00
|
|
|
server := abciserver.NewGRPCServer(socket, gapp)
|
2017-05-15 12:51:24 -04:00
|
|
|
server.SetLogger(logger.With("module", "abci-server"))
|
2018-01-05 22:19:37 -05:00
|
|
|
if err := server.Start(); err != nil {
|
2017-01-10 18:12:20 +01:00
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
2017-05-15 11:29:34 -04:00
|
|
|
client := abcicli.NewGRPCClient(socket, true)
|
2017-05-15 12:51:24 -04:00
|
|
|
client.SetLogger(logger.With("module", "abci-client"))
|
2018-01-05 22:19:37 -05:00
|
|
|
if err := client.Start(); err != nil {
|
2017-01-10 18:12:20 +01:00
|
|
|
server.Stop()
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2017-05-15 12:51:24 -04:00
|
|
|
return client, server, nil
|
2017-01-10 18:12:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestClientServer(t *testing.T) {
|
|
|
|
// set up socket app
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore := NewKVStoreApplication()
|
|
|
|
client, server, err := makeSocketClientServer(kvstore, "kvstore-socket")
|
2017-01-10 18:12:20 +01:00
|
|
|
require.Nil(t, err)
|
|
|
|
defer server.Stop()
|
|
|
|
defer client.Stop()
|
|
|
|
|
|
|
|
runClientTests(t, client)
|
|
|
|
|
|
|
|
// set up grpc app
|
2018-02-19 20:34:51 +00:00
|
|
|
kvstore = NewKVStoreApplication()
|
|
|
|
gclient, gserver, err := makeGRPCClientServer(kvstore, "kvstore-grpc")
|
2017-01-10 18:12:20 +01:00
|
|
|
require.Nil(t, err)
|
|
|
|
defer gserver.Stop()
|
|
|
|
defer gclient.Stop()
|
|
|
|
|
|
|
|
runClientTests(t, gclient)
|
|
|
|
}
|
|
|
|
|
|
|
|
func runClientTests(t *testing.T, client abcicli.Client) {
|
|
|
|
// run some tests....
|
|
|
|
key := "abc"
|
|
|
|
value := key
|
|
|
|
tx := []byte(key)
|
|
|
|
testClient(t, client, tx, key, value)
|
|
|
|
|
|
|
|
value = "def"
|
|
|
|
tx = []byte(key + "=" + value)
|
|
|
|
testClient(t, client, tx, key, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) {
|
abci: Refactor CheckTx to notify of recheck (#3744)
As per #2127, this refactors the RequestCheckTx ProtoBuf struct to allow for a flag indicating whether a query is a recheck or not (and allows for possible future, more nuanced states).
In order to pass this extended information through to the ABCI app, the proxy.AppConnMempool (and, for consistency, the proxy.AppConnConsensus) interface seems to need to be refactored along with abcicli.Client.
And, as per this comment, I've made the following modification to the protobuf definition for the RequestCheckTx structure:
enum CheckTxType {
New = 0;
Recheck = 1;
}
message RequestCheckTx {
bytes tx = 1;
CheckTxType type = 2;
}
* Refactor ABCI CheckTx to notify of recheck
As per #2127, this refactors the `RequestCheckTx` ProtoBuf struct to allow for:
1. a flag indicating whether a query is a recheck or not (and allows for
possible future, more nuanced states)
2. an `additional_data` bytes array to provide information for those more
nuanced states.
In order to pass this extended information through to the ABCI app, the
`proxy.AppConnMempool` (and, for consistency, the
`proxy.AppConnConsensus`) interface seems to need to be refactored.
Commits:
* Fix linting issue
* Add CHANGELOG_PENDING entry
* Remove extraneous explicit initialization
* Update ABCI spec doc to include new CheckTx params
* Rename method param for consistency
* Rename CheckTxType enum values and remove additional_data param
2019-07-02 10:14:53 -04:00
|
|
|
ar, err := app.DeliverTxSync(types.RequestDeliverTx{Tx: tx})
|
2017-11-22 17:34:00 -06:00
|
|
|
require.NoError(t, err)
|
2017-01-10 18:12:20 +01:00
|
|
|
require.False(t, ar.IsErr(), ar)
|
|
|
|
// repeating tx doesn't raise error
|
abci: Refactor CheckTx to notify of recheck (#3744)
As per #2127, this refactors the RequestCheckTx ProtoBuf struct to allow for a flag indicating whether a query is a recheck or not (and allows for possible future, more nuanced states).
In order to pass this extended information through to the ABCI app, the proxy.AppConnMempool (and, for consistency, the proxy.AppConnConsensus) interface seems to need to be refactored along with abcicli.Client.
And, as per this comment, I've made the following modification to the protobuf definition for the RequestCheckTx structure:
enum CheckTxType {
New = 0;
Recheck = 1;
}
message RequestCheckTx {
bytes tx = 1;
CheckTxType type = 2;
}
* Refactor ABCI CheckTx to notify of recheck
As per #2127, this refactors the `RequestCheckTx` ProtoBuf struct to allow for:
1. a flag indicating whether a query is a recheck or not (and allows for
possible future, more nuanced states)
2. an `additional_data` bytes array to provide information for those more
nuanced states.
In order to pass this extended information through to the ABCI app, the
`proxy.AppConnMempool` (and, for consistency, the
`proxy.AppConnConsensus`) interface seems to need to be refactored.
Commits:
* Fix linting issue
* Add CHANGELOG_PENDING entry
* Remove extraneous explicit initialization
* Update ABCI spec doc to include new CheckTx params
* Rename method param for consistency
* Rename CheckTxType enum values and remove additional_data param
2019-07-02 10:14:53 -04:00
|
|
|
ar, err = app.DeliverTxSync(types.RequestDeliverTx{Tx: tx})
|
2017-11-22 17:34:00 -06:00
|
|
|
require.NoError(t, err)
|
2017-01-10 18:12:20 +01:00
|
|
|
require.False(t, ar.IsErr(), ar)
|
|
|
|
|
|
|
|
// make sure query is fine
|
2017-01-23 23:42:09 -08:00
|
|
|
resQuery, err := app.QuerySync(types.RequestQuery{
|
|
|
|
Path: "/store",
|
|
|
|
Data: []byte(key),
|
|
|
|
})
|
2017-01-10 18:12:20 +01:00
|
|
|
require.Nil(t, err)
|
2017-11-30 15:37:31 -05:00
|
|
|
require.Equal(t, code.CodeTypeOK, resQuery.Code)
|
2017-01-23 23:42:09 -08:00
|
|
|
require.Equal(t, value, string(resQuery.Value))
|
2017-01-10 18:12:20 +01:00
|
|
|
|
|
|
|
// make sure proof is fine
|
2017-01-23 23:42:09 -08:00
|
|
|
resQuery, err = app.QuerySync(types.RequestQuery{
|
|
|
|
Path: "/store",
|
|
|
|
Data: []byte(key),
|
|
|
|
Prove: true,
|
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
2017-11-30 15:37:31 -05:00
|
|
|
require.Equal(t, code.CodeTypeOK, resQuery.Code)
|
2017-01-23 23:42:09 -08:00
|
|
|
require.Equal(t, value, string(resQuery.Value))
|
2017-01-10 18:12:20 +01:00
|
|
|
}
|