From 50ac52e28d9264a8ddc6b14ff1642cbe2b29b9e0 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Tue, 11 Jan 2022 11:47:56 -0800 Subject: [PATCH] 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. --- internal/rpc/core/abci.go | 11 +- internal/rpc/core/blocks.go | 20 +-- internal/rpc/core/blocks_test.go | 5 +- internal/rpc/core/consensus.go | 11 +- internal/rpc/core/dev.go | 5 +- internal/rpc/core/events.go | 25 +-- internal/rpc/core/evidence.go | 4 +- internal/rpc/core/health.go | 5 +- internal/rpc/core/mempool.go | 26 +-- internal/rpc/core/net.go | 8 +- internal/rpc/core/status.go | 4 +- internal/rpc/core/tx.go | 8 +- light/proxy/routes.go | 165 ++++++++++--------- light/rpc/client.go | 17 +- rpc/client/local/local.go | 63 ++++--- rpc/client/mock/client.go | 39 +++-- rpc/jsonrpc/jsonrpc_test.go | 11 +- rpc/jsonrpc/server/http_json_handler.go | 11 +- rpc/jsonrpc/server/http_json_handler_test.go | 5 +- rpc/jsonrpc/server/http_uri_handler.go | 2 +- rpc/jsonrpc/server/parse_test.go | 6 +- rpc/jsonrpc/server/ws_handler.go | 7 +- rpc/jsonrpc/server/ws_handler_test.go | 3 +- rpc/jsonrpc/test/main.go | 3 +- rpc/jsonrpc/types/types.go | 70 ++++---- 25 files changed, 268 insertions(+), 266 deletions(-) diff --git a/internal/rpc/core/abci.go b/internal/rpc/core/abci.go index 06c033050..783a78cb3 100644 --- a/internal/rpc/core/abci.go +++ b/internal/rpc/core/abci.go @@ -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 } diff --git a/internal/rpc/core/blocks.go b/internal/rpc/core/blocks.go index 725a2f972..9f6c872ca 100644 --- a/internal/rpc/core/blocks.go +++ b/internal/rpc/core/blocks.go @@ -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 } diff --git a/internal/rpc/core/blocks_test.go b/internal/rpc/core/blocks_test.go index 213845bf4..b1746acb7 100644 --- a/internal/rpc/core/blocks_test.go +++ b/internal/rpc/core/blocks_test.go @@ -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 { diff --git a/internal/rpc/core/consensus.go b/internal/rpc/core/consensus.go index d17796fff..bc3a23ec8 100644 --- a/internal/rpc/core/consensus.go +++ b/internal/rpc/core/consensus.go @@ -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 diff --git a/internal/rpc/core/dev.go b/internal/rpc/core/dev.go index 21c5154ff..702413ab8 100644 --- a/internal/rpc/core/dev.go +++ b/internal/rpc/core/dev.go @@ -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 } diff --git a/internal/rpc/core/events.go b/internal/rpc/core/events.go index 965291cdb..82235ae50 100644 --- a/internal/rpc/core/events.go +++ b/internal/rpc/core/events.go @@ -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 } diff --git a/internal/rpc/core/evidence.go b/internal/rpc/core/evidence.go index a7641b99d..f85892d99 100644 --- a/internal/rpc/core/evidence.go +++ b/internal/rpc/core/evidence.go @@ -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 { diff --git a/internal/rpc/core/health.go b/internal/rpc/core/health.go index fc355c7e7..c55aa58dc 100644 --- a/internal/rpc/core/health.go +++ b/internal/rpc/core/health.go @@ -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 } diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index 6c145d3ad..751c7ee73 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -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) } diff --git a/internal/rpc/core/net.go b/internal/rpc/core/net.go index fdf4be69b..3cead393c 100644 --- a/internal/rpc/core/net.go +++ b/internal/rpc/core/net.go @@ -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") } diff --git a/internal/rpc/core/status.go b/internal/rpc/core/status.go index b883c6dc2..44a2b7469 100644 --- a/internal/rpc/core/status.go +++ b/internal/rpc/core/status.go @@ -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 diff --git a/internal/rpc/core/tx.go b/internal/rpc/core/tx.go index 98fedc10a..126875d0d 100644 --- a/internal/rpc/core/tx.go +++ b/internal/rpc/core/tx.go @@ -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 } diff --git a/light/proxy/routes.go b/light/proxy/routes.go index ac2e8b5df..4fb815b7e 100644 --- a/light/proxy/routes.go +++ b/light/proxy/routes.go @@ -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) } } diff --git a/light/rpc/client.go b/light/rpc/client.go index 08ef27a6d..41ed97401 100644 --- a/light/rpc/client.go +++ b/light/rpc/client.go @@ -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 } diff --git a/rpc/client/local/local.go b/rpc/client/local/local.go index 4a833af9c..69cbb3ebd 100644 --- a/rpc/client/local/local.go +++ b/rpc/client/local/local.go @@ -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( diff --git a/rpc/client/mock/client.go b/rpc/client/mock/client.go index b57e661cb..05a3ca9cb 100644 --- a/rpc/client/mock/client.go +++ b/rpc/client/mock/client.go @@ -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) } diff --git a/rpc/jsonrpc/jsonrpc_test.go b/rpc/jsonrpc/jsonrpc_test.go index 2c353e508..3ad0599ed 100644 --- a/rpc/jsonrpc/jsonrpc_test.go +++ b/rpc/jsonrpc/jsonrpc_test.go @@ -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 } diff --git a/rpc/jsonrpc/server/http_json_handler.go b/rpc/jsonrpc/server/http_json_handler.go index 879a58df9..6111aa084 100644 --- a/rpc/jsonrpc/server/http_json_handler.go +++ b/rpc/jsonrpc/server/http_json_handler.go @@ -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 diff --git a/rpc/jsonrpc/server/http_json_handler_test.go b/rpc/jsonrpc/server/http_json_handler_test.go index 1a65d414d..8c53a3747 100644 --- a/rpc/jsonrpc/server/http_json_handler_test.go +++ b/rpc/jsonrpc/server/http_json_handler_test.go @@ -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() diff --git a/rpc/jsonrpc/server/http_uri_handler.go b/rpc/jsonrpc/server/http_uri_handler.go index 9fb5c1cde..d9e8b0cbb 100644 --- a/rpc/jsonrpc/server/http_uri_handler.go +++ b/rpc/jsonrpc/server/http_uri_handler.go @@ -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) diff --git a/rpc/jsonrpc/server/parse_test.go b/rpc/jsonrpc/server/parse_test.go index 6e7464739..ceb0e2020 100644 --- a/rpc/jsonrpc/server/parse_test.go +++ b/rpc/jsonrpc/server/parse_test.go @@ -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 { diff --git a/rpc/jsonrpc/server/ws_handler.go b/rpc/jsonrpc/server/ws_handler.go index cfba6d13a..6705adb81 100644 --- a/rpc/jsonrpc/server/ws_handler.go +++ b/rpc/jsonrpc/server/ws_handler.go @@ -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 { diff --git a/rpc/jsonrpc/server/ws_handler_test.go b/rpc/jsonrpc/server/ws_handler_test.go index 00d6a18a5..4bd8d72a0 100644 --- a/rpc/jsonrpc/server/ws_handler_test.go +++ b/rpc/jsonrpc/server/ws_handler_test.go @@ -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) diff --git a/rpc/jsonrpc/test/main.go b/rpc/jsonrpc/test/main.go index 4517f0298..524acc383 100644 --- a/rpc/jsonrpc/test/main.go +++ b/rpc/jsonrpc/test/main.go @@ -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 } diff --git a/rpc/jsonrpc/types/types.go b/rpc/jsonrpc/types/types.go index a44faf92f..d13c2b842 100644 --- a/rpc/jsonrpc/types/types.go +++ b/rpc/jsonrpc/types/types.go @@ -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 "" } //----------------------------------------