-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tx broadcast gRPC endpoint #7852
Changes from 38 commits
4d22fdf
6674921
6134a9b
0f09eb9
437b1bf
4871d32
ccf6f0c
d65d3ee
abc49b8
05f6282
a0e5111
dc8e1f3
c1d323e
1401b00
3ed9110
75d7f8b
c7031a6
24030a4
846946f
52a9860
152022e
6e2c50d
c70daf7
d2ec8f9
4b323c4
48b8e4c
41039b0
ce8f657
04cdc23
4fb6f7f
d5152d8
e2c75f1
aade13d
00683e5
b37c04c
8803107
57cc0e8
3113060
64d4719
7c3ad41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ package client | |
import ( | ||
gocontext "context" | ||
"fmt" | ||
"reflect" | ||
"strconv" | ||
|
||
gogogrpc "github.com/gogo/protobuf/grpc" | ||
|
@@ -12,18 +13,48 @@ import ( | |
"google.golang.org/grpc/encoding/proto" | ||
"google.golang.org/grpc/metadata" | ||
|
||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" | ||
"github.com/cosmos/cosmos-sdk/types/tx" | ||
) | ||
|
||
var _ gogogrpc.ClientConn = Context{} | ||
|
||
var protoCodec = encoding.GetCodec(proto.Name) | ||
|
||
// Invoke implements the grpc ClientConn.Invoke method | ||
func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply interface{}, opts ...grpc.CallOption) error { | ||
func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply interface{}, opts ...grpc.CallOption) (err error) { | ||
// Two things can happen here: | ||
// 1. either we're broadcasting a Tx, in which call we call Tendermint's broadcast endpoint directly, | ||
// 2. or we are querying for state, in which case we call ABCI's Query. | ||
|
||
// In both cases, we don't allow empty request args (it will panic unexpectedly). | ||
if reflect.ValueOf(args).IsNil() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure why Anyways, this works. |
||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "request cannot be nil") | ||
} | ||
|
||
// Case 1. Broadcasting a Tx. | ||
if isBroadcast(method) { | ||
req, ok := args.(*tx.BroadcastTxRequest) | ||
if !ok { | ||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "expected %T, got %T", (*tx.BroadcastTxRequest)(nil), args) | ||
} | ||
res, ok := reply.(*tx.BroadcastTxResponse) | ||
if !ok { | ||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "expected %T, got %T", (*tx.BroadcastTxResponse)(nil), args) | ||
} | ||
|
||
broadcastRes, err := TxServiceBroadcast(grpcCtx, ctx, req) | ||
if err != nil { | ||
return err | ||
} | ||
*res = *broadcastRes | ||
|
||
return err | ||
} | ||
|
||
// Case 2. Querying state. | ||
reqBz, err := protoCodec.Marshal(args) | ||
if err != nil { | ||
return err | ||
|
@@ -86,3 +117,7 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply | |
func (Context) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) { | ||
return nil, fmt.Errorf("streaming rpc not supported") | ||
} | ||
|
||
func isBroadcast(method string) bool { | ||
return method == "/cosmos.tx.v1beta1.Service/BroadcastTx" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ package cosmos.tx.v1beta1; | |
import "google/api/annotations.proto"; | ||
import "cosmos/base/abci/v1beta1/abci.proto"; | ||
import "cosmos/tx/v1beta1/tx.proto"; | ||
import "gogoproto/gogo.proto"; | ||
import "cosmos/base/query/v1beta1/pagination.proto"; | ||
|
||
option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; | ||
|
@@ -12,13 +13,22 @@ option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; | |
service Service { | ||
// Simulate simulates executing a transaction for estimating gas usage. | ||
rpc Simulate(SimulateRequest) returns (SimulateResponse) { | ||
option (google.api.http).post = "/cosmos/tx/v1beta1/simulate"; | ||
option (google.api.http) = { | ||
post: "/cosmos/tx/v1beta1/simulate" | ||
body: "*" | ||
}; | ||
} | ||
// GetTx fetches a tx by hash. | ||
rpc GetTx(GetTxRequest) returns (GetTxResponse) { | ||
option (google.api.http).get = "/cosmos/tx/v1beta1/tx/{hash}"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not related to this PR, but I also noticed this, we could also: - "/cosmos/tx/v1beta1/tx/{hash}"
+ "/cosmos/tx/v1beta1/txs/{hash}" this matches what we do in modules, e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ACK. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 7c3ad41 |
||
} | ||
|
||
// BroadcastTx broadcast transaction. | ||
rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) { | ||
option (google.api.http) = { | ||
post: "/cosmos/tx/v1beta1/txs" | ||
body: "*" | ||
}; | ||
} | ||
// GetTxsEvent fetches txs by event. | ||
rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) { | ||
option (google.api.http).get = "/cosmos/tx/v1beta1/txs"; | ||
|
@@ -45,6 +55,36 @@ message GetTxsEventResponse { | |
cosmos.base.query.v1beta1.PageResponse pagination = 3; | ||
} | ||
|
||
// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest | ||
// RPC method. | ||
message BroadcastTxRequest { | ||
// tx_bytes is the raw transaction. | ||
bytes tx_bytes = 1; | ||
BroadcastMode mode = 2; | ||
} | ||
|
||
// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. | ||
enum BroadcastMode { | ||
// zero-value for mode ordering | ||
BROADCAST_MODE_UNSPECIFIED = 0; | ||
// BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for | ||
// the tx to be committed in a block. | ||
BROADCAST_MODE_BLOCK = 1; | ||
// BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for | ||
// a CheckTx execution response only. | ||
BROADCAST_MODE_SYNC = 2; | ||
// BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns | ||
// immediately. | ||
BROADCAST_MODE_ASYNC = 3; | ||
} | ||
|
||
// BroadcastTxResponse is the response type for the | ||
// Service.BroadcastTx method. | ||
message BroadcastTxResponse { | ||
// tx_response is the queried TxResponses. | ||
cosmos.base.abci.v1beta1.TxResponse tx_response = 1; | ||
} | ||
|
||
// SimulateRequest is the request type for the Service.Simulate | ||
// RPC method. | ||
message SimulateRequest { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ref: #8021