rpc/client: take context as first param (#5347)

Closes #5145

also applies to light/client
This commit is contained in:
Anton Kaliaev
2020-09-23 09:21:57 +04:00
committed by GitHub
parent 0aecda68fc
commit 85a4be87a7
41 changed files with 706 additions and 503 deletions

View File

@@ -126,12 +126,13 @@ func testTxEventsSent(t *testing.T, broadcastMethod string) {
var (
txres *ctypes.ResultBroadcastTx
err error
ctx = context.Background()
)
switch broadcastMethod {
case "async":
txres, err = c.BroadcastTxAsync(tx)
txres, err = c.BroadcastTxAsync(ctx, tx)
case "sync":
txres, err = c.BroadcastTxSync(tx)
txres, err = c.BroadcastTxSync(ctx, tx)
default:
panic(fmt.Sprintf("Unknown broadcastMethod %s", broadcastMethod))
}

View File

@@ -2,6 +2,7 @@ package client_test
import (
"bytes"
"context"
"testing"
"time"
@@ -119,18 +120,18 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
correct, fakes := makeEvidences(t, pv, chainID)
t.Logf("client %d", i)
result, err := c.BroadcastEvidence(correct)
result, err := c.BroadcastEvidence(context.Background(), correct)
require.NoError(t, err, "BroadcastEvidence(%s) failed", correct)
assert.Equal(t, correct.Hash(), result.Hash, "expected result hash to match evidence hash")
status, err := c.Status()
status, err := c.Status(context.Background())
require.NoError(t, err)
err = client.WaitForHeight(c, status.SyncInfo.LatestBlockHeight+2, nil)
require.NoError(t, err)
ed25519pub := pv.Key.PubKey.(ed25519.PubKey)
rawpub := ed25519pub.Bytes()
result2, err := c.ABCIQuery("/val", rawpub)
result2, err := c.ABCIQuery(context.Background(), "/val", rawpub)
require.NoError(t, err)
qres := result2.Response
require.True(t, qres.IsOK())
@@ -146,7 +147,7 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
require.Equal(t, int64(9), v.Power, "Stored Power not equal with expected, value %v", string(qres.Value))
for _, fake := range fakes {
_, err := c.BroadcastEvidence(fake)
_, err := c.BroadcastEvidence(context.Background(), fake)
require.Error(t, err, "BroadcastEvidence(%s) succeeded, but the evidence was fake", fake)
}
}
@@ -154,7 +155,7 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
func TestBroadcastEmptyEvidence(t *testing.T) {
for _, c := range GetClients() {
_, err := c.BroadcastEvidence(nil)
_, err := c.BroadcastEvidence(context.Background(), nil)
assert.Error(t, err)
}
}

View File

@@ -2,6 +2,7 @@ package client_test
import (
"bytes"
"context"
"fmt"
"log"
@@ -31,7 +32,7 @@ func ExampleHTTP_simple() {
// Broadcast the transaction and wait for it to commit (rather use
// c.BroadcastTxSync though in production).
bres, err := c.BroadcastTxCommit(tx)
bres, err := c.BroadcastTxCommit(context.Background(), tx)
if err != nil {
log.Fatal(err)
}
@@ -40,7 +41,7 @@ func ExampleHTTP_simple() {
}
// Now try to fetch the value for the key
qres, err := c.ABCIQuery("/key", k)
qres, err := c.ABCIQuery(context.Background(), "/key", k)
if err != nil {
log.Fatal(err)
}
@@ -95,26 +96,26 @@ func ExampleHTTP_batching() {
for _, tx := range txs {
// Broadcast the transaction and wait for it to commit (rather use
// c.BroadcastTxSync though in production).
if _, err := batch.BroadcastTxCommit(tx); err != nil {
if _, err := batch.BroadcastTxCommit(context.Background(), tx); err != nil {
log.Fatal(err)
}
}
// Send the batch of 2 transactions
if _, err := batch.Send(); err != nil {
if _, err := batch.Send(context.Background()); err != nil {
log.Fatal(err)
}
// Now let's query for the original results as a batch
keys := [][]byte{k1, k2}
for _, key := range keys {
if _, err := batch.ABCIQuery("/key", key); err != nil {
if _, err := batch.ABCIQuery(context.Background(), "/key", key); err != nil {
log.Fatal(err)
}
}
// Send the 2 queries and keep the results
results, err := batch.Send()
results, err := batch.Send(context.Background())
if err != nil {
log.Fatal(err)
}

View File

@@ -38,7 +38,7 @@ func WaitForHeight(c StatusClient, h int64, waiter Waiter) error {
}
delta := int64(1)
for delta > 0 {
s, err := c.Status()
s, err := c.Status(context.Background())
if err != nil {
return err
}

View File

@@ -183,8 +183,8 @@ func (c *HTTP) NewBatch() *BatchHTTP {
// compilation of the batched requests and send them off using the client as a
// single request. On success, this returns a list of the deserialized results
// from each request in the sent batch.
func (b *BatchHTTP) Send() ([]interface{}, error) {
return b.rpcBatch.Send()
func (b *BatchHTTP) Send(ctx context.Context) ([]interface{}, error) {
return b.rpcBatch.Send(ctx)
}
// Clear will empty out this batch of requests and return the number of requests
@@ -201,9 +201,9 @@ func (b *BatchHTTP) Count() int {
//-----------------------------------------------------------------------------
// baseRPCClient
func (c *baseRPCClient) Status() (*ctypes.ResultStatus, error) {
func (c *baseRPCClient) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
result := new(ctypes.ResultStatus)
_, err := c.caller.Call("status", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "status", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
@@ -211,9 +211,9 @@ func (c *baseRPCClient) Status() (*ctypes.ResultStatus, error) {
return result, nil
}
func (c *baseRPCClient) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
func (c *baseRPCClient) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
result := new(ctypes.ResultABCIInfo)
_, err := c.caller.Call("abci_info", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "abci_info", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
@@ -221,16 +221,21 @@ func (c *baseRPCClient) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
return result, nil
}
func (c *baseRPCClient) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(path, data, rpcclient.DefaultABCIQueryOptions)
func (c *baseRPCClient) ABCIQuery(
ctx context.Context,
path string,
data bytes.HexBytes,
) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
}
func (c *baseRPCClient) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
result := new(ctypes.ResultABCIQuery)
_, err := c.caller.Call("abci_query",
_, err := c.caller.Call(ctx, "abci_query",
map[string]interface{}{"path": path, "data": data, "height": opts.Height, "prove": opts.Prove},
result)
if err != nil {
@@ -240,115 +245,138 @@ func (c *baseRPCClient) ABCIQueryWithOptions(
return result, nil
}
func (c *baseRPCClient) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
func (c *baseRPCClient) BroadcastTxCommit(
ctx context.Context,
tx types.Tx,
) (*ctypes.ResultBroadcastTxCommit, error) {
result := new(ctypes.ResultBroadcastTxCommit)
_, err := c.caller.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
_, err := c.caller.Call(ctx, "broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return c.broadcastTX("broadcast_tx_async", tx)
func (c *baseRPCClient) BroadcastTxAsync(
ctx context.Context,
tx types.Tx,
) (*ctypes.ResultBroadcastTx, error) {
return c.broadcastTX(ctx, "broadcast_tx_async", tx)
}
func (c *baseRPCClient) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return c.broadcastTX("broadcast_tx_sync", tx)
func (c *baseRPCClient) BroadcastTxSync(
ctx context.Context,
tx types.Tx,
) (*ctypes.ResultBroadcastTx, error) {
return c.broadcastTX(ctx, "broadcast_tx_sync", tx)
}
func (c *baseRPCClient) broadcastTX(route string, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (c *baseRPCClient) broadcastTX(
ctx context.Context,
route string,
tx types.Tx,
) (*ctypes.ResultBroadcastTx, error) {
result := new(ctypes.ResultBroadcastTx)
_, err := c.caller.Call(route, map[string]interface{}{"tx": tx}, result)
_, err := c.caller.Call(ctx, route, map[string]interface{}{"tx": tx}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
func (c *baseRPCClient) UnconfirmedTxs(
ctx context.Context,
limit *int,
) (*ctypes.ResultUnconfirmedTxs, error) {
result := new(ctypes.ResultUnconfirmedTxs)
params := make(map[string]interface{})
if limit != nil {
params["limit"] = limit
}
_, err := c.caller.Call("unconfirmed_txs", params, result)
_, err := c.caller.Call(ctx, "unconfirmed_txs", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
func (c *baseRPCClient) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) {
result := new(ctypes.ResultUnconfirmedTxs)
_, err := c.caller.Call("num_unconfirmed_txs", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "num_unconfirmed_txs", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
func (c *baseRPCClient) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
result := new(ctypes.ResultCheckTx)
_, err := c.caller.Call("check_tx", map[string]interface{}{"tx": tx}, result)
_, err := c.caller.Call(ctx, "check_tx", map[string]interface{}{"tx": tx}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) NetInfo() (*ctypes.ResultNetInfo, error) {
func (c *baseRPCClient) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
result := new(ctypes.ResultNetInfo)
_, err := c.caller.Call("net_info", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "net_info", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
func (c *baseRPCClient) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
result := new(ctypes.ResultDumpConsensusState)
_, err := c.caller.Call("dump_consensus_state", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "dump_consensus_state", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) ConsensusState() (*ctypes.ResultConsensusState, error) {
func (c *baseRPCClient) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
result := new(ctypes.ResultConsensusState)
_, err := c.caller.Call("consensus_state", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "consensus_state", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
func (c *baseRPCClient) ConsensusParams(
ctx context.Context,
height *int64,
) (*ctypes.ResultConsensusParams, error) {
result := new(ctypes.ResultConsensusParams)
params := make(map[string]interface{})
if height != nil {
params["height"] = height
}
_, err := c.caller.Call("consensus_params", params, result)
_, err := c.caller.Call(ctx, "consensus_params", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) Health() (*ctypes.ResultHealth, error) {
func (c *baseRPCClient) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
result := new(ctypes.ResultHealth)
_, err := c.caller.Call("health", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "health", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
func (c *baseRPCClient) BlockchainInfo(
ctx context.Context,
minHeight,
maxHeight int64,
) (*ctypes.ResultBlockchainInfo, error) {
result := new(ctypes.ResultBlockchainInfo)
_, err := c.caller.Call("blockchain",
_, err := c.caller.Call(ctx, "blockchain",
map[string]interface{}{"minHeight": minHeight, "maxHeight": maxHeight},
result)
if err != nil {
@@ -357,80 +385,90 @@ func (c *baseRPCClient) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.Resu
return result, nil
}
func (c *baseRPCClient) Genesis() (*ctypes.ResultGenesis, error) {
func (c *baseRPCClient) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
result := new(ctypes.ResultGenesis)
_, err := c.caller.Call("genesis", map[string]interface{}{}, result)
_, err := c.caller.Call(ctx, "genesis", map[string]interface{}{}, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) Block(height *int64) (*ctypes.ResultBlock, error) {
func (c *baseRPCClient) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
result := new(ctypes.ResultBlock)
params := make(map[string]interface{})
if height != nil {
params["height"] = height
}
_, err := c.caller.Call("block", params, result)
_, err := c.caller.Call(ctx, "block", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
func (c *baseRPCClient) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
result := new(ctypes.ResultBlock)
params := map[string]interface{}{
"hash": hash,
}
_, err := c.caller.Call("block_by_hash", params, result)
_, err := c.caller.Call(ctx, "block_by_hash", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) BlockResults(height *int64) (*ctypes.ResultBlockResults, error) {
func (c *baseRPCClient) BlockResults(
ctx context.Context,
height *int64,
) (*ctypes.ResultBlockResults, error) {
result := new(ctypes.ResultBlockResults)
params := make(map[string]interface{})
if height != nil {
params["height"] = height
}
_, err := c.caller.Call("block_results", params, result)
_, err := c.caller.Call(ctx, "block_results", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) Commit(height *int64) (*ctypes.ResultCommit, error) {
func (c *baseRPCClient) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
result := new(ctypes.ResultCommit)
params := make(map[string]interface{})
if height != nil {
params["height"] = height
}
_, err := c.caller.Call("commit", params, result)
_, err := c.caller.Call(ctx, "commit", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
func (c *baseRPCClient) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
result := new(ctypes.ResultTx)
params := map[string]interface{}{
"hash": hash,
"prove": prove,
}
_, err := c.caller.Call("tx", params, result)
_, err := c.caller.Call(ctx, "tx", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) TxSearch(query string, prove bool, page, perPage *int, orderBy string) (
func (c *baseRPCClient) TxSearch(
ctx context.Context,
query string,
prove bool,
page,
perPage *int,
orderBy string,
) (
*ctypes.ResultTxSearch, error) {
result := new(ctypes.ResultTxSearch)
params := map[string]interface{}{
@@ -444,14 +482,19 @@ func (c *baseRPCClient) TxSearch(query string, prove bool, page, perPage *int, o
if perPage != nil {
params["per_page"] = perPage
}
_, err := c.caller.Call("tx_search", params, result)
_, err := c.caller.Call(ctx, "tx_search", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
func (c *baseRPCClient) Validators(
ctx context.Context,
height *int64,
page,
perPage *int,
) (*ctypes.ResultValidators, error) {
result := new(ctypes.ResultValidators)
params := make(map[string]interface{})
if page != nil {
@@ -463,16 +506,19 @@ func (c *baseRPCClient) Validators(height *int64, page, perPage *int) (*ctypes.R
if height != nil {
params["height"] = height
}
_, err := c.caller.Call("validators", params, result)
_, err := c.caller.Call(ctx, "validators", params, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *baseRPCClient) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
func (c *baseRPCClient) BroadcastEvidence(
ctx context.Context,
ev types.Evidence,
) (*ctypes.ResultBroadcastEvidence, error) {
result := new(ctypes.ResultBroadcastEvidence)
_, err := c.caller.Call("broadcast_evidence", map[string]interface{}{"evidence": ev}, result)
_, err := c.caller.Call(ctx, "broadcast_evidence", map[string]interface{}{"evidence": ev}, result)
if err != nil {
return nil, err
}

View File

@@ -50,48 +50,49 @@ type Client interface {
// is easier to mock.
type ABCIClient interface {
// Reading from abci app
ABCIInfo() (*ctypes.ResultABCIInfo, error)
ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error)
ABCIQueryWithOptions(path string, data bytes.HexBytes,
ABCIInfo(context.Context) (*ctypes.ResultABCIInfo, error)
ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error)
ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes,
opts ABCIQueryOptions) (*ctypes.ResultABCIQuery, error)
// Writing to abci app
BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error)
BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error)
BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error)
BroadcastTxCommit(context.Context, types.Tx) (*ctypes.ResultBroadcastTxCommit, error)
BroadcastTxAsync(context.Context, types.Tx) (*ctypes.ResultBroadcastTx, error)
BroadcastTxSync(context.Context, types.Tx) (*ctypes.ResultBroadcastTx, error)
}
// SignClient groups together the functionality needed to get valid signatures
// and prove anything about the chain.
type SignClient interface {
Block(height *int64) (*ctypes.ResultBlock, error)
BlockByHash(hash []byte) (*ctypes.ResultBlock, error)
BlockResults(height *int64) (*ctypes.ResultBlockResults, error)
Commit(height *int64) (*ctypes.ResultCommit, error)
Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error)
Tx(hash []byte, prove bool) (*ctypes.ResultTx, error)
TxSearch(query string, prove bool, page, perPage *int, orderBy string) (*ctypes.ResultTxSearch, error)
Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error)
BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error)
BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error)
Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error)
Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error)
Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error)
TxSearch(ctx context.Context, query string, prove bool, page, perPage *int,
orderBy string) (*ctypes.ResultTxSearch, error)
}
// HistoryClient provides access to data from genesis to now in large chunks.
type HistoryClient interface {
Genesis() (*ctypes.ResultGenesis, error)
BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error)
Genesis(context.Context) (*ctypes.ResultGenesis, error)
BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error)
}
// StatusClient provides access to general chain info.
type StatusClient interface {
Status() (*ctypes.ResultStatus, error)
Status(context.Context) (*ctypes.ResultStatus, error)
}
// NetworkClient is general info about the network state. May not be needed
// usually.
type NetworkClient interface {
NetInfo() (*ctypes.ResultNetInfo, error)
DumpConsensusState() (*ctypes.ResultDumpConsensusState, error)
ConsensusState() (*ctypes.ResultConsensusState, error)
ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error)
Health() (*ctypes.ResultHealth, error)
NetInfo(context.Context) (*ctypes.ResultNetInfo, error)
DumpConsensusState(context.Context) (*ctypes.ResultDumpConsensusState, error)
ConsensusState(context.Context) (*ctypes.ResultConsensusState, error)
ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error)
Health(context.Context) (*ctypes.ResultHealth, error)
}
// EventsClient is reactive, you can subscribe to any message, given the proper
@@ -113,15 +114,15 @@ type EventsClient interface {
// MempoolClient shows us data about current mempool state.
type MempoolClient interface {
UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error)
NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error)
CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error)
UnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error)
NumUnconfirmedTxs(context.Context) (*ctypes.ResultUnconfirmedTxs, error)
CheckTx(context.Context, types.Tx) (*ctypes.ResultCheckTx, error)
}
// EvidenceClient is used for submitting an evidence of the malicious
// behaviour.
type EvidenceClient interface {
BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error)
BroadcastEvidence(context.Context, types.Evidence) (*ctypes.ResultBroadcastEvidence, error)
}
// RemoteClient is a Client, which can also return the remote network address.

View File

@@ -67,115 +67,128 @@ func (c *Local) SetLogger(l log.Logger) {
c.Logger = l
}
func (c *Local) Status() (*ctypes.ResultStatus, error) {
func (c *Local) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
return core.Status(c.ctx)
}
func (c *Local) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
func (c *Local) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
return core.ABCIInfo(c.ctx)
}
func (c *Local) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(path, data, rpcclient.DefaultABCIQueryOptions)
func (c *Local) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
}
func (c *Local) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
return core.ABCIQuery(c.ctx, path, data, opts.Height, opts.Prove)
}
func (c *Local) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
func (c *Local) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
return core.BroadcastTxCommit(c.ctx, tx)
}
func (c *Local) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (c *Local) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return core.BroadcastTxAsync(c.ctx, tx)
}
func (c *Local) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (c *Local) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return core.BroadcastTxSync(c.ctx, tx)
}
func (c *Local) UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
func (c *Local) UnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
return core.UnconfirmedTxs(c.ctx, limit)
}
func (c *Local) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
func (c *Local) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) {
return core.NumUnconfirmedTxs(c.ctx)
}
func (c *Local) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
func (c *Local) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
return core.CheckTx(c.ctx, tx)
}
func (c *Local) NetInfo() (*ctypes.ResultNetInfo, error) {
func (c *Local) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
return core.NetInfo(c.ctx)
}
func (c *Local) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
func (c *Local) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
return core.DumpConsensusState(c.ctx)
}
func (c *Local) ConsensusState() (*ctypes.ResultConsensusState, error) {
func (c *Local) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
return core.ConsensusState(c.ctx)
}
func (c *Local) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
func (c *Local) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) {
return core.ConsensusParams(c.ctx, height)
}
func (c *Local) Health() (*ctypes.ResultHealth, error) {
func (c *Local) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
return core.Health(c.ctx)
}
func (c *Local) DialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
func (c *Local) DialSeeds(ctx context.Context, seeds []string) (*ctypes.ResultDialSeeds, error) {
return core.UnsafeDialSeeds(c.ctx, seeds)
}
func (c *Local) DialPeers(peers []string, persistent, unconditional, private bool) (*ctypes.ResultDialPeers, error) {
func (c *Local) DialPeers(
ctx context.Context,
peers []string,
persistent,
unconditional,
private bool,
) (*ctypes.ResultDialPeers, error) {
return core.UnsafeDialPeers(c.ctx, peers, persistent, unconditional, private)
}
func (c *Local) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
func (c *Local) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
return core.BlockchainInfo(c.ctx, minHeight, maxHeight)
}
func (c *Local) Genesis() (*ctypes.ResultGenesis, error) {
func (c *Local) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
return core.Genesis(c.ctx)
}
func (c *Local) Block(height *int64) (*ctypes.ResultBlock, error) {
func (c *Local) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
return core.Block(c.ctx, height)
}
func (c *Local) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
func (c *Local) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
return core.BlockByHash(c.ctx, hash)
}
func (c *Local) BlockResults(height *int64) (*ctypes.ResultBlockResults, error) {
func (c *Local) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) {
return core.BlockResults(c.ctx, height)
}
func (c *Local) Commit(height *int64) (*ctypes.ResultCommit, error) {
func (c *Local) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
return core.Commit(c.ctx, height)
}
func (c *Local) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
func (c *Local) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
return core.Validators(c.ctx, height, page, perPage)
}
func (c *Local) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
func (c *Local) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
return core.Tx(c.ctx, hash, prove)
}
func (c *Local) TxSearch(query string, prove bool, page, perPage *int, orderBy string) (
*ctypes.ResultTxSearch, error) {
func (c *Local) TxSearch(
ctx context.Context,
query string,
prove bool,
page,
perPage *int,
orderBy string,
) (*ctypes.ResultTxSearch, error) {
return core.TxSearch(c.ctx, query, prove, page, perPage, orderBy)
}
func (c *Local) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
return core.BroadcastEvidence(c.ctx, ev)
}

View File

@@ -1,6 +1,8 @@
package mock
import (
"context"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/proxy"
@@ -22,15 +24,16 @@ var (
_ client.ABCIClient = (*ABCIRecorder)(nil)
)
func (a ABCIApp) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
func (a ABCIApp) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
return &ctypes.ResultABCIInfo{Response: a.App.Info(proxy.RequestInfo)}, nil
}
func (a ABCIApp) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return a.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return a.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
}
func (a ABCIApp) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
@@ -46,7 +49,7 @@ func (a ABCIApp) ABCIQueryWithOptions(
// NOTE: Caller should call a.App.Commit() separately,
// this function does not actually wait for a commit.
// TODO: Make it wait for a commit and set res.Height appropriately.
func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
res := ctypes.ResultBroadcastTxCommit{}
res.CheckTx = a.App.CheckTx(abci.RequestCheckTx{Tx: tx})
if res.CheckTx.IsErr() {
@@ -57,7 +60,7 @@ func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit
return &res, nil
}
func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx})
// and this gets written in a background thread...
if !c.IsErr() {
@@ -72,7 +75,7 @@ func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error
}, nil
}
func (a ABCIApp) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx})
// and this gets written in a background thread...
if !c.IsErr() {
@@ -97,7 +100,7 @@ type ABCIMock struct {
Broadcast Call
}
func (m ABCIMock) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
func (m ABCIMock) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
res, err := m.Info.GetResponse(nil)
if err != nil {
return nil, err
@@ -105,11 +108,12 @@ func (m ABCIMock) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
return &ctypes.ResultABCIInfo{Response: res.(abci.ResponseInfo)}, nil
}
func (m ABCIMock) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return m.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
func (m ABCIMock) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return m.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
}
func (m ABCIMock) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
@@ -121,7 +125,7 @@ func (m ABCIMock) ABCIQueryWithOptions(
return &ctypes.ResultABCIQuery{Response: resQuery}, nil
}
func (m ABCIMock) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
func (m ABCIMock) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
res, err := m.BroadcastCommit.GetResponse(tx)
if err != nil {
return nil, err
@@ -129,7 +133,7 @@ func (m ABCIMock) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommi
return res.(*ctypes.ResultBroadcastTxCommit), nil
}
func (m ABCIMock) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (m ABCIMock) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
res, err := m.Broadcast.GetResponse(tx)
if err != nil {
return nil, err
@@ -137,7 +141,7 @@ func (m ABCIMock) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, erro
return res.(*ctypes.ResultBroadcastTx), nil
}
func (m ABCIMock) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (m ABCIMock) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
res, err := m.Broadcast.GetResponse(tx)
if err != nil {
return nil, err
@@ -170,8 +174,8 @@ func (r *ABCIRecorder) addCall(call Call) {
r.Calls = append(r.Calls, call)
}
func (r *ABCIRecorder) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
res, err := r.Client.ABCIInfo()
func (r *ABCIRecorder) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
res, err := r.Client.ABCIInfo(ctx)
r.addCall(Call{
Name: "abci_info",
Response: res,
@@ -180,15 +184,20 @@ func (r *ABCIRecorder) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
return res, err
}
func (r *ABCIRecorder) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return r.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
func (r *ABCIRecorder) ABCIQuery(
ctx context.Context,
path string,
data bytes.HexBytes,
) (*ctypes.ResultABCIQuery, error) {
return r.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
}
func (r *ABCIRecorder) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
res, err := r.Client.ABCIQueryWithOptions(path, data, opts)
res, err := r.Client.ABCIQueryWithOptions(ctx, path, data, opts)
r.addCall(Call{
Name: "abci_query",
Args: QueryArgs{path, data, opts.Height, opts.Prove},
@@ -198,8 +207,8 @@ func (r *ABCIRecorder) ABCIQueryWithOptions(
return res, err
}
func (r *ABCIRecorder) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
res, err := r.Client.BroadcastTxCommit(tx)
func (r *ABCIRecorder) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
res, err := r.Client.BroadcastTxCommit(ctx, tx)
r.addCall(Call{
Name: "broadcast_tx_commit",
Args: tx,
@@ -209,8 +218,8 @@ func (r *ABCIRecorder) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTx
return res, err
}
func (r *ABCIRecorder) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
res, err := r.Client.BroadcastTxAsync(tx)
func (r *ABCIRecorder) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
res, err := r.Client.BroadcastTxAsync(ctx, tx)
r.addCall(Call{
Name: "broadcast_tx_async",
Args: tx,
@@ -220,8 +229,8 @@ func (r *ABCIRecorder) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx,
return res, err
}
func (r *ABCIRecorder) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
res, err := r.Client.BroadcastTxSync(tx)
func (r *ABCIRecorder) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
res, err := r.Client.BroadcastTxSync(ctx, tx)
r.addCall(Call{
Name: "broadcast_tx_sync",
Args: tx,

View File

@@ -1,6 +1,7 @@
package mock_test
import (
"context"
"errors"
"fmt"
"testing"
@@ -45,12 +46,12 @@ func TestABCIMock(t *testing.T) {
}
// now, let's try to make some calls
_, err := m.ABCIInfo()
_, err := m.ABCIInfo(context.Background())
require.NotNil(err)
assert.Equal("foobar", err.Error())
// query always returns the response
_query, err := m.ABCIQueryWithOptions("/", nil, client.ABCIQueryOptions{Prove: false})
_query, err := m.ABCIQueryWithOptions(context.Background(), "/", nil, client.ABCIQueryOptions{Prove: false})
query := _query.Response
require.Nil(err)
require.NotNil(query)
@@ -59,18 +60,18 @@ func TestABCIMock(t *testing.T) {
assert.Equal(height, query.Height)
// non-commit calls always return errors
_, err = m.BroadcastTxSync(goodTx)
_, err = m.BroadcastTxSync(context.Background(), goodTx)
require.NotNil(err)
assert.Equal("must commit", err.Error())
_, err = m.BroadcastTxAsync(goodTx)
_, err = m.BroadcastTxAsync(context.Background(), goodTx)
require.NotNil(err)
assert.Equal("must commit", err.Error())
// commit depends on the input
_, err = m.BroadcastTxCommit(badTx)
_, err = m.BroadcastTxCommit(context.Background(), badTx)
require.NotNil(err)
assert.Equal("bad tx", err.Error())
bres, err := m.BroadcastTxCommit(goodTx)
bres, err := m.BroadcastTxCommit(context.Background(), goodTx)
require.Nil(err, "%+v", err)
assert.EqualValues(0, bres.CheckTx.Code)
assert.EqualValues("stand", bres.CheckTx.Data)
@@ -94,10 +95,15 @@ func TestABCIRecorder(t *testing.T) {
require.Equal(0, len(r.Calls))
_, err := r.ABCIInfo()
_, err := r.ABCIInfo(context.Background())
assert.Nil(err, "expected no err on info")
_, err = r.ABCIQueryWithOptions("path", bytes.HexBytes("data"), client.ABCIQueryOptions{Prove: false})
_, err = r.ABCIQueryWithOptions(
context.Background(),
"path",
bytes.HexBytes("data"),
client.ABCIQueryOptions{Prove: false},
)
assert.NotNil(err, "expected error on query")
require.Equal(2, len(r.Calls))
@@ -125,11 +131,11 @@ func TestABCIRecorder(t *testing.T) {
// now add some broadcasts (should all err)
txs := []types.Tx{{1}, {2}, {3}}
_, err = r.BroadcastTxCommit(txs[0])
_, err = r.BroadcastTxCommit(context.Background(), txs[0])
assert.NotNil(err, "expected err on broadcast")
_, err = r.BroadcastTxSync(txs[1])
_, err = r.BroadcastTxSync(context.Background(), txs[1])
assert.NotNil(err, "expected err on broadcast")
_, err = r.BroadcastTxAsync(txs[2])
_, err = r.BroadcastTxAsync(context.Background(), txs[2])
assert.NotNil(err, "expected err on broadcast")
require.Equal(5, len(r.Calls))
@@ -159,14 +165,14 @@ func TestABCIApp(t *testing.T) {
m := mock.ABCIApp{app}
// get some info
info, err := m.ABCIInfo()
info, err := m.ABCIInfo(context.Background())
require.Nil(err)
assert.Equal(`{"size":0}`, info.Response.GetData())
// add a key
key, value := "foo", "bar"
tx := fmt.Sprintf("%s=%s", key, value)
res, err := m.BroadcastTxCommit(types.Tx(tx))
res, err := m.BroadcastTxCommit(context.Background(), types.Tx(tx))
require.Nil(err)
assert.True(res.CheckTx.IsOK())
require.NotNil(res.DeliverTx)
@@ -179,7 +185,12 @@ func TestABCIApp(t *testing.T) {
}
// check the key
_qres, err := m.ABCIQueryWithOptions("/key", bytes.HexBytes(key), client.ABCIQueryOptions{Prove: true})
_qres, err := m.ABCIQueryWithOptions(
context.Background(),
"/key",
bytes.HexBytes(key),
client.ABCIQueryOptions{Prove: true},
)
qres := _qres.Response
require.Nil(err)
assert.EqualValues(value, qres.Value)

View File

@@ -15,6 +15,7 @@ want to directly call a tendermint node in process, you can use the
*/
import (
"context"
"reflect"
"github.com/tendermint/tendermint/libs/bytes"
@@ -79,93 +80,100 @@ func (c Call) GetResponse(args interface{}) (interface{}, error) {
return nil, c.Error
}
func (c Client) Status() (*ctypes.ResultStatus, error) {
func (c Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
return core.Status(&rpctypes.Context{})
}
func (c Client) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
func (c Client) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
return core.ABCIInfo(&rpctypes.Context{})
}
func (c Client) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
func (c Client) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
}
func (c Client) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
return core.ABCIQuery(&rpctypes.Context{}, path, data, opts.Height, opts.Prove)
}
func (c Client) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
func (c Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
return core.BroadcastTxCommit(&rpctypes.Context{}, tx)
}
func (c Client) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (c Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return core.BroadcastTxAsync(&rpctypes.Context{}, tx)
}
func (c Client) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
func (c Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return core.BroadcastTxSync(&rpctypes.Context{}, tx)
}
func (c Client) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
func (c Client) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
return core.CheckTx(&rpctypes.Context{}, tx)
}
func (c Client) NetInfo() (*ctypes.ResultNetInfo, error) {
func (c Client) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
return core.NetInfo(&rpctypes.Context{})
}
func (c Client) ConsensusState() (*ctypes.ResultConsensusState, error) {
func (c Client) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
return core.ConsensusState(&rpctypes.Context{})
}
func (c Client) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
func (c Client) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
return core.DumpConsensusState(&rpctypes.Context{})
}
func (c Client) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
func (c Client) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) {
return core.ConsensusParams(&rpctypes.Context{}, height)
}
func (c Client) Health() (*ctypes.ResultHealth, error) {
func (c Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
return core.Health(&rpctypes.Context{})
}
func (c Client) DialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
func (c Client) DialSeeds(ctx context.Context, seeds []string) (*ctypes.ResultDialSeeds, error) {
return core.UnsafeDialSeeds(&rpctypes.Context{}, seeds)
}
func (c Client) DialPeers(peers []string, persistent, unconditional, private bool) (*ctypes.ResultDialPeers, error) {
func (c Client) DialPeers(
ctx context.Context,
peers []string,
persistent,
unconditional,
private bool,
) (*ctypes.ResultDialPeers, error) {
return core.UnsafeDialPeers(&rpctypes.Context{}, peers, persistent, unconditional, private)
}
func (c Client) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
func (c Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
return core.BlockchainInfo(&rpctypes.Context{}, minHeight, maxHeight)
}
func (c Client) Genesis() (*ctypes.ResultGenesis, error) {
func (c Client) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
return core.Genesis(&rpctypes.Context{})
}
func (c Client) Block(height *int64) (*ctypes.ResultBlock, error) {
func (c Client) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
return core.Block(&rpctypes.Context{}, height)
}
func (c Client) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
func (c Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
return core.BlockByHash(&rpctypes.Context{}, hash)
}
func (c Client) Commit(height *int64) (*ctypes.ResultCommit, error) {
func (c Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
return core.Commit(&rpctypes.Context{}, height)
}
func (c Client) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
func (c Client) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
return core.Validators(&rpctypes.Context{}, height, page, perPage)
}
func (c Client) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
func (c Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
return core.BroadcastEvidence(&rpctypes.Context{}, ev)
}

View File

@@ -1,6 +1,8 @@
package mock
import (
"context"
"github.com/tendermint/tendermint/rpc/client"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
@@ -15,7 +17,7 @@ var (
_ client.StatusClient = (*StatusRecorder)(nil)
)
func (m *StatusMock) Status() (*ctypes.ResultStatus, error) {
func (m *StatusMock) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
res, err := m.GetResponse(nil)
if err != nil {
return nil, err
@@ -41,8 +43,8 @@ func (r *StatusRecorder) addCall(call Call) {
r.Calls = append(r.Calls, call)
}
func (r *StatusRecorder) Status() (*ctypes.ResultStatus, error) {
res, err := r.Client.Status()
func (r *StatusRecorder) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
res, err := r.Client.Status(ctx)
r.addCall(Call{
Name: "status",
Response: res,

View File

@@ -1,6 +1,7 @@
package mock_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
@@ -29,7 +30,7 @@ func TestStatus(t *testing.T) {
require.Equal(0, len(r.Calls))
// make sure response works proper
status, err := r.Status()
status, err := r.Status(context.Background())
require.Nil(err, "%+v", err)
assert.EqualValues("block", status.SyncInfo.LatestBlockHash)
assert.EqualValues(10, status.SyncInfo.LatestBlockHeight)

View File

@@ -1,6 +1,7 @@
package client_test
import (
"context"
"fmt"
"math"
"net/http"
@@ -25,6 +26,10 @@ import (
"github.com/tendermint/tendermint/types"
)
var (
ctx = context.Background()
)
func getHTTPClient() *rpchttp.HTTP {
rpcAddr := rpctest.GetConfig().RPC.ListenAddress
c, err := rpchttp.New(rpcAddr, "/websocket")
@@ -70,7 +75,7 @@ func TestCustomHTTPClient(t *testing.T) {
remote := rpctest.GetConfig().RPC.ListenAddress
c, err := rpchttp.NewWithClient(remote, "/websocket", http.DefaultClient)
require.Nil(t, err)
status, err := c.Status()
status, err := c.Status(context.Background())
require.NoError(t, err)
require.NotNil(t, status)
}
@@ -94,7 +99,7 @@ func TestCorsEnabled(t *testing.T) {
func TestStatus(t *testing.T) {
for i, c := range GetClients() {
moniker := rpctest.GetConfig().Moniker
status, err := c.Status()
status, err := c.Status(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
assert.Equal(t, moniker, status.NodeInfo.Moniker)
}
@@ -105,7 +110,7 @@ func TestInfo(t *testing.T) {
for i, c := range GetClients() {
// status, err := c.Status()
// require.Nil(t, err, "%+v", err)
info, err := c.ABCIInfo()
info, err := c.ABCIInfo(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
// TODO: this is not correct - fix merkleeyes!
// assert.EqualValues(t, status.SyncInfo.LatestBlockHeight, info.Response.LastBlockHeight)
@@ -117,7 +122,7 @@ func TestNetInfo(t *testing.T) {
for i, c := range GetClients() {
nc, ok := c.(client.NetworkClient)
require.True(t, ok, "%d", i)
netinfo, err := nc.NetInfo()
netinfo, err := nc.NetInfo(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
assert.True(t, netinfo.Listening)
assert.Equal(t, 0, len(netinfo.Peers))
@@ -129,7 +134,7 @@ func TestDumpConsensusState(t *testing.T) {
// FIXME: fix server so it doesn't panic on invalid input
nc, ok := c.(client.NetworkClient)
require.True(t, ok, "%d", i)
cons, err := nc.DumpConsensusState()
cons, err := nc.DumpConsensusState(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
assert.NotEmpty(t, cons.RoundState)
assert.Empty(t, cons.Peers)
@@ -141,7 +146,7 @@ func TestConsensusState(t *testing.T) {
// FIXME: fix server so it doesn't panic on invalid input
nc, ok := c.(client.NetworkClient)
require.True(t, ok, "%d", i)
cons, err := nc.ConsensusState()
cons, err := nc.ConsensusState(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
assert.NotEmpty(t, cons.RoundState)
}
@@ -151,7 +156,7 @@ func TestHealth(t *testing.T) {
for i, c := range GetClients() {
nc, ok := c.(client.NetworkClient)
require.True(t, ok, "%d", i)
_, err := nc.Health()
_, err := nc.Health(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
}
}
@@ -160,7 +165,7 @@ func TestGenesisAndValidators(t *testing.T) {
for i, c := range GetClients() {
// make sure this is the right genesis file
gen, err := c.Genesis()
gen, err := c.Genesis(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
// get the genesis validator
require.Equal(t, 1, len(gen.Genesis.Validators))
@@ -168,7 +173,7 @@ func TestGenesisAndValidators(t *testing.T) {
// get the current validators
h := int64(1)
vals, err := c.Validators(&h, nil, nil)
vals, err := c.Validators(context.Background(), &h, nil, nil)
require.Nil(t, err, "%d: %+v", i, err)
require.Equal(t, 1, len(vals.Validators))
require.Equal(t, 1, vals.Count)
@@ -185,14 +190,14 @@ func TestABCIQuery(t *testing.T) {
for i, c := range GetClients() {
// write something
k, v, tx := MakeTxKV()
bres, err := c.BroadcastTxCommit(tx)
bres, err := c.BroadcastTxCommit(context.Background(), tx)
require.Nil(t, err, "%d: %+v", i, err)
apph := bres.Height + 1 // this is where the tx will be applied to the state
// wait before querying
err = client.WaitForHeight(c, apph, nil)
require.NoError(t, err)
res, err := c.ABCIQuery("/key", k)
res, err := c.ABCIQuery(context.Background(), "/key", k)
qres := res.Response
if assert.Nil(t, err) && assert.True(t, qres.IsOK()) {
assert.EqualValues(t, v, qres.Value)
@@ -206,19 +211,19 @@ func TestAppCalls(t *testing.T) {
for i, c := range GetClients() {
// get an offset of height to avoid racing and guessing
s, err := c.Status()
s, err := c.Status(context.Background())
require.NoError(err)
// sh is start height or status height
sh := s.SyncInfo.LatestBlockHeight
// look for the future
h := sh + 20
_, err = c.Block(&h)
_, err = c.Block(context.Background(), &h)
require.Error(err) // no block yet
// write something
k, v, tx := MakeTxKV()
bres, err := c.BroadcastTxCommit(tx)
bres, err := c.BroadcastTxCommit(context.Background(), tx)
require.NoError(err)
require.True(bres.DeliverTx.IsOK())
txh := bres.Height
@@ -228,7 +233,7 @@ func TestAppCalls(t *testing.T) {
err = client.WaitForHeight(c, apph, nil)
require.NoError(err)
_qres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: false})
_qres, err := c.ABCIQueryWithOptions(context.Background(), "/key", k, client.ABCIQueryOptions{Prove: false})
require.NoError(err)
qres := _qres.Response
if assert.True(qres.IsOK()) {
@@ -237,24 +242,24 @@ func TestAppCalls(t *testing.T) {
}
// make sure we can lookup the tx with proof
ptx, err := c.Tx(bres.Hash, true)
ptx, err := c.Tx(context.Background(), bres.Hash, true)
require.NoError(err)
assert.EqualValues(txh, ptx.Height)
assert.EqualValues(tx, ptx.Tx)
// and we can even check the block is added
block, err := c.Block(&apph)
block, err := c.Block(context.Background(), &apph)
require.NoError(err)
appHash := block.Block.Header.AppHash
assert.True(len(appHash) > 0)
assert.EqualValues(apph, block.Block.Header.Height)
blockByHash, err := c.BlockByHash(block.BlockID.Hash)
blockByHash, err := c.BlockByHash(context.Background(), block.BlockID.Hash)
require.NoError(err)
require.Equal(block, blockByHash)
// now check the results
blockResults, err := c.BlockResults(&txh)
blockResults, err := c.BlockResults(context.Background(), &txh)
require.Nil(err, "%d: %+v", i, err)
assert.Equal(txh, blockResults.Height)
if assert.Equal(1, len(blockResults.TxsResults)) {
@@ -263,7 +268,7 @@ func TestAppCalls(t *testing.T) {
}
// check blockchain info, now that we know there is info
info, err := c.BlockchainInfo(apph, apph)
info, err := c.BlockchainInfo(context.Background(), apph, apph)
require.NoError(err)
assert.True(info.LastHeight >= apph)
if assert.Equal(1, len(info.BlockMetas)) {
@@ -275,7 +280,7 @@ func TestAppCalls(t *testing.T) {
}
// and get the corresponding commit with the same apphash
commit, err := c.Commit(&apph)
commit, err := c.Commit(context.Background(), &apph)
require.NoError(err)
cappHash := commit.Header.AppHash
assert.Equal(appHash, cappHash)
@@ -283,12 +288,12 @@ func TestAppCalls(t *testing.T) {
// compare the commits (note Commit(2) has commit from Block(3))
h = apph - 1
commit2, err := c.Commit(&h)
commit2, err := c.Commit(context.Background(), &h)
require.NoError(err)
assert.Equal(block.Block.LastCommit, commit2.Commit)
// and we got a proof that works!
_pres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: true})
_pres, err := c.ABCIQueryWithOptions(context.Background(), "/key", k, client.ABCIQueryOptions{Prove: true})
require.NoError(err)
pres := _pres.Response
assert.True(pres.IsOK())
@@ -306,7 +311,7 @@ func TestBroadcastTxSync(t *testing.T) {
for i, c := range GetClients() {
_, _, tx := MakeTxKV()
bres, err := c.BroadcastTxSync(tx)
bres, err := c.BroadcastTxSync(context.Background(), tx)
require.Nil(err, "%d: %+v", i, err)
require.Equal(bres.Code, abci.CodeTypeOK) // FIXME
@@ -324,7 +329,7 @@ func TestBroadcastTxCommit(t *testing.T) {
mempool := node.Mempool()
for i, c := range GetClients() {
_, _, tx := MakeTxKV()
bres, err := c.BroadcastTxCommit(tx)
bres, err := c.BroadcastTxCommit(context.Background(), tx)
require.Nil(err, "%d: %+v", i, err)
require.True(bres.CheckTx.IsOK())
require.True(bres.DeliverTx.IsOK())
@@ -351,7 +356,7 @@ func TestUnconfirmedTxs(t *testing.T) {
for _, c := range GetClients() {
mc := c.(client.MempoolClient)
limit := 1
res, err := mc.UnconfirmedTxs(&limit)
res, err := mc.UnconfirmedTxs(context.Background(), &limit)
require.NoError(t, err)
assert.Equal(t, 1, res.Count)
@@ -382,7 +387,7 @@ func TestNumUnconfirmedTxs(t *testing.T) {
for i, c := range GetClients() {
mc, ok := c.(client.MempoolClient)
require.True(t, ok, "%d", i)
res, err := mc.NumUnconfirmedTxs()
res, err := mc.NumUnconfirmedTxs(context.Background())
require.Nil(t, err, "%d: %+v", i, err)
assert.Equal(t, mempoolSize, res.Count)
@@ -399,7 +404,7 @@ func TestCheckTx(t *testing.T) {
for _, c := range GetClients() {
_, _, tx := MakeTxKV()
res, err := c.CheckTx(tx)
res, err := c.CheckTx(context.Background(), tx)
require.NoError(t, err)
assert.Equal(t, abci.CodeTypeOK, res.Code)
@@ -411,7 +416,7 @@ func TestTx(t *testing.T) {
// first we broadcast a tx
c := getHTTPClient()
_, _, tx := MakeTxKV()
bres, err := c.BroadcastTxCommit(tx)
bres, err := c.BroadcastTxCommit(context.Background(), tx)
require.Nil(t, err, "%+v", err)
txHeight := bres.Height
@@ -439,7 +444,7 @@ func TestTx(t *testing.T) {
// now we query for the tx.
// since there's only one tx, we know index=0.
ptx, err := c.Tx(tc.hash, tc.prove)
ptx, err := c.Tx(context.Background(), tc.hash, tc.prove)
if !tc.valid {
require.NotNil(t, err)
@@ -466,11 +471,11 @@ func TestTxSearchWithTimeout(t *testing.T) {
timeoutClient := getHTTPClientWithTimeout(10)
_, _, tx := MakeTxKV()
_, err := timeoutClient.BroadcastTxCommit(tx)
_, err := timeoutClient.BroadcastTxCommit(context.Background(), tx)
require.NoError(t, err)
// query using a compositeKey (see kvstore application)
result, err := timeoutClient.TxSearch("app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
result, err := timeoutClient.TxSearch(context.Background(), "app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
require.Nil(t, err)
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
}
@@ -481,13 +486,13 @@ func TestTxSearch(t *testing.T) {
// first we broadcast a few txs
for i := 0; i < 10; i++ {
_, _, tx := MakeTxKV()
_, err := c.BroadcastTxCommit(tx)
_, err := c.BroadcastTxCommit(context.Background(), tx)
require.NoError(t, err)
}
// since we're not using an isolated test server, we'll have lingering transactions
// from other tests as well
result, err := c.TxSearch("tx.height >= 0", true, nil, nil, "asc")
result, err := c.TxSearch(context.Background(), "tx.height >= 0", true, nil, nil, "asc")
require.NoError(t, err)
txCount := len(result.Txs)
@@ -499,7 +504,7 @@ func TestTxSearch(t *testing.T) {
t.Logf("client %d", i)
// now we query for the tx.
result, err := c.TxSearch(fmt.Sprintf("tx.hash='%v'", find.Hash), true, nil, nil, "asc")
result, err := c.TxSearch(context.Background(), fmt.Sprintf("tx.hash='%v'", find.Hash), true, nil, nil, "asc")
require.Nil(t, err)
require.Len(t, result.Txs, 1)
require.Equal(t, find.Hash, result.Txs[0].Hash)
@@ -517,50 +522,51 @@ func TestTxSearch(t *testing.T) {
}
// query by height
result, err = c.TxSearch(fmt.Sprintf("tx.height=%d", find.Height), true, nil, nil, "asc")
result, err = c.TxSearch(context.Background(), fmt.Sprintf("tx.height=%d", find.Height), true, nil, nil, "asc")
require.Nil(t, err)
require.Len(t, result.Txs, 1)
// query for non existing tx
result, err = c.TxSearch(fmt.Sprintf("tx.hash='%X'", anotherTxHash), false, nil, nil, "asc")
result, err = c.TxSearch(context.Background(), fmt.Sprintf("tx.hash='%X'", anotherTxHash), false, nil, nil, "asc")
require.Nil(t, err)
require.Len(t, result.Txs, 0)
// query using a compositeKey (see kvstore application)
result, err = c.TxSearch("app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
result, err = c.TxSearch(context.Background(), "app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
require.Nil(t, err)
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
// query using an index key
result, err = c.TxSearch("app.index_key='index is working'", false, nil, nil, "asc")
result, err = c.TxSearch(context.Background(), "app.index_key='index is working'", false, nil, nil, "asc")
require.Nil(t, err)
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
// query using an noindex key
result, err = c.TxSearch("app.noindex_key='index is working'", false, nil, nil, "asc")
result, err = c.TxSearch(context.Background(), "app.noindex_key='index is working'", false, nil, nil, "asc")
require.Nil(t, err)
require.Equal(t, len(result.Txs), 0, "expected a lot of transactions")
// query using a compositeKey (see kvstore application) and height
result, err = c.TxSearch("app.creator='Cosmoshi Netowoko' AND tx.height<10000", true, nil, nil, "asc")
result, err = c.TxSearch(context.Background(),
"app.creator='Cosmoshi Netowoko' AND tx.height<10000", true, nil, nil, "asc")
require.Nil(t, err)
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
// query a non existing tx with page 1 and txsPerPage 1
perPage := 1
result, err = c.TxSearch("app.creator='Cosmoshi Neetowoko'", true, nil, &perPage, "asc")
result, err = c.TxSearch(context.Background(), "app.creator='Cosmoshi Neetowoko'", true, nil, &perPage, "asc")
require.Nil(t, err)
require.Len(t, result.Txs, 0)
// check sorting
result, err = c.TxSearch("tx.height >= 1", false, nil, nil, "asc")
result, err = c.TxSearch(context.Background(), "tx.height >= 1", false, nil, nil, "asc")
require.Nil(t, err)
for k := 0; k < len(result.Txs)-1; k++ {
require.LessOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height)
require.LessOrEqual(t, result.Txs[k].Index, result.Txs[k+1].Index)
}
result, err = c.TxSearch("tx.height >= 1", false, nil, nil, "desc")
result, err = c.TxSearch(context.Background(), "tx.height >= 1", false, nil, nil, "desc")
require.Nil(t, err)
for k := 0; k < len(result.Txs)-1; k++ {
require.GreaterOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height)
@@ -576,7 +582,7 @@ func TestTxSearch(t *testing.T) {
for page := 1; page <= pages; page++ {
page := page
result, err := c.TxSearch("tx.height >= 1", false, &page, &perPage, "asc")
result, err := c.TxSearch(context.Background(), "tx.height >= 1", false, &page, &perPage, "asc")
require.NoError(t, err)
if page < pages {
require.Len(t, result.Txs, perPage)
@@ -607,12 +613,12 @@ func testBatchedJSONRPCCalls(t *testing.T, c *rpchttp.HTTP) {
k2, v2, tx2 := MakeTxKV()
batch := c.NewBatch()
r1, err := batch.BroadcastTxCommit(tx1)
r1, err := batch.BroadcastTxCommit(context.Background(), tx1)
require.NoError(t, err)
r2, err := batch.BroadcastTxCommit(tx2)
r2, err := batch.BroadcastTxCommit(context.Background(), tx2)
require.NoError(t, err)
require.Equal(t, 2, batch.Count())
bresults, err := batch.Send()
bresults, err := batch.Send(ctx)
require.NoError(t, err)
require.Len(t, bresults, 2)
require.Equal(t, 0, batch.Count())
@@ -628,12 +634,12 @@ func testBatchedJSONRPCCalls(t *testing.T, c *rpchttp.HTTP) {
err = client.WaitForHeight(c, apph, nil)
require.NoError(t, err)
q1, err := batch.ABCIQuery("/key", k1)
q1, err := batch.ABCIQuery(context.Background(), "/key", k1)
require.NoError(t, err)
q2, err := batch.ABCIQuery("/key", k2)
q2, err := batch.ABCIQuery(context.Background(), "/key", k2)
require.NoError(t, err)
require.Equal(t, 2, batch.Count())
qresults, err := batch.Send()
qresults, err := batch.Send(ctx)
require.NoError(t, err)
require.Len(t, qresults, 2)
require.Equal(t, 0, batch.Count())
@@ -657,9 +663,9 @@ func TestBatchedJSONRPCCallsCancellation(t *testing.T) {
_, _, tx2 := MakeTxKV()
batch := c.NewBatch()
_, err := batch.BroadcastTxCommit(tx1)
_, err := batch.BroadcastTxCommit(context.Background(), tx1)
require.NoError(t, err)
_, err = batch.BroadcastTxCommit(tx2)
_, err = batch.BroadcastTxCommit(context.Background(), tx2)
require.NoError(t, err)
// we should have 2 requests waiting
require.Equal(t, 2, batch.Count())
@@ -672,7 +678,7 @@ func TestBatchedJSONRPCCallsCancellation(t *testing.T) {
func TestSendingEmptyRequestBatch(t *testing.T) {
c := getHTTPClient()
batch := c.NewBatch()
_, err := batch.Send()
_, err := batch.Send(ctx)
require.Error(t, err, "sending an empty batch of JSON RPC requests should result in an error")
}