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