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 }