Browse Source

rpc: replace custom context-like argument with context.Context (#7559)

* Rename rpctypes.Context to CallInfo.

Add methods to attach and recover this value from a context.Context.

* Rework RPC method handlers to accept "real" contexts.

- Replace *rpctypes.Context arguments with context.Context.
- Update usage of RPC context fields to use CallInfo.
wb/rollback-test-fix
M. J. Fromberger 2 years ago
committed by GitHub
parent
commit
50ac52e28d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 268 additions and 266 deletions
  1. +6
    -5
      internal/rpc/core/abci.go
  2. +10
    -10
      internal/rpc/core/blocks.go
  3. +3
    -2
      internal/rpc/core/blocks_test.go
  4. +6
    -5
      internal/rpc/core/consensus.go
  5. +3
    -2
      internal/rpc/core/dev.go
  6. +13
    -12
      internal/rpc/core/events.go
  7. +2
    -2
      internal/rpc/core/evidence.go
  8. +3
    -2
      internal/rpc/core/health.go
  9. +13
    -13
      internal/rpc/core/mempool.go
  10. +4
    -4
      internal/rpc/core/net.go
  11. +2
    -2
      internal/rpc/core/status.go
  12. +4
    -4
      internal/rpc/core/tx.go
  13. +83
    -82
      light/proxy/routes.go
  14. +9
    -8
      light/rpc/client.go
  15. +30
    -33
      rpc/client/local/local.go
  16. +19
    -20
      rpc/client/mock/client.go
  17. +5
    -6
      rpc/jsonrpc/jsonrpc_test.go
  18. +6
    -5
      rpc/jsonrpc/server/http_json_handler.go
  19. +3
    -2
      rpc/jsonrpc/server/http_json_handler_test.go
  20. +1
    -1
      rpc/jsonrpc/server/http_uri_handler.go
  21. +3
    -3
      rpc/jsonrpc/server/parse_test.go
  22. +5
    -2
      rpc/jsonrpc/server/ws_handler.go
  23. +2
    -1
      rpc/jsonrpc/server/ws_handler_test.go
  24. +1
    -2
      rpc/jsonrpc/test/main.go
  25. +32
    -38
      rpc/jsonrpc/types/types.go

+ 6
- 5
internal/rpc/core/abci.go View File

@ -1,23 +1,24 @@
package core
import (
"context"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/internal/proxy"
"github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
// ABCIQuery queries the application for some information.
// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_query
func (env *Environment) ABCIQuery(
ctx *rpctypes.Context,
ctx context.Context,
path string,
data bytes.HexBytes,
height int64,
prove bool,
) (*coretypes.ResultABCIQuery, error) {
resQuery, err := env.ProxyAppQuery.QuerySync(ctx.Context(), abci.RequestQuery{
resQuery, err := env.ProxyAppQuery.QuerySync(ctx, abci.RequestQuery{
Path: path,
Data: data,
Height: height,
@ -32,8 +33,8 @@ func (env *Environment) ABCIQuery(
// ABCIInfo gets some info about the application.
// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info
func (env *Environment) ABCIInfo(ctx *rpctypes.Context) (*coretypes.ResultABCIInfo, error) {
resInfo, err := env.ProxyAppQuery.InfoSync(ctx.Context(), proxy.RequestInfo)
func (env *Environment) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
resInfo, err := env.ProxyAppQuery.InfoSync(ctx, proxy.RequestInfo)
if err != nil {
return nil, err
}


+ 10
- 10
internal/rpc/core/blocks.go View File

@ -1,6 +1,7 @@
package core
import (
"context"
"fmt"
"sort"
@ -9,7 +10,6 @@ import (
"github.com/tendermint/tendermint/libs/bytes"
tmmath "github.com/tendermint/tendermint/libs/math"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
@ -24,7 +24,7 @@ import (
//
// More: https://docs.tendermint.com/master/rpc/#/Info/blockchain
func (env *Environment) BlockchainInfo(
ctx *rpctypes.Context,
ctx context.Context,
minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
const limit int64 = 20
@ -92,7 +92,7 @@ func filterMinMax(base, height, min, max, limit int64) (int64, int64, error) {
// Block gets block at a given height.
// If no height is provided, it will fetch the latest block.
// More: https://docs.tendermint.com/master/rpc/#/Info/block
func (env *Environment) Block(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultBlock, error) {
func (env *Environment) Block(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlock, error) {
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
if err != nil {
return nil, err
@ -109,7 +109,7 @@ func (env *Environment) Block(ctx *rpctypes.Context, heightPtr *int64) (*coretyp
// BlockByHash gets block by hash.
// More: https://docs.tendermint.com/master/rpc/#/Info/block_by_hash
func (env *Environment) BlockByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) {
func (env *Environment) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) {
// N.B. The hash parameter is HexBytes so that the reflective parameter
// decoding logic in the HTTP service will correctly translate from JSON.
// See https://github.com/tendermint/tendermint/issues/6802 for context.
@ -126,7 +126,7 @@ func (env *Environment) BlockByHash(ctx *rpctypes.Context, hash bytes.HexBytes)
// Header gets block header at a given height.
// If no height is provided, it will fetch the latest header.
// More: https://docs.tendermint.com/master/rpc/#/Info/header
func (env *Environment) Header(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultHeader, error) {
func (env *Environment) Header(ctx context.Context, heightPtr *int64) (*coretypes.ResultHeader, error) {
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
if err != nil {
return nil, err
@ -142,7 +142,7 @@ func (env *Environment) Header(ctx *rpctypes.Context, heightPtr *int64) (*corety
// HeaderByHash gets header by hash.
// More: https://docs.tendermint.com/master/rpc/#/Info/header_by_hash
func (env *Environment) HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) {
func (env *Environment) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) {
// N.B. The hash parameter is HexBytes so that the reflective parameter
// decoding logic in the HTTP service will correctly translate from JSON.
// See https://github.com/tendermint/tendermint/issues/6802 for context.
@ -158,7 +158,7 @@ func (env *Environment) HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes)
// Commit gets block commit at a given height.
// If no height is provided, it will fetch the commit for the latest block.
// More: https://docs.tendermint.com/master/rpc/#/Info/commit
func (env *Environment) Commit(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultCommit, error) {
func (env *Environment) Commit(ctx context.Context, heightPtr *int64) (*coretypes.ResultCommit, error) {
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
if err != nil {
return nil, err
@ -196,7 +196,7 @@ func (env *Environment) Commit(ctx *rpctypes.Context, heightPtr *int64) (*corety
// Thus response.results.deliver_tx[5] is the results of executing
// getBlock(h).Txs[5]
// More: https://docs.tendermint.com/master/rpc/#/Info/block_results
func (env *Environment) BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error) {
func (env *Environment) BlockResults(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error) {
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
if err != nil {
return nil, err
@ -226,7 +226,7 @@ func (env *Environment) BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*
// BlockSearch searches for a paginated set of blocks matching BeginBlock and
// EndBlock event search criteria.
func (env *Environment) BlockSearch(
ctx *rpctypes.Context,
ctx context.Context,
query string,
pagePtr, perPagePtr *int,
orderBy string,
@ -248,7 +248,7 @@ func (env *Environment) BlockSearch(
}
}
results, err := kvsink.SearchBlockEvents(ctx.Context(), q)
results, err := kvsink.SearchBlockEvents(ctx, q)
if err != nil {
return nil, err
}


+ 3
- 2
internal/rpc/core/blocks_test.go View File

@ -1,6 +1,7 @@
package core
import (
"context"
"fmt"
"testing"
@ -14,7 +15,6 @@ import (
"github.com/tendermint/tendermint/internal/state/mocks"
tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
func TestBlockchainInfo(t *testing.T) {
@ -108,8 +108,9 @@ func TestBlockResults(t *testing.T) {
}},
}
ctx := context.Background()
for _, tc := range testCases {
res, err := env.BlockResults(&rpctypes.Context{}, &tc.height)
res, err := env.BlockResults(ctx, &tc.height)
if tc.wantErr {
assert.Error(t, err)
} else {


+ 6
- 5
internal/rpc/core/consensus.go View File

@ -1,9 +1,10 @@
package core
import (
"context"
tmmath "github.com/tendermint/tendermint/libs/math"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
// Validators gets the validator set at the given block height.
@ -14,7 +15,7 @@ import (
//
// More: https://docs.tendermint.com/master/rpc/#/Info/validators
func (env *Environment) Validators(
ctx *rpctypes.Context,
ctx context.Context,
heightPtr *int64,
pagePtr, perPagePtr *int) (*coretypes.ResultValidators, error) {
@ -50,7 +51,7 @@ func (env *Environment) Validators(
// DumpConsensusState dumps consensus state.
// UNSTABLE
// More: https://docs.tendermint.com/master/rpc/#/Info/dump_consensus_state
func (env *Environment) DumpConsensusState(ctx *rpctypes.Context) (*coretypes.ResultDumpConsensusState, error) {
func (env *Environment) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) {
// Get Peer consensus states.
var peerStates []coretypes.PeerStateInfo
@ -91,7 +92,7 @@ func (env *Environment) DumpConsensusState(ctx *rpctypes.Context) (*coretypes.Re
// ConsensusState returns a concise summary of the consensus state.
// UNSTABLE
// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_state
func (env *Environment) GetConsensusState(ctx *rpctypes.Context) (*coretypes.ResultConsensusState, error) {
func (env *Environment) GetConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) {
// Get self round state.
bz, err := env.ConsensusState.GetRoundStateSimpleJSON()
return &coretypes.ResultConsensusState{RoundState: bz}, err
@ -101,7 +102,7 @@ func (env *Environment) GetConsensusState(ctx *rpctypes.Context) (*coretypes.Res
// If no height is provided, it will fetch the latest consensus params.
// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_params
func (env *Environment) ConsensusParams(
ctx *rpctypes.Context,
ctx context.Context,
heightPtr *int64) (*coretypes.ResultConsensusParams, error) {
// The latest consensus params that we know is the consensus params after the


+ 3
- 2
internal/rpc/core/dev.go View File

@ -1,12 +1,13 @@
package core
import (
"context"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
// UnsafeFlushMempool removes all transactions from the mempool.
func (env *Environment) UnsafeFlushMempool(ctx *rpctypes.Context) (*coretypes.ResultUnsafeFlushMempool, error) {
func (env *Environment) UnsafeFlushMempool(ctx context.Context) (*coretypes.ResultUnsafeFlushMempool, error) {
env.Mempool.Flush()
return &coretypes.ResultUnsafeFlushMempool{}, nil
}

+ 13
- 12
internal/rpc/core/events.go View File

@ -23,8 +23,9 @@ const (
// Subscribe for events via WebSocket.
// More: https://docs.tendermint.com/master/rpc/#/Websocket/subscribe
func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretypes.ResultSubscribe, error) {
addr := ctx.RemoteAddr()
func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) {
callInfo := rpctypes.GetCallInfo(ctx)
addr := callInfo.RemoteAddr()
if env.EventBus.NumClients() >= env.Config.MaxSubscriptionClients {
return nil, fmt.Errorf("max_subscription_clients %d reached", env.Config.MaxSubscriptionClients)
@ -41,7 +42,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
return nil, fmt.Errorf("failed to parse query: %w", err)
}
subCtx, cancel := context.WithTimeout(ctx.Context(), SubscribeTimeout)
subCtx, cancel := context.WithTimeout(ctx, SubscribeTimeout)
defer cancel()
sub, err := env.EventBus.SubscribeWithArgs(subCtx, tmpubsub.SubscribeArgs{
@ -54,7 +55,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
}
// Capture the current ID, since it can change in the future.
subscriptionID := ctx.JSONReq.ID
subscriptionID := callInfo.RPCRequest.ID
go func() {
opctx, opcancel := context.WithCancel(context.Background())
defer opcancel()
@ -67,7 +68,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
} else if errors.Is(err, tmpubsub.ErrTerminated) {
// The subscription was terminated by the publisher.
resp := rpctypes.RPCServerError(subscriptionID, err)
ok := ctx.WSConn.TryWriteRPCResponse(opctx, resp)
ok := callInfo.WSConn.TryWriteRPCResponse(opctx, resp)
if !ok {
env.Logger.Info("Unable to write response (slow client)",
"to", addr, "subscriptionID", subscriptionID, "err", err)
@ -82,7 +83,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
Events: msg.Events(),
})
wctx, cancel := context.WithTimeout(opctx, 10*time.Second)
err = ctx.WSConn.WriteRPCResponse(wctx, resp)
err = callInfo.WSConn.WriteRPCResponse(wctx, resp)
cancel()
if err != nil {
env.Logger.Info("Unable to write response (slow client)",
@ -96,8 +97,8 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
// Unsubscribe from events via WebSocket.
// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe
func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*coretypes.ResultUnsubscribe, error) {
args := tmpubsub.UnsubscribeArgs{Subscriber: ctx.RemoteAddr()}
func (env *Environment) Unsubscribe(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) {
args := tmpubsub.UnsubscribeArgs{Subscriber: rpctypes.GetCallInfo(ctx).RemoteAddr()}
env.Logger.Info("Unsubscribe from query", "remote", args.Subscriber, "subscription", query)
var err error
@ -107,7 +108,7 @@ func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*coret
args.ID = query
}
err = env.EventBus.Unsubscribe(ctx.Context(), args)
err = env.EventBus.Unsubscribe(ctx, args)
if err != nil {
return nil, err
}
@ -116,10 +117,10 @@ func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*coret
// UnsubscribeAll from all events via WebSocket.
// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe_all
func (env *Environment) UnsubscribeAll(ctx *rpctypes.Context) (*coretypes.ResultUnsubscribe, error) {
addr := ctx.RemoteAddr()
func (env *Environment) UnsubscribeAll(ctx context.Context) (*coretypes.ResultUnsubscribe, error) {
addr := rpctypes.GetCallInfo(ctx).RemoteAddr()
env.Logger.Info("Unsubscribe from all", "remote", addr)
err := env.EventBus.UnsubscribeAll(ctx.Context(), addr)
err := env.EventBus.UnsubscribeAll(ctx, addr)
if err != nil {
return nil, err
}


+ 2
- 2
internal/rpc/core/evidence.go View File

@ -1,17 +1,17 @@
package core
import (
"context"
"fmt"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
// BroadcastEvidence broadcasts evidence of the misbehavior.
// More: https://docs.tendermint.com/master/rpc/#/Evidence/broadcast_evidence
func (env *Environment) BroadcastEvidence(
ctx *rpctypes.Context,
ctx context.Context,
ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
if ev == nil {


+ 3
- 2
internal/rpc/core/health.go View File

@ -1,13 +1,14 @@
package core
import (
"context"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
// Health gets node health. Returns empty result (200 OK) on success, no
// response - in case of an error.
// More: https://docs.tendermint.com/master/rpc/#/Info/health
func (env *Environment) Health(ctx *rpctypes.Context) (*coretypes.ResultHealth, error) {
func (env *Environment) Health(ctx context.Context) (*coretypes.ResultHealth, error) {
return &coretypes.ResultHealth{}, nil
}

+ 13
- 13
internal/rpc/core/mempool.go View File

@ -1,6 +1,7 @@
package core
import (
"context"
"errors"
"fmt"
"math/rand"
@ -10,7 +11,6 @@ import (
"github.com/tendermint/tendermint/internal/mempool"
"github.com/tendermint/tendermint/internal/state/indexer"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
@ -20,8 +20,8 @@ import (
// BroadcastTxAsync returns right away, with no response. Does not wait for
// CheckTx nor DeliverTx results.
// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async
func (env *Environment) BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
err := env.Mempool.CheckTx(ctx.Context(), tx, nil, mempool.TxInfo{})
func (env *Environment) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
err := env.Mempool.CheckTx(ctx, tx, nil, mempool.TxInfo{})
if err != nil {
return nil, err
}
@ -32,10 +32,10 @@ func (env *Environment) BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*c
// BroadcastTxSync returns with the response from CheckTx. Does not wait for
// DeliverTx result.
// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync
func (env *Environment) BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
func (env *Environment) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
resCh := make(chan *abci.Response, 1)
err := env.Mempool.CheckTx(
ctx.Context(),
ctx,
tx,
func(res *abci.Response) { resCh <- res },
mempool.TxInfo{},
@ -59,10 +59,10 @@ func (env *Environment) BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*co
// BroadcastTxCommit returns with the responses from CheckTx and DeliverTx.
// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_commit
func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
resCh := make(chan *abci.Response, 1)
err := env.Mempool.CheckTx(
ctx.Context(),
ctx,
tx,
func(res *abci.Response) { resCh <- res },
mempool.TxInfo{},
@ -89,7 +89,7 @@ func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*
for {
count++
select {
case <-ctx.Context().Done():
case <-ctx.Done():
env.Logger.Error("error on broadcastTxCommit",
"duration", time.Since(startAt),
"err", err)
@ -120,7 +120,7 @@ func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*
// UnconfirmedTxs gets unconfirmed transactions (maximum ?limit entries)
// including their number.
// More: https://docs.tendermint.com/master/rpc/#/Info/unconfirmed_txs
func (env *Environment) UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*coretypes.ResultUnconfirmedTxs, error) {
func (env *Environment) UnconfirmedTxs(ctx context.Context, limitPtr *int) (*coretypes.ResultUnconfirmedTxs, error) {
// reuse per_page validator
limit := env.validatePerPage(limitPtr)
@ -134,7 +134,7 @@ func (env *Environment) UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*c
// NumUnconfirmedTxs gets number of unconfirmed transactions.
// More: https://docs.tendermint.com/master/rpc/#/Info/num_unconfirmed_txs
func (env *Environment) NumUnconfirmedTxs(ctx *rpctypes.Context) (*coretypes.ResultUnconfirmedTxs, error) {
func (env *Environment) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) {
return &coretypes.ResultUnconfirmedTxs{
Count: env.Mempool.Size(),
Total: env.Mempool.Size(),
@ -144,14 +144,14 @@ func (env *Environment) NumUnconfirmedTxs(ctx *rpctypes.Context) (*coretypes.Res
// CheckTx checks the transaction without executing it. The transaction won't
// be added to the mempool either.
// More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx
func (env *Environment) CheckTx(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
res, err := env.ProxyAppMempool.CheckTxSync(ctx.Context(), abci.RequestCheckTx{Tx: tx})
func (env *Environment) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
res, err := env.ProxyAppMempool.CheckTxSync(ctx, abci.RequestCheckTx{Tx: tx})
if err != nil {
return nil, err
}
return &coretypes.ResultCheckTx{ResponseCheckTx: *res}, nil
}
func (env *Environment) RemoveTx(ctx *rpctypes.Context, txkey types.TxKey) error {
func (env *Environment) RemoveTx(ctx context.Context, txkey types.TxKey) error {
return env.Mempool.RemoveTxByKey(txkey)
}

+ 4
- 4
internal/rpc/core/net.go View File

@ -1,16 +1,16 @@
package core
import (
"context"
"errors"
"fmt"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
// NetInfo returns network info.
// More: https://docs.tendermint.com/master/rpc/#/Info/net_info
func (env *Environment) NetInfo(ctx *rpctypes.Context) (*coretypes.ResultNetInfo, error) {
func (env *Environment) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) {
peerList := env.PeerManager.Peers()
peers := make([]coretypes.Peer, 0, len(peerList))
@ -36,7 +36,7 @@ func (env *Environment) NetInfo(ctx *rpctypes.Context) (*coretypes.ResultNetInfo
// Genesis returns genesis file.
// More: https://docs.tendermint.com/master/rpc/#/Info/genesis
func (env *Environment) Genesis(ctx *rpctypes.Context) (*coretypes.ResultGenesis, error) {
func (env *Environment) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) {
if len(env.genChunks) > 1 {
return nil, errors.New("genesis response is large, please use the genesis_chunked API instead")
}
@ -44,7 +44,7 @@ func (env *Environment) Genesis(ctx *rpctypes.Context) (*coretypes.ResultGenesis
return &coretypes.ResultGenesis{Genesis: env.GenDoc}, nil
}
func (env *Environment) GenesisChunked(ctx *rpctypes.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
func (env *Environment) GenesisChunked(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
if env.genChunks == nil {
return nil, fmt.Errorf("service configuration error, genesis chunks are not initialized")
}


+ 2
- 2
internal/rpc/core/status.go View File

@ -2,18 +2,18 @@ package core
import (
"bytes"
"context"
"time"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
// Status returns Tendermint status including node info, pubkey, latest block
// hash, app hash, block height, current max peer block height, and time.
// More: https://docs.tendermint.com/master/rpc/#/Info/status
func (env *Environment) Status(ctx *rpctypes.Context) (*coretypes.ResultStatus, error) {
func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, error) {
var (
earliestBlockHeight int64
earliestBlockHash tmbytes.HexBytes


+ 4
- 4
internal/rpc/core/tx.go View File

@ -1,6 +1,7 @@
package core
import (
"context"
"errors"
"fmt"
"sort"
@ -10,7 +11,6 @@ import (
"github.com/tendermint/tendermint/libs/bytes"
tmmath "github.com/tendermint/tendermint/libs/math"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
@ -18,7 +18,7 @@ import (
// transaction is in the mempool, invalidated, or was not sent in the first
// place.
// More: https://docs.tendermint.com/master/rpc/#/Info/tx
func (env *Environment) Tx(ctx *rpctypes.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) {
func (env *Environment) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) {
// if index is disabled, return error
// N.B. The hash parameter is HexBytes so that the reflective parameter
@ -63,7 +63,7 @@ func (env *Environment) Tx(ctx *rpctypes.Context, hash bytes.HexBytes, prove boo
// list of transactions (maximum ?per_page entries) and the total count.
// More: https://docs.tendermint.com/master/rpc/#/Info/tx_search
func (env *Environment) TxSearch(
ctx *rpctypes.Context,
ctx context.Context,
query string,
prove bool,
pagePtr, perPagePtr *int,
@ -83,7 +83,7 @@ func (env *Environment) TxSearch(
for _, sink := range env.EventSinks {
if sink.Type() == indexer.KV {
results, err := sink.SearchTxEvents(ctx.Context(), q)
results, err := sink.SearchTxEvents(ctx, q)
if err != nil {
return nil, err
}


+ 83
- 82
light/proxy/routes.go View File

@ -1,12 +1,13 @@
package proxy
import (
"context"
"github.com/tendermint/tendermint/libs/bytes"
lrpc "github.com/tendermint/tendermint/light/rpc"
rpcclient "github.com/tendermint/tendermint/rpc/client"
"github.com/tendermint/tendermint/rpc/coretypes"
rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
@ -54,113 +55,113 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
}
}
type rpcHealthFunc func(ctx *rpctypes.Context) (*coretypes.ResultHealth, error)
type rpcHealthFunc func(ctx context.Context) (*coretypes.ResultHealth, error)
func makeHealthFunc(c *lrpc.Client) rpcHealthFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultHealth, error) {
return c.Health(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultHealth, error) {
return c.Health(ctx)
}
}
type rpcStatusFunc func(ctx *rpctypes.Context) (*coretypes.ResultStatus, error)
type rpcStatusFunc func(ctx context.Context) (*coretypes.ResultStatus, error)
// nolint: interfacer
func makeStatusFunc(c *lrpc.Client) rpcStatusFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultStatus, error) {
return c.Status(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultStatus, error) {
return c.Status(ctx)
}
}
type rpcNetInfoFunc func(ctx *rpctypes.Context) (*coretypes.ResultNetInfo, error)
type rpcNetInfoFunc func(ctx context.Context) (*coretypes.ResultNetInfo, error)
func makeNetInfoFunc(c *lrpc.Client) rpcNetInfoFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultNetInfo, error) {
return c.NetInfo(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultNetInfo, error) {
return c.NetInfo(ctx)
}
}
type rpcBlockchainInfoFunc func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error)
type rpcBlockchainInfoFunc func(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error)
func makeBlockchainInfoFunc(c *lrpc.Client) rpcBlockchainInfoFunc {
return func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
return c.BlockchainInfo(ctx.Context(), minHeight, maxHeight)
return func(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
return c.BlockchainInfo(ctx, minHeight, maxHeight)
}
}
type rpcGenesisFunc func(ctx *rpctypes.Context) (*coretypes.ResultGenesis, error)
type rpcGenesisFunc func(ctx context.Context) (*coretypes.ResultGenesis, error)
func makeGenesisFunc(c *lrpc.Client) rpcGenesisFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultGenesis, error) {
return c.Genesis(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultGenesis, error) {
return c.Genesis(ctx)
}
}
type rpcGenesisChunkedFunc func(ctx *rpctypes.Context, chunk uint) (*coretypes.ResultGenesisChunk, error)
type rpcGenesisChunkedFunc func(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error)
func makeGenesisChunkedFunc(c *lrpc.Client) rpcGenesisChunkedFunc {
return func(ctx *rpctypes.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
return c.GenesisChunked(ctx.Context(), chunk)
return func(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
return c.GenesisChunked(ctx, chunk)
}
}
type rpcHeaderFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultHeader, error)
type rpcHeaderFunc func(ctx context.Context, height *int64) (*coretypes.ResultHeader, error)
func makeHeaderFunc(c *lrpc.Client) rpcHeaderFunc {
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultHeader, error) {
return c.Header(ctx.Context(), height)
return func(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) {
return c.Header(ctx, height)
}
}
type rpcHeaderByHashFunc func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultHeader, error)
type rpcHeaderByHashFunc func(ctx context.Context, hash []byte) (*coretypes.ResultHeader, error)
func makeHeaderByHashFunc(c *lrpc.Client) rpcHeaderByHashFunc {
return func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultHeader, error) {
return c.HeaderByHash(ctx.Context(), hash)
return func(ctx context.Context, hash []byte) (*coretypes.ResultHeader, error) {
return c.HeaderByHash(ctx, hash)
}
}
type rpcBlockFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlock, error)
type rpcBlockFunc func(ctx context.Context, height *int64) (*coretypes.ResultBlock, error)
func makeBlockFunc(c *lrpc.Client) rpcBlockFunc {
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlock, error) {
return c.Block(ctx.Context(), height)
return func(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) {
return c.Block(ctx, height)
}
}
type rpcBlockByHashFunc func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultBlock, error)
type rpcBlockByHashFunc func(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error)
func makeBlockByHashFunc(c *lrpc.Client) rpcBlockByHashFunc {
return func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultBlock, error) {
return c.BlockByHash(ctx.Context(), hash)
return func(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) {
return c.BlockByHash(ctx, hash)
}
}
type rpcBlockResultsFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlockResults, error)
type rpcBlockResultsFunc func(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error)
func makeBlockResultsFunc(c *lrpc.Client) rpcBlockResultsFunc {
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlockResults, error) {
return c.BlockResults(ctx.Context(), height)
return func(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) {
return c.BlockResults(ctx, height)
}
}
type rpcCommitFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultCommit, error)
type rpcCommitFunc func(ctx context.Context, height *int64) (*coretypes.ResultCommit, error)
func makeCommitFunc(c *lrpc.Client) rpcCommitFunc {
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultCommit, error) {
return c.Commit(ctx.Context(), height)
return func(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) {
return c.Commit(ctx, height)
}
}
type rpcTxFunc func(ctx *rpctypes.Context, hash []byte, prove bool) (*coretypes.ResultTx, error)
type rpcTxFunc func(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error)
func makeTxFunc(c *lrpc.Client) rpcTxFunc {
return func(ctx *rpctypes.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) {
return c.Tx(ctx.Context(), hash, prove)
return func(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) {
return c.Tx(ctx, hash, prove)
}
}
type rpcTxSearchFunc func(
ctx *rpctypes.Context,
ctx context.Context,
query string,
prove bool,
page, perPage *int,
@ -169,18 +170,18 @@ type rpcTxSearchFunc func(
func makeTxSearchFunc(c *lrpc.Client) rpcTxSearchFunc {
return func(
ctx *rpctypes.Context,
ctx context.Context,
query string,
prove bool,
page, perPage *int,
orderBy string,
) (*coretypes.ResultTxSearch, error) {
return c.TxSearch(ctx.Context(), query, prove, page, perPage, orderBy)
return c.TxSearch(ctx, query, prove, page, perPage, orderBy)
}
}
type rpcBlockSearchFunc func(
ctx *rpctypes.Context,
ctx context.Context,
query string,
prove bool,
page, perPage *int,
@ -189,116 +190,116 @@ type rpcBlockSearchFunc func(
func makeBlockSearchFunc(c *lrpc.Client) rpcBlockSearchFunc {
return func(
ctx *rpctypes.Context,
ctx context.Context,
query string,
prove bool,
page, perPage *int,
orderBy string,
) (*coretypes.ResultBlockSearch, error) {
return c.BlockSearch(ctx.Context(), query, page, perPage, orderBy)
return c.BlockSearch(ctx, query, page, perPage, orderBy)
}
}
type rpcValidatorsFunc func(ctx *rpctypes.Context, height *int64,
type rpcValidatorsFunc func(ctx context.Context, height *int64,
page, perPage *int) (*coretypes.ResultValidators, error)
func makeValidatorsFunc(c *lrpc.Client) rpcValidatorsFunc {
return func(ctx *rpctypes.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
return c.Validators(ctx.Context(), height, page, perPage)
return func(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
return c.Validators(ctx, height, page, perPage)
}
}
type rpcDumpConsensusStateFunc func(ctx *rpctypes.Context) (*coretypes.ResultDumpConsensusState, error)
type rpcDumpConsensusStateFunc func(ctx context.Context) (*coretypes.ResultDumpConsensusState, error)
func makeDumpConsensusStateFunc(c *lrpc.Client) rpcDumpConsensusStateFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultDumpConsensusState, error) {
return c.DumpConsensusState(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) {
return c.DumpConsensusState(ctx)
}
}
type rpcConsensusStateFunc func(ctx *rpctypes.Context) (*coretypes.ResultConsensusState, error)
type rpcConsensusStateFunc func(ctx context.Context) (*coretypes.ResultConsensusState, error)
func makeConsensusStateFunc(c *lrpc.Client) rpcConsensusStateFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultConsensusState, error) {
return c.ConsensusState(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultConsensusState, error) {
return c.ConsensusState(ctx)
}
}
type rpcConsensusParamsFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultConsensusParams, error)
type rpcConsensusParamsFunc func(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error)
func makeConsensusParamsFunc(c *lrpc.Client) rpcConsensusParamsFunc {
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
return c.ConsensusParams(ctx.Context(), height)
return func(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
return c.ConsensusParams(ctx, height)
}
}
type rpcUnconfirmedTxsFunc func(ctx *rpctypes.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error)
type rpcUnconfirmedTxsFunc func(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error)
func makeUnconfirmedTxsFunc(c *lrpc.Client) rpcUnconfirmedTxsFunc {
return func(ctx *rpctypes.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) {
return c.UnconfirmedTxs(ctx.Context(), limit)
return func(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) {
return c.UnconfirmedTxs(ctx, limit)
}
}
type rpcNumUnconfirmedTxsFunc func(ctx *rpctypes.Context) (*coretypes.ResultUnconfirmedTxs, error)
type rpcNumUnconfirmedTxsFunc func(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error)
func makeNumUnconfirmedTxsFunc(c *lrpc.Client) rpcNumUnconfirmedTxsFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultUnconfirmedTxs, error) {
return c.NumUnconfirmedTxs(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) {
return c.NumUnconfirmedTxs(ctx)
}
}
type rpcBroadcastTxCommitFunc func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error)
type rpcBroadcastTxCommitFunc func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error)
func makeBroadcastTxCommitFunc(c *lrpc.Client) rpcBroadcastTxCommitFunc {
return func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
return c.BroadcastTxCommit(ctx.Context(), tx)
return func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
return c.BroadcastTxCommit(ctx, tx)
}
}
type rpcBroadcastTxSyncFunc func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
type rpcBroadcastTxSyncFunc func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
func makeBroadcastTxSyncFunc(c *lrpc.Client) rpcBroadcastTxSyncFunc {
return func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.BroadcastTxSync(ctx.Context(), tx)
return func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.BroadcastTxSync(ctx, tx)
}
}
type rpcBroadcastTxAsyncFunc func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
type rpcBroadcastTxAsyncFunc func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
func makeBroadcastTxAsyncFunc(c *lrpc.Client) rpcBroadcastTxAsyncFunc {
return func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.BroadcastTxAsync(ctx.Context(), tx)
return func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.BroadcastTxAsync(ctx, tx)
}
}
type rpcABCIQueryFunc func(ctx *rpctypes.Context, path string,
type rpcABCIQueryFunc func(ctx context.Context, path string,
data bytes.HexBytes, height int64, prove bool) (*coretypes.ResultABCIQuery, error)
func makeABCIQueryFunc(c *lrpc.Client) rpcABCIQueryFunc {
return func(ctx *rpctypes.Context, path string, data bytes.HexBytes,
return func(ctx context.Context, path string, data bytes.HexBytes,
height int64, prove bool) (*coretypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(ctx.Context(), path, data, rpcclient.ABCIQueryOptions{
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.ABCIQueryOptions{
Height: height,
Prove: prove,
})
}
}
type rpcABCIInfoFunc func(ctx *rpctypes.Context) (*coretypes.ResultABCIInfo, error)
type rpcABCIInfoFunc func(ctx context.Context) (*coretypes.ResultABCIInfo, error)
func makeABCIInfoFunc(c *lrpc.Client) rpcABCIInfoFunc {
return func(ctx *rpctypes.Context) (*coretypes.ResultABCIInfo, error) {
return c.ABCIInfo(ctx.Context())
return func(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
return c.ABCIInfo(ctx)
}
}
type rpcBroadcastEvidenceFunc func(ctx *rpctypes.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error)
type rpcBroadcastEvidenceFunc func(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error)
// nolint: interfacer
func makeBroadcastEvidenceFunc(c *lrpc.Client) rpcBroadcastEvidenceFunc {
return func(ctx *rpctypes.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
return c.BroadcastEvidence(ctx.Context(), ev)
return func(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
return c.BroadcastEvidence(ctx, ev)
}
}

+ 9
- 8
light/rpc/client.go View File

@ -615,11 +615,12 @@ func (c *Client) RegisterOpDecoder(typ string, dec merkle.OpDecoder) {
// SubscribeWS subscribes for events using the given query and remote address as
// a subscriber, but does not verify responses (UNSAFE)!
// TODO: verify data
func (c *Client) SubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.ResultSubscribe, error) {
func (c *Client) SubscribeWS(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) {
bctx, bcancel := context.WithCancel(context.Background())
c.closers = append(c.closers, bcancel)
out, err := c.next.Subscribe(bctx, ctx.RemoteAddr(), query)
callInfo := rpctypes.GetCallInfo(ctx)
out, err := c.next.Subscribe(bctx, callInfo.RemoteAddr(), query)
if err != nil {
return nil, err
}
@ -630,9 +631,9 @@ func (c *Client) SubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.Re
case resultEvent := <-out:
// We should have a switch here that performs a validation
// depending on the event's type.
ctx.WSConn.TryWriteRPCResponse(bctx,
callInfo.WSConn.TryWriteRPCResponse(bctx,
rpctypes.NewRPCSuccessResponse(
rpctypes.JSONRPCStringID(fmt.Sprintf("%v#event", ctx.JSONReq.ID)),
rpctypes.JSONRPCStringID(fmt.Sprintf("%v#event", callInfo.RPCRequest.ID)),
resultEvent,
))
case <-bctx.Done():
@ -646,8 +647,8 @@ func (c *Client) SubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.Re
// UnsubscribeWS calls original client's Unsubscribe using remote address as a
// subscriber.
func (c *Client) UnsubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.ResultUnsubscribe, error) {
err := c.next.Unsubscribe(context.Background(), ctx.RemoteAddr(), query)
func (c *Client) UnsubscribeWS(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) {
err := c.next.Unsubscribe(context.Background(), rpctypes.GetCallInfo(ctx).RemoteAddr(), query)
if err != nil {
return nil, err
}
@ -656,8 +657,8 @@ func (c *Client) UnsubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.
// UnsubscribeAllWS calls original client's UnsubscribeAll using remote address
// as a subscriber.
func (c *Client) UnsubscribeAllWS(ctx *rpctypes.Context) (*coretypes.ResultUnsubscribe, error) {
err := c.next.UnsubscribeAll(context.Background(), ctx.RemoteAddr())
func (c *Client) UnsubscribeAllWS(ctx context.Context) (*coretypes.ResultUnsubscribe, error) {
err := c.next.UnsubscribeAll(context.Background(), rpctypes.GetCallInfo(ctx).RemoteAddr())
if err != nil {
return nil, err
}


+ 30
- 33
rpc/client/local/local.go View File

@ -14,7 +14,6 @@ import (
"github.com/tendermint/tendermint/libs/log"
rpcclient "github.com/tendermint/tendermint/rpc/client"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
@ -41,7 +40,6 @@ backoff (10ms -> 20ms -> 40ms) until successful.
type Local struct {
*eventbus.EventBus
Logger log.Logger
ctx *rpctypes.Context
env *rpccore.Environment
}
@ -61,7 +59,6 @@ func New(node NodeService) (*Local, error) {
return &Local{
EventBus: node.EventBus(),
Logger: log.NewNopLogger(),
ctx: &rpctypes.Context{},
env: env,
}, nil
}
@ -74,11 +71,11 @@ func (c *Local) SetLogger(l log.Logger) {
}
func (c *Local) Status(ctx context.Context) (*coretypes.ResultStatus, error) {
return c.env.Status(c.ctx)
return c.env.Status(ctx)
}
func (c *Local) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
return c.env.ABCIInfo(c.ctx)
return c.env.ABCIInfo(ctx)
}
func (c *Local) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) {
@ -90,31 +87,31 @@ func (c *Local) ABCIQueryWithOptions(
path string,
data bytes.HexBytes,
opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) {
return c.env.ABCIQuery(c.ctx, path, data, opts.Height, opts.Prove)
return c.env.ABCIQuery(ctx, path, data, opts.Height, opts.Prove)
}
func (c *Local) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
return c.env.BroadcastTxCommit(c.ctx, tx)
return c.env.BroadcastTxCommit(ctx, tx)
}
func (c *Local) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.env.BroadcastTxAsync(c.ctx, tx)
return c.env.BroadcastTxAsync(ctx, tx)
}
func (c *Local) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.env.BroadcastTxSync(c.ctx, tx)
return c.env.BroadcastTxSync(ctx, tx)
}
func (c *Local) UnconfirmedTxs(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) {
return c.env.UnconfirmedTxs(c.ctx, limit)
return c.env.UnconfirmedTxs(ctx, limit)
}
func (c *Local) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) {
return c.env.NumUnconfirmedTxs(c.ctx)
return c.env.NumUnconfirmedTxs(ctx)
}
func (c *Local) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
return c.env.CheckTx(c.ctx, tx)
return c.env.CheckTx(ctx, tx)
}
func (c *Local) RemoveTx(ctx context.Context, txKey types.TxKey) error {
@ -122,91 +119,91 @@ func (c *Local) RemoveTx(ctx context.Context, txKey types.TxKey) error {
}
func (c *Local) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) {
return c.env.NetInfo(c.ctx)
return c.env.NetInfo(ctx)
}
func (c *Local) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) {
return c.env.DumpConsensusState(c.ctx)
return c.env.DumpConsensusState(ctx)
}
func (c *Local) ConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) {
return c.env.GetConsensusState(c.ctx)
return c.env.GetConsensusState(ctx)
}
func (c *Local) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
return c.env.ConsensusParams(c.ctx, height)
return c.env.ConsensusParams(ctx, height)
}
func (c *Local) Health(ctx context.Context) (*coretypes.ResultHealth, error) {
return c.env.Health(c.ctx)
return c.env.Health(ctx)
}
func (c *Local) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
return c.env.BlockchainInfo(c.ctx, minHeight, maxHeight)
return c.env.BlockchainInfo(ctx, minHeight, maxHeight)
}
func (c *Local) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) {
return c.env.Genesis(c.ctx)
return c.env.Genesis(ctx)
}
func (c *Local) GenesisChunked(ctx context.Context, id uint) (*coretypes.ResultGenesisChunk, error) {
return c.env.GenesisChunked(c.ctx, id)
return c.env.GenesisChunked(ctx, id)
}
func (c *Local) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) {
return c.env.Block(c.ctx, height)
return c.env.Block(ctx, height)
}
func (c *Local) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) {
return c.env.BlockByHash(c.ctx, hash)
return c.env.BlockByHash(ctx, hash)
}
func (c *Local) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) {
return c.env.BlockResults(c.ctx, height)
return c.env.BlockResults(ctx, height)
}
func (c *Local) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) {
return c.env.Header(c.ctx, height)
return c.env.Header(ctx, height)
}
func (c *Local) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) {
return c.env.HeaderByHash(c.ctx, hash)
return c.env.HeaderByHash(ctx, hash)
}
func (c *Local) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) {
return c.env.Commit(c.ctx, height)
return c.env.Commit(ctx, height)
}
func (c *Local) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
return c.env.Validators(c.ctx, height, page, perPage)
return c.env.Validators(ctx, height, page, perPage)
}
func (c *Local) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) {
return c.env.Tx(c.ctx, hash, prove)
return c.env.Tx(ctx, hash, prove)
}
func (c *Local) TxSearch(
_ context.Context,
ctx context.Context,
queryString string,
prove bool,
page,
perPage *int,
orderBy string,
) (*coretypes.ResultTxSearch, error) {
return c.env.TxSearch(c.ctx, queryString, prove, page, perPage, orderBy)
return c.env.TxSearch(ctx, queryString, prove, page, perPage, orderBy)
}
func (c *Local) BlockSearch(
_ context.Context,
ctx context.Context,
queryString string,
page, perPage *int,
orderBy string,
) (*coretypes.ResultBlockSearch, error) {
return c.env.BlockSearch(c.ctx, queryString, page, perPage, orderBy)
return c.env.BlockSearch(ctx, queryString, page, perPage, orderBy)
}
func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
return c.env.BroadcastEvidence(c.ctx, ev)
return c.env.BroadcastEvidence(ctx, ev)
}
func (c *Local) Subscribe(


+ 19
- 20
rpc/client/mock/client.go View File

@ -22,7 +22,6 @@ import (
"github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/rpc/client"
"github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
"github.com/tendermint/tendermint/types"
)
@ -76,11 +75,11 @@ func (c Call) GetResponse(args interface{}) (interface{}, error) {
}
func (c Client) Status(ctx context.Context) (*coretypes.ResultStatus, error) {
return c.env.Status(&rpctypes.Context{})
return c.env.Status(ctx)
}
func (c Client) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
return c.env.ABCIInfo(&rpctypes.Context{})
return c.env.ABCIInfo(ctx)
}
func (c Client) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) {
@ -92,69 +91,69 @@ func (c Client) ABCIQueryWithOptions(
path string,
data bytes.HexBytes,
opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) {
return c.env.ABCIQuery(&rpctypes.Context{}, path, data, opts.Height, opts.Prove)
return c.env.ABCIQuery(ctx, path, data, opts.Height, opts.Prove)
}
func (c Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
return c.env.BroadcastTxCommit(&rpctypes.Context{}, tx)
return c.env.BroadcastTxCommit(ctx, tx)
}
func (c Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.env.BroadcastTxAsync(&rpctypes.Context{}, tx)
return c.env.BroadcastTxAsync(ctx, tx)
}
func (c Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.env.BroadcastTxSync(&rpctypes.Context{}, tx)
return c.env.BroadcastTxSync(ctx, tx)
}
func (c Client) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
return c.env.CheckTx(&rpctypes.Context{}, tx)
return c.env.CheckTx(ctx, tx)
}
func (c Client) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) {
return c.env.NetInfo(&rpctypes.Context{})
return c.env.NetInfo(ctx)
}
func (c Client) ConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) {
return c.env.GetConsensusState(&rpctypes.Context{})
return c.env.GetConsensusState(ctx)
}
func (c Client) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) {
return c.env.DumpConsensusState(&rpctypes.Context{})
return c.env.DumpConsensusState(ctx)
}
func (c Client) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
return c.env.ConsensusParams(&rpctypes.Context{}, height)
return c.env.ConsensusParams(ctx, height)
}
func (c Client) Health(ctx context.Context) (*coretypes.ResultHealth, error) {
return c.env.Health(&rpctypes.Context{})
return c.env.Health(ctx)
}
func (c Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
return c.env.BlockchainInfo(&rpctypes.Context{}, minHeight, maxHeight)
return c.env.BlockchainInfo(ctx, minHeight, maxHeight)
}
func (c Client) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) {
return c.env.Genesis(&rpctypes.Context{})
return c.env.Genesis(ctx)
}
func (c Client) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) {
return c.env.Block(&rpctypes.Context{}, height)
return c.env.Block(ctx, height)
}
func (c Client) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) {
return c.env.BlockByHash(&rpctypes.Context{}, hash)
return c.env.BlockByHash(ctx, hash)
}
func (c Client) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) {
return c.env.Commit(&rpctypes.Context{}, height)
return c.env.Commit(ctx, height)
}
func (c Client) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
return c.env.Validators(&rpctypes.Context{}, height, page, perPage)
return c.env.Validators(ctx, height, page, perPage)
}
func (c Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
return c.env.BroadcastEvidence(&rpctypes.Context{}, ev)
return c.env.BroadcastEvidence(ctx, ev)
}

+ 5
- 6
rpc/jsonrpc/jsonrpc_test.go View File

@ -21,7 +21,6 @@ import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/rpc/jsonrpc/client"
"github.com/tendermint/tendermint/rpc/jsonrpc/server"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
// Client and Server should work over tcp or unix sockets
@ -61,23 +60,23 @@ var Routes = map[string]*server.RPCFunc{
"echo_int": server.NewRPCFunc(EchoIntResult, "arg", false),
}
func EchoResult(ctx *rpctypes.Context, v string) (*ResultEcho, error) {
func EchoResult(ctx context.Context, v string) (*ResultEcho, error) {
return &ResultEcho{v}, nil
}
func EchoWSResult(ctx *rpctypes.Context, v string) (*ResultEcho, error) {
func EchoWSResult(ctx context.Context, v string) (*ResultEcho, error) {
return &ResultEcho{v}, nil
}
func EchoIntResult(ctx *rpctypes.Context, v int) (*ResultEchoInt, error) {
func EchoIntResult(ctx context.Context, v int) (*ResultEchoInt, error) {
return &ResultEchoInt{v}, nil
}
func EchoBytesResult(ctx *rpctypes.Context, v []byte) (*ResultEchoBytes, error) {
func EchoBytesResult(ctx context.Context, v []byte) (*ResultEchoBytes, error) {
return &ResultEchoBytes{v}, nil
}
func EchoDataBytesResult(ctx *rpctypes.Context, v tmbytes.HexBytes) (*ResultEchoDataBytes, error) {
func EchoDataBytesResult(ctx context.Context, v tmbytes.HexBytes) (*ResultEchoDataBytes, error) {
return &ResultEchoDataBytes{v}, nil
}


+ 6
- 5
rpc/jsonrpc/server/http_json_handler.go View File

@ -206,10 +206,11 @@ func arrayParamsToArgs(
// parseParams parses the JSON parameters of rpcReq into the arguments of fn,
// returning the corresponding argument values or an error.
func parseParams(fn *RPCFunc, httpReq *http.Request, rpcReq rpctypes.RPCRequest) ([]reflect.Value, error) {
args := []reflect.Value{reflect.ValueOf(&rpctypes.Context{
JSONReq: &rpcReq,
HTTPReq: httpReq,
})}
ctx := rpctypes.WithCallInfo(httpReq.Context(), &rpctypes.CallInfo{
RPCRequest: &rpcReq,
HTTPRequest: httpReq,
})
args := []reflect.Value{reflect.ValueOf(ctx)}
if len(rpcReq.Params) == 0 {
return args, nil
}
@ -224,7 +225,7 @@ func parseParams(fn *RPCFunc, httpReq *http.Request, rpcReq rpctypes.RPCRequest)
// array.
//
// Example:
// rpcFunc.args = [rpctypes.Context string]
// rpcFunc.args = [context.Context string]
// rpcFunc.argNames = ["arg"]
func jsonParamsToArgs(rpcFunc *RPCFunc, raw []byte) ([]reflect.Value, error) {
const argsOffset = 1


+ 3
- 2
rpc/jsonrpc/server/http_json_handler_test.go View File

@ -1,6 +1,7 @@
package server
import (
"context"
"encoding/json"
"io"
"net/http"
@ -17,8 +18,8 @@ import (
func testMux() *http.ServeMux {
funcMap := map[string]*RPCFunc{
"c": NewRPCFunc(func(ctx *rpctypes.Context, s string, i int) (string, error) { return "foo", nil }, "s,i", false),
"block": NewRPCFunc(func(ctx *rpctypes.Context, h int) (string, error) { return "block", nil }, "height", true),
"c": NewRPCFunc(func(ctx context.Context, s string, i int) (string, error) { return "foo", nil }, "s,i", false),
"block": NewRPCFunc(func(ctx context.Context, h int) (string, error) { return "block", nil }, "height", true),
}
mux := http.NewServeMux()
logger := log.NewNopLogger()


+ 1
- 1
rpc/jsonrpc/server/http_uri_handler.go View File

@ -39,7 +39,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit
return func(w http.ResponseWriter, r *http.Request) {
logger.Debug("HTTP HANDLER", "req", dumpHTTPRequest(r))
ctx := &rpctypes.Context{HTTPReq: r}
ctx := rpctypes.WithCallInfo(r.Context(), &rpctypes.CallInfo{HTTPRequest: r})
args := []reflect.Value{reflect.ValueOf(ctx)}
fnArgs, err := httpParamsToArgs(rpcFunc, r)


+ 3
- 3
rpc/jsonrpc/server/parse_test.go View File

@ -1,6 +1,7 @@
package server
import (
"context"
"encoding/json"
"fmt"
"net/http"
@ -10,7 +11,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/libs/bytes"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
func TestParseJSONMap(t *testing.T) {
@ -134,7 +134,7 @@ func TestParseJSONArray(t *testing.T) {
}
func TestParseJSONRPC(t *testing.T) {
demo := func(ctx *rpctypes.Context, height int, name string) {}
demo := func(ctx context.Context, height int, name string) {}
call := NewRPCFunc(demo, "height,name", false)
cases := []struct {
@ -171,7 +171,7 @@ func TestParseJSONRPC(t *testing.T) {
}
func TestParseURI(t *testing.T) {
demo := func(ctx *rpctypes.Context, height int, name string) {}
demo := func(ctx context.Context, height int, name string) {}
call := NewRPCFunc(demo, "height,name", false)
cases := []struct {


+ 5
- 2
rpc/jsonrpc/server/ws_handler.go View File

@ -369,8 +369,11 @@ func (wsc *wsConnection) readRoutine(ctx context.Context) {
continue
}
ctx := &rpctypes.Context{JSONReq: &request, WSConn: wsc}
args := []reflect.Value{reflect.ValueOf(ctx)}
fctx := rpctypes.WithCallInfo(wsc.Context(), &rpctypes.CallInfo{
RPCRequest: &request,
WSConn: wsc,
})
args := []reflect.Value{reflect.ValueOf(fctx)}
if len(request.Params) > 0 {
fnArgs, err := jsonParamsToArgs(rpcFunc, request.Params)
if err != nil {


+ 2
- 1
rpc/jsonrpc/server/ws_handler_test.go View File

@ -1,6 +1,7 @@
package server
import (
"context"
"net/http"
"net/http/httptest"
"testing"
@ -46,7 +47,7 @@ func TestWebsocketManagerHandler(t *testing.T) {
func newWSServer(t *testing.T, logger log.Logger) *httptest.Server {
funcMap := map[string]*RPCFunc{
"c": NewWSRPCFunc(func(ctx *rpctypes.Context, s string, i int) (string, error) { return "foo", nil }, "s,i"),
"c": NewWSRPCFunc(func(ctx context.Context, s string, i int) (string, error) { return "foo", nil }, "s,i"),
}
wm := NewWebsocketManager(funcMap)


+ 1
- 2
rpc/jsonrpc/test/main.go View File

@ -10,14 +10,13 @@ import (
"github.com/tendermint/tendermint/libs/log"
rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
var routes = map[string]*rpcserver.RPCFunc{
"hello_world": rpcserver.NewRPCFunc(HelloWorld, "name,num", false),
}
func HelloWorld(ctx *rpctypes.Context, name string, num int) (Result, error) {
func HelloWorld(ctx context.Context, name string, num int) (Result, error) {
return Result{fmt.Sprintf("hi %s %d", name, num)}, nil
}


+ 32
- 38
rpc/jsonrpc/types/types.go View File

@ -250,50 +250,44 @@ type WSRPCConnection interface {
Context() context.Context
}
// Context is the first parameter for all functions. It carries a json-rpc
// request, http request and websocket connection.
//
// - JSONReq is non-nil when JSONRPC is called over websocket or HTTP.
// - WSConn is non-nil when we're connected via a websocket.
// - HTTPReq is non-nil when URI or JSONRPC is called over HTTP.
type Context struct {
// json-rpc request
JSONReq *RPCRequest
// websocket connection
WSConn WSRPCConnection
// http request
HTTPReq *http.Request
// CallInfo carries JSON-RPC request metadata for RPC functions invoked via
// JSON-RPC. It can be recovered from the context with GetCallInfo.
type CallInfo struct {
RPCRequest *RPCRequest // non-nil for requests via HTTP or websocket
HTTPRequest *http.Request // non-nil for requests via HTTP
WSConn WSRPCConnection // non-nil for requests via websocket
}
type callInfoKey struct{}
// WithCallInfo returns a child context of ctx with the ci attached.
func WithCallInfo(ctx context.Context, ci *CallInfo) context.Context {
return context.WithValue(ctx, callInfoKey{}, ci)
}
// RemoteAddr returns the remote address (usually a string "IP:port").
// If neither HTTPReq nor WSConn is set, an empty string is returned.
// HTTP:
// http.Request#RemoteAddr
// WS:
// result of GetRemoteAddr
func (ctx *Context) RemoteAddr() string {
if ctx.HTTPReq != nil {
return ctx.HTTPReq.RemoteAddr
} else if ctx.WSConn != nil {
return ctx.WSConn.GetRemoteAddr()
// GetCallInfo returns the CallInfo record attached to ctx, or nil if ctx does
// not contain a call record.
func GetCallInfo(ctx context.Context) *CallInfo {
if v := ctx.Value(callInfoKey{}); v != nil {
return v.(*CallInfo)
}
return ""
return nil
}
// Context returns the request's context.
// The returned context is always non-nil; it defaults to the background context.
// HTTP:
// The context is canceled when the client's connection closes, the request
// is canceled (with HTTP/2), or when the ServeHTTP method returns.
// WS:
// The context is canceled when the client's connections closes.
func (ctx *Context) Context() context.Context {
if ctx.HTTPReq != nil {
return ctx.HTTPReq.Context()
} else if ctx.WSConn != nil {
return ctx.WSConn.Context()
// RemoteAddr returns the remote address (usually a string "IP:port"). If
// neither HTTPRequest nor WSConn is set, an empty string is returned.
//
// For HTTP requests, this reports the request's RemoteAddr.
// For websocket requests, this reports the connection's GetRemoteAddr.
func (ci *CallInfo) RemoteAddr() string {
if ci == nil {
return ""
} else if ci.HTTPRequest != nil {
return ci.HTTPRequest.RemoteAddr
} else if ci.WSConn != nil {
return ci.WSConn.GetRemoteAddr()
}
return context.Background()
return ""
}
//----------------------------------------


Loading…
Cancel
Save