github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/lite/proxy/query_test.go (about)

     1  package proxy
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/franono/tendermint/abci/example/kvstore"
    13  	"github.com/franono/tendermint/crypto/merkle"
    14  	"github.com/franono/tendermint/lite"
    15  	certclient "github.com/franono/tendermint/lite/client"
    16  	nm "github.com/franono/tendermint/node"
    17  	"github.com/franono/tendermint/rpc/client"
    18  	rpclocal "github.com/franono/tendermint/rpc/client/local"
    19  	rpctest "github.com/franono/tendermint/rpc/test"
    20  	"github.com/franono/tendermint/types"
    21  )
    22  
    23  var node *nm.Node
    24  var chainID = "tendermint_test" // TODO use from config.
    25  //nolint:unused
    26  var waitForEventTimeout = 5 * time.Second
    27  
    28  // TODO fix tests!!
    29  
    30  func TestMain(m *testing.M) {
    31  	app := kvstore.NewApplication()
    32  	node = rpctest.StartTendermint(app)
    33  
    34  	code := m.Run()
    35  
    36  	rpctest.StopTendermint(node)
    37  	os.Exit(code)
    38  }
    39  
    40  func kvstoreTx(k, v []byte) []byte {
    41  	return []byte(fmt.Sprintf("%s=%s", k, v))
    42  }
    43  
    44  // TODO: enable it after general proof format has been adapted
    45  // in abci/examples/kvstore.go
    46  //nolint:unused,deadcode
    47  func _TestAppProofs(t *testing.T) {
    48  	assert, require := assert.New(t), require.New(t)
    49  
    50  	prt := defaultProofRuntime()
    51  	cl := rpclocal.New(node)
    52  	client.WaitForHeight(cl, 1, nil)
    53  
    54  	// This sets up our trust on the node based on some past point.
    55  	source := certclient.NewProvider(chainID, cl)
    56  	seed, err := source.LatestFullCommit(chainID, 1, 1)
    57  	require.NoError(err, "%#v", err)
    58  	cert := lite.NewBaseVerifier(chainID, seed.Height(), seed.Validators)
    59  
    60  	// Wait for tx confirmation.
    61  	done := make(chan int64)
    62  	go func() {
    63  		evtTyp := types.EventTx
    64  		_, err = client.WaitForOneEvent(cl, evtTyp, waitForEventTimeout)
    65  		require.Nil(err, "%#v", err)
    66  		close(done)
    67  	}()
    68  
    69  	// Submit a transaction.
    70  	k := []byte("my-key")
    71  	v := []byte("my-value")
    72  	tx := kvstoreTx(k, v)
    73  	br, err := cl.BroadcastTxCommit(tx)
    74  	require.NoError(err, "%#v", err)
    75  	require.EqualValues(0, br.CheckTx.Code, "%#v", br.CheckTx)
    76  	require.EqualValues(0, br.DeliverTx.Code)
    77  	brh := br.Height
    78  
    79  	// Fetch latest after tx commit.
    80  	<-done
    81  	latest, err := source.LatestFullCommit(chainID, 1, 1<<63-1)
    82  	require.NoError(err, "%#v", err)
    83  	rootHash := latest.SignedHeader.AppHash
    84  	if rootHash == nil {
    85  		// Fetch one block later, AppHash hasn't been committed yet.
    86  		// TODO find a way to avoid doing this.
    87  		client.WaitForHeight(cl, latest.SignedHeader.Height+1, nil)
    88  		latest, err = source.LatestFullCommit(chainID, latest.SignedHeader.Height+1, 1<<63-1)
    89  		require.NoError(err, "%#v", err)
    90  		rootHash = latest.SignedHeader.AppHash
    91  	}
    92  	require.NotNil(rootHash)
    93  
    94  	// verify a query before the tx block has no data (and valid non-exist proof)
    95  	bs, height, proof, err := GetWithProof(prt, k, brh-1, cl, cert)
    96  	require.NoError(err, "%#v", err)
    97  	require.NotNil(proof)
    98  	require.Equal(height, brh-1)
    99  	// require.NotNil(proof)
   100  	// TODO: Ensure that *some* keys will be there, ensuring that proof is nil,
   101  	// (currently there's a race condition)
   102  	// and ensure that proof proves absence of k.
   103  	require.Nil(bs)
   104  
   105  	// but given that block it is good
   106  	bs, height, proof, err = GetWithProof(prt, k, brh, cl, cert)
   107  	require.NoError(err, "%#v", err)
   108  	require.NotNil(proof)
   109  	require.Equal(height, brh)
   110  
   111  	assert.EqualValues(v, bs)
   112  	err = prt.VerifyValue(proof, rootHash, string(k), bs) // XXX key encoding
   113  	assert.NoError(err, "%#v", err)
   114  
   115  	// Test non-existing key.
   116  	missing := []byte("my-missing-key")
   117  	bs, _, proof, err = GetWithProof(prt, missing, 0, cl, cert)
   118  	require.NoError(err)
   119  	require.Nil(bs)
   120  	require.NotNil(proof)
   121  	err = prt.VerifyAbsence(proof, rootHash, string(missing)) // XXX VerifyAbsence(), keyencoding
   122  	assert.NoError(err, "%#v", err)
   123  	err = prt.VerifyAbsence(proof, rootHash, string(k)) // XXX VerifyAbsence(), keyencoding
   124  	assert.Error(err, "%#v", err)
   125  }
   126  
   127  func TestTxProofs(t *testing.T) {
   128  	assert, require := assert.New(t), require.New(t)
   129  
   130  	cl := rpclocal.New(node)
   131  	client.WaitForHeight(cl, 1, nil)
   132  
   133  	tx := kvstoreTx([]byte("key-a"), []byte("value-a"))
   134  	br, err := cl.BroadcastTxCommit(tx)
   135  	require.NoError(err, "%#v", err)
   136  	require.EqualValues(0, br.CheckTx.Code, "%#v", br.CheckTx)
   137  	require.EqualValues(0, br.DeliverTx.Code)
   138  	brh := br.Height
   139  
   140  	source := certclient.NewProvider(chainID, cl)
   141  	seed, err := source.LatestFullCommit(chainID, brh-2, brh-2)
   142  	require.NoError(err, "%#v", err)
   143  	cert := lite.NewBaseVerifier(chainID, seed.Height(), seed.Validators)
   144  
   145  	// First let's make sure a bogus transaction hash returns a valid non-existence proof.
   146  	key := types.Tx([]byte("bogus")).Hash()
   147  	_, err = cl.Tx(key, true)
   148  	require.NotNil(err)
   149  	require.Contains(err.Error(), "not found")
   150  
   151  	// Now let's check with the real tx root hash.
   152  	key = types.Tx(tx).Hash()
   153  	res, err := cl.Tx(key, true)
   154  	require.NoError(err, "%#v", err)
   155  	require.NotNil(res)
   156  	keyHash := merkle.SimpleHashFromByteSlices([][]byte{key})
   157  	err = res.Proof.Validate(keyHash)
   158  	assert.NoError(err, "%#v", err)
   159  
   160  	commit, err := GetCertifiedCommit(br.Height, cl, cert)
   161  	require.Nil(err, "%#v", err)
   162  	require.Equal(res.Proof.RootHash, commit.Header.DataHash)
   163  }