Add support for announcing market hours (#380)

* feat: add market hour configuration for optimal payment timing

This commit adds market hour configuration to help users determine optimal
times for making payments with lower fees. The configuration is managed
through environment variables and exposed via the GetInfo RPC.

Changes:
- Add MarketHour message type to protobuf service definition
- Add market hour configuration fields to Config struct
- Update covenant and covenantless services to handle market hour data
- Extend GetInfo RPC response to include market hour information
- Set default market hour period to 24 hours
- Initialize market hour fields after other service fields

Configuration:
- ARK_FIRST_MARKET_HOUR: Initial market hour timestamp
  (default: current server start time)
- ARK_MARKET_HOUR_PERIOD: Time between market hours in seconds
  (default: 86400)
- ARK_MARKET_HOUR_ROUND_LIFETIME: Round lifetime for market hours
  (default: 0, falls back to ARK_ROUND_LIFETIME)

* feat: add admin RPC for updating market hour configuration

Add new UpdateMarketHour RPC to AdminService for configuring market hour parameters:
- Add request/response messages to admin.proto
- Add UpdateMarketHour method to Service interface
- Implement market hour updates in covenant and covenantless services
- Add validation for market hour parameters
- Implement admin gRPC handler

The RPC allows updating:
- First market hour timestamp
- Market hour period
- Market hour round lifetime (optional, defaults to round lifetime

* feat: add market hour persistence with sqlite

- Add MarketHourRepo interface in domain layer
- Implement market hour persistence using SQLite
- Add market hour queries to sqlc/query.sql
- Update service initialization to load market hours from DB
- Add fallback to config values if no DB entry exists
- Update RepoManager interface with new MarketHourRepo method
This commit is contained in:
Dusan Sekulic
2024-11-22 10:36:51 +01:00
committed by GitHub
parent d6b8508f6d
commit ae3ccb3579
31 changed files with 2464 additions and 827 deletions

View File

@@ -16,6 +16,58 @@
"application/json"
],
"paths": {
"/v1/admin/market-hour": {
"get": {
"operationId": "AdminService_GetMarketHourConfig",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetMarketHourConfigResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"tags": [
"AdminService"
]
},
"post": {
"operationId": "AdminService_UpdateMarketHourConfig",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1UpdateMarketHourConfigResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1UpdateMarketHourConfigRequest"
}
}
],
"tags": [
"AdminService"
]
}
},
"/v1/admin/note": {
"post": {
"operationId": "AdminService_CreateNote",
@@ -186,6 +238,14 @@
}
}
},
"v1GetMarketHourConfigResponse": {
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/v1MarketHourConfig"
}
}
},
"v1GetRoundDetailsResponse": {
"type": "object",
"properties": {
@@ -263,6 +323,25 @@
}
}
},
"v1MarketHourConfig": {
"type": "object",
"properties": {
"startTime": {
"type": "string",
"format": "date-time"
},
"endTime": {
"type": "string",
"format": "date-time"
},
"period": {
"type": "string"
},
"roundInterval": {
"type": "string"
}
}
},
"v1ScheduledSweep": {
"type": "object",
"properties": {
@@ -296,6 +375,17 @@
"format": "int64"
}
}
},
"v1UpdateMarketHourConfigRequest": {
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/v1MarketHourConfig"
}
}
},
"v1UpdateMarketHourConfigResponse": {
"type": "object"
}
}
}

View File

@@ -713,6 +713,9 @@
},
"forfeitAddress": {
"type": "string"
},
"marketHour": {
"$ref": "#/definitions/v1MarketHour"
}
}
},
@@ -776,6 +779,25 @@
}
}
},
"v1MarketHour": {
"type": "object",
"properties": {
"nextStartTime": {
"type": "string",
"format": "date-time"
},
"nextEndTime": {
"type": "string",
"format": "date-time"
},
"period": {
"type": "string"
},
"roundInterval": {
"type": "string"
}
}
},
"v1Node": {
"type": "object",
"properties": {

View File

@@ -3,6 +3,8 @@ syntax = "proto3";
package ark.v1;
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
service AdminService {
rpc GetScheduledSweep(GetScheduledSweepRequest) returns (GetScheduledSweepResponse) {
@@ -27,6 +29,17 @@ service AdminService {
body: "*"
};
}
rpc GetMarketHourConfig(GetMarketHourConfigRequest) returns (GetMarketHourConfigResponse) {
option (google.api.http) = {
get: "/v1/admin/market-hour"
};
}
rpc UpdateMarketHourConfig(UpdateMarketHourConfigRequest) returns (UpdateMarketHourConfigResponse) {
option (google.api.http) = {
post: "/v1/admin/market-hour"
body: "*"
};
}
}
message GetScheduledSweepRequest {}
@@ -79,3 +92,22 @@ message CreateNoteRequest {
message CreateNoteResponse {
repeated string notes = 1;
}
message GetMarketHourConfigRequest {}
message GetMarketHourConfigResponse {
MarketHourConfig config = 1;
}
message UpdateMarketHourConfigRequest {
MarketHourConfig config = 1;
}
message UpdateMarketHourConfigResponse {}
message MarketHourConfig {
google.protobuf.Timestamp start_time = 1;
google.protobuf.Timestamp end_time = 2;
google.protobuf.Duration period = 3;
google.protobuf.Duration round_interval = 4;
}

View File

@@ -3,6 +3,8 @@ syntax = "proto3";
package ark.v1;
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
service ArkService {
rpc GetInfo(GetInfoRequest) returns (GetInfoResponse) {
@@ -126,6 +128,7 @@ message GetInfoResponse {
string boarding_descriptor_template = 7;
repeated string vtxo_descriptor_templates = 8;
string forfeit_address = 9;
MarketHour market_hour = 10;
}
message GetBoardingAddressRequest {
@@ -389,3 +392,10 @@ message DeleteNostrRecipientResponse {}
message Tapscripts {
repeated string scripts = 1;
}
message MarketHour {
google.protobuf.Timestamp next_start_time = 1;
google.protobuf.Timestamp next_end_time = 2;
google.protobuf.Duration period = 3;
google.protobuf.Duration round_interval = 4;
}

View File

@@ -10,6 +10,8 @@ import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
)
@@ -594,110 +596,402 @@ func (x *CreateNoteResponse) GetNotes() []string {
return nil
}
type GetMarketHourConfigRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetMarketHourConfigRequest) Reset() {
*x = GetMarketHourConfigRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_admin_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetMarketHourConfigRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetMarketHourConfigRequest) ProtoMessage() {}
func (x *GetMarketHourConfigRequest) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_admin_proto_msgTypes[10]
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 GetMarketHourConfigRequest.ProtoReflect.Descriptor instead.
func (*GetMarketHourConfigRequest) Descriptor() ([]byte, []int) {
return file_ark_v1_admin_proto_rawDescGZIP(), []int{10}
}
type GetMarketHourConfigResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Config *MarketHourConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
}
func (x *GetMarketHourConfigResponse) Reset() {
*x = GetMarketHourConfigResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_admin_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetMarketHourConfigResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetMarketHourConfigResponse) ProtoMessage() {}
func (x *GetMarketHourConfigResponse) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_admin_proto_msgTypes[11]
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 GetMarketHourConfigResponse.ProtoReflect.Descriptor instead.
func (*GetMarketHourConfigResponse) Descriptor() ([]byte, []int) {
return file_ark_v1_admin_proto_rawDescGZIP(), []int{11}
}
func (x *GetMarketHourConfigResponse) GetConfig() *MarketHourConfig {
if x != nil {
return x.Config
}
return nil
}
type UpdateMarketHourConfigRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Config *MarketHourConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
}
func (x *UpdateMarketHourConfigRequest) Reset() {
*x = UpdateMarketHourConfigRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_admin_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateMarketHourConfigRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateMarketHourConfigRequest) ProtoMessage() {}
func (x *UpdateMarketHourConfigRequest) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_admin_proto_msgTypes[12]
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 UpdateMarketHourConfigRequest.ProtoReflect.Descriptor instead.
func (*UpdateMarketHourConfigRequest) Descriptor() ([]byte, []int) {
return file_ark_v1_admin_proto_rawDescGZIP(), []int{12}
}
func (x *UpdateMarketHourConfigRequest) GetConfig() *MarketHourConfig {
if x != nil {
return x.Config
}
return nil
}
type UpdateMarketHourConfigResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *UpdateMarketHourConfigResponse) Reset() {
*x = UpdateMarketHourConfigResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_admin_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateMarketHourConfigResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateMarketHourConfigResponse) ProtoMessage() {}
func (x *UpdateMarketHourConfigResponse) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_admin_proto_msgTypes[13]
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 UpdateMarketHourConfigResponse.ProtoReflect.Descriptor instead.
func (*UpdateMarketHourConfigResponse) Descriptor() ([]byte, []int) {
return file_ark_v1_admin_proto_rawDescGZIP(), []int{13}
}
type MarketHourConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
StartTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
EndTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"`
Period *durationpb.Duration `protobuf:"bytes,3,opt,name=period,proto3" json:"period,omitempty"`
RoundInterval *durationpb.Duration `protobuf:"bytes,4,opt,name=round_interval,json=roundInterval,proto3" json:"round_interval,omitempty"`
}
func (x *MarketHourConfig) Reset() {
*x = MarketHourConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_ark_v1_admin_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MarketHourConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MarketHourConfig) ProtoMessage() {}
func (x *MarketHourConfig) ProtoReflect() protoreflect.Message {
mi := &file_ark_v1_admin_proto_msgTypes[14]
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 MarketHourConfig.ProtoReflect.Descriptor instead.
func (*MarketHourConfig) Descriptor() ([]byte, []int) {
return file_ark_v1_admin_proto_rawDescGZIP(), []int{14}
}
func (x *MarketHourConfig) GetStartTime() *timestamppb.Timestamp {
if x != nil {
return x.StartTime
}
return nil
}
func (x *MarketHourConfig) GetEndTime() *timestamppb.Timestamp {
if x != nil {
return x.EndTime
}
return nil
}
func (x *MarketHourConfig) GetPeriod() *durationpb.Duration {
if x != nil {
return x.Period
}
return nil
}
func (x *MarketHourConfig) GetRoundInterval() *durationpb.Duration {
if x != nil {
return x.RoundInterval
}
return nil
}
var File_ark_v1_admin_proto protoreflect.FileDescriptor
var file_ark_v1_admin_proto_rawDesc = []byte{
0x0a, 0x12, 0x61, 0x72, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65,
0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x77, 0x65, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x06, 0x73, 0x77, 0x65,
0x65, 0x70, 0x73, 0x22, 0x74, 0x0a, 0x0f, 0x53, 0x77, 0x65, 0x65, 0x70, 0x61, 0x62, 0x6c, 0x65,
0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x6f,
0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x12, 0x16,
0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
0x6c, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x63,
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x41, 0x74, 0x22, 0x5e, 0x0a, 0x0e, 0x53, 0x63, 0x68,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x72,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1a, 0x0a, 0x18, 0x47,
0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x63,
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x77, 0x65, 0x65, 0x70, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63,
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x06, 0x73, 0x77,
0x65, 0x65, 0x70, 0x73, 0x22, 0x74, 0x0a, 0x0f, 0x53, 0x77, 0x65, 0x65, 0x70, 0x61, 0x62, 0x6c,
0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76,
0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x12,
0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x64,
0x75, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73,
0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x41, 0x74, 0x22, 0x5e, 0x0a, 0x0e, 0x53, 0x63,
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x19, 0x0a, 0x08,
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75,
0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x77, 0x65, 0x65, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75,
0x74, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x33, 0x0a, 0x16, 0x47, 0x65,
0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x64, 0x22,
0xdd, 0x02, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72,
0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72,
0x6f, 0x75, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x77, 0x65, 0x65, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74,
0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x33, 0x0a, 0x16, 0x47, 0x65, 0x74,
0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x64, 0x22, 0xdd,
0x02, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69,
0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f,
0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f,
0x75, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x6f, 0x72,
0x66, 0x65, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x65, 0x64, 0x41, 0x6d,
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x76, 0x74,
0x78, 0x6f, 0x73, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x41, 0x6d, 0x6f, 0x75,
0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74,
0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74,
0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f,
0x0a, 0x0b, 0x66, 0x65, 0x65, 0x73, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18,
0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x56, 0x74, 0x78,
0x6f, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x76, 0x74,
0x78, 0x6f, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75,
0x74, 0x73, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x69, 0x74, 0x5f,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52,
0x0d, 0x65, 0x78, 0x69, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x40,
0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f,
0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65,
0x22, 0x2b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x47, 0x0a,
0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0d, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75,
0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x71, 0x75,
0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x2a, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05,
0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74,
0x65, 0x73, 0x32, 0xb9, 0x03, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75,
0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53, 0x77,
0x65, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x72, 0x6b,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64,
0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e,
0x2f, 0x73, 0x77, 0x65, 0x65, 0x70, 0x73, 0x12, 0x76, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f,
0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72,
0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x12,
0x5d, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x18, 0x2e, 0x61,
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x76,
0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x5e,
0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61,
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e,
0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x42, 0x90,
0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x41,
0x64, 0x6d, 0x69, 0x6e, 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,
0x6f, 0x75, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x6f,
0x72, 0x66, 0x65, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x65, 0x64, 0x41,
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x76,
0x74, 0x78, 0x6f, 0x73, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x41, 0x6d, 0x6f,
0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69,
0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x1f, 0x0a, 0x0b, 0x66, 0x65, 0x65, 0x73, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73,
0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x56, 0x74,
0x78, 0x6f, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x76,
0x74, 0x78, 0x6f, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70,
0x75, 0x74, 0x73, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x69, 0x74,
0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09,
0x52, 0x0d, 0x65, 0x78, 0x69, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22,
0x40, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x66,
0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72,
0x65, 0x22, 0x2b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x47,
0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x71,
0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x71,
0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x2a, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a,
0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f,
0x74, 0x65, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74,
0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x22, 0x4f, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48, 0x6f,
0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x30, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74,
0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x22, 0x51, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x72, 0x6b,
0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72,
0x6b, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x20, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d,
0x61, 0x72, 0x6b, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf9, 0x01, 0x0a, 0x10, 0x4d, 0x61, 0x72, 0x6b,
0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x0a,
0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74,
0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x31,
0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f,
0x64, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x76, 0x61, 0x6c, 0x32, 0xc4, 0x05, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64,
0x75, 0x6c, 0x65, 0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x53,
0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x72,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
0x64, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69,
0x6e, 0x2f, 0x73, 0x77, 0x65, 0x65, 0x70, 0x73, 0x12, 0x76, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52,
0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x72,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72,
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f,
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d,
0x12, 0x5d, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x18, 0x2e,
0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f,
0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12,
0x5e, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x19, 0x2e,
0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22,
0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x12,
0x7d, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x61, 0x72, 0x6b,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48, 0x6f, 0x75,
0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d,
0x69, 0x6e, 0x2f, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x2d, 0x68, 0x6f, 0x75, 0x72, 0x12, 0x89,
0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48,
0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48,
0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x26, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a,
0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6d,
0x61, 0x72, 0x6b, 0x65, 0x74, 0x2d, 0x68, 0x6f, 0x75, 0x72, 0x42, 0x90, 0x01, 0x0a, 0x0a, 0x63,
0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e,
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 (
@@ -712,7 +1006,7 @@ func file_ark_v1_admin_proto_rawDescGZIP() []byte {
return file_ark_v1_admin_proto_rawDescData
}
var file_ark_v1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_ark_v1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_ark_v1_admin_proto_goTypes = []interface{}{
(*GetScheduledSweepRequest)(nil), // 0: ark.v1.GetScheduledSweepRequest
(*GetScheduledSweepResponse)(nil), // 1: ark.v1.GetScheduledSweepResponse
@@ -724,23 +1018,40 @@ var file_ark_v1_admin_proto_goTypes = []interface{}{
(*GetRoundsResponse)(nil), // 7: ark.v1.GetRoundsResponse
(*CreateNoteRequest)(nil), // 8: ark.v1.CreateNoteRequest
(*CreateNoteResponse)(nil), // 9: ark.v1.CreateNoteResponse
(*GetMarketHourConfigRequest)(nil), // 10: ark.v1.GetMarketHourConfigRequest
(*GetMarketHourConfigResponse)(nil), // 11: ark.v1.GetMarketHourConfigResponse
(*UpdateMarketHourConfigRequest)(nil), // 12: ark.v1.UpdateMarketHourConfigRequest
(*UpdateMarketHourConfigResponse)(nil), // 13: ark.v1.UpdateMarketHourConfigResponse
(*MarketHourConfig)(nil), // 14: ark.v1.MarketHourConfig
(*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp
(*durationpb.Duration)(nil), // 16: google.protobuf.Duration
}
var file_ark_v1_admin_proto_depIdxs = []int32{
3, // 0: ark.v1.GetScheduledSweepResponse.sweeps:type_name -> ark.v1.ScheduledSweep
2, // 1: ark.v1.ScheduledSweep.outputs:type_name -> ark.v1.SweepableOutput
0, // 2: ark.v1.AdminService.GetScheduledSweep:input_type -> ark.v1.GetScheduledSweepRequest
4, // 3: ark.v1.AdminService.GetRoundDetails:input_type -> ark.v1.GetRoundDetailsRequest
6, // 4: ark.v1.AdminService.GetRounds:input_type -> ark.v1.GetRoundsRequest
8, // 5: ark.v1.AdminService.CreateNote:input_type -> ark.v1.CreateNoteRequest
1, // 6: ark.v1.AdminService.GetScheduledSweep:output_type -> ark.v1.GetScheduledSweepResponse
5, // 7: ark.v1.AdminService.GetRoundDetails:output_type -> ark.v1.GetRoundDetailsResponse
7, // 8: ark.v1.AdminService.GetRounds:output_type -> ark.v1.GetRoundsResponse
9, // 9: ark.v1.AdminService.CreateNote:output_type -> ark.v1.CreateNoteResponse
6, // [6:10] is the sub-list for method output_type
2, // [2:6] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
14, // 2: ark.v1.GetMarketHourConfigResponse.config:type_name -> ark.v1.MarketHourConfig
14, // 3: ark.v1.UpdateMarketHourConfigRequest.config:type_name -> ark.v1.MarketHourConfig
15, // 4: ark.v1.MarketHourConfig.start_time:type_name -> google.protobuf.Timestamp
15, // 5: ark.v1.MarketHourConfig.end_time:type_name -> google.protobuf.Timestamp
16, // 6: ark.v1.MarketHourConfig.period:type_name -> google.protobuf.Duration
16, // 7: ark.v1.MarketHourConfig.round_interval:type_name -> google.protobuf.Duration
0, // 8: ark.v1.AdminService.GetScheduledSweep:input_type -> ark.v1.GetScheduledSweepRequest
4, // 9: ark.v1.AdminService.GetRoundDetails:input_type -> ark.v1.GetRoundDetailsRequest
6, // 10: ark.v1.AdminService.GetRounds:input_type -> ark.v1.GetRoundsRequest
8, // 11: ark.v1.AdminService.CreateNote:input_type -> ark.v1.CreateNoteRequest
10, // 12: ark.v1.AdminService.GetMarketHourConfig:input_type -> ark.v1.GetMarketHourConfigRequest
12, // 13: ark.v1.AdminService.UpdateMarketHourConfig:input_type -> ark.v1.UpdateMarketHourConfigRequest
1, // 14: ark.v1.AdminService.GetScheduledSweep:output_type -> ark.v1.GetScheduledSweepResponse
5, // 15: ark.v1.AdminService.GetRoundDetails:output_type -> ark.v1.GetRoundDetailsResponse
7, // 16: ark.v1.AdminService.GetRounds:output_type -> ark.v1.GetRoundsResponse
9, // 17: ark.v1.AdminService.CreateNote:output_type -> ark.v1.CreateNoteResponse
11, // 18: ark.v1.AdminService.GetMarketHourConfig:output_type -> ark.v1.GetMarketHourConfigResponse
13, // 19: ark.v1.AdminService.UpdateMarketHourConfig:output_type -> ark.v1.UpdateMarketHourConfigResponse
14, // [14:20] is the sub-list for method output_type
8, // [8:14] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_ark_v1_admin_proto_init() }
@@ -869,6 +1180,66 @@ func file_ark_v1_admin_proto_init() {
return nil
}
}
file_ark_v1_admin_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetMarketHourConfigRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_admin_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetMarketHourConfigResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_admin_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateMarketHourConfigRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_admin_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateMarketHourConfigResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ark_v1_admin_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MarketHourConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -876,7 +1247,7 @@ func file_ark_v1_admin_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ark_v1_admin_proto_rawDesc,
NumEnums: 0,
NumMessages: 10,
NumMessages: 15,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -153,6 +153,50 @@ func local_request_AdminService_CreateNote_0(ctx context.Context, marshaler runt
}
func request_AdminService_GetMarketHourConfig_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetMarketHourConfigRequest
var metadata runtime.ServerMetadata
msg, err := client.GetMarketHourConfig(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AdminService_GetMarketHourConfig_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetMarketHourConfigRequest
var metadata runtime.ServerMetadata
msg, err := server.GetMarketHourConfig(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_UpdateMarketHourConfig_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq UpdateMarketHourConfigRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.UpdateMarketHourConfig(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AdminService_UpdateMarketHourConfig_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq UpdateMarketHourConfigRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.UpdateMarketHourConfig(ctx, &protoReq)
return msg, metadata, err
}
// RegisterAdminServiceHandlerServer registers the http handlers for service AdminService to "mux".
// UnaryRPC :call AdminServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -260,6 +304,56 @@ func RegisterAdminServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu
})
mux.Handle("GET", pattern_AdminService_GetMarketHourConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ark.v1.AdminService/GetMarketHourConfig", runtime.WithHTTPPathPattern("/v1/admin/market-hour"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_GetMarketHourConfig_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_GetMarketHourConfig_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AdminService_UpdateMarketHourConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ark.v1.AdminService/UpdateMarketHourConfig", runtime.WithHTTPPathPattern("/v1/admin/market-hour"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_UpdateMarketHourConfig_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_UpdateMarketHourConfig_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@@ -389,6 +483,50 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu
})
mux.Handle("GET", pattern_AdminService_GetMarketHourConfig_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.AdminService/GetMarketHourConfig", runtime.WithHTTPPathPattern("/v1/admin/market-hour"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AdminService_GetMarketHourConfig_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_GetMarketHourConfig_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AdminService_UpdateMarketHourConfig_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.AdminService/UpdateMarketHourConfig", runtime.WithHTTPPathPattern("/v1/admin/market-hour"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AdminService_UpdateMarketHourConfig_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_UpdateMarketHourConfig_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@@ -400,6 +538,10 @@ var (
pattern_AdminService_GetRounds_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "rounds"}, ""))
pattern_AdminService_CreateNote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "note"}, ""))
pattern_AdminService_GetMarketHourConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "market-hour"}, ""))
pattern_AdminService_UpdateMarketHourConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "market-hour"}, ""))
)
var (
@@ -410,4 +552,8 @@ var (
forward_AdminService_GetRounds_0 = runtime.ForwardResponseMessage
forward_AdminService_CreateNote_0 = runtime.ForwardResponseMessage
forward_AdminService_GetMarketHourConfig_0 = runtime.ForwardResponseMessage
forward_AdminService_UpdateMarketHourConfig_0 = runtime.ForwardResponseMessage
)

View File

@@ -22,6 +22,8 @@ type AdminServiceClient interface {
GetRoundDetails(ctx context.Context, in *GetRoundDetailsRequest, opts ...grpc.CallOption) (*GetRoundDetailsResponse, error)
GetRounds(ctx context.Context, in *GetRoundsRequest, opts ...grpc.CallOption) (*GetRoundsResponse, error)
CreateNote(ctx context.Context, in *CreateNoteRequest, opts ...grpc.CallOption) (*CreateNoteResponse, error)
GetMarketHourConfig(ctx context.Context, in *GetMarketHourConfigRequest, opts ...grpc.CallOption) (*GetMarketHourConfigResponse, error)
UpdateMarketHourConfig(ctx context.Context, in *UpdateMarketHourConfigRequest, opts ...grpc.CallOption) (*UpdateMarketHourConfigResponse, error)
}
type adminServiceClient struct {
@@ -68,6 +70,24 @@ func (c *adminServiceClient) CreateNote(ctx context.Context, in *CreateNoteReque
return out, nil
}
func (c *adminServiceClient) GetMarketHourConfig(ctx context.Context, in *GetMarketHourConfigRequest, opts ...grpc.CallOption) (*GetMarketHourConfigResponse, error) {
out := new(GetMarketHourConfigResponse)
err := c.cc.Invoke(ctx, "/ark.v1.AdminService/GetMarketHourConfig", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *adminServiceClient) UpdateMarketHourConfig(ctx context.Context, in *UpdateMarketHourConfigRequest, opts ...grpc.CallOption) (*UpdateMarketHourConfigResponse, error) {
out := new(UpdateMarketHourConfigResponse)
err := c.cc.Invoke(ctx, "/ark.v1.AdminService/UpdateMarketHourConfig", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AdminServiceServer is the server API for AdminService service.
// All implementations should embed UnimplementedAdminServiceServer
// for forward compatibility
@@ -76,6 +96,8 @@ type AdminServiceServer interface {
GetRoundDetails(context.Context, *GetRoundDetailsRequest) (*GetRoundDetailsResponse, error)
GetRounds(context.Context, *GetRoundsRequest) (*GetRoundsResponse, error)
CreateNote(context.Context, *CreateNoteRequest) (*CreateNoteResponse, error)
GetMarketHourConfig(context.Context, *GetMarketHourConfigRequest) (*GetMarketHourConfigResponse, error)
UpdateMarketHourConfig(context.Context, *UpdateMarketHourConfigRequest) (*UpdateMarketHourConfigResponse, error)
}
// UnimplementedAdminServiceServer should be embedded to have forward compatible implementations.
@@ -94,6 +116,12 @@ func (UnimplementedAdminServiceServer) GetRounds(context.Context, *GetRoundsRequ
func (UnimplementedAdminServiceServer) CreateNote(context.Context, *CreateNoteRequest) (*CreateNoteResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateNote not implemented")
}
func (UnimplementedAdminServiceServer) GetMarketHourConfig(context.Context, *GetMarketHourConfigRequest) (*GetMarketHourConfigResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetMarketHourConfig not implemented")
}
func (UnimplementedAdminServiceServer) UpdateMarketHourConfig(context.Context, *UpdateMarketHourConfigRequest) (*UpdateMarketHourConfigResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateMarketHourConfig not implemented")
}
// UnsafeAdminServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AdminServiceServer will
@@ -178,6 +206,42 @@ func _AdminService_CreateNote_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _AdminService_GetMarketHourConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetMarketHourConfigRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AdminServiceServer).GetMarketHourConfig(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ark.v1.AdminService/GetMarketHourConfig",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AdminServiceServer).GetMarketHourConfig(ctx, req.(*GetMarketHourConfigRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AdminService_UpdateMarketHourConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateMarketHourConfigRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AdminServiceServer).UpdateMarketHourConfig(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ark.v1.AdminService/UpdateMarketHourConfig",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AdminServiceServer).UpdateMarketHourConfig(ctx, req.(*UpdateMarketHourConfigRequest))
}
return interceptor(ctx, in, info, handler)
}
// AdminService_ServiceDesc is the grpc.ServiceDesc for AdminService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -201,6 +265,14 @@ var AdminService_ServiceDesc = grpc.ServiceDesc{
MethodName: "CreateNote",
Handler: _AdminService_CreateNote_Handler,
},
{
MethodName: "GetMarketHourConfig",
Handler: _AdminService_GetMarketHourConfig_Handler,
},
{
MethodName: "UpdateMarketHourConfig",
Handler: _AdminService_UpdateMarketHourConfig_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "ark/v1/admin.proto",

File diff suppressed because it is too large Load Diff

View File

@@ -404,6 +404,7 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/apache/arrow/go/v10 v10.0.1 h1:n9dERvixoC/1JjDmBcs9FPaEryoANa2sCgVFo6ez9cI=
github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
@@ -453,6 +454,7 @@ github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11/go.mod h1:fmgDANqTUCxciViKl9hb/
github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA=
github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/bluekeyes/go-gitdiff v0.7.1 h1:graP4ElLRshr8ecu0UtqfNTCHrtSyZd3DABQm/DWesQ=
github.com/bluekeyes/go-gitdiff v0.7.1/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.22.0-beta.0.20220204213055-eaf0459ff879/go.mod h1:osu7EoKiL36UThEgzYPqdRaxeo0NU8VoXqgcnwpey0g=
@@ -530,6 +532,7 @@ github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZ
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fiatjaf/eventstore v0.9.0 h1:WsGDVAaRaVaV/J8PdrQDGfzChrL13q+lTO4C44rhu3E=
github.com/fiatjaf/eventstore v0.9.0/go.mod h1:JrAce5h0wi79+Sw4gsEq5kz0NtUxbVkOZ7lAo7ay6R8=
github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8=
github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
@@ -590,7 +593,9 @@ github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YAR
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/graph-gophers/dataloader/v7 v7.1.0 h1:Wn8HGF/q7MNXcvfaBnLEPEFJttVHR8zuEqP1obys/oc=
github.com/graph-gophers/dataloader/v7 v7.1.0/go.mod h1:1bKE0Dm6OUcTB/OAuYVOZctgIz7Q3d0XrYtlIzTgg6Q=
github.com/greatroar/blobloom v0.8.0 h1:I9RlEkfqK9/6f1v9mFmDYegDQ/x0mISCpiNpAm23Pt4=
github.com/greatroar/blobloom v0.8.0/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
@@ -616,6 +621,7 @@ github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
@@ -627,6 +633,7 @@ github.com/jedib0t/go-pretty/v6 v6.2.7 h1:4823Lult/tJ0VI1PgW3aSKw59pMWQ6Kzv9b3Bj
github.com/jedib0t/go-pretty/v6 v6.2.7/go.mod h1:FMkOpgGD3EZ91cW8g/96RfxoV7bdeJyzXPYgz1L1ln0=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -658,6 +665,7 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
github.com/ktrysmt/go-bitbucket v0.6.4 h1:C8dUGp0qkwncKtAnozHCbbqhptefzEd1I0sfnuy9rYQ=
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 h1:JLvn7D+wXjH9g4Jsjo+VqmzTUpl/LX7vfr6VOfSWTdM=
github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06/go.mod h1:FUkZ5OHjlGPjnM2UyGJz9TypXQFgYqw6AFNO1UiROTM=
github.com/lightninglabs/neutrino v0.16.0/go.mod h1:x3OmY2wsA18+Kc3TSV2QpSUewOCiscw2mKpXgZv2kZk=
github.com/lightninglabs/neutrino/cache v1.1.0/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo=
@@ -684,6 +692,7 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -715,7 +724,9 @@ github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/ncruces/go-sqlite3 v0.18.3 h1:tyMa75uh7LcINcfo0WrzOvcTkfz8Hqu0TEPX+KVyes4=
github.com/ncruces/go-sqlite3 v0.18.3/go.mod h1:HAwOtA+cyEX3iN6YmkpQwfT4vMMgCB7rQRFUdOgEFik=
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba h1:fhFP5RliM2HW/8XdcO5QngSfFli9GcRIpMXvypTQt6E=
github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI=
@@ -759,14 +770,18 @@ github.com/snowflakedb/gosnowflake v1.6.19 h1:KSHXrQ5o7uso25hNIzi/RObXtnSGkFgie9
github.com/snowflakedb/gosnowflake v1.6.19/go.mod h1:FM1+PWUdwB9udFDsXdfD58NONC0m+MlOSmQRvimobSM=
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g=
github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/tursodatabase/go-libsql v0.0.0-20240916111504-922dfa87e1e6 h1:bFxO2fsY5mHZRrVvhmrAo/O8Agi9HDAIMmmOClZMrkQ=
github.com/tursodatabase/go-libsql v0.0.0-20240916111504-922dfa87e1e6/go.mod h1:TjsB2miB8RW2Sse8sdxzVTdeGlx74GloD5zJYUC38d8=
github.com/tv42/zbase32 v0.0.0-20160707012821-501572607d02 h1:tcJ6OjwOMvExLlzrAVZute09ocAGa7KqOON60++Gz4E=
github.com/tv42/zbase32 v0.0.0-20160707012821-501572607d02/go.mod h1:tHlrkM198S068ZqfrO6S8HsoJq2bF3ETfTL+kt4tInY=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw=

View File

@@ -85,6 +85,10 @@ func mainAction(_ *cli.Context) error {
UnlockerPassword: cfg.UnlockerPassword,
NostrDefaultRelays: cfg.NostrDefaultRelays,
NoteUriPrefix: cfg.NoteUriPrefix,
MarketHourStartTime: cfg.MarketHourStartTime,
MarketHourEndTime: cfg.MarketHourEndTime,
MarketHourPeriod: cfg.MarketHourPeriod,
MarketHourRoundInterval: cfg.MarketHourRoundInterval,
}
svc, err := grpcservice.NewService(svcConfig, appConfig)
if err != nil {

View File

@@ -3,6 +3,7 @@ package appconfig
import (
"fmt"
"strings"
"time"
"github.com/ark-network/ark/common"
"github.com/ark-network/ark/server/internal/core/application"
@@ -69,6 +70,10 @@ type Config struct {
BoardingExitDelay int64
NostrDefaultRelays []string
NoteUriPrefix string
MarketHourStartTime time.Time
MarketHourEndTime time.Time
MarketHourPeriod time.Duration
MarketHourRoundInterval time.Duration
EsploraURL string
NeutrinoPeer string
@@ -354,6 +359,7 @@ func (c *Config) appService() error {
svc, err := application.NewCovenantService(
c.Network, c.RoundInterval, c.RoundLifetime, c.UnilateralExitDelay, c.BoardingExitDelay, c.NostrDefaultRelays,
c.wallet, c.repo, c.txBuilder, c.scanner, c.scheduler, c.NoteUriPrefix,
c.MarketHourStartTime, c.MarketHourEndTime, c.MarketHourPeriod, c.MarketHourRoundInterval,
)
if err != nil {
return err
@@ -366,6 +372,7 @@ func (c *Config) appService() error {
svc, err := application.NewCovenantlessService(
c.Network, c.RoundInterval, c.RoundLifetime, c.UnilateralExitDelay, c.BoardingExitDelay, c.NostrDefaultRelays,
c.wallet, c.repo, c.txBuilder, c.scanner, c.scheduler, c.NoteUriPrefix,
c.MarketHourStartTime, c.MarketHourEndTime, c.MarketHourPeriod, c.MarketHourRoundInterval,
)
if err != nil {
return err

View File

@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"strings"
"time"
"github.com/ark-network/ark/common"
"github.com/spf13/viper"
@@ -42,6 +43,10 @@ type Config struct {
UnlockerPassword string
NostrDefaultRelays []string
NoteUriPrefix string
MarketHourStartTime time.Time
MarketHourEndTime time.Time
MarketHourPeriod time.Duration
MarketHourRoundInterval time.Duration
}
var (
@@ -77,6 +82,10 @@ var (
UnlockerFilePath = "UNLOCKER_FILE_PATH"
UnlockerPassword = "UNLOCKER_PASSWORD"
NoteUriPrefix = "NOTE_URI_PREFIX"
MarketHourStartTime = "MARKET_HOUR_START_TIME"
MarketHourEndTime = "MARKET_HOUR_END_TIME"
MarketHourPeriod = "MARKET_HOUR_PERIOD"
MarketHourRoundInterval = "MARKET_HOUR_ROUND_INTERVAL"
defaultDatadir = common.AppDataDir("arkd", false)
defaultRoundInterval = 15
@@ -95,6 +104,10 @@ var (
defaultNoMacaroons = false
defaultNoTLS = true
defaultNostrDefaultRelays = []string{"wss://relay.primal.net", "wss://relay.damus.io"}
defaultMarketHourStartTime = time.Now()
defaultMarketHourEndTime = defaultMarketHourStartTime.Add(time.Duration(defaultRoundInterval) * time.Second)
defaultMarketHourPeriod = time.Duration(24) * time.Hour
defaultMarketHourInterval = time.Duration(defaultRoundInterval) * time.Second
)
func LoadConfig() (*Config, error) {
@@ -118,6 +131,11 @@ func LoadConfig() (*Config, error) {
viper.SetDefault(NoMacaroons, defaultNoMacaroons)
viper.SetDefault(BoardingExitDelay, defaultBoardingExitDelay)
viper.SetDefault(NostrDefaultRelays, defaultNostrDefaultRelays)
viper.SetDefault(MarketHourStartTime, defaultMarketHourStartTime)
viper.SetDefault(MarketHourEndTime, defaultMarketHourEndTime)
viper.SetDefault(MarketHourPeriod, defaultMarketHourPeriod)
viper.SetDefault(MarketHourRoundInterval, defaultMarketHourInterval)
net, err := getNetwork()
if err != nil {
return nil, fmt.Errorf("error while getting network: %s", err)
@@ -159,6 +177,10 @@ func LoadConfig() (*Config, error) {
UnlockerPassword: viper.GetString(UnlockerPassword),
NostrDefaultRelays: viper.GetStringSlice(NostrDefaultRelays),
NoteUriPrefix: viper.GetString(NoteUriPrefix),
MarketHourStartTime: viper.GetTime(MarketHourStartTime),
MarketHourEndTime: viper.GetTime(MarketHourEndTime),
MarketHourPeriod: viper.GetDuration(MarketHourPeriod),
MarketHourRoundInterval: viper.GetDuration(MarketHourRoundInterval),
}, nil
}

View File

@@ -63,12 +63,25 @@ func NewCovenantService(
builder ports.TxBuilder, scanner ports.BlockchainScanner,
scheduler ports.SchedulerService,
notificationPrefix string,
marketHourStartTime, marketHourEndTime time.Time, marketHourPeriod, marketHourRoundInterval time.Duration,
) (Service, error) {
pubkey, err := walletSvc.GetPubkey(context.Background())
if err != nil {
return nil, fmt.Errorf("failed to fetch pubkey: %s", err)
}
marketHour, err := repoManager.MarketHourRepo().Get(context.Background())
if err != nil {
return nil, fmt.Errorf("failed to get market hours from db: %w", err)
}
if marketHour == nil {
marketHour = domain.NewMarketHour(marketHourStartTime, marketHourEndTime, marketHourPeriod, marketHourRoundInterval)
if err := repoManager.MarketHourRepo().Upsert(context.Background(), *marketHour); err != nil {
return nil, fmt.Errorf("failed to upsert initial market hours to db: %w", err)
}
}
svc := &covenantService{
network: network,
pubkey: pubkey,
@@ -430,6 +443,22 @@ func (s *covenantService) GetInfo(ctx context.Context) (*ServiceInfo, error) {
return nil, err
}
marketHourConfig, err := s.repoManager.MarketHourRepo().Get(ctx)
if err != nil {
return nil, err
}
marketHourNextStart, marketHourNextEnd, err := calcNextMarketHour(
marketHourConfig.StartTime,
marketHourConfig.EndTime,
marketHourConfig.Period,
marketHourDelta,
time.Now(),
)
if err != nil {
return nil, err
}
return &ServiceInfo{
PubKey: pubkey,
RoundLifetime: s.roundLifetime,
@@ -438,6 +467,12 @@ func (s *covenantService) GetInfo(ctx context.Context) (*ServiceInfo, error) {
Network: s.network.Name,
Dust: dust,
ForfeitAddress: forfeitAddress,
NextMarketHour: &NextMarketHour{
StartTime: marketHourNextStart,
EndTime: marketHourNextEnd,
Period: marketHourConfig.Period,
RoundInterval: marketHourConfig.RoundInterval,
},
}, nil
}
@@ -1153,3 +1188,24 @@ func findForfeitTxLiquid(
return "", fmt.Errorf("forfeit tx not found")
}
func (s *covenantService) GetMarketHourConfig(ctx context.Context) (*domain.MarketHour, error) {
return s.repoManager.MarketHourRepo().Get(ctx)
}
func (s *covenantService) UpdateMarketHourConfig(
ctx context.Context,
marketHourStartTime, marketHourEndTime time.Time, period, roundInterval time.Duration,
) error {
marketHour := domain.NewMarketHour(
marketHourStartTime,
marketHourEndTime,
period,
roundInterval,
)
if err := s.repoManager.MarketHourRepo().Upsert(ctx, *marketHour); err != nil {
return fmt.Errorf("failed to upsert market hours: %w", err)
}
return nil
}

View File

@@ -26,6 +26,8 @@ import (
log "github.com/sirupsen/logrus"
)
const marketHourDelta = 5 * time.Minute
type covenantlessService struct {
network common.Network
pubkey *secp256k1.PublicKey
@@ -59,17 +61,32 @@ type covenantlessService struct {
func NewCovenantlessService(
network common.Network,
roundInterval, roundLifetime, unilateralExitDelay, boardingExitDelay int64,
defaultNostrRelays []string,
nostrDefaultRelays []string,
walletSvc ports.WalletService, repoManager ports.RepoManager,
builder ports.TxBuilder, scanner ports.BlockchainScanner,
scheduler ports.SchedulerService,
notificationPrefix string,
noteUriPrefix string,
marketHourStartTime, marketHourEndTime time.Time,
marketHourPeriod, marketHourRoundInterval time.Duration,
) (Service, error) {
pubkey, err := walletSvc.GetPubkey(context.Background())
if err != nil {
return nil, fmt.Errorf("failed to fetch pubkey: %s", err)
}
// Try to load market hours from DB first
marketHour, err := repoManager.MarketHourRepo().Get(context.Background())
if err != nil {
return nil, fmt.Errorf("failed to get market hours from db: %w", err)
}
if marketHour == nil {
marketHour = domain.NewMarketHour(marketHourStartTime, marketHourEndTime, marketHourPeriod, marketHourRoundInterval)
if err := repoManager.MarketHourRepo().Upsert(context.Background(), *marketHour); err != nil {
return nil, fmt.Errorf("failed to upsert initial market hours to db: %w", err)
}
}
svc := &covenantlessService{
network: network,
pubkey: pubkey,
@@ -80,7 +97,7 @@ func NewCovenantlessService(
repoManager: repoManager,
builder: builder,
scanner: scanner,
sweeper: newSweeper(walletSvc, repoManager, builder, scheduler, notificationPrefix),
sweeper: newSweeper(walletSvc, repoManager, builder, scheduler, noteUriPrefix),
paymentRequests: newPaymentsMap(),
forfeitTxs: newForfeitTxsMap(builder),
eventsCh: make(chan domain.RoundEvent),
@@ -89,7 +106,7 @@ func NewCovenantlessService(
asyncPaymentsCache: make(map[string]asyncPaymentData),
treeSigningSessions: make(map[string]*musigSigningSession),
boardingExitDelay: boardingExitDelay,
nostrDefaultRelays: defaultNostrRelays,
nostrDefaultRelays: nostrDefaultRelays,
}
repoManager.RegisterEventsHandler(
@@ -693,6 +710,22 @@ func (s *covenantlessService) GetInfo(ctx context.Context) (*ServiceInfo, error)
return nil, fmt.Errorf("failed to get forfeit address: %s", err)
}
marketHourConfig, err := s.repoManager.MarketHourRepo().Get(ctx)
if err != nil {
return nil, err
}
marketHourNextStart, marketHourNextEnd, err := calcNextMarketHour(
marketHourConfig.StartTime,
marketHourConfig.EndTime,
marketHourConfig.Period,
marketHourDelta,
time.Now(),
)
if err != nil {
return nil, err
}
return &ServiceInfo{
PubKey: pubkey,
RoundLifetime: s.roundLifetime,
@@ -701,9 +734,61 @@ func (s *covenantlessService) GetInfo(ctx context.Context) (*ServiceInfo, error)
Network: s.network.Name,
Dust: dust,
ForfeitAddress: forfeitAddr,
NextMarketHour: &NextMarketHour{
StartTime: marketHourNextStart,
EndTime: marketHourNextEnd,
Period: marketHourConfig.Period,
RoundInterval: marketHourConfig.RoundInterval,
},
}, nil
}
func calcNextMarketHour(marketHourStartTime, marketHourEndTime time.Time, period, marketHourDelta time.Duration, now time.Time) (time.Time, time.Time, error) {
// Validate input parameters
if period <= 0 {
return time.Time{}, time.Time{}, fmt.Errorf("period must be greater than 0")
}
if !marketHourEndTime.After(marketHourStartTime) {
return time.Time{}, time.Time{}, fmt.Errorf("market hour end time must be after start time")
}
// Calculate the duration of the market hour
duration := marketHourEndTime.Sub(marketHourStartTime)
// Calculate the number of periods since the initial marketHourStartTime
elapsed := now.Sub(marketHourStartTime)
var n int64
if elapsed >= 0 {
n = int64(elapsed / period)
} else {
n = int64((elapsed - period + 1) / period)
}
// Calculate the current market hour start and end times
currentStartTime := marketHourStartTime.Add(time.Duration(n) * period)
currentEndTime := currentStartTime.Add(duration)
// Adjust if now is before the currentStartTime
if now.Before(currentStartTime) {
n -= 1
currentStartTime = marketHourStartTime.Add(time.Duration(n) * period)
currentEndTime = currentStartTime.Add(duration)
}
timeUntilEnd := currentEndTime.Sub(now)
if !now.Before(currentStartTime) && now.Before(currentEndTime) && timeUntilEnd >= marketHourDelta {
// Return the current market hour
return currentStartTime, currentEndTime, nil
} else {
// Move to the next market hour
n += 1
nextStartTime := marketHourStartTime.Add(time.Duration(n) * period)
nextEndTime := nextStartTime.Add(duration)
return nextStartTime, nextEndTime, nil
}
}
func (s *covenantlessService) RegisterCosignerPubkey(ctx context.Context, paymentId string, pubkey string) error {
pubkeyBytes, err := hex.DecodeString(pubkey)
if err != nil {
@@ -1478,9 +1563,11 @@ func (s *covenantlessService) getNewVtxos(round *domain.Round) []domain.Vtxo {
continue
}
vtxoPubkey := hex.EncodeToString(schnorr.SerializePubKey(vtxoTapKey))
vtxos = append(vtxos, domain.Vtxo{
VtxoKey: domain.VtxoKey{Txid: node.Txid, VOut: uint32(i)},
Pubkey: hex.EncodeToString(schnorr.SerializePubKey(vtxoTapKey)),
Pubkey: vtxoPubkey,
Amount: uint64(out.Value),
RoundTxid: round.Txid,
CreatedAt: createdAt,
@@ -1739,3 +1826,24 @@ func newMusigSigningSession(nbCosigners int) *musigSigningSession {
nbCosigners: nbCosigners,
}
}
func (s *covenantlessService) GetMarketHourConfig(ctx context.Context) (*domain.MarketHour, error) {
return s.repoManager.MarketHourRepo().Get(ctx)
}
func (s *covenantlessService) UpdateMarketHourConfig(
ctx context.Context,
marketHourStartTime, marketHourEndTime time.Time, period, roundInterval time.Duration,
) error {
marketHour := domain.NewMarketHour(
marketHourStartTime,
marketHourEndTime,
period,
roundInterval,
)
if err := s.repoManager.MarketHourRepo().Upsert(ctx, *marketHour); err != nil {
return fmt.Errorf("failed to upsert market hours: %w", err)
}
return nil
}

View File

@@ -0,0 +1,91 @@
package application
import (
"github.com/stretchr/testify/require"
"testing"
"time"
)
func TestNextMarketHour(t *testing.T) {
marketHourStartTime := parseTime(t, "2023-10-10 13:00:00")
marketHourEndTime := parseTime(t, "2023-10-10 14:00:00")
period := 3 * time.Hour
testCases := []struct {
now time.Time
expectedStart time.Time
expectedEnd time.Time
expectError bool
description string
}{
{
now: parseTime(t, "2023-10-10 13:00:00"),
expectedStart: parseTime(t, "2023-10-10 13:00:00"),
expectedEnd: parseTime(t, "2023-10-10 14:00:00"),
expectError: false,
description: "Now is exactly at the initial market hour start time",
},
{
now: parseTime(t, "2023-10-10 13:55:00"),
expectedStart: parseTime(t, "2023-10-10 13:00:00"),
expectedEnd: parseTime(t, "2023-10-10 14:00:00"),
expectError: false,
description: "Now is during the market period, equals to delta",
},
{
now: parseTime(t, "2023-10-10 13:56:00"),
expectedStart: parseTime(t, "2023-10-10 16:00:00"),
expectedEnd: parseTime(t, "2023-10-10 17:00:00"),
expectError: false,
description: "Now is during the market period, but after delta",
},
{
now: parseTime(t, "2023-10-10 14:06:00"),
expectedStart: parseTime(t, "2023-10-10 16:00:00"),
expectedEnd: parseTime(t, "2023-10-10 17:00:00"),
expectError: false,
description: "Now is after market period",
},
{
now: parseTime(t, "2023-10-10 23:06:00"),
expectedStart: parseTime(t, "2023-10-11 01:00:00"),
expectedEnd: parseTime(t, "2023-10-11 02:00:00"),
expectError: false,
description: "More periods, return next round",
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
startTime, endTime, err := calcNextMarketHour(
marketHourStartTime,
marketHourEndTime,
period,
marketHourDelta,
tc.now,
)
if tc.expectError {
if err == nil {
t.Errorf("Expected an error but got none")
}
} else {
if err != nil {
t.Errorf("Did not expect an error but got: %v", err)
}
if !startTime.Equal(tc.expectedStart) {
t.Errorf("Expected start time %v, got %v", tc.expectedStart.UTC(), startTime.UTC())
}
if !endTime.Equal(tc.expectedEnd) {
t.Errorf("Expected end time %v, got %v", tc.expectedEnd.UTC(), endTime.UTC())
}
}
})
}
}
func parseTime(t *testing.T, value string) time.Time {
layout := "2006-01-02 15:04:05"
tm, err := time.ParseInLocation(layout, value, time.UTC)
require.NoError(t, err)
return tm
}

View File

@@ -2,6 +2,7 @@ package application
import (
"context"
"time"
"github.com/ark-network/ark/common/note"
"github.com/ark-network/ark/server/internal/core/domain"
@@ -59,6 +60,8 @@ type Service interface {
GetTransactionEventsChannel(ctx context.Context) <-chan TransactionEvent
SetNostrRecipient(ctx context.Context, nostrRecipient string, signedVtxoOutpoints []SignedVtxoOutpoint) error
DeleteNostrRecipient(ctx context.Context, signedVtxoOutpoints []SignedVtxoOutpoint) error
GetMarketHourConfig(ctx context.Context) (*domain.MarketHour, error)
UpdateMarketHourConfig(ctx context.Context, marketHourStartTime, marketHourEndTime time.Time, period, roundInterval time.Duration) error
}
type ServiceInfo struct {
@@ -69,6 +72,14 @@ type ServiceInfo struct {
Network string
Dust uint64
ForfeitAddress string
NextMarketHour *NextMarketHour
}
type NextMarketHour struct {
StartTime time.Time
EndTime time.Time
Period time.Duration
RoundInterval time.Duration
}
type WalletStatus struct {

View File

@@ -0,0 +1,20 @@
package domain
import "time"
type MarketHour struct {
StartTime time.Time
EndTime time.Time
Period time.Duration
RoundInterval time.Duration
UpdatedAt time.Time
}
func NewMarketHour(startTime, endTime time.Time, period, roundInterval time.Duration) *MarketHour {
return &MarketHour{
StartTime: startTime,
EndTime: endTime,
Period: period,
RoundInterval: roundInterval,
}
}

View File

@@ -33,3 +33,9 @@ type VtxoRepository interface {
UpdateExpireAt(ctx context.Context, vtxos []VtxoKey, expireAt int64) error
Close()
}
type MarketHourRepo interface {
Get(ctx context.Context) (*MarketHour, error)
Upsert(ctx context.Context, marketHour MarketHour) error
Close()
}

View File

@@ -8,6 +8,7 @@ type RepoManager interface {
Vtxos() domain.VtxoRepository
Notes() domain.NoteRepository
Entities() domain.EntityRepository
MarketHourRepo() domain.MarketHourRepo
RegisterEventsHandler(func(*domain.Round))
Close()
}

View File

@@ -0,0 +1,73 @@
package badgerdb
import (
"context"
"errors"
"fmt"
"path/filepath"
"github.com/ark-network/ark/server/internal/core/domain"
"github.com/dgraph-io/badger/v4"
"github.com/timshannon/badgerhold/v4"
)
const (
marketHourStoreDir = "market_hour"
marketHourKey = "market_hour"
)
type marketHourRepository struct {
store *badgerhold.Store
}
func NewMarketHourRepository(config ...interface{}) (domain.MarketHourRepo, error) {
if len(config) != 2 {
return nil, fmt.Errorf("invalid config")
}
baseDir, ok := config[0].(string)
if !ok {
return nil, fmt.Errorf("invalid base directory")
}
var logger badger.Logger
if config[1] != nil {
logger, ok = config[1].(badger.Logger)
if !ok {
return nil, fmt.Errorf("invalid logger")
}
}
var dir string
if len(baseDir) > 0 {
dir = filepath.Join(baseDir, marketHourStoreDir)
}
store, err := createDB(dir, logger)
if err != nil {
return nil, fmt.Errorf("failed to open market hour store: %s", err)
}
return &marketHourRepository{store}, nil
}
func (r *marketHourRepository) Get(ctx context.Context) (*domain.MarketHour, error) {
var marketHour domain.MarketHour
err := r.store.Get("market_hour", &marketHour)
if errors.Is(err, badgerhold.ErrNotFound) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("failed to get market hour: %w", err)
}
return &marketHour, nil
}
func (r *marketHourRepository) Upsert(ctx context.Context, marketHour domain.MarketHour) error {
err := r.store.Upsert("market_hour", &marketHour)
if err != nil {
return fmt.Errorf("failed to upsert market hour: %w", err)
}
return nil
}
func (r *marketHourRepository) Close() {
r.store.Close()
}

View File

@@ -34,6 +34,10 @@ var (
"badger": badgerdb.NewEntityRepository,
"sqlite": sqlitedb.NewEntityRepository,
}
marketHourStoreTypes = map[string]func(...interface{}) (domain.MarketHourRepo, error){
"badger": badgerdb.NewMarketHourRepository,
"sqlite": sqlitedb.NewMarketHourRepository,
}
)
const (
@@ -54,6 +58,7 @@ type service struct {
vtxoStore domain.VtxoRepository
noteStore domain.NoteRepository
entityStore domain.EntityRepository
marketHourRepo domain.MarketHourRepo
}
func NewService(config ServiceConfig) (ports.RepoManager, error) {
@@ -77,12 +82,17 @@ func NewService(config ServiceConfig) (ports.RepoManager, error) {
if !ok {
return nil, fmt.Errorf("entity store type not supported")
}
marketHourStoreFactory, ok := marketHourStoreTypes[config.DataStoreType]
if !ok {
return nil, fmt.Errorf("invalid data store type: %s", config.DataStoreType)
}
var eventStore domain.RoundEventRepository
var roundStore domain.RoundRepository
var vtxoStore domain.VtxoRepository
var noteStore domain.NoteRepository
var entityStore domain.EntityRepository
var marketHourRepo domain.MarketHourRepo
var err error
switch config.EventStoreType {
@@ -113,6 +123,10 @@ func NewService(config ServiceConfig) (ports.RepoManager, error) {
if err != nil {
return nil, fmt.Errorf("failed to open note store: %s", err)
}
marketHourRepo, err = marketHourStoreFactory(config.DataStoreConfig...)
if err != nil {
return nil, fmt.Errorf("failed to create market hour store: %w", err)
}
case "sqlite":
if len(config.DataStoreConfig) != 2 {
return nil, fmt.Errorf("invalid data store config")
@@ -168,9 +182,21 @@ func NewService(config ServiceConfig) (ports.RepoManager, error) {
if err != nil {
return nil, fmt.Errorf("failed to open note store: %s", err)
}
marketHourRepo, err = marketHourStoreFactory(db)
if err != nil {
return nil, fmt.Errorf("failed to create market hour store: %w", err)
}
}
return &service{eventStore, roundStore, vtxoStore, noteStore, entityStore}, nil
return &service{
eventStore: eventStore,
roundStore: roundStore,
vtxoStore: vtxoStore,
noteStore: noteStore,
entityStore: entityStore,
marketHourRepo: marketHourRepo,
}, nil
}
func (s *service) RegisterEventsHandler(handler func(round *domain.Round)) {
@@ -197,9 +223,14 @@ func (s *service) Entities() domain.EntityRepository {
return s.entityStore
}
func (s *service) MarketHourRepo() domain.MarketHourRepo {
return s.marketHourRepo
}
func (s *service) Close() {
s.eventStore.Close()
s.roundStore.Close()
s.vtxoStore.Close()
s.noteStore.Close()
s.marketHourRepo.Close()
}

View File

@@ -105,15 +105,14 @@ func TestService(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
svc, err := db.NewService(tt.config)
require.NoError(t, err)
require.NotNil(t, svc)
defer svc.Close()
testRoundEventRepository(t, svc)
testRoundRepository(t, svc)
testVtxoRepository(t, svc)
testNoteRepository(t, svc)
testEntityRepository(t, svc)
time.Sleep(5 * time.Second)
svc.Close()
testMarketHourRepository(t, svc)
})
}
}
@@ -505,6 +504,54 @@ func testEntityRepository(t *testing.T, svc ports.RepoManager) {
})
}
func testMarketHourRepository(t *testing.T, svc ports.RepoManager) {
t.Run("test_market_hour_repository", func(t *testing.T) {
ctx := context.Background()
repo := svc.MarketHourRepo()
defer repo.Close()
marketHour, err := repo.Get(ctx)
require.NoError(t, err)
require.Nil(t, marketHour)
now := time.Now().Truncate(time.Second)
expected := domain.MarketHour{
StartTime: now,
Period: time.Duration(3) * time.Hour,
RoundInterval: time.Duration(20) * time.Second,
UpdatedAt: now,
}
err = repo.Upsert(ctx, expected)
require.NoError(t, err)
got, err := repo.Get(ctx)
require.NoError(t, err)
require.NotNil(t, got)
assertMarketHourEqual(t, expected, *got)
expected.Period = time.Duration(4) * time.Hour
expected.RoundInterval = time.Duration(40) * time.Second
expected.UpdatedAt = now.Add(100 * time.Second)
err = repo.Upsert(ctx, expected)
require.NoError(t, err)
got, err = repo.Get(ctx)
require.NoError(t, err)
require.NotNil(t, got)
assertMarketHourEqual(t, expected, *got)
})
}
func assertMarketHourEqual(t *testing.T, expected, actual domain.MarketHour) {
assert.True(t, expected.StartTime.Equal(actual.StartTime), "StartTime not equal")
assert.Equal(t, expected.Period, actual.Period, "Period not equal")
assert.Equal(t, expected.RoundInterval, actual.RoundInterval, "RoundInterval not equal")
assert.True(t, expected.UpdatedAt.Equal(actual.UpdatedAt), "UpdatedAt not equal")
assert.True(t, expected.EndTime.Equal(actual.EndTime), "EndTime not equal")
}
func roundsMatch(expected, got domain.Round) assert.Comparison {
return func() bool {
if expected.Id != got.Id {

View File

@@ -0,0 +1,84 @@
package sqlitedb
import (
"context"
"database/sql"
"errors"
"fmt"
"github.com/ark-network/ark/server/internal/core/domain"
"github.com/ark-network/ark/server/internal/infrastructure/db/sqlite/sqlc/queries"
"time"
)
type marketHourRepository struct {
db *sql.DB
querier *queries.Queries
}
func NewMarketHourRepository(config ...interface{}) (domain.MarketHourRepo, error) {
if len(config) != 1 {
return nil, fmt.Errorf("invalid config")
}
db, ok := config[0].(*sql.DB)
if !ok {
return nil, fmt.Errorf("cannot open market hour repository: invalid config, expected db at 0")
}
return &marketHourRepository{
db: db,
querier: queries.New(db),
}, nil
}
func (r *marketHourRepository) Get(ctx context.Context) (*domain.MarketHour, error) {
marketHour, err := r.querier.GetLatestMarketHour(ctx)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("failed to get market hour: %w", err)
}
return &domain.MarketHour{
StartTime: time.Unix(marketHour.StartTime, 0),
EndTime: time.Unix(marketHour.EndTime, 0),
Period: time.Duration(marketHour.Period),
RoundInterval: time.Duration(marketHour.RoundInterval),
UpdatedAt: time.Unix(marketHour.UpdatedAt, 0),
}, nil
}
func (r *marketHourRepository) Upsert(ctx context.Context, marketHour domain.MarketHour) error {
latest, err := r.querier.GetLatestMarketHour(ctx)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return fmt.Errorf("failed to get latest market hour: %w", err)
}
if errors.Is(err, sql.ErrNoRows) {
_, err = r.querier.InsertMarketHour(ctx, queries.InsertMarketHourParams{
StartTime: marketHour.StartTime.Unix(),
EndTime: marketHour.EndTime.Unix(),
Period: int64(marketHour.Period),
RoundInterval: int64(marketHour.RoundInterval),
UpdatedAt: marketHour.UpdatedAt.Unix(),
})
} else {
_, err = r.querier.UpdateMarketHour(ctx, queries.UpdateMarketHourParams{
StartTime: marketHour.StartTime.Unix(),
EndTime: marketHour.EndTime.Unix(),
Period: int64(marketHour.Period),
RoundInterval: int64(marketHour.RoundInterval),
UpdatedAt: marketHour.UpdatedAt.Unix(),
ID: latest.ID,
})
}
if err != nil {
return fmt.Errorf("failed to upsert market hour: %w", err)
}
return nil
}
func (r *marketHourRepository) Close() {
_ = r.db.Close()
}

View File

@@ -0,0 +1 @@
DROP TABLE IF EXISTS market_hours;

View File

@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS market_hour (
id INTEGER PRIMARY KEY AUTOINCREMENT,
start_time INTEGER NOT NULL,
end_time INTEGER NOT NULL,
period INTEGER NOT NULL,
round_interval INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);

View File

@@ -26,6 +26,15 @@ type EntityVw struct {
VtxoVout sql.NullInt64
}
type MarketHour struct {
ID int64
StartTime int64
EndTime int64
Period int64
RoundInterval int64
UpdatedAt int64
}
type Note struct {
ID int64
}

View File

@@ -39,6 +39,63 @@ func (q *Queries) DeleteEntityVtxo(ctx context.Context, entityID int64) error {
return err
}
const getLatestMarketHour = `-- name: GetLatestMarketHour :one
SELECT id, start_time, end_time, period, round_interval, updated_at FROM market_hour ORDER BY updated_at DESC LIMIT 1
`
func (q *Queries) GetLatestMarketHour(ctx context.Context) (MarketHour, error) {
row := q.db.QueryRowContext(ctx, getLatestMarketHour)
var i MarketHour
err := row.Scan(
&i.ID,
&i.StartTime,
&i.EndTime,
&i.Period,
&i.RoundInterval,
&i.UpdatedAt,
)
return i, err
}
const insertMarketHour = `-- name: InsertMarketHour :one
INSERT INTO market_hour (
start_time,
end_time,
period,
round_interval,
updated_at
) VALUES (?, ?, ?, ?, ?)
RETURNING id, start_time, end_time, period, round_interval, updated_at
`
type InsertMarketHourParams struct {
StartTime int64
EndTime int64
Period int64
RoundInterval int64
UpdatedAt int64
}
func (q *Queries) InsertMarketHour(ctx context.Context, arg InsertMarketHourParams) (MarketHour, error) {
row := q.db.QueryRowContext(ctx, insertMarketHour,
arg.StartTime,
arg.EndTime,
arg.Period,
arg.RoundInterval,
arg.UpdatedAt,
)
var i MarketHour
err := row.Scan(
&i.ID,
&i.StartTime,
&i.EndTime,
&i.Period,
&i.RoundInterval,
&i.UpdatedAt,
)
return i, err
}
const insertNote = `-- name: InsertNote :exec
INSERT INTO note (id) VALUES (?)
`
@@ -755,6 +812,47 @@ func (q *Queries) SelectVtxosByPoolTxid(ctx context.Context, poolTx string) ([]S
return items, nil
}
const updateMarketHour = `-- name: UpdateMarketHour :one
UPDATE market_hour
SET start_time = ?,
end_time = ?,
period = ?,
round_interval = ?,
updated_at = ?
WHERE id = ?
RETURNING id, start_time, end_time, period, round_interval, updated_at
`
type UpdateMarketHourParams struct {
StartTime int64
EndTime int64
Period int64
RoundInterval int64
UpdatedAt int64
ID int64
}
func (q *Queries) UpdateMarketHour(ctx context.Context, arg UpdateMarketHourParams) (MarketHour, error) {
row := q.db.QueryRowContext(ctx, updateMarketHour,
arg.StartTime,
arg.EndTime,
arg.Period,
arg.RoundInterval,
arg.UpdatedAt,
arg.ID,
)
var i MarketHour
err := row.Scan(
&i.ID,
&i.StartTime,
&i.EndTime,
&i.Period,
&i.RoundInterval,
&i.UpdatedAt,
)
return i, err
}
const updateVtxoExpireAt = `-- name: UpdateVtxoExpireAt :exec
UPDATE vtxo SET expire_at = ? WHERE txid = ? AND vout = ?
`

View File

@@ -185,3 +185,26 @@ INSERT INTO note (id) VALUES (?);
-- name: ContainsNote :one
SELECT EXISTS(SELECT 1 FROM note WHERE id = ?);
-- name: InsertMarketHour :one
INSERT INTO market_hour (
start_time,
end_time,
period,
round_interval,
updated_at
) VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: UpdateMarketHour :one
UPDATE market_hour
SET start_time = ?,
end_time = ?,
period = ?,
round_interval = ?,
updated_at = ?
WHERE id = ?
RETURNING *;
-- name: GetLatestMarketHour :one
SELECT * FROM market_hour ORDER BY updated_at DESC LIMIT 1;

View File

@@ -3,6 +3,8 @@ package handlers
import (
"context"
"fmt"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
arkv1 "github.com/ark-network/ark/api-spec/protobuf/gen/ark/v1"
"github.com/ark-network/ark/server/internal/core/application"
@@ -128,6 +130,42 @@ func (a *adminHandler) CreateNote(ctx context.Context, req *arkv1.CreateNoteRequ
return &arkv1.CreateNoteResponse{Notes: notes}, nil
}
func (a *adminHandler) GetMarketHourConfig(
ctx context.Context,
request *arkv1.GetMarketHourConfigRequest,
) (*arkv1.GetMarketHourConfigResponse, error) {
config, err := a.aspService.GetMarketHourConfig(ctx)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &arkv1.GetMarketHourConfigResponse{
Config: &arkv1.MarketHourConfig{
StartTime: timestamppb.New(config.StartTime),
EndTime: timestamppb.New(config.EndTime),
Period: durationpb.New(config.Period),
RoundInterval: durationpb.New(config.RoundInterval),
},
}, nil
}
func (a *adminHandler) UpdateMarketHourConfig(
ctx context.Context,
req *arkv1.UpdateMarketHourConfigRequest,
) (*arkv1.UpdateMarketHourConfigResponse, error) {
if err := a.aspService.UpdateMarketHourConfig(
ctx,
req.GetConfig().GetStartTime().AsTime(),
req.GetConfig().GetEndTime().AsTime(),
req.GetConfig().GetPeriod().AsDuration(),
req.GetConfig().GetRoundInterval().AsDuration(),
); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &arkv1.UpdateMarketHourConfigResponse{}, nil
}
// convert sats to string BTC
func convertSatoshis(sats uint64) string {
btc := float64(sats) * 1e-8

View File

@@ -3,6 +3,8 @@ package handlers
import (
"context"
"encoding/hex"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
"fmt"
"sync"
@@ -43,7 +45,7 @@ func (h *handler) GetInfo(
) (*arkv1.GetInfoResponse, error) {
info, err := h.svc.GetInfo(ctx)
if err != nil {
return nil, err
return nil, status.Error(codes.Internal, err.Error())
}
desc := fmt.Sprintf(
@@ -65,6 +67,12 @@ func (h *handler) GetInfo(
ForfeitAddress: info.ForfeitAddress,
BoardingDescriptorTemplate: desc,
VtxoDescriptorTemplates: []string{desc},
MarketHour: &arkv1.MarketHour{
NextStartTime: timestamppb.New(info.NextMarketHour.StartTime),
NextEndTime: timestamppb.New(info.NextMarketHour.EndTime),
Period: durationpb.New(info.NextMarketHour.Period),
RoundInterval: durationpb.New(info.NextMarketHour.RoundInterval),
},
}, nil
}

View File

@@ -212,5 +212,13 @@ func AllPermissionsByMethod() map[string][]bakery.Op {
Entity: EntityManager,
Action: "write",
}},
fmt.Sprintf("/%s/GetMarketHourConfig", arkv1.AdminService_ServiceDesc.ServiceName): {{
Entity: EntityManager,
Action: "read",
}},
fmt.Sprintf("/%s/UpdateMarketHourConfig", arkv1.AdminService_ServiceDesc.ServiceName): {{
Entity: EntityManager,
Action: "write",
}},
}
}