Add GetTransactionsStream RPC (#345)

* RPC GetPaymentsStream

This introduces a new feature to the ArkService API that allows clients to subscribe to payment events. Here's a breakdown of the changes:

1. **OpenAPI Specification (`service.swagger.json`):**
   - A new endpoint `/v1/payments` is added to the API, supporting a `GET` operation for streaming payment events.
   - New definitions `v1GetPaymentsStreamResponse`, `v1RoundPayment`, and `v1AsyncPayment` are added to describe the structure of the streaming responses.

2. **Protobuf Definition (`service.proto`):**
   - Added a new RPC method `GetPaymentsStream` that streams `GetPaymentsStreamResponse` messages.
   - Defined new message types: `GetPaymentsStreamRequest`, `GetPaymentsStreamResponse`, `RoundPayment`, and `AsyncPayment`.

3. **Generated Protobuf Code (`service.pb.go`, `service.pb.gw.go`, `service_grpc.pb.go`):**
   - The generated code is updated to include the new RPC method and message types.
   - The gateway code includes functions to handle HTTP requests and responses for the new streaming endpoint.

4. **Application Logic (`covenant.go`, `covenantless.go`):**
   - New payment events channels are introduced (`paymentEventsCh`).
   - Payment events are propagated to these channels when a round is finalized or an async payment is completed.
   - New event types `RoundPaymentEvent` and `AsyncPaymentEvent` are defined, implementing a `PaymentEvent` interface.

5. **gRPC Handlers (`arkservice.go`):**
   - Added logic to handle `GetPaymentsStream` requests and manage payment listeners.
   - A new goroutine is started to listen to payment events and forward them to active listeners.

Overall, this patch extends the ArkService to support real-time streaming of payment events, allowing clients to receive updates on both round payments and async payments as they occur.

* Move emit events in updateVtxoSet & Use generics and parsers (#1)

* Move sending event to updateVtxoSet

* Use generics and parsers

* pr review refactor

* pr review refactor

* fix

---------

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
This commit is contained in:
Dusan Sekulic
2024-10-04 12:23:16 +02:00
committed by GitHub
parent 26bcbc8163
commit d37af7daf5
10 changed files with 996 additions and 206 deletions

View File

@@ -415,6 +415,37 @@
] ]
} }
}, },
"/v1/transactions": {
"get": {
"operationId": "ArkService_GetTransactionsStream",
"responses": {
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/v1GetTransactionsStreamResponse"
},
"error": {
"$ref": "#/definitions/rpcStatus"
}
},
"title": "Stream result of v1GetTransactionsStreamResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"tags": [
"ArkService"
]
}
},
"/v1/vtxos/{address}": { "/v1/vtxos/{address}": {
"get": { "get": {
"operationId": "ArkService_ListVtxos", "operationId": "ArkService_ListVtxos",
@@ -620,6 +651,17 @@
} }
} }
}, },
"v1GetTransactionsStreamResponse": {
"type": "object",
"properties": {
"round": {
"$ref": "#/definitions/v1RoundTransaction"
},
"redeem": {
"$ref": "#/definitions/v1RedeemTransaction"
}
}
},
"v1Input": { "v1Input": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -727,6 +769,28 @@
} }
} }
}, },
"v1RedeemTransaction": {
"type": "object",
"properties": {
"txid": {
"type": "string"
},
"spentVtxos": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/v1Outpoint"
}
},
"spendableVtxos": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/v1Vtxo"
}
}
}
},
"v1RegisterInputsForNextRoundRequest": { "v1RegisterInputsForNextRoundRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -896,6 +960,35 @@
], ],
"default": "ROUND_STAGE_UNSPECIFIED" "default": "ROUND_STAGE_UNSPECIFIED"
}, },
"v1RoundTransaction": {
"type": "object",
"properties": {
"txid": {
"type": "string"
},
"spentVtxos": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/v1Outpoint"
}
},
"spendableVtxos": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/v1Vtxo"
}
},
"claimedBoardingUtxos": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/v1Outpoint"
}
}
}
},
"v1SubmitSignedForfeitTxsRequest": { "v1SubmitSignedForfeitTxsRequest": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@@ -92,6 +92,11 @@ service ArkService {
get: "/v1/vtxos/{address}" get: "/v1/vtxos/{address}"
}; };
} }
rpc GetTransactionsStream(GetTransactionsStreamRequest) returns (stream GetTransactionsStreamResponse) {
option (google.api.http) = {
get: "/v1/transactions"
};
}
} }
message GetInfoRequest {} message GetInfoRequest {}
@@ -321,3 +326,24 @@ message PendingPayment {
string redeem_tx = 1; string redeem_tx = 1;
repeated string unconditional_forfeit_txs =2; repeated string unconditional_forfeit_txs =2;
} }
message GetTransactionsStreamRequest {}
message GetTransactionsStreamResponse {
oneof tx {
RoundTransaction round = 1;
RedeemTransaction redeem = 2;
}
}
message RoundTransaction {
string txid = 1;
repeated Outpoint spent_vtxos = 2;
repeated Vtxo spendable_vtxos = 3;
repeated Outpoint claimed_boarding_utxos = 4;
}
message RedeemTransaction {
string txid = 1;
repeated Outpoint spent_vtxos = 2;
repeated Vtxo spendable_vtxos = 3;
}

View File

@@ -2568,6 +2568,259 @@ func (x *PendingPayment) GetUnconditionalForfeitTxs() []string {
return nil return nil
} }
type GetTransactionsStreamRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetTransactionsStreamRequest) Reset() {
*x = GetTransactionsStreamRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_service_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetTransactionsStreamRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetTransactionsStreamRequest) ProtoMessage() {}
func (x *GetTransactionsStreamRequest) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_service_proto_msgTypes[42]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetTransactionsStreamRequest.ProtoReflect.Descriptor instead.
func (*GetTransactionsStreamRequest) Descriptor() ([]byte, []int) {
return file_ark_v1_service_proto_rawDescGZIP(), []int{42}
}
type GetTransactionsStreamResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to Tx:
//
// *GetTransactionsStreamResponse_Round
// *GetTransactionsStreamResponse_Redeem
Tx isGetTransactionsStreamResponse_Tx `protobuf_oneof:"tx"`
}
func (x *GetTransactionsStreamResponse) Reset() {
*x = GetTransactionsStreamResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_service_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetTransactionsStreamResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetTransactionsStreamResponse) ProtoMessage() {}
func (x *GetTransactionsStreamResponse) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_service_proto_msgTypes[43]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetTransactionsStreamResponse.ProtoReflect.Descriptor instead.
func (*GetTransactionsStreamResponse) Descriptor() ([]byte, []int) {
return file_ark_v1_service_proto_rawDescGZIP(), []int{43}
}
func (m *GetTransactionsStreamResponse) GetTx() isGetTransactionsStreamResponse_Tx {
if m != nil {
return m.Tx
}
return nil
}
func (x *GetTransactionsStreamResponse) GetRound() *RoundTransaction {
if x, ok := x.GetTx().(*GetTransactionsStreamResponse_Round); ok {
return x.Round
}
return nil
}
func (x *GetTransactionsStreamResponse) GetRedeem() *RedeemTransaction {
if x, ok := x.GetTx().(*GetTransactionsStreamResponse_Redeem); ok {
return x.Redeem
}
return nil
}
type isGetTransactionsStreamResponse_Tx interface {
isGetTransactionsStreamResponse_Tx()
}
type GetTransactionsStreamResponse_Round struct {
Round *RoundTransaction `protobuf:"bytes,1,opt,name=round,proto3,oneof"`
}
type GetTransactionsStreamResponse_Redeem struct {
Redeem *RedeemTransaction `protobuf:"bytes,2,opt,name=redeem,proto3,oneof"`
}
func (*GetTransactionsStreamResponse_Round) isGetTransactionsStreamResponse_Tx() {}
func (*GetTransactionsStreamResponse_Redeem) isGetTransactionsStreamResponse_Tx() {}
type RoundTransaction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Txid string `protobuf:"bytes,1,opt,name=txid,proto3" json:"txid,omitempty"`
SpentVtxos []*Outpoint `protobuf:"bytes,2,rep,name=spent_vtxos,json=spentVtxos,proto3" json:"spent_vtxos,omitempty"`
SpendableVtxos []*Vtxo `protobuf:"bytes,3,rep,name=spendable_vtxos,json=spendableVtxos,proto3" json:"spendable_vtxos,omitempty"`
ClaimedBoardingUtxos []*Outpoint `protobuf:"bytes,4,rep,name=claimed_boarding_utxos,json=claimedBoardingUtxos,proto3" json:"claimed_boarding_utxos,omitempty"`
}
func (x *RoundTransaction) Reset() {
*x = RoundTransaction{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_service_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RoundTransaction) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RoundTransaction) ProtoMessage() {}
func (x *RoundTransaction) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_service_proto_msgTypes[44]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RoundTransaction.ProtoReflect.Descriptor instead.
func (*RoundTransaction) Descriptor() ([]byte, []int) {
return file_ark_v1_service_proto_rawDescGZIP(), []int{44}
}
func (x *RoundTransaction) GetTxid() string {
if x != nil {
return x.Txid
}
return ""
}
func (x *RoundTransaction) GetSpentVtxos() []*Outpoint {
if x != nil {
return x.SpentVtxos
}
return nil
}
func (x *RoundTransaction) GetSpendableVtxos() []*Vtxo {
if x != nil {
return x.SpendableVtxos
}
return nil
}
func (x *RoundTransaction) GetClaimedBoardingUtxos() []*Outpoint {
if x != nil {
return x.ClaimedBoardingUtxos
}
return nil
}
type RedeemTransaction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Txid string `protobuf:"bytes,1,opt,name=txid,proto3" json:"txid,omitempty"`
SpentVtxos []*Outpoint `protobuf:"bytes,2,rep,name=spent_vtxos,json=spentVtxos,proto3" json:"spent_vtxos,omitempty"`
SpendableVtxos []*Vtxo `protobuf:"bytes,3,rep,name=spendable_vtxos,json=spendableVtxos,proto3" json:"spendable_vtxos,omitempty"`
}
func (x *RedeemTransaction) Reset() {
*x = RedeemTransaction{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_service_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RedeemTransaction) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RedeemTransaction) ProtoMessage() {}
func (x *RedeemTransaction) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_service_proto_msgTypes[45]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RedeemTransaction.ProtoReflect.Descriptor instead.
func (*RedeemTransaction) Descriptor() ([]byte, []int) {
return file_ark_v1_service_proto_rawDescGZIP(), []int{45}
}
func (x *RedeemTransaction) GetTxid() string {
if x != nil {
return x.Txid
}
return ""
}
func (x *RedeemTransaction) GetSpentVtxos() []*Outpoint {
if x != nil {
return x.SpentVtxos
}
return nil
}
func (x *RedeemTransaction) GetSpendableVtxos() []*Vtxo {
if x != nil {
return x.SpendableVtxos
}
return nil
}
var File_ark_v1_service_proto protoreflect.FileDescriptor var File_ark_v1_service_proto protoreflect.FileDescriptor
var file_ark_v1_service_proto_rawDesc = []byte{ var file_ark_v1_service_proto_rawDesc = []byte{
@@ -2869,129 +3122,172 @@ var file_ark_v1_service_proto_rawDesc = []byte{
0x78, 0x12, 0x3a, 0x0a, 0x19, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x78, 0x12, 0x3a, 0x0a, 0x19, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x61, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, 0x73, 0x18, 0x02, 0x61, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, 0x73, 0x18, 0x02,
0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x61, 0x6c, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x2a, 0x98, 0x01, 0x6e, 0x61, 0x6c, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x22, 0x1e, 0x0a,
0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x1c, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8c, 0x01,
0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x30, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,
0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x54, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x72, 0x61,
0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e,
0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x03, 0x64, 0x12, 0x33, 0x0a, 0x06, 0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28,
0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x65,
0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x32, 0xe8, 0x0c, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x42, 0x04, 0x0a, 0x02, 0x74, 0x78, 0x22, 0xd8, 0x01, 0x0a,
0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x10, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0b, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x76,
0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b,
0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x74, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x70,
0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x73, 0x70, 0x65, 0x6e,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, 0x52,
0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12,
0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x46, 0x0a, 0x16, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64,
0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x3a, 0x01, 0x2a, 0x22, 0x0c, 0x2f, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x76, 0x31, 0x2f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x98, 0x01, 0x0a, 0x1a, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x74, 0x52, 0x14, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69,
0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x29, 0x2e, 0x61, 0x72, 0x6b, 0x6e, 0x67, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x65, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x64, 0x12, 0x31, 0x0a, 0x0b, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x56,
0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18, 0x2f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c,
0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x9c, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x67, 0x69, 0x73, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, 0x52, 0x0e, 0x73, 0x70, 0x65,
0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x2a, 0x98, 0x01, 0x0a, 0x0a,
0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x2a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x4f,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44,
0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x41, 0x54,
0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53,
0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f,
0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41,
0x47, 0x45, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16,
0x0a, 0x12, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x41,
0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x32, 0xeb, 0x0d, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f,
0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66,
0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x69,
0x6e, 0x66, 0x6f, 0x12, 0x74, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69,
0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61,
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e,
0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x3a, 0x01, 0x2a, 0x22, 0x0c, 0x2f, 0x76, 0x31,
0x2f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x98, 0x01, 0x0a, 0x1a, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e,
0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x29, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73,
0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65,
0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f,
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e,
0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x7d, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x70, 0x75, 0x74, 0x73, 0x12, 0x9c, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52,
0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x2a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0x1a, 0x2b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74,
0x6e, 0x64, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4e, 0x6f, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82,
0x6e, 0x63, 0x65, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f,
0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x75, 0x6e, 0x64, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70,
0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x75, 0x74, 0x73, 0x12, 0x7d, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65,
0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65,
0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63,
0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93,
0x72, 0x65, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64,
0x75, 0x72, 0x65, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4e, 0x6f, 0x6e, 0x63,
0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x65, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65,
0x25, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x61, 0x72,
0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x52, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x1a, 0x24, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74,
0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01,
0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x74, 0x72, 0x65,
0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x6b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x65, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67,
0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x25, 0x2e,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67,
0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75,
0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69,
0x30, 0x01, 0x12, 0x56, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x74, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3,
0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75,
0x14, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x6e, 0x64, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x54, 0x78, 0x73, 0x12, 0x6b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53,
0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71,
0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x61, 0x72, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70,
0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10,
0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
0x12, 0x73, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d,
0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d,
0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d,
0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22,
0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6d,
0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e,
0x64, 0x12, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f,
0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76,
0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x30, 0x01,
0x0a, 0x0c, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x12, 0x1b, 0x12, 0x56, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31,
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79,
0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x69, 0x64, 0x2f, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61,
0x7b, 0x69, 0x64, 0x7d, 0x12, 0x5d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x73, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01,
0x2f, 0x76, 0x31, 0x2f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x73,
0x73, 0x73, 0x7d, 0x42, 0x92, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x61, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x72, 0x6b, 0x76, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f,
0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x2e, 0x56, 0x31, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c,
0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x41, 0x72, 0x6b, 0x5c, 0x65, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12,
0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e,
0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f,
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0c,
0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x12, 0x1b, 0x2e, 0x61,
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79,
0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12,
0x11, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x69, 0x64, 0x2f, 0x7b, 0x69,
0x64, 0x7d, 0x12, 0x5d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12,
0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78,
0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76,
0x31, 0x2f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x7d, 0x12, 0x80, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x24, 0x2e, 0x61, 0x72,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x25, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12,
0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x30, 0x01, 0x42, 0x92, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b,
0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x61, 0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x61, 0x72, 0x6b, 0x2f,
0x61, 0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x72, 0x6b,
0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x2e, 0x56,
0x31, 0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x41, 0x72, 0x6b,
0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
0x02, 0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
} }
var ( var (
@@ -3007,7 +3303,7 @@ func file_ark_v1_service_proto_rawDescGZIP() []byte {
} }
var file_ark_v1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_ark_v1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_ark_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 42) var file_ark_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 46)
var file_ark_v1_service_proto_goTypes = []interface{}{ var file_ark_v1_service_proto_goTypes = []interface{}{
(RoundStage)(0), // 0: ark.v1.RoundStage (RoundStage)(0), // 0: ark.v1.RoundStage
(*GetInfoRequest)(nil), // 1: ark.v1.GetInfoRequest (*GetInfoRequest)(nil), // 1: ark.v1.GetInfoRequest
@@ -3052,6 +3348,10 @@ var file_ark_v1_service_proto_goTypes = []interface{}{
(*Node)(nil), // 40: ark.v1.Node (*Node)(nil), // 40: ark.v1.Node
(*Vtxo)(nil), // 41: ark.v1.Vtxo (*Vtxo)(nil), // 41: ark.v1.Vtxo
(*PendingPayment)(nil), // 42: ark.v1.PendingPayment (*PendingPayment)(nil), // 42: ark.v1.PendingPayment
(*GetTransactionsStreamRequest)(nil), // 43: ark.v1.GetTransactionsStreamRequest
(*GetTransactionsStreamResponse)(nil), // 44: ark.v1.GetTransactionsStreamResponse
(*RoundTransaction)(nil), // 45: ark.v1.RoundTransaction
(*RedeemTransaction)(nil), // 46: ark.v1.RedeemTransaction
} }
var file_ark_v1_service_proto_depIdxs = []int32{ var file_ark_v1_service_proto_depIdxs = []int32{
36, // 0: ark.v1.RegisterInputsForNextRoundRequest.inputs:type_name -> ark.v1.Input 36, // 0: ark.v1.RegisterInputsForNextRoundRequest.inputs:type_name -> ark.v1.Input
@@ -3081,39 +3381,48 @@ var file_ark_v1_service_proto_depIdxs = []int32{
40, // 24: ark.v1.TreeLevel.nodes:type_name -> ark.v1.Node 40, // 24: ark.v1.TreeLevel.nodes:type_name -> ark.v1.Node
35, // 25: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Outpoint 35, // 25: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Outpoint
42, // 26: ark.v1.Vtxo.pending_data:type_name -> ark.v1.PendingPayment 42, // 26: ark.v1.Vtxo.pending_data:type_name -> ark.v1.PendingPayment
1, // 27: ark.v1.ArkService.GetInfo:input_type -> ark.v1.GetInfoRequest 45, // 27: ark.v1.GetTransactionsStreamResponse.round:type_name -> ark.v1.RoundTransaction
3, // 28: ark.v1.ArkService.GetBoardingAddress:input_type -> ark.v1.GetBoardingAddressRequest 46, // 28: ark.v1.GetTransactionsStreamResponse.redeem:type_name -> ark.v1.RedeemTransaction
5, // 29: ark.v1.ArkService.RegisterInputsForNextRound:input_type -> ark.v1.RegisterInputsForNextRoundRequest 35, // 29: ark.v1.RoundTransaction.spent_vtxos:type_name -> ark.v1.Outpoint
7, // 30: ark.v1.ArkService.RegisterOutputsForNextRound:input_type -> ark.v1.RegisterOutputsForNextRoundRequest 41, // 30: ark.v1.RoundTransaction.spendable_vtxos:type_name -> ark.v1.Vtxo
9, // 31: ark.v1.ArkService.SubmitTreeNonces:input_type -> ark.v1.SubmitTreeNoncesRequest 35, // 31: ark.v1.RoundTransaction.claimed_boarding_utxos:type_name -> ark.v1.Outpoint
11, // 32: ark.v1.ArkService.SubmitTreeSignatures:input_type -> ark.v1.SubmitTreeSignaturesRequest 35, // 32: ark.v1.RedeemTransaction.spent_vtxos:type_name -> ark.v1.Outpoint
13, // 33: ark.v1.ArkService.SubmitSignedForfeitTxs:input_type -> ark.v1.SubmitSignedForfeitTxsRequest 41, // 33: ark.v1.RedeemTransaction.spendable_vtxos:type_name -> ark.v1.Vtxo
15, // 34: ark.v1.ArkService.GetEventStream:input_type -> ark.v1.GetEventStreamRequest 1, // 34: ark.v1.ArkService.GetInfo:input_type -> ark.v1.GetInfoRequest
17, // 35: ark.v1.ArkService.Ping:input_type -> ark.v1.PingRequest 3, // 35: ark.v1.ArkService.GetBoardingAddress:input_type -> ark.v1.GetBoardingAddressRequest
19, // 36: ark.v1.ArkService.CreatePayment:input_type -> ark.v1.CreatePaymentRequest 5, // 36: ark.v1.ArkService.RegisterInputsForNextRound:input_type -> ark.v1.RegisterInputsForNextRoundRequest
21, // 37: ark.v1.ArkService.CompletePayment:input_type -> ark.v1.CompletePaymentRequest 7, // 37: ark.v1.ArkService.RegisterOutputsForNextRound:input_type -> ark.v1.RegisterOutputsForNextRoundRequest
23, // 38: ark.v1.ArkService.GetRound:input_type -> ark.v1.GetRoundRequest 9, // 38: ark.v1.ArkService.SubmitTreeNonces:input_type -> ark.v1.SubmitTreeNoncesRequest
25, // 39: ark.v1.ArkService.GetRoundById:input_type -> ark.v1.GetRoundByIdRequest 11, // 39: ark.v1.ArkService.SubmitTreeSignatures:input_type -> ark.v1.SubmitTreeSignaturesRequest
27, // 40: ark.v1.ArkService.ListVtxos:input_type -> ark.v1.ListVtxosRequest 13, // 40: ark.v1.ArkService.SubmitSignedForfeitTxs:input_type -> ark.v1.SubmitSignedForfeitTxsRequest
2, // 41: ark.v1.ArkService.GetInfo:output_type -> ark.v1.GetInfoResponse 15, // 41: ark.v1.ArkService.GetEventStream:input_type -> ark.v1.GetEventStreamRequest
4, // 42: ark.v1.ArkService.GetBoardingAddress:output_type -> ark.v1.GetBoardingAddressResponse 17, // 42: ark.v1.ArkService.Ping:input_type -> ark.v1.PingRequest
6, // 43: ark.v1.ArkService.RegisterInputsForNextRound:output_type -> ark.v1.RegisterInputsForNextRoundResponse 19, // 43: ark.v1.ArkService.CreatePayment:input_type -> ark.v1.CreatePaymentRequest
8, // 44: ark.v1.ArkService.RegisterOutputsForNextRound:output_type -> ark.v1.RegisterOutputsForNextRoundResponse 21, // 44: ark.v1.ArkService.CompletePayment:input_type -> ark.v1.CompletePaymentRequest
10, // 45: ark.v1.ArkService.SubmitTreeNonces:output_type -> ark.v1.SubmitTreeNoncesResponse 23, // 45: ark.v1.ArkService.GetRound:input_type -> ark.v1.GetRoundRequest
12, // 46: ark.v1.ArkService.SubmitTreeSignatures:output_type -> ark.v1.SubmitTreeSignaturesResponse 25, // 46: ark.v1.ArkService.GetRoundById:input_type -> ark.v1.GetRoundByIdRequest
14, // 47: ark.v1.ArkService.SubmitSignedForfeitTxs:output_type -> ark.v1.SubmitSignedForfeitTxsResponse 27, // 47: ark.v1.ArkService.ListVtxos:input_type -> ark.v1.ListVtxosRequest
16, // 48: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse 43, // 48: ark.v1.ArkService.GetTransactionsStream:input_type -> ark.v1.GetTransactionsStreamRequest
18, // 49: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse 2, // 49: ark.v1.ArkService.GetInfo:output_type -> ark.v1.GetInfoResponse
20, // 50: ark.v1.ArkService.CreatePayment:output_type -> ark.v1.CreatePaymentResponse 4, // 50: ark.v1.ArkService.GetBoardingAddress:output_type -> ark.v1.GetBoardingAddressResponse
22, // 51: ark.v1.ArkService.CompletePayment:output_type -> ark.v1.CompletePaymentResponse 6, // 51: ark.v1.ArkService.RegisterInputsForNextRound:output_type -> ark.v1.RegisterInputsForNextRoundResponse
24, // 52: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse 8, // 52: ark.v1.ArkService.RegisterOutputsForNextRound:output_type -> ark.v1.RegisterOutputsForNextRoundResponse
26, // 53: ark.v1.ArkService.GetRoundById:output_type -> ark.v1.GetRoundByIdResponse 10, // 53: ark.v1.ArkService.SubmitTreeNonces:output_type -> ark.v1.SubmitTreeNoncesResponse
28, // 54: ark.v1.ArkService.ListVtxos:output_type -> ark.v1.ListVtxosResponse 12, // 54: ark.v1.ArkService.SubmitTreeSignatures:output_type -> ark.v1.SubmitTreeSignaturesResponse
41, // [41:55] is the sub-list for method output_type 14, // 55: ark.v1.ArkService.SubmitSignedForfeitTxs:output_type -> ark.v1.SubmitSignedForfeitTxsResponse
27, // [27:41] is the sub-list for method input_type 16, // 56: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse
27, // [27:27] is the sub-list for extension type_name 18, // 57: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse
27, // [27:27] is the sub-list for extension extendee 20, // 58: ark.v1.ArkService.CreatePayment:output_type -> ark.v1.CreatePaymentResponse
0, // [0:27] is the sub-list for field type_name 22, // 59: ark.v1.ArkService.CompletePayment:output_type -> ark.v1.CompletePaymentResponse
24, // 60: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse
26, // 61: ark.v1.ArkService.GetRoundById:output_type -> ark.v1.GetRoundByIdResponse
28, // 62: ark.v1.ArkService.ListVtxos:output_type -> ark.v1.ListVtxosResponse
44, // 63: ark.v1.ArkService.GetTransactionsStream:output_type -> ark.v1.GetTransactionsStreamResponse
49, // [49:64] is the sub-list for method output_type
34, // [34:49] is the sub-list for method input_type
34, // [34:34] is the sub-list for extension type_name
34, // [34:34] is the sub-list for extension extendee
0, // [0:34] is the sub-list for field type_name
} }
func init() { file_ark_v1_service_proto_init() } func init() { file_ark_v1_service_proto_init() }
@@ -3626,6 +3935,54 @@ func file_ark_v1_service_proto_init() {
return nil return nil
} }
} }
file_ark_v1_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetTransactionsStreamRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_service_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetTransactionsStreamResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_service_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RoundTransaction); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_service_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RedeemTransaction); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
} }
file_ark_v1_service_proto_msgTypes[4].OneofWrappers = []interface{}{} file_ark_v1_service_proto_msgTypes[4].OneofWrappers = []interface{}{}
file_ark_v1_service_proto_msgTypes[12].OneofWrappers = []interface{}{} file_ark_v1_service_proto_msgTypes[12].OneofWrappers = []interface{}{}
@@ -3643,13 +4000,17 @@ func file_ark_v1_service_proto_init() {
(*PingResponse_RoundSigning)(nil), (*PingResponse_RoundSigning)(nil),
(*PingResponse_RoundSigningNoncesGenerated)(nil), (*PingResponse_RoundSigningNoncesGenerated)(nil),
} }
file_ark_v1_service_proto_msgTypes[43].OneofWrappers = []interface{}{
(*GetTransactionsStreamResponse_Round)(nil),
(*GetTransactionsStreamResponse_Redeem)(nil),
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ark_v1_service_proto_rawDesc, RawDescriptor: file_ark_v1_service_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 42, NumMessages: 46,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@@ -482,6 +482,23 @@ func local_request_ArkService_ListVtxos_0(ctx context.Context, marshaler runtime
} }
func request_ArkService_GetTransactionsStream_0(ctx context.Context, marshaler runtime.Marshaler, client ArkServiceClient, req *http.Request, pathParams map[string]string) (ArkService_GetTransactionsStreamClient, runtime.ServerMetadata, error) {
var protoReq GetTransactionsStreamRequest
var metadata runtime.ServerMetadata
stream, err := client.GetTransactionsStream(ctx, &protoReq)
if err != nil {
return nil, metadata, err
}
header, err := stream.Header()
if err != nil {
return nil, metadata, err
}
metadata.HeaderMD = header
return stream, metadata, nil
}
// RegisterArkServiceHandlerServer registers the http handlers for service ArkService to "mux". // RegisterArkServiceHandlerServer registers the http handlers for service ArkService to "mux".
// UnaryRPC :call ArkServiceServer directly. // UnaryRPC :call ArkServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -821,6 +838,13 @@ func RegisterArkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux,
}) })
mux.Handle("GET", pattern_ArkService_GetTransactionsStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport")
_, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
})
return nil return nil
} }
@@ -1170,6 +1194,28 @@ func RegisterArkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux,
}) })
mux.Handle("GET", pattern_ArkService_GetTransactionsStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ark.v1.ArkService/GetTransactionsStream", runtime.WithHTTPPathPattern("/v1/transactions"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ArkService_GetTransactionsStream_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ArkService_GetTransactionsStream_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
})
return nil return nil
} }
@@ -1201,6 +1247,8 @@ var (
pattern_ArkService_GetRoundById_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 2}, []string{"v1", "round", "id"}, "")) pattern_ArkService_GetRoundById_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 2}, []string{"v1", "round", "id"}, ""))
pattern_ArkService_ListVtxos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "vtxos", "address"}, "")) pattern_ArkService_ListVtxos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "vtxos", "address"}, ""))
pattern_ArkService_GetTransactionsStream_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "transactions"}, ""))
) )
var ( var (
@@ -1231,4 +1279,6 @@ var (
forward_ArkService_GetRoundById_0 = runtime.ForwardResponseMessage forward_ArkService_GetRoundById_0 = runtime.ForwardResponseMessage
forward_ArkService_ListVtxos_0 = runtime.ForwardResponseMessage forward_ArkService_ListVtxos_0 = runtime.ForwardResponseMessage
forward_ArkService_GetTransactionsStream_0 = runtime.ForwardResponseStream
) )

View File

@@ -32,6 +32,7 @@ type ArkServiceClient interface {
GetRound(ctx context.Context, in *GetRoundRequest, opts ...grpc.CallOption) (*GetRoundResponse, error) GetRound(ctx context.Context, in *GetRoundRequest, opts ...grpc.CallOption) (*GetRoundResponse, error)
GetRoundById(ctx context.Context, in *GetRoundByIdRequest, opts ...grpc.CallOption) (*GetRoundByIdResponse, error) GetRoundById(ctx context.Context, in *GetRoundByIdRequest, opts ...grpc.CallOption) (*GetRoundByIdResponse, error)
ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error) ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error)
GetTransactionsStream(ctx context.Context, in *GetTransactionsStreamRequest, opts ...grpc.CallOption) (ArkService_GetTransactionsStreamClient, error)
} }
type arkServiceClient struct { type arkServiceClient struct {
@@ -191,6 +192,38 @@ func (c *arkServiceClient) ListVtxos(ctx context.Context, in *ListVtxosRequest,
return out, nil return out, nil
} }
func (c *arkServiceClient) GetTransactionsStream(ctx context.Context, in *GetTransactionsStreamRequest, opts ...grpc.CallOption) (ArkService_GetTransactionsStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &ArkService_ServiceDesc.Streams[1], "/ark.v1.ArkService/GetTransactionsStream", opts...)
if err != nil {
return nil, err
}
x := &arkServiceGetTransactionsStreamClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type ArkService_GetTransactionsStreamClient interface {
Recv() (*GetTransactionsStreamResponse, error)
grpc.ClientStream
}
type arkServiceGetTransactionsStreamClient struct {
grpc.ClientStream
}
func (x *arkServiceGetTransactionsStreamClient) Recv() (*GetTransactionsStreamResponse, error) {
m := new(GetTransactionsStreamResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// ArkServiceServer is the server API for ArkService service. // ArkServiceServer is the server API for ArkService service.
// All implementations should embed UnimplementedArkServiceServer // All implementations should embed UnimplementedArkServiceServer
// for forward compatibility // for forward compatibility
@@ -209,6 +242,7 @@ type ArkServiceServer interface {
GetRound(context.Context, *GetRoundRequest) (*GetRoundResponse, error) GetRound(context.Context, *GetRoundRequest) (*GetRoundResponse, error)
GetRoundById(context.Context, *GetRoundByIdRequest) (*GetRoundByIdResponse, error) GetRoundById(context.Context, *GetRoundByIdRequest) (*GetRoundByIdResponse, error)
ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error)
GetTransactionsStream(*GetTransactionsStreamRequest, ArkService_GetTransactionsStreamServer) error
} }
// UnimplementedArkServiceServer should be embedded to have forward compatible implementations. // UnimplementedArkServiceServer should be embedded to have forward compatible implementations.
@@ -257,6 +291,9 @@ func (UnimplementedArkServiceServer) GetRoundById(context.Context, *GetRoundById
func (UnimplementedArkServiceServer) ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) { func (UnimplementedArkServiceServer) ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListVtxos not implemented") return nil, status.Errorf(codes.Unimplemented, "method ListVtxos not implemented")
} }
func (UnimplementedArkServiceServer) GetTransactionsStream(*GetTransactionsStreamRequest, ArkService_GetTransactionsStreamServer) error {
return status.Errorf(codes.Unimplemented, "method GetTransactionsStream not implemented")
}
// UnsafeArkServiceServer may be embedded to opt out of forward compatibility for this service. // UnsafeArkServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ArkServiceServer will // Use of this interface is not recommended, as added methods to ArkServiceServer will
@@ -524,6 +561,27 @@ func _ArkService_ListVtxos_Handler(srv interface{}, ctx context.Context, dec fun
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _ArkService_GetTransactionsStream_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(GetTransactionsStreamRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(ArkServiceServer).GetTransactionsStream(m, &arkServiceGetTransactionsStreamServer{stream})
}
type ArkService_GetTransactionsStreamServer interface {
Send(*GetTransactionsStreamResponse) error
grpc.ServerStream
}
type arkServiceGetTransactionsStreamServer struct {
grpc.ServerStream
}
func (x *arkServiceGetTransactionsStreamServer) Send(m *GetTransactionsStreamResponse) error {
return x.ServerStream.SendMsg(m)
}
// ArkService_ServiceDesc is the grpc.ServiceDesc for ArkService service. // ArkService_ServiceDesc is the grpc.ServiceDesc for ArkService service.
// It's only intended for direct use with grpc.RegisterService, // It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy) // and not to be introspected or modified (even as a copy)
@@ -590,6 +648,11 @@ var ArkService_ServiceDesc = grpc.ServiceDesc{
Handler: _ArkService_GetEventStream_Handler, Handler: _ArkService_GetEventStream_Handler,
ServerStreams: true, ServerStreams: true,
}, },
{
StreamName: "GetTransactionsStream",
Handler: _ArkService_GetTransactionsStream_Handler,
ServerStreams: true,
},
}, },
Metadata: "ark/v1/service.proto", Metadata: "ark/v1/service.proto",
} }

View File

@@ -46,6 +46,7 @@ type covenantService struct {
forfeitTxs *forfeitTxsMap forfeitTxs *forfeitTxsMap
eventsCh chan domain.RoundEvent eventsCh chan domain.RoundEvent
transactionEventsCh chan TransactionEvent
currentRoundLock sync.Mutex currentRoundLock sync.Mutex
currentRound *domain.Round currentRound *domain.Round
@@ -59,23 +60,30 @@ func NewCovenantService(
builder ports.TxBuilder, scanner ports.BlockchainScanner, builder ports.TxBuilder, scanner ports.BlockchainScanner,
scheduler ports.SchedulerService, scheduler ports.SchedulerService,
) (Service, error) { ) (Service, error) {
eventsCh := make(chan domain.RoundEvent)
paymentRequests := newPaymentsMap()
forfeitTxs := newForfeitTxsMap(builder)
pubkey, err := walletSvc.GetPubkey(context.Background()) pubkey, err := walletSvc.GetPubkey(context.Background())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch pubkey: %s", err) return nil, fmt.Errorf("failed to fetch pubkey: %s", err)
} }
sweeper := newSweeper(walletSvc, repoManager, builder, scheduler)
svc := &covenantService{ svc := &covenantService{
network, pubkey, network: network,
roundLifetime, roundInterval, unilateralExitDelay, boardingExitDelay, pubkey: pubkey,
walletSvc, repoManager, builder, scanner, sweeper, roundLifetime: roundLifetime,
paymentRequests, forfeitTxs, eventsCh, sync.Mutex{}, nil, nil, roundInterval: roundInterval,
unilateralExitDelay: unilateralExitDelay,
boardingExitDelay: boardingExitDelay,
wallet: walletSvc,
repoManager: repoManager,
builder: builder,
scanner: scanner,
sweeper: newSweeper(walletSvc, repoManager, builder, scheduler),
paymentRequests: newPaymentsMap(),
forfeitTxs: newForfeitTxsMap(builder),
eventsCh: make(chan domain.RoundEvent),
transactionEventsCh: make(chan TransactionEvent),
currentRoundLock: sync.Mutex{},
} }
repoManager.RegisterEventsHandler( repoManager.RegisterEventsHandler(
func(round *domain.Round) { func(round *domain.Round) {
go svc.propagateEvents(round) go svc.propagateEvents(round)
@@ -346,6 +354,10 @@ func (s *covenantService) GetEventsChannel(ctx context.Context) <-chan domain.Ro
return s.eventsCh return s.eventsCh
} }
func (s *covenantService) GetTransactionEventsChannel(ctx context.Context) <-chan TransactionEvent {
return s.transactionEventsCh
}
func (s *covenantService) GetRoundByTxid(ctx context.Context, poolTxid string) (*domain.Round, error) { func (s *covenantService) GetRoundByTxid(ctx context.Context, poolTxid string) (*domain.Round, error) {
return s.repoManager.Rounds().GetRoundWithTxid(ctx, poolTxid) return s.repoManager.Rounds().GetRoundWithTxid(ctx, poolTxid)
} }
@@ -851,6 +863,26 @@ func (s *covenantService) updateVtxoSet(round *domain.Round) {
} }
}() }()
} }
go func() {
// nolint:all
tx, _ := psetv2.NewPsetFromBase64(round.UnsignedTx)
boardingInputs := make([]domain.VtxoKey, 0)
for _, in := range tx.Inputs {
if len(in.TapLeafScript) > 0 {
boardingInputs = append(boardingInputs, domain.VtxoKey{
Txid: elementsutil.TxIDFromBytes(in.PreviousTxid),
VOut: in.PreviousTxIndex,
})
}
}
s.transactionEventsCh <- RoundTransactionEvent{
RoundTxID: round.Txid,
SpentVtxos: getSpentVtxos(round.Payments),
SpendableVtxos: s.getNewVtxos(round),
ClaimedBoardingInputs: boardingInputs,
}
}()
} }
func (s *covenantService) propagateEvents(round *domain.Round) { func (s *covenantService) propagateEvents(round *domain.Round) {

View File

@@ -43,6 +43,7 @@ type covenantlessService struct {
forfeitTxs *forfeitTxsMap forfeitTxs *forfeitTxsMap
eventsCh chan domain.RoundEvent eventsCh chan domain.RoundEvent
transactionEventsCh chan TransactionEvent
// cached data for the current round // cached data for the current round
lastEvent domain.RoundEvent lastEvent domain.RoundEvent
@@ -62,16 +63,11 @@ func NewCovenantlessService(
builder ports.TxBuilder, scanner ports.BlockchainScanner, builder ports.TxBuilder, scanner ports.BlockchainScanner,
scheduler ports.SchedulerService, scheduler ports.SchedulerService,
) (Service, error) { ) (Service, error) {
eventsCh := make(chan domain.RoundEvent)
paymentRequests := newPaymentsMap()
forfeitTxs := newForfeitTxsMap(builder)
pubkey, err := walletSvc.GetPubkey(context.Background()) pubkey, err := walletSvc.GetPubkey(context.Background())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch pubkey: %s", err) return nil, fmt.Errorf("failed to fetch pubkey: %s", err)
} }
sweeper := newSweeper(walletSvc, repoManager, builder, scheduler)
asyncPaymentsCache := make(map[string]struct { asyncPaymentsCache := make(map[string]struct {
receivers []domain.Receiver receivers []domain.Receiver
expireAt int64 expireAt int64
@@ -87,10 +83,11 @@ func NewCovenantlessService(
repoManager: repoManager, repoManager: repoManager,
builder: builder, builder: builder,
scanner: scanner, scanner: scanner,
sweeper: sweeper, sweeper: newSweeper(walletSvc, repoManager, builder, scheduler),
paymentRequests: paymentRequests, paymentRequests: newPaymentsMap(),
forfeitTxs: forfeitTxs, forfeitTxs: newForfeitTxsMap(builder),
eventsCh: eventsCh, eventsCh: make(chan domain.RoundEvent),
transactionEventsCh: make(chan TransactionEvent),
currentRoundLock: sync.Mutex{}, currentRoundLock: sync.Mutex{},
asyncPaymentsCache: asyncPaymentsCache, asyncPaymentsCache: asyncPaymentsCache,
treeSigningSessions: make(map[string]*musigSigningSession), treeSigningSessions: make(map[string]*musigSigningSession),
@@ -303,6 +300,14 @@ func (s *covenantlessService) CompleteAsyncPayment(
delete(s.asyncPaymentsCache, redeemTxid) delete(s.asyncPaymentsCache, redeemTxid)
go func() {
s.transactionEventsCh <- RedeemTransactionEvent{
AsyncTxID: redeemTxid,
SpentVtxos: spentVtxos,
SpendableVtxos: vtxos,
}
}()
return nil return nil
} }
@@ -579,6 +584,10 @@ func (s *covenantlessService) GetEventsChannel(ctx context.Context) <-chan domai
return s.eventsCh return s.eventsCh
} }
func (s *covenantlessService) GetTransactionEventsChannel(ctx context.Context) <-chan TransactionEvent {
return s.transactionEventsCh
}
func (s *covenantlessService) GetRoundByTxid(ctx context.Context, roundTxid string) (*domain.Round, error) { func (s *covenantlessService) GetRoundByTxid(ctx context.Context, roundTxid string) (*domain.Round, error) {
return s.repoManager.Rounds().GetRoundWithTxid(ctx, roundTxid) return s.repoManager.Rounds().GetRoundWithTxid(ctx, roundTxid)
} }
@@ -1262,7 +1271,27 @@ func (s *covenantlessService) updateVtxoSet(round *domain.Round) {
return return
} }
}() }()
} }
go func() {
// nolint:all
tx, _ := psbt.NewFromRawBytes(strings.NewReader(round.UnsignedTx), true)
boardingInputs := make([]domain.VtxoKey, 0)
for i, in := range tx.Inputs {
if len(in.TaprootLeafScript) > 0 {
boardingInputs = append(boardingInputs, domain.VtxoKey{
Txid: tx.UnsignedTx.TxIn[i].PreviousOutPoint.Hash.String(),
VOut: tx.UnsignedTx.TxIn[i].PreviousOutPoint.Index,
})
}
}
s.transactionEventsCh <- RoundTransactionEvent{
RoundTxID: round.Txid,
SpentVtxos: getSpentVtxos(round.Payments),
SpendableVtxos: s.getNewVtxos(round),
ClaimedBoardingInputs: boardingInputs,
}
}()
} }
func (s *covenantlessService) propagateEvents(round *domain.Round) { func (s *covenantlessService) propagateEvents(round *domain.Round) {

View File

@@ -50,6 +50,7 @@ type Service interface {
ctx context.Context, roundID string, ctx context.Context, roundID string,
pubkey *secp256k1.PublicKey, signatures string, pubkey *secp256k1.PublicKey, signatures string,
) error ) error
GetTransactionEventsChannel(ctx context.Context) <-chan TransactionEvent
} }
type ServiceInfo struct { type ServiceInfo struct {
@@ -81,3 +82,35 @@ func (outpoint txOutpoint) GetTxid() string {
func (outpoint txOutpoint) GetIndex() uint32 { func (outpoint txOutpoint) GetIndex() uint32 {
return outpoint.vout return outpoint.vout
} }
const (
RoundTransaction TransactionEventType = "round_tx"
RedeemTransaction TransactionEventType = "redeem_tx"
)
type TransactionEventType string
type TransactionEvent interface {
Type() TransactionEventType
}
type RoundTransactionEvent struct {
RoundTxID string
SpentVtxos []domain.VtxoKey
SpendableVtxos []domain.Vtxo
ClaimedBoardingInputs []domain.VtxoKey
}
func (r RoundTransactionEvent) Type() TransactionEventType {
return RoundTransaction
}
type RedeemTransactionEvent struct {
AsyncTxID string
SpentVtxos []domain.VtxoKey
SpendableVtxos []domain.Vtxo
}
func (a RedeemTransactionEvent) Type() TransactionEventType {
return RedeemTransaction
}

View File

@@ -15,27 +15,22 @@ import (
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
type listener struct {
id string
done chan struct{}
ch chan *arkv1.GetEventStreamResponse
}
type handler struct { type handler struct {
svc application.Service svc application.Service
listenersLock *sync.Mutex eventsListenerHandler *listenerHanlder[*arkv1.GetEventStreamResponse]
listeners []*listener transactionsListenerHandler *listenerHanlder[*arkv1.GetTransactionsStreamResponse]
} }
func NewHandler(service application.Service) arkv1.ArkServiceServer { func NewHandler(service application.Service) arkv1.ArkServiceServer {
h := &handler{ h := &handler{
svc: service, svc: service,
listenersLock: &sync.Mutex{}, eventsListenerHandler: newListenerHandler[*arkv1.GetEventStreamResponse](),
listeners: make([]*listener, 0), transactionsListenerHandler: newListenerHandler[*arkv1.GetTransactionsStreamResponse](),
} }
go h.listenToEvents() go h.listenToEvents()
go h.listenToPaymentEvents()
return h return h
} }
@@ -234,14 +229,14 @@ func (h *handler) GetEventStream(
) error { ) error {
doneCh := make(chan struct{}) doneCh := make(chan struct{})
listener := &listener{ listener := &listener[*arkv1.GetEventStreamResponse]{
id: uuid.NewString(), id: uuid.NewString(),
done: doneCh, done: doneCh,
ch: make(chan *arkv1.GetEventStreamResponse), ch: make(chan *arkv1.GetEventStreamResponse),
} }
h.pushListener(listener) h.eventsListenerHandler.pushListener(listener)
defer h.removeListener(listener.id) defer h.eventsListenerHandler.removeListener(listener.id)
defer close(listener.ch) defer close(listener.ch)
defer close(doneCh) defer close(doneCh)
@@ -488,21 +483,31 @@ func (h *handler) ListVtxos(
}, nil }, nil
} }
func (h *handler) pushListener(l *listener) { func (h *handler) GetTransactionsStream(
h.listenersLock.Lock() _ *arkv1.GetTransactionsStreamRequest,
defer h.listenersLock.Unlock() stream arkv1.ArkService_GetTransactionsStreamServer,
) error {
h.listeners = append(h.listeners, l) listener := &listener[*arkv1.GetTransactionsStreamResponse]{
id: uuid.NewString(),
done: make(chan struct{}),
ch: make(chan *arkv1.GetTransactionsStreamResponse),
} }
func (h *handler) removeListener(id string) { h.transactionsListenerHandler.pushListener(listener)
h.listenersLock.Lock()
defer h.listenersLock.Unlock()
for i, listener := range h.listeners { defer func() {
if listener.id == id { h.transactionsListenerHandler.removeListener(listener.id)
h.listeners = append(h.listeners[:i], h.listeners[i+1:]...) close(listener.ch)
return }()
for {
select {
case <-stream.Context().Done():
return nil
case ev := <-listener.ch:
if err := stream.Send(ev); err != nil {
return err
}
} }
} }
} }
@@ -582,9 +587,9 @@ func (h *handler) listenToEvents() {
} }
if ev != nil { if ev != nil {
logrus.Debugf("forwarding event to %d listeners", len(h.listeners)) logrus.Debugf("forwarding event to %d listeners", len(h.eventsListenerHandler.listeners))
for _, l := range h.listeners { for _, l := range h.eventsListenerHandler.listeners {
go func(l *listener) { go func(l *listener[*arkv1.GetEventStreamResponse]) {
l.ch <- ev l.ch <- ev
if shouldClose { if shouldClose {
l.done <- struct{}{} l.done <- struct{}{}
@@ -594,3 +599,88 @@ func (h *handler) listenToEvents() {
} }
} }
} }
func (h *handler) listenToPaymentEvents() {
paymentEventsCh := h.svc.GetTransactionEventsChannel(context.Background())
for event := range paymentEventsCh {
var paymentEvent *arkv1.GetTransactionsStreamResponse
switch event.Type() {
case application.RoundTransaction:
paymentEvent = &arkv1.GetTransactionsStreamResponse{
Tx: &arkv1.GetTransactionsStreamResponse_Round{
Round: convertRoundPaymentEvent(event.(application.RoundTransactionEvent)),
},
}
case application.RedeemTransaction:
paymentEvent = &arkv1.GetTransactionsStreamResponse{
Tx: &arkv1.GetTransactionsStreamResponse_Redeem{
Redeem: convertAsyncPaymentEvent(event.(application.RedeemTransactionEvent)),
},
}
}
if paymentEvent != nil {
logrus.Debugf("forwarding event to %d listeners", len(h.transactionsListenerHandler.listeners))
for _, l := range h.transactionsListenerHandler.listeners {
go func(l *listener[*arkv1.GetTransactionsStreamResponse]) {
l.ch <- paymentEvent
}(l)
}
}
}
}
func convertRoundPaymentEvent(e application.RoundTransactionEvent) *arkv1.RoundTransaction {
return &arkv1.RoundTransaction{
Txid: e.RoundTxID,
SpentVtxos: vtxoKeyList(e.SpentVtxos).toProto(),
SpendableVtxos: vtxoList(e.SpendableVtxos).toProto(),
ClaimedBoardingUtxos: vtxoKeyList(e.ClaimedBoardingInputs).toProto(),
}
}
func convertAsyncPaymentEvent(e application.RedeemTransactionEvent) *arkv1.RedeemTransaction {
return &arkv1.RedeemTransaction{
Txid: e.AsyncTxID,
SpentVtxos: vtxoKeyList(e.SpentVtxos).toProto(),
SpendableVtxos: vtxoList(e.SpendableVtxos).toProto(),
}
}
type listener[T any] struct {
id string
done chan struct{}
ch chan T
}
type listenerHanlder[T any] struct {
lock *sync.Mutex
listeners []*listener[T]
}
func newListenerHandler[T any]() *listenerHanlder[T] {
return &listenerHanlder[T]{
lock: &sync.Mutex{},
listeners: make([]*listener[T], 0),
}
}
func (h *listenerHanlder[T]) pushListener(l *listener[T]) {
h.lock.Lock()
defer h.lock.Unlock()
h.listeners = append(h.listeners, l)
}
func (h *listenerHanlder[T]) removeListener(id string) {
h.lock.Lock()
defer h.lock.Unlock()
for i, listener := range h.listeners {
if listener.id == id {
h.listeners = append(h.listeners[:i], h.listeners[i+1:]...)
return
}
}
}

View File

@@ -92,6 +92,19 @@ func (v vtxoList) toProto() []*arkv1.Vtxo {
return list return list
} }
type vtxoKeyList []domain.VtxoKey
func (v vtxoKeyList) toProto() []*arkv1.Outpoint {
list := make([]*arkv1.Outpoint, 0, len(v))
for _, vtxoKey := range v {
list = append(list, &arkv1.Outpoint{
Txid: vtxoKey.Txid,
Vout: vtxoKey.VOut,
})
}
return list
}
type congestionTree tree.CongestionTree type congestionTree tree.CongestionTree
func (t congestionTree) toProto() *arkv1.Tree { func (t congestionTree) toProto() *arkv1.Tree {