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