diff --git a/Makefile b/Makefile index 904f6541..631eb642 100644 --- a/Makefile +++ b/Makefile @@ -16,16 +16,12 @@ DOCKER_COMPOSE_BRIDGE := xlayer-bridge-service DOCKER_COMPOSE_BRIDGE_V1TOV2 := xlayer-bridge-service-v1tov2 DOCKER_COMPOSE_REDIS := xlayer-bridge-redis -DOCKER_COMPOSE_COIN_KAFKA_NODE := xlayer-bridge-coin-kafka -DOCKER_COMPOSE_ZOOKEEPER := kafka-zookeeper RUN_STATE_DB := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_STATE_DB) RUN_POOL_DB := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_POOL_DB) RUN_BRIDGE_DB := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_BRIDGE_DB) RUN_REDIS := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_REDIS) -RUN_COIN_KAFKA := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_COIN_KAFKA_NODE) -RUN_ZOOKEEPER := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_ZOOKEEPER) -RUN_DBS := ${RUN_BRIDGE_DB} && ${RUN_STATE_DB} && ${RUN_POOL_DB} && ${RUN_REDIS} && ${RUN_COIN_KAFKA} && ${RUN_ZOOKEEPER} +RUN_DBS := ${RUN_BRIDGE_DB} && ${RUN_STATE_DB} && ${RUN_POOL_DB} && ${RUN_REDIS} RUN_NODE := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_ZKEVM_NODE) RUN_NODE_V1TOV2 := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_ZKEVM_NODE_V1TOV2) RUN_AGGREGATOR_V1TOV2 := $(DOCKER_COMPOSE) up -d $(DOCKER_COMPOSE_ZKEVM_AGGREGATOR_V1TOV2) diff --git a/bridgectrl/hash.go b/bridgectrl/hash.go index a59ddfc2..ab131ba0 100644 --- a/bridgectrl/hash.go +++ b/bridgectrl/hash.go @@ -4,6 +4,8 @@ import ( "encoding/binary" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" + "github.com/0xPolygonHermez/zkevm-bridge-service/utils" + "github.com/ethereum/go-ethereum/common" "github.com/iden3/go-iden3-crypto/keccak256" "golang.org/x/crypto/sha3" ) @@ -42,6 +44,11 @@ func hashDeposit(deposit *etherman.Deposit) [KeyLen]byte { binary.BigEndian.PutUint32(destNet, uint32(deposit.DestinationNetwork)) var buf [KeyLen]byte metaHash := keccak256.Hash(deposit.Metadata) - copy(res[:], keccak256.Hash([]byte{deposit.LeafType}, origNet, deposit.OriginalAddress[:], destNet, deposit.DestinationAddress[:], deposit.Amount.FillBytes(buf[:]), metaHash)) + destAddr := deposit.DestinationAddress + emptyAddr := common.Address{} + if deposit.LeafType == uint8(utils.LeafTypeMessage) && deposit.DestContractAddress != emptyAddr { + destAddr = deposit.DestContractAddress + } + copy(res[:], keccak256.Hash([]byte{deposit.LeafType}, origNet, deposit.OriginalAddress[:], destNet, destAddr[:], deposit.Amount.FillBytes(buf[:]), metaHash)) return res } diff --git a/bridgectrl/pb/query.pb.go b/bridgectrl/pb/query.pb.go index 7076df64..c6d1a854 100644 --- a/bridgectrl/pb/query.pb.go +++ b/bridgectrl/pb/query.pb.go @@ -3,8 +3,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.21.5 +// protoc-gen-go v1.28.1 +// protoc v4.24.3 // source: query.proto package pb @@ -79,6 +79,59 @@ func (TransactionStatus) EnumDescriptor() ([]byte, []int) { return file_query_proto_rawDescGZIP(), []int{0} } +type ErrorCode int32 + +const ( + ErrorCode_ERROR_OK ErrorCode = 0 + // Start from 1000 so that it will not conflict with gRPC error code range + ErrorCode_ERROR_DEFAULT ErrorCode = 1000 + ErrorCode_ERROR_BUSINESS ErrorCode = 1001 // General business error + ErrorCode_ERROR_IP_RESTRICTED ErrorCode = 1009 +) + +// Enum value maps for ErrorCode. +var ( + ErrorCode_name = map[int32]string{ + 0: "ERROR_OK", + 1000: "ERROR_DEFAULT", + 1001: "ERROR_BUSINESS", + 1009: "ERROR_IP_RESTRICTED", + } + ErrorCode_value = map[string]int32{ + "ERROR_OK": 0, + "ERROR_DEFAULT": 1000, + "ERROR_BUSINESS": 1001, + "ERROR_IP_RESTRICTED": 1009, + } +) + +func (x ErrorCode) Enum() *ErrorCode { + p := new(ErrorCode) + *p = x + return p +} + +func (x ErrorCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ErrorCode) Descriptor() protoreflect.EnumDescriptor { + return file_query_proto_enumTypes[1].Descriptor() +} + +func (ErrorCode) Type() protoreflect.EnumType { + return &file_query_proto_enumTypes[1] +} + +func (x ErrorCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ErrorCode.Descriptor instead. +func (ErrorCode) EnumDescriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{1} +} + // TokenWrapped message type TokenWrapped struct { state protoimpl.MessageState @@ -1383,25 +1436,28 @@ type Transaction struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - FromChain uint32 `protobuf:"varint,1,opt,name=fromChain,proto3" json:"fromChain,omitempty"` // 0:L1, 1:L2 - ToChain uint32 `protobuf:"varint,2,opt,name=toChain,proto3" json:"toChain,omitempty"` // 0:L1, 1:L2 - BridgeToken string `protobuf:"bytes,3,opt,name=bridgeToken,proto3" json:"bridgeToken,omitempty"` - TokenAmount string `protobuf:"bytes,4,opt,name=tokenAmount,proto3" json:"tokenAmount,omitempty"` - EstimateTime uint32 `protobuf:"varint,5,opt,name=estimateTime,proto3" json:"estimateTime,omitempty"` - Status uint32 `protobuf:"varint,6,opt,name=status,proto3" json:"status,omitempty"` // Enum: TransactionStatus - Time uint64 `protobuf:"varint,7,opt,name=time,proto3" json:"time,omitempty"` // Deposit's block time - TxHash string `protobuf:"bytes,8,opt,name=txHash,proto3" json:"txHash,omitempty"` // Deposit tx hash - ClaimTxHash string `protobuf:"bytes,9,opt,name=claimTxHash,proto3" json:"claimTxHash,omitempty"` - ClaimTime uint64 `protobuf:"varint,10,opt,name=claimTime,proto3" json:"claimTime,omitempty"` // Claim's block time - FromChainId uint32 `protobuf:"varint,11,opt,name=fromChainId,proto3" json:"fromChainId,omitempty"` - ToChainId uint32 `protobuf:"varint,12,opt,name=toChainId,proto3" json:"toChainId,omitempty"` - Id uint64 `protobuf:"varint,13,opt,name=id,proto3" json:"id,omitempty"` - Index uint64 `protobuf:"varint,14,opt,name=index,proto3" json:"index,omitempty"` - Metadata string `protobuf:"bytes,15,opt,name=metadata,proto3" json:"metadata,omitempty"` - DestAddr string `protobuf:"bytes,16,opt,name=destAddr,proto3" json:"destAddr,omitempty"` - LeafType uint32 `protobuf:"varint,17,opt,name=leafType,proto3" json:"leafType,omitempty"` - BlockNumber uint64 `protobuf:"varint,18,opt,name=blockNumber,proto3" json:"blockNumber,omitempty"` - GlobalIndex string `protobuf:"bytes,19,opt,name=globalIndex,proto3" json:"globalIndex,omitempty"` + FromChain uint32 `protobuf:"varint,1,opt,name=fromChain,proto3" json:"fromChain,omitempty"` // 0:L1, 1:L2 + ToChain uint32 `protobuf:"varint,2,opt,name=toChain,proto3" json:"toChain,omitempty"` // 0:L1, 1:L2 + BridgeToken string `protobuf:"bytes,3,opt,name=bridgeToken,proto3" json:"bridgeToken,omitempty"` + TokenAmount string `protobuf:"bytes,4,opt,name=tokenAmount,proto3" json:"tokenAmount,omitempty"` + EstimateTime uint32 `protobuf:"varint,5,opt,name=estimateTime,proto3" json:"estimateTime,omitempty"` + Status uint32 `protobuf:"varint,6,opt,name=status,proto3" json:"status,omitempty"` // Enum: TransactionStatus + Time uint64 `protobuf:"varint,7,opt,name=time,proto3" json:"time,omitempty"` // Deposit's block time + TxHash string `protobuf:"bytes,8,opt,name=txHash,proto3" json:"txHash,omitempty"` // Deposit tx hash + ClaimTxHash string `protobuf:"bytes,9,opt,name=claimTxHash,proto3" json:"claimTxHash,omitempty"` + ClaimTime uint64 `protobuf:"varint,10,opt,name=claimTime,proto3" json:"claimTime,omitempty"` // Claim's block time + FromChainId uint32 `protobuf:"varint,11,opt,name=fromChainId,proto3" json:"fromChainId,omitempty"` + ToChainId uint32 `protobuf:"varint,12,opt,name=toChainId,proto3" json:"toChainId,omitempty"` + Id uint64 `protobuf:"varint,13,opt,name=id,proto3" json:"id,omitempty"` + Index uint64 `protobuf:"varint,14,opt,name=index,proto3" json:"index,omitempty"` + Metadata string `protobuf:"bytes,15,opt,name=metadata,proto3" json:"metadata,omitempty"` + DestAddr string `protobuf:"bytes,16,opt,name=destAddr,proto3" json:"destAddr,omitempty"` + LeafType uint32 `protobuf:"varint,17,opt,name=leafType,proto3" json:"leafType,omitempty"` + BlockNumber uint64 `protobuf:"varint,18,opt,name=blockNumber,proto3" json:"blockNumber,omitempty"` + GlobalIndex string `protobuf:"bytes,19,opt,name=globalIndex,proto3" json:"globalIndex,omitempty"` + DestContractAddr string `protobuf:"bytes,20,opt,name=destContractAddr,proto3" json:"destContractAddr,omitempty"` + LogoInfo *TokenLogoInfo `protobuf:"bytes,21,opt,name=logoInfo,proto3" json:"logoInfo,omitempty"` + OriginalNetwork uint32 `protobuf:"varint,22,opt,name=originalNetwork,proto3" json:"originalNetwork,omitempty"` } func (x *Transaction) Reset() { @@ -1569,6 +1625,98 @@ func (x *Transaction) GetGlobalIndex() string { return "" } +func (x *Transaction) GetDestContractAddr() string { + if x != nil { + return x.DestContractAddr + } + return "" +} + +func (x *Transaction) GetLogoInfo() *TokenLogoInfo { + if x != nil { + return x.LogoInfo + } + return nil +} + +func (x *Transaction) GetOriginalNetwork() uint32 { + if x != nil { + return x.OriginalNetwork + } + return 0 +} + +type TokenLogoInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"` + TokenName string `protobuf:"bytes,2,opt,name=tokenName,proto3" json:"tokenName,omitempty"` + LogoOssUrl string `protobuf:"bytes,3,opt,name=logoOssUrl,proto3" json:"logoOssUrl,omitempty"` + Decimal uint32 `protobuf:"varint,4,opt,name=decimal,proto3" json:"decimal,omitempty"` +} + +func (x *TokenLogoInfo) Reset() { + *x = TokenLogoInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TokenLogoInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TokenLogoInfo) ProtoMessage() {} + +func (x *TokenLogoInfo) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[20] + 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 TokenLogoInfo.ProtoReflect.Descriptor instead. +func (*TokenLogoInfo) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{20} +} + +func (x *TokenLogoInfo) GetSymbol() string { + if x != nil { + return x.Symbol + } + return "" +} + +func (x *TokenLogoInfo) GetTokenName() string { + if x != nil { + return x.TokenName + } + return "" +} + +func (x *TokenLogoInfo) GetLogoOssUrl() string { + if x != nil { + return x.LogoOssUrl + } + return "" +} + +func (x *TokenLogoInfo) GetDecimal() uint32 { + if x != nil { + return x.Decimal + } + return 0 +} + // Monitored tx type MonitoredTx struct { state protoimpl.MessageState @@ -1593,7 +1741,7 @@ type MonitoredTx struct { func (x *MonitoredTx) Reset() { *x = MonitoredTx{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[20] + mi := &file_query_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1606,7 +1754,7 @@ func (x *MonitoredTx) String() string { func (*MonitoredTx) ProtoMessage() {} func (x *MonitoredTx) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[20] + mi := &file_query_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1619,7 +1767,7 @@ func (x *MonitoredTx) ProtoReflect() protoreflect.Message { // Deprecated: Use MonitoredTx.ProtoReflect.Descriptor instead. func (*MonitoredTx) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{20} + return file_query_proto_rawDescGZIP(), []int{21} } func (x *MonitoredTx) GetId() uint64 { @@ -1724,7 +1872,7 @@ type GetCoinPriceRequest struct { func (x *GetCoinPriceRequest) Reset() { *x = GetCoinPriceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[21] + mi := &file_query_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1737,7 +1885,7 @@ func (x *GetCoinPriceRequest) String() string { func (*GetCoinPriceRequest) ProtoMessage() {} func (x *GetCoinPriceRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[21] + mi := &file_query_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1750,7 +1898,7 @@ func (x *GetCoinPriceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCoinPriceRequest.ProtoReflect.Descriptor instead. func (*GetCoinPriceRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{21} + return file_query_proto_rawDescGZIP(), []int{22} } func (x *GetCoinPriceRequest) GetSymbolInfos() []*SymbolInfo { @@ -1776,7 +1924,7 @@ type CommonCoinPricesResponse struct { func (x *CommonCoinPricesResponse) Reset() { *x = CommonCoinPricesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[22] + mi := &file_query_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1789,7 +1937,7 @@ func (x *CommonCoinPricesResponse) String() string { func (*CommonCoinPricesResponse) ProtoMessage() {} func (x *CommonCoinPricesResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[22] + mi := &file_query_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1802,7 +1950,7 @@ func (x *CommonCoinPricesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonCoinPricesResponse.ProtoReflect.Descriptor instead. func (*CommonCoinPricesResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{22} + return file_query_proto_rawDescGZIP(), []int{23} } func (x *CommonCoinPricesResponse) GetCode() uint32 { @@ -1858,7 +2006,7 @@ type GetMainCoinsRequest struct { func (x *GetMainCoinsRequest) Reset() { *x = GetMainCoinsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[23] + mi := &file_query_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1871,7 +2019,7 @@ func (x *GetMainCoinsRequest) String() string { func (*GetMainCoinsRequest) ProtoMessage() {} func (x *GetMainCoinsRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[23] + mi := &file_query_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1884,7 +2032,7 @@ func (x *GetMainCoinsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMainCoinsRequest.ProtoReflect.Descriptor instead. func (*GetMainCoinsRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{23} + return file_query_proto_rawDescGZIP(), []int{24} } func (x *GetMainCoinsRequest) GetNetworkId() uint32 { @@ -1910,7 +2058,7 @@ type CommonCoinsResponse struct { func (x *CommonCoinsResponse) Reset() { *x = CommonCoinsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[24] + mi := &file_query_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1923,7 +2071,7 @@ func (x *CommonCoinsResponse) String() string { func (*CommonCoinsResponse) ProtoMessage() {} func (x *CommonCoinsResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[24] + mi := &file_query_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1936,7 +2084,7 @@ func (x *CommonCoinsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonCoinsResponse.ProtoReflect.Descriptor instead. func (*CommonCoinsResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{24} + return file_query_proto_rawDescGZIP(), []int{25} } func (x *CommonCoinsResponse) GetCode() uint32 { @@ -1994,7 +2142,7 @@ type GetPendingTransactionsRequest struct { func (x *GetPendingTransactionsRequest) Reset() { *x = GetPendingTransactionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[25] + mi := &file_query_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2007,7 +2155,7 @@ func (x *GetPendingTransactionsRequest) String() string { func (*GetPendingTransactionsRequest) ProtoMessage() {} func (x *GetPendingTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[25] + mi := &file_query_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2020,7 +2168,7 @@ func (x *GetPendingTransactionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPendingTransactionsRequest.ProtoReflect.Descriptor instead. func (*GetPendingTransactionsRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{25} + return file_query_proto_rawDescGZIP(), []int{26} } func (x *GetPendingTransactionsRequest) GetDestAddr() string { @@ -2060,7 +2208,7 @@ type CommonTransactionsResponse struct { func (x *CommonTransactionsResponse) Reset() { *x = CommonTransactionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[26] + mi := &file_query_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2073,7 +2221,7 @@ func (x *CommonTransactionsResponse) String() string { func (*CommonTransactionsResponse) ProtoMessage() {} func (x *CommonTransactionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[26] + mi := &file_query_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2086,7 +2234,7 @@ func (x *CommonTransactionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonTransactionsResponse.ProtoReflect.Descriptor instead. func (*CommonTransactionsResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{26} + return file_query_proto_rawDescGZIP(), []int{27} } func (x *CommonTransactionsResponse) GetCode() uint32 { @@ -2143,7 +2291,7 @@ type TransactionDetail struct { func (x *TransactionDetail) Reset() { *x = TransactionDetail{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[27] + mi := &file_query_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2156,7 +2304,7 @@ func (x *TransactionDetail) String() string { func (*TransactionDetail) ProtoMessage() {} func (x *TransactionDetail) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[27] + mi := &file_query_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2169,7 +2317,7 @@ func (x *TransactionDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use TransactionDetail.ProtoReflect.Descriptor instead. func (*TransactionDetail) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{27} + return file_query_proto_rawDescGZIP(), []int{28} } func (x *TransactionDetail) GetHasNext() bool { @@ -2199,7 +2347,7 @@ type GetAllTransactionsRequest struct { func (x *GetAllTransactionsRequest) Reset() { *x = GetAllTransactionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[28] + mi := &file_query_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2212,7 +2360,7 @@ func (x *GetAllTransactionsRequest) String() string { func (*GetAllTransactionsRequest) ProtoMessage() {} func (x *GetAllTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[28] + mi := &file_query_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2225,7 +2373,7 @@ func (x *GetAllTransactionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAllTransactionsRequest.ProtoReflect.Descriptor instead. func (*GetAllTransactionsRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{28} + return file_query_proto_rawDescGZIP(), []int{29} } func (x *GetAllTransactionsRequest) GetDestAddr() string { @@ -2261,7 +2409,7 @@ type GetSmtProofRequest struct { func (x *GetSmtProofRequest) Reset() { *x = GetSmtProofRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[29] + mi := &file_query_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2274,7 +2422,7 @@ func (x *GetSmtProofRequest) String() string { func (*GetSmtProofRequest) ProtoMessage() {} func (x *GetSmtProofRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[29] + mi := &file_query_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2287,7 +2435,7 @@ func (x *GetSmtProofRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSmtProofRequest.ProtoReflect.Descriptor instead. func (*GetSmtProofRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{29} + return file_query_proto_rawDescGZIP(), []int{30} } func (x *GetSmtProofRequest) GetIndex() uint64 { @@ -2320,7 +2468,7 @@ type CommonProofResponse struct { func (x *CommonProofResponse) Reset() { *x = CommonProofResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[30] + mi := &file_query_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2333,7 +2481,7 @@ func (x *CommonProofResponse) String() string { func (*CommonProofResponse) ProtoMessage() {} func (x *CommonProofResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[30] + mi := &file_query_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2346,7 +2494,7 @@ func (x *CommonProofResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonProofResponse.ProtoReflect.Descriptor instead. func (*CommonProofResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{30} + return file_query_proto_rawDescGZIP(), []int{31} } func (x *CommonProofResponse) GetCode() uint32 { @@ -2405,7 +2553,7 @@ type ProofDetail struct { func (x *ProofDetail) Reset() { *x = ProofDetail{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[31] + mi := &file_query_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2418,7 +2566,7 @@ func (x *ProofDetail) String() string { func (*ProofDetail) ProtoMessage() {} func (x *ProofDetail) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[31] + mi := &file_query_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2431,7 +2579,7 @@ func (x *ProofDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use ProofDetail.ProtoReflect.Descriptor instead. func (*ProofDetail) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{31} + return file_query_proto_rawDescGZIP(), []int{32} } func (x *ProofDetail) GetSmtProof() []string { @@ -2474,7 +2622,7 @@ type GetNotReadyTransactionsRequest struct { func (x *GetNotReadyTransactionsRequest) Reset() { *x = GetNotReadyTransactionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[32] + mi := &file_query_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2487,7 +2635,7 @@ func (x *GetNotReadyTransactionsRequest) String() string { func (*GetNotReadyTransactionsRequest) ProtoMessage() {} func (x *GetNotReadyTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[32] + mi := &file_query_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2500,7 +2648,7 @@ func (x *GetNotReadyTransactionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetNotReadyTransactionsRequest.ProtoReflect.Descriptor instead. func (*GetNotReadyTransactionsRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{32} + return file_query_proto_rawDescGZIP(), []int{33} } func (x *GetNotReadyTransactionsRequest) GetOffset() uint64 { @@ -2530,7 +2678,7 @@ type GetMonitoredTxsByStatusRequest struct { func (x *GetMonitoredTxsByStatusRequest) Reset() { *x = GetMonitoredTxsByStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[33] + mi := &file_query_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2543,7 +2691,7 @@ func (x *GetMonitoredTxsByStatusRequest) String() string { func (*GetMonitoredTxsByStatusRequest) ProtoMessage() {} func (x *GetMonitoredTxsByStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[33] + mi := &file_query_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2556,7 +2704,7 @@ func (x *GetMonitoredTxsByStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMonitoredTxsByStatusRequest.ProtoReflect.Descriptor instead. func (*GetMonitoredTxsByStatusRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{33} + return file_query_proto_rawDescGZIP(), []int{34} } func (x *GetMonitoredTxsByStatusRequest) GetStatus() string { @@ -2596,7 +2744,7 @@ type CommonMonitoredTxsResponse struct { func (x *CommonMonitoredTxsResponse) Reset() { *x = CommonMonitoredTxsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[34] + mi := &file_query_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2609,7 +2757,7 @@ func (x *CommonMonitoredTxsResponse) String() string { func (*CommonMonitoredTxsResponse) ProtoMessage() {} func (x *CommonMonitoredTxsResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[34] + mi := &file_query_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2622,7 +2770,7 @@ func (x *CommonMonitoredTxsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonMonitoredTxsResponse.ProtoReflect.Descriptor instead. func (*CommonMonitoredTxsResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{34} + return file_query_proto_rawDescGZIP(), []int{35} } func (x *CommonMonitoredTxsResponse) GetCode() uint32 { @@ -2679,7 +2827,7 @@ type MonitoredTxsDetail struct { func (x *MonitoredTxsDetail) Reset() { *x = MonitoredTxsDetail{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[35] + mi := &file_query_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2692,7 +2840,7 @@ func (x *MonitoredTxsDetail) String() string { func (*MonitoredTxsDetail) ProtoMessage() {} func (x *MonitoredTxsDetail) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[35] + mi := &file_query_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2705,7 +2853,7 @@ func (x *MonitoredTxsDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use MonitoredTxsDetail.ProtoReflect.Descriptor instead. func (*MonitoredTxsDetail) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{35} + return file_query_proto_rawDescGZIP(), []int{36} } func (x *MonitoredTxsDetail) GetHasNext() bool { @@ -2731,7 +2879,7 @@ type GetEstimateTimeRequest struct { func (x *GetEstimateTimeRequest) Reset() { *x = GetEstimateTimeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[36] + mi := &file_query_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2744,7 +2892,7 @@ func (x *GetEstimateTimeRequest) String() string { func (*GetEstimateTimeRequest) ProtoMessage() {} func (x *GetEstimateTimeRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[36] + mi := &file_query_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2757,7 +2905,7 @@ func (x *GetEstimateTimeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEstimateTimeRequest.ProtoReflect.Descriptor instead. func (*GetEstimateTimeRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{36} + return file_query_proto_rawDescGZIP(), []int{37} } type CommonEstimateTimeResponse struct { @@ -2776,7 +2924,7 @@ type CommonEstimateTimeResponse struct { func (x *CommonEstimateTimeResponse) Reset() { *x = CommonEstimateTimeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[37] + mi := &file_query_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2789,7 +2937,7 @@ func (x *CommonEstimateTimeResponse) String() string { func (*CommonEstimateTimeResponse) ProtoMessage() {} func (x *CommonEstimateTimeResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[37] + mi := &file_query_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2802,7 +2950,7 @@ func (x *CommonEstimateTimeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonEstimateTimeResponse.ProtoReflect.Descriptor instead. func (*CommonEstimateTimeResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{37} + return file_query_proto_rawDescGZIP(), []int{38} } func (x *CommonEstimateTimeResponse) GetCode() uint32 { @@ -2860,7 +3008,7 @@ type ManualClaimRequest struct { func (x *ManualClaimRequest) Reset() { *x = ManualClaimRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[38] + mi := &file_query_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2873,7 +3021,7 @@ func (x *ManualClaimRequest) String() string { func (*ManualClaimRequest) ProtoMessage() {} func (x *ManualClaimRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[38] + mi := &file_query_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2886,7 +3034,7 @@ func (x *ManualClaimRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ManualClaimRequest.ProtoReflect.Descriptor instead. func (*ManualClaimRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{38} + return file_query_proto_rawDescGZIP(), []int{39} } func (x *ManualClaimRequest) GetFromChain() uint32 { @@ -2921,7 +3069,7 @@ type ManualClaimResponse struct { func (x *ManualClaimResponse) Reset() { *x = ManualClaimResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[39] + mi := &file_query_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2934,7 +3082,7 @@ func (x *ManualClaimResponse) String() string { func (*ManualClaimResponse) ProtoMessage() {} func (x *ManualClaimResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[39] + mi := &file_query_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2947,7 +3095,7 @@ func (x *ManualClaimResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ManualClaimResponse.ProtoReflect.Descriptor instead. func (*ManualClaimResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{39} + return file_query_proto_rawDescGZIP(), []int{40} } func (x *ManualClaimResponse) GetClaimTxHash() string { @@ -2973,7 +3121,7 @@ type CommonManualClaimResponse struct { func (x *CommonManualClaimResponse) Reset() { *x = CommonManualClaimResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[40] + mi := &file_query_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2986,7 +3134,7 @@ func (x *CommonManualClaimResponse) String() string { func (*CommonManualClaimResponse) ProtoMessage() {} func (x *CommonManualClaimResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[40] + mi := &file_query_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2999,7 +3147,7 @@ func (x *CommonManualClaimResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommonManualClaimResponse.ProtoReflect.Descriptor instead. func (*CommonManualClaimResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{40} + return file_query_proto_rawDescGZIP(), []int{41} } func (x *CommonManualClaimResponse) GetCode() uint32 { @@ -3057,7 +3205,7 @@ type GetReadyPendingTransactionsRequest struct { func (x *GetReadyPendingTransactionsRequest) Reset() { *x = GetReadyPendingTransactionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[41] + mi := &file_query_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3070,7 +3218,7 @@ func (x *GetReadyPendingTransactionsRequest) String() string { func (*GetReadyPendingTransactionsRequest) ProtoMessage() {} func (x *GetReadyPendingTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[41] + mi := &file_query_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3083,7 +3231,7 @@ func (x *GetReadyPendingTransactionsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use GetReadyPendingTransactionsRequest.ProtoReflect.Descriptor instead. func (*GetReadyPendingTransactionsRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{41} + return file_query_proto_rawDescGZIP(), []int{42} } func (x *GetReadyPendingTransactionsRequest) GetNetworkId() uint32 { @@ -3118,7 +3266,7 @@ type GetFakePushMessagesRequest struct { func (x *GetFakePushMessagesRequest) Reset() { *x = GetFakePushMessagesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[42] + mi := &file_query_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3131,7 +3279,7 @@ func (x *GetFakePushMessagesRequest) String() string { func (*GetFakePushMessagesRequest) ProtoMessage() {} func (x *GetFakePushMessagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[42] + mi := &file_query_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3144,7 +3292,7 @@ func (x *GetFakePushMessagesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFakePushMessagesRequest.ProtoReflect.Descriptor instead. func (*GetFakePushMessagesRequest) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{42} + return file_query_proto_rawDescGZIP(), []int{43} } func (x *GetFakePushMessagesRequest) GetTopic() string { @@ -3170,7 +3318,7 @@ type GetFakePushMessagesResponse struct { func (x *GetFakePushMessagesResponse) Reset() { *x = GetFakePushMessagesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[43] + mi := &file_query_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3183,7 +3331,7 @@ func (x *GetFakePushMessagesResponse) String() string { func (*GetFakePushMessagesResponse) ProtoMessage() {} func (x *GetFakePushMessagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[43] + mi := &file_query_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3196,7 +3344,7 @@ func (x *GetFakePushMessagesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFakePushMessagesResponse.ProtoReflect.Descriptor instead. func (*GetFakePushMessagesResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{43} + return file_query_proto_rawDescGZIP(), []int{44} } func (x *GetFakePushMessagesResponse) GetCode() uint32 { @@ -3241,6 +3389,85 @@ func (x *GetFakePushMessagesResponse) GetData() []string { return nil } +type CommonResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + ErrorCode string `protobuf:"bytes,3,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + ErrorMessage string `protobuf:"bytes,4,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + DetailMsg string `protobuf:"bytes,5,opt,name=detailMsg,proto3" json:"detailMsg,omitempty"` +} + +func (x *CommonResponse) Reset() { + *x = CommonResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommonResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommonResponse) ProtoMessage() {} + +func (x *CommonResponse) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommonResponse.ProtoReflect.Descriptor instead. +func (*CommonResponse) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{45} +} + +func (x *CommonResponse) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *CommonResponse) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +func (x *CommonResponse) GetErrorCode() string { + if x != nil { + return x.ErrorCode + } + return "" +} + +func (x *CommonResponse) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +func (x *CommonResponse) GetDetailMsg() string { + if x != nil { + return x.DetailMsg + } + return "" +} + var File_query_proto protoreflect.FileDescriptor var file_query_proto_rawDesc = []byte{ @@ -3399,7 +3626,7 @@ var file_query_proto_rawDesc = []byte{ 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xaf, 0x04, 0x0a, 0x0b, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xbb, 0x05, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x6f, 0x43, @@ -3434,49 +3661,196 @@ var file_query_proto_rawDesc = []byte{ 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xb7, 0x02, - 0x0a, 0x0b, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, - 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, - 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, - 0x67, 0x61, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x6f, - 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, - 0x0a, 0x0b, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x22, 0xce, 0x01, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x2a, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x50, 0x72, 0x69, - 0x63, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x33, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, - 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x22, 0xc6, 0x01, - 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x52, 0x0b, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, + 0x10, 0x64, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, + 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x34, 0x0a, 0x08, 0x6c, 0x6f, 0x67, + 0x6f, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x6f, 0x67, + 0x6f, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x28, 0x0a, 0x0f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x7f, 0x0a, 0x0d, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x4c, 0x6f, 0x67, 0x6f, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x6f, 0x4f, 0x73, 0x73, 0x55, 0x72, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x6f, 0x4f, 0x73, 0x73, 0x55, 0x72, 0x6c, + 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x07, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x22, 0xb7, 0x02, 0x0a, 0x0b, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, + 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, + 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x22, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x73, 0x22, 0xce, 0x01, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, + 0x6f, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x33, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, + 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x22, 0xc6, 0x01, 0x0a, 0x13, 0x43, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x27, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xd6, + 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x30, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, + 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, + 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x65, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x48, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x22, 0xc9, 0x01, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, + 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, + 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x4d, 0x73, 0x67, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, + 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, + 0x1a, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x26, 0x0a, 0x0e, 0x72, + 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x53, 0x6d, 0x74, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x12, 0x28, 0x0a, 0x0f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x65, 0x74, 0x45, 0x78, + 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x61, + 0x69, 0x6e, 0x6e, 0x65, 0x74, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, + 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x45, 0x78, 0x69, + 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x4e, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x52, + 0x65, 0x61, 0x64, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x66, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xd7, 0x01, + 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, + 0x64, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, + 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x31, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x6a, 0x0a, 0x12, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, + 0x07, 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x65, 0x64, 0x54, 0x78, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb8, 0x01, + 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, + 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0d, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x12, 0x4d, 0x61, 0x6e, 0x75, + 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x37, + 0x0a, 0x13, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x78, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0xd7, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, @@ -3485,300 +3859,185 @@ var file_query_proto_rawDesc = []byte{ 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x27, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, + 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x32, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x22, 0x70, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x22, 0xd6, 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x46, 0x61, 0x6b, 0x65, 0x50, 0x75, + 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x46, + 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, + 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, + 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x2a, 0x86, + 0x01, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x58, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x58, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, + 0x4e, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x01, 0x12, + 0x0e, 0x0a, 0x0a, 0x54, 0x58, 0x5f, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, 0x44, 0x10, 0x02, 0x12, + 0x19, 0x0a, 0x15, 0x54, 0x58, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, + 0x54, 0x4f, 0x5f, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x58, + 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x2a, 0x5c, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x4b, + 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x10, 0xe8, 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x42, 0x55, 0x53, 0x49, 0x4e, 0x45, 0x53, 0x53, 0x10, 0xe9, 0x07, 0x12, 0x18, 0x0a, 0x13, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x50, 0x5f, 0x52, 0x45, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, + 0x45, 0x44, 0x10, 0xf1, 0x07, 0x32, 0xbb, 0x0f, 0x0a, 0x0d, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x41, 0x50, 0x49, 0x12, 0x1a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x50, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x41, 0x50, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0c, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x06, 0x12, 0x04, 0x2f, 0x61, 0x70, 0x69, 0x12, 0x67, 0x0a, 0x0a, 0x47, 0x65, + 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x7d, 0x12, 0x5a, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, + 0x1a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, + 0x12, 0x0d, 0x2f, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x2d, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x12, + 0x57, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, + 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x09, 0x12, + 0x07, 0x2f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x63, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x73, 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x7d, 0x12, 0x6f, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x12, 0x21, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, + 0x0d, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x12, 0x6b, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1e, + 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22, 0x0b, 0x2f, 0x63, 0x6f, + 0x69, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x6f, 0x0a, 0x0c, 0x47, + 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x43, + 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, + 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2d, 0x63, 0x6f, 0x69, 0x6e, 0x73, + 0x2f, 0x7b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x7d, 0x12, 0x86, 0x01, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, + 0x12, 0x13, 0x2f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x7d, 0x12, 0x7a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, + 0x12, 0x0f, 0x2f, 0x61, 0x6c, 0x6c, 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x7d, 0x12, 0x60, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x12, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x73, 0x6d, 0x74, 0x2d, 0x70, 0x72, + 0x6f, 0x6f, 0x66, 0x12, 0x7f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, + 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, + 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, + 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x30, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x11, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, - 0x18, 0x0a, 0x07, 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x65, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x48, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, - 0x43, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x6f, - 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0xc9, 0x01, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, - 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, - 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x22, 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x26, - 0x0a, 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x53, 0x6d, - 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x28, 0x0a, 0x0f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x65, - 0x74, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x65, 0x74, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, - 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, - 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, - 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x4e, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4e, - 0x6f, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x66, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x22, 0xd7, 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x31, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x6a, 0x0a, 0x12, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x12, 0x18, 0x0a, 0x07, 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x68, 0x61, 0x73, 0x4e, 0x65, 0x78, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, + 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x6e, 0x6f, 0x74, 0x2d, 0x72, + 0x65, 0x61, 0x64, 0x79, 0x12, 0x93, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x29, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x42, 0x79, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x2d, 0x74, 0x78, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x7d, 0x12, 0x73, 0x0a, 0x0f, 0x47, 0x65, + 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x2e, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0xb8, 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x45, 0x73, 0x74, 0x69, 0x6d, - 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x12, 0x4d, - 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x64, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x54, 0x78, 0x48, 0x61, 0x73, - 0x68, 0x22, 0x37, 0x0a, 0x13, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x61, 0x69, - 0x6d, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, - 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0xd7, 0x01, 0x0a, 0x19, 0x43, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1d, - 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, 0x67, - 0x12, 0x32, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, + 0x0e, 0x2f, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x12, + 0x6c, 0x0a, 0x0b, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x75, 0x61, - 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x22, 0x70, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x46, 0x61, 0x6b, - 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x1b, 0x47, - 0x65, 0x74, 0x46, 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, - 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, - 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, 0x73, - 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4d, - 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x86, 0x01, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x0a, - 0x54, 0x58, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, - 0x54, 0x58, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, - 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x58, 0x5f, 0x43, 0x4c, - 0x41, 0x49, 0x4d, 0x45, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x58, 0x5f, 0x50, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x43, 0x4c, 0x41, 0x49, 0x4d, - 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x58, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, - 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x32, - 0xbb, 0x0f, 0x0a, 0x0d, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x51, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x50, 0x49, 0x12, 0x1a, 0x2e, - 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, - 0x50, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x50, 0x49, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x06, 0x12, 0x04, - 0x2f, 0x61, 0x70, 0x69, 0x12, 0x67, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x73, 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x7d, 0x12, 0x5a, 0x0a, - 0x08, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, 0x2e, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x6d, 0x65, 0x72, - 0x6b, 0x6c, 0x65, 0x2d, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x57, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x0f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x09, 0x12, 0x07, 0x2f, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x12, 0x63, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, - 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, - 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, - 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x61, 0x69, - 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x15, 0x12, 0x13, 0x2f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x2f, 0x7b, 0x64, 0x65, 0x73, - 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x7d, 0x12, 0x6f, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x12, 0x21, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x57, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, - 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x12, 0x6b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x50, - 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22, 0x0b, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2d, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x6f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, - 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, - 0x6d, 0x61, 0x69, 0x6e, 0x2d, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0x2f, 0x7b, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x7d, 0x12, 0x86, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x28, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x70, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x7d, 0x12, - 0x7a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x6c, 0x6c, - 0x2f, 0x7b, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x7d, 0x12, 0x60, 0x0a, 0x0b, 0x47, - 0x65, 0x74, 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1d, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6d, 0x74, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x0c, 0x12, 0x0a, 0x2f, 0x73, 0x6d, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x7f, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x6e, 0x6f, 0x74, 0x2d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x93, - 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x54, - 0x78, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x65, 0x64, 0x54, 0x78, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, - 0x64, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, - 0x2d, 0x74, 0x78, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x7d, 0x12, 0x73, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, - 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x54, - 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x45, 0x73, 0x74, - 0x69, 0x6d, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x65, 0x73, 0x74, 0x69, - 0x6d, 0x61, 0x74, 0x65, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x6c, 0x0a, 0x0b, 0x4d, 0x61, 0x6e, - 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, - 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x2d, 0x63, - 0x6c, 0x61, 0x69, 0x6d, 0x3a, 0x01, 0x2a, 0x12, 0x97, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x61, 0x64, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x2d, 0x70, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, - 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x46, 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, - 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, - 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x26, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x46, 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, - 0x12, 0x1b, 0x2f, 0x66, 0x61, 0x6b, 0x65, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x7d, 0x42, 0x3f, 0x5a, - 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x78, 0x50, 0x6f, - 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x48, 0x65, 0x72, 0x6d, 0x65, 0x7a, 0x2f, 0x7a, 0x6b, 0x65, 0x76, - 0x6d, 0x2d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x70, 0x62, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x6d, 0x61, + 0x6e, 0x75, 0x61, 0x6c, 0x2d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x3a, 0x01, 0x2a, 0x12, 0x97, 0x01, + 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x2e, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x72, 0x65, + 0x61, 0x64, 0x79, 0x2d, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x46, + 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, + 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, + 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x61, 0x6b, 0x65, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x66, 0x61, 0x6b, 0x65, 0x2d, 0x70, 0x75, + 0x73, 0x68, 0x2d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x7d, 0x42, 0x3f, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x30, 0x78, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x48, 0x65, 0x72, 0x6d, 0x65, + 0x7a, 0x2f, 0x7a, 0x6b, 0x65, 0x76, 0x6d, 0x2d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2d, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x74, 0x72, 0x65, + 0x65, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3793,109 +4052,113 @@ func file_query_proto_rawDescGZIP() []byte { return file_query_proto_rawDescData } -var file_query_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_query_proto_msgTypes = make([]protoimpl.MessageInfo, 44) +var file_query_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_query_proto_msgTypes = make([]protoimpl.MessageInfo, 46) var file_query_proto_goTypes = []interface{}{ (TransactionStatus)(0), // 0: bridge.v1.TransactionStatus - (*TokenWrapped)(nil), // 1: bridge.v1.TokenWrapped - (*Deposit)(nil), // 2: bridge.v1.Deposit - (*Claim)(nil), // 3: bridge.v1.Claim - (*Proof)(nil), // 4: bridge.v1.Proof - (*CheckAPIRequest)(nil), // 5: bridge.v1.CheckAPIRequest - (*GetBridgesRequest)(nil), // 6: bridge.v1.GetBridgesRequest - (*GetProofRequest)(nil), // 7: bridge.v1.GetProofRequest - (*GetTokenWrappedRequest)(nil), // 8: bridge.v1.GetTokenWrappedRequest - (*GetBridgeRequest)(nil), // 9: bridge.v1.GetBridgeRequest - (*GetClaimsRequest)(nil), // 10: bridge.v1.GetClaimsRequest - (*CheckAPIResponse)(nil), // 11: bridge.v1.CheckAPIResponse - (*GetBridgesResponse)(nil), // 12: bridge.v1.GetBridgesResponse - (*GetProofResponse)(nil), // 13: bridge.v1.GetProofResponse - (*GetTokenWrappedResponse)(nil), // 14: bridge.v1.GetTokenWrappedResponse - (*GetBridgeResponse)(nil), // 15: bridge.v1.GetBridgeResponse - (*GetClaimsResponse)(nil), // 16: bridge.v1.GetClaimsResponse - (*SymbolInfo)(nil), // 17: bridge.v1.SymbolInfo - (*SymbolPrice)(nil), // 18: bridge.v1.SymbolPrice - (*CoinInfo)(nil), // 19: bridge.v1.CoinInfo - (*Transaction)(nil), // 20: bridge.v1.Transaction - (*MonitoredTx)(nil), // 21: bridge.v1.MonitoredTx - (*GetCoinPriceRequest)(nil), // 22: bridge.v1.GetCoinPriceRequest - (*CommonCoinPricesResponse)(nil), // 23: bridge.v1.CommonCoinPricesResponse - (*GetMainCoinsRequest)(nil), // 24: bridge.v1.GetMainCoinsRequest - (*CommonCoinsResponse)(nil), // 25: bridge.v1.CommonCoinsResponse - (*GetPendingTransactionsRequest)(nil), // 26: bridge.v1.GetPendingTransactionsRequest - (*CommonTransactionsResponse)(nil), // 27: bridge.v1.CommonTransactionsResponse - (*TransactionDetail)(nil), // 28: bridge.v1.TransactionDetail - (*GetAllTransactionsRequest)(nil), // 29: bridge.v1.GetAllTransactionsRequest - (*GetSmtProofRequest)(nil), // 30: bridge.v1.GetSmtProofRequest - (*CommonProofResponse)(nil), // 31: bridge.v1.CommonProofResponse - (*ProofDetail)(nil), // 32: bridge.v1.ProofDetail - (*GetNotReadyTransactionsRequest)(nil), // 33: bridge.v1.GetNotReadyTransactionsRequest - (*GetMonitoredTxsByStatusRequest)(nil), // 34: bridge.v1.GetMonitoredTxsByStatusRequest - (*CommonMonitoredTxsResponse)(nil), // 35: bridge.v1.CommonMonitoredTxsResponse - (*MonitoredTxsDetail)(nil), // 36: bridge.v1.MonitoredTxsDetail - (*GetEstimateTimeRequest)(nil), // 37: bridge.v1.GetEstimateTimeRequest - (*CommonEstimateTimeResponse)(nil), // 38: bridge.v1.CommonEstimateTimeResponse - (*ManualClaimRequest)(nil), // 39: bridge.v1.ManualClaimRequest - (*ManualClaimResponse)(nil), // 40: bridge.v1.ManualClaimResponse - (*CommonManualClaimResponse)(nil), // 41: bridge.v1.CommonManualClaimResponse - (*GetReadyPendingTransactionsRequest)(nil), // 42: bridge.v1.GetReadyPendingTransactionsRequest - (*GetFakePushMessagesRequest)(nil), // 43: bridge.v1.GetFakePushMessagesRequest - (*GetFakePushMessagesResponse)(nil), // 44: bridge.v1.GetFakePushMessagesResponse + (ErrorCode)(0), // 1: bridge.v1.ErrorCode + (*TokenWrapped)(nil), // 2: bridge.v1.TokenWrapped + (*Deposit)(nil), // 3: bridge.v1.Deposit + (*Claim)(nil), // 4: bridge.v1.Claim + (*Proof)(nil), // 5: bridge.v1.Proof + (*CheckAPIRequest)(nil), // 6: bridge.v1.CheckAPIRequest + (*GetBridgesRequest)(nil), // 7: bridge.v1.GetBridgesRequest + (*GetProofRequest)(nil), // 8: bridge.v1.GetProofRequest + (*GetTokenWrappedRequest)(nil), // 9: bridge.v1.GetTokenWrappedRequest + (*GetBridgeRequest)(nil), // 10: bridge.v1.GetBridgeRequest + (*GetClaimsRequest)(nil), // 11: bridge.v1.GetClaimsRequest + (*CheckAPIResponse)(nil), // 12: bridge.v1.CheckAPIResponse + (*GetBridgesResponse)(nil), // 13: bridge.v1.GetBridgesResponse + (*GetProofResponse)(nil), // 14: bridge.v1.GetProofResponse + (*GetTokenWrappedResponse)(nil), // 15: bridge.v1.GetTokenWrappedResponse + (*GetBridgeResponse)(nil), // 16: bridge.v1.GetBridgeResponse + (*GetClaimsResponse)(nil), // 17: bridge.v1.GetClaimsResponse + (*SymbolInfo)(nil), // 18: bridge.v1.SymbolInfo + (*SymbolPrice)(nil), // 19: bridge.v1.SymbolPrice + (*CoinInfo)(nil), // 20: bridge.v1.CoinInfo + (*Transaction)(nil), // 21: bridge.v1.Transaction + (*TokenLogoInfo)(nil), // 22: bridge.v1.TokenLogoInfo + (*MonitoredTx)(nil), // 23: bridge.v1.MonitoredTx + (*GetCoinPriceRequest)(nil), // 24: bridge.v1.GetCoinPriceRequest + (*CommonCoinPricesResponse)(nil), // 25: bridge.v1.CommonCoinPricesResponse + (*GetMainCoinsRequest)(nil), // 26: bridge.v1.GetMainCoinsRequest + (*CommonCoinsResponse)(nil), // 27: bridge.v1.CommonCoinsResponse + (*GetPendingTransactionsRequest)(nil), // 28: bridge.v1.GetPendingTransactionsRequest + (*CommonTransactionsResponse)(nil), // 29: bridge.v1.CommonTransactionsResponse + (*TransactionDetail)(nil), // 30: bridge.v1.TransactionDetail + (*GetAllTransactionsRequest)(nil), // 31: bridge.v1.GetAllTransactionsRequest + (*GetSmtProofRequest)(nil), // 32: bridge.v1.GetSmtProofRequest + (*CommonProofResponse)(nil), // 33: bridge.v1.CommonProofResponse + (*ProofDetail)(nil), // 34: bridge.v1.ProofDetail + (*GetNotReadyTransactionsRequest)(nil), // 35: bridge.v1.GetNotReadyTransactionsRequest + (*GetMonitoredTxsByStatusRequest)(nil), // 36: bridge.v1.GetMonitoredTxsByStatusRequest + (*CommonMonitoredTxsResponse)(nil), // 37: bridge.v1.CommonMonitoredTxsResponse + (*MonitoredTxsDetail)(nil), // 38: bridge.v1.MonitoredTxsDetail + (*GetEstimateTimeRequest)(nil), // 39: bridge.v1.GetEstimateTimeRequest + (*CommonEstimateTimeResponse)(nil), // 40: bridge.v1.CommonEstimateTimeResponse + (*ManualClaimRequest)(nil), // 41: bridge.v1.ManualClaimRequest + (*ManualClaimResponse)(nil), // 42: bridge.v1.ManualClaimResponse + (*CommonManualClaimResponse)(nil), // 43: bridge.v1.CommonManualClaimResponse + (*GetReadyPendingTransactionsRequest)(nil), // 44: bridge.v1.GetReadyPendingTransactionsRequest + (*GetFakePushMessagesRequest)(nil), // 45: bridge.v1.GetFakePushMessagesRequest + (*GetFakePushMessagesResponse)(nil), // 46: bridge.v1.GetFakePushMessagesResponse + (*CommonResponse)(nil), // 47: bridge.v1.CommonResponse } var file_query_proto_depIdxs = []int32{ - 2, // 0: bridge.v1.GetBridgesResponse.deposits:type_name -> bridge.v1.Deposit - 4, // 1: bridge.v1.GetProofResponse.proof:type_name -> bridge.v1.Proof - 1, // 2: bridge.v1.GetTokenWrappedResponse.tokenwrapped:type_name -> bridge.v1.TokenWrapped - 2, // 3: bridge.v1.GetBridgeResponse.deposit:type_name -> bridge.v1.Deposit - 3, // 4: bridge.v1.GetClaimsResponse.claims:type_name -> bridge.v1.Claim - 17, // 5: bridge.v1.GetCoinPriceRequest.symbolInfos:type_name -> bridge.v1.SymbolInfo - 18, // 6: bridge.v1.CommonCoinPricesResponse.data:type_name -> bridge.v1.SymbolPrice - 19, // 7: bridge.v1.CommonCoinsResponse.data:type_name -> bridge.v1.CoinInfo - 28, // 8: bridge.v1.CommonTransactionsResponse.data:type_name -> bridge.v1.TransactionDetail - 20, // 9: bridge.v1.TransactionDetail.transactions:type_name -> bridge.v1.Transaction - 32, // 10: bridge.v1.CommonProofResponse.data:type_name -> bridge.v1.ProofDetail - 36, // 11: bridge.v1.CommonMonitoredTxsResponse.data:type_name -> bridge.v1.MonitoredTxsDetail - 21, // 12: bridge.v1.MonitoredTxsDetail.transactions:type_name -> bridge.v1.MonitoredTx - 40, // 13: bridge.v1.CommonManualClaimResponse.data:type_name -> bridge.v1.ManualClaimResponse - 5, // 14: bridge.v1.BridgeService.CheckAPI:input_type -> bridge.v1.CheckAPIRequest - 6, // 15: bridge.v1.BridgeService.GetBridges:input_type -> bridge.v1.GetBridgesRequest - 7, // 16: bridge.v1.BridgeService.GetProof:input_type -> bridge.v1.GetProofRequest - 9, // 17: bridge.v1.BridgeService.GetBridge:input_type -> bridge.v1.GetBridgeRequest - 10, // 18: bridge.v1.BridgeService.GetClaims:input_type -> bridge.v1.GetClaimsRequest - 8, // 19: bridge.v1.BridgeService.GetTokenWrapped:input_type -> bridge.v1.GetTokenWrappedRequest - 22, // 20: bridge.v1.BridgeService.GetCoinPrice:input_type -> bridge.v1.GetCoinPriceRequest - 24, // 21: bridge.v1.BridgeService.GetMainCoins:input_type -> bridge.v1.GetMainCoinsRequest - 26, // 22: bridge.v1.BridgeService.GetPendingTransactions:input_type -> bridge.v1.GetPendingTransactionsRequest - 29, // 23: bridge.v1.BridgeService.GetAllTransactions:input_type -> bridge.v1.GetAllTransactionsRequest - 30, // 24: bridge.v1.BridgeService.GetSmtProof:input_type -> bridge.v1.GetSmtProofRequest - 33, // 25: bridge.v1.BridgeService.GetNotReadyTransactions:input_type -> bridge.v1.GetNotReadyTransactionsRequest - 34, // 26: bridge.v1.BridgeService.GetMonitoredTxsByStatus:input_type -> bridge.v1.GetMonitoredTxsByStatusRequest - 37, // 27: bridge.v1.BridgeService.GetEstimateTime:input_type -> bridge.v1.GetEstimateTimeRequest - 39, // 28: bridge.v1.BridgeService.ManualClaim:input_type -> bridge.v1.ManualClaimRequest - 42, // 29: bridge.v1.BridgeService.GetReadyPendingTransactions:input_type -> bridge.v1.GetReadyPendingTransactionsRequest - 43, // 30: bridge.v1.BridgeService.GetFakePushMessages:input_type -> bridge.v1.GetFakePushMessagesRequest - 11, // 31: bridge.v1.BridgeService.CheckAPI:output_type -> bridge.v1.CheckAPIResponse - 12, // 32: bridge.v1.BridgeService.GetBridges:output_type -> bridge.v1.GetBridgesResponse - 13, // 33: bridge.v1.BridgeService.GetProof:output_type -> bridge.v1.GetProofResponse - 15, // 34: bridge.v1.BridgeService.GetBridge:output_type -> bridge.v1.GetBridgeResponse - 16, // 35: bridge.v1.BridgeService.GetClaims:output_type -> bridge.v1.GetClaimsResponse - 14, // 36: bridge.v1.BridgeService.GetTokenWrapped:output_type -> bridge.v1.GetTokenWrappedResponse - 23, // 37: bridge.v1.BridgeService.GetCoinPrice:output_type -> bridge.v1.CommonCoinPricesResponse - 25, // 38: bridge.v1.BridgeService.GetMainCoins:output_type -> bridge.v1.CommonCoinsResponse - 27, // 39: bridge.v1.BridgeService.GetPendingTransactions:output_type -> bridge.v1.CommonTransactionsResponse - 27, // 40: bridge.v1.BridgeService.GetAllTransactions:output_type -> bridge.v1.CommonTransactionsResponse - 31, // 41: bridge.v1.BridgeService.GetSmtProof:output_type -> bridge.v1.CommonProofResponse - 27, // 42: bridge.v1.BridgeService.GetNotReadyTransactions:output_type -> bridge.v1.CommonTransactionsResponse - 35, // 43: bridge.v1.BridgeService.GetMonitoredTxsByStatus:output_type -> bridge.v1.CommonMonitoredTxsResponse - 38, // 44: bridge.v1.BridgeService.GetEstimateTime:output_type -> bridge.v1.CommonEstimateTimeResponse - 41, // 45: bridge.v1.BridgeService.ManualClaim:output_type -> bridge.v1.CommonManualClaimResponse - 27, // 46: bridge.v1.BridgeService.GetReadyPendingTransactions:output_type -> bridge.v1.CommonTransactionsResponse - 44, // 47: bridge.v1.BridgeService.GetFakePushMessages:output_type -> bridge.v1.GetFakePushMessagesResponse - 31, // [31:48] is the sub-list for method output_type - 14, // [14:31] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 3, // 0: bridge.v1.GetBridgesResponse.deposits:type_name -> bridge.v1.Deposit + 5, // 1: bridge.v1.GetProofResponse.proof:type_name -> bridge.v1.Proof + 2, // 2: bridge.v1.GetTokenWrappedResponse.tokenwrapped:type_name -> bridge.v1.TokenWrapped + 3, // 3: bridge.v1.GetBridgeResponse.deposit:type_name -> bridge.v1.Deposit + 4, // 4: bridge.v1.GetClaimsResponse.claims:type_name -> bridge.v1.Claim + 22, // 5: bridge.v1.Transaction.logoInfo:type_name -> bridge.v1.TokenLogoInfo + 18, // 6: bridge.v1.GetCoinPriceRequest.symbolInfos:type_name -> bridge.v1.SymbolInfo + 19, // 7: bridge.v1.CommonCoinPricesResponse.data:type_name -> bridge.v1.SymbolPrice + 20, // 8: bridge.v1.CommonCoinsResponse.data:type_name -> bridge.v1.CoinInfo + 30, // 9: bridge.v1.CommonTransactionsResponse.data:type_name -> bridge.v1.TransactionDetail + 21, // 10: bridge.v1.TransactionDetail.transactions:type_name -> bridge.v1.Transaction + 34, // 11: bridge.v1.CommonProofResponse.data:type_name -> bridge.v1.ProofDetail + 38, // 12: bridge.v1.CommonMonitoredTxsResponse.data:type_name -> bridge.v1.MonitoredTxsDetail + 23, // 13: bridge.v1.MonitoredTxsDetail.transactions:type_name -> bridge.v1.MonitoredTx + 42, // 14: bridge.v1.CommonManualClaimResponse.data:type_name -> bridge.v1.ManualClaimResponse + 6, // 15: bridge.v1.BridgeService.CheckAPI:input_type -> bridge.v1.CheckAPIRequest + 7, // 16: bridge.v1.BridgeService.GetBridges:input_type -> bridge.v1.GetBridgesRequest + 8, // 17: bridge.v1.BridgeService.GetProof:input_type -> bridge.v1.GetProofRequest + 10, // 18: bridge.v1.BridgeService.GetBridge:input_type -> bridge.v1.GetBridgeRequest + 11, // 19: bridge.v1.BridgeService.GetClaims:input_type -> bridge.v1.GetClaimsRequest + 9, // 20: bridge.v1.BridgeService.GetTokenWrapped:input_type -> bridge.v1.GetTokenWrappedRequest + 24, // 21: bridge.v1.BridgeService.GetCoinPrice:input_type -> bridge.v1.GetCoinPriceRequest + 26, // 22: bridge.v1.BridgeService.GetMainCoins:input_type -> bridge.v1.GetMainCoinsRequest + 28, // 23: bridge.v1.BridgeService.GetPendingTransactions:input_type -> bridge.v1.GetPendingTransactionsRequest + 31, // 24: bridge.v1.BridgeService.GetAllTransactions:input_type -> bridge.v1.GetAllTransactionsRequest + 32, // 25: bridge.v1.BridgeService.GetSmtProof:input_type -> bridge.v1.GetSmtProofRequest + 35, // 26: bridge.v1.BridgeService.GetNotReadyTransactions:input_type -> bridge.v1.GetNotReadyTransactionsRequest + 36, // 27: bridge.v1.BridgeService.GetMonitoredTxsByStatus:input_type -> bridge.v1.GetMonitoredTxsByStatusRequest + 39, // 28: bridge.v1.BridgeService.GetEstimateTime:input_type -> bridge.v1.GetEstimateTimeRequest + 41, // 29: bridge.v1.BridgeService.ManualClaim:input_type -> bridge.v1.ManualClaimRequest + 44, // 30: bridge.v1.BridgeService.GetReadyPendingTransactions:input_type -> bridge.v1.GetReadyPendingTransactionsRequest + 45, // 31: bridge.v1.BridgeService.GetFakePushMessages:input_type -> bridge.v1.GetFakePushMessagesRequest + 12, // 32: bridge.v1.BridgeService.CheckAPI:output_type -> bridge.v1.CheckAPIResponse + 13, // 33: bridge.v1.BridgeService.GetBridges:output_type -> bridge.v1.GetBridgesResponse + 14, // 34: bridge.v1.BridgeService.GetProof:output_type -> bridge.v1.GetProofResponse + 16, // 35: bridge.v1.BridgeService.GetBridge:output_type -> bridge.v1.GetBridgeResponse + 17, // 36: bridge.v1.BridgeService.GetClaims:output_type -> bridge.v1.GetClaimsResponse + 15, // 37: bridge.v1.BridgeService.GetTokenWrapped:output_type -> bridge.v1.GetTokenWrappedResponse + 25, // 38: bridge.v1.BridgeService.GetCoinPrice:output_type -> bridge.v1.CommonCoinPricesResponse + 27, // 39: bridge.v1.BridgeService.GetMainCoins:output_type -> bridge.v1.CommonCoinsResponse + 29, // 40: bridge.v1.BridgeService.GetPendingTransactions:output_type -> bridge.v1.CommonTransactionsResponse + 29, // 41: bridge.v1.BridgeService.GetAllTransactions:output_type -> bridge.v1.CommonTransactionsResponse + 33, // 42: bridge.v1.BridgeService.GetSmtProof:output_type -> bridge.v1.CommonProofResponse + 29, // 43: bridge.v1.BridgeService.GetNotReadyTransactions:output_type -> bridge.v1.CommonTransactionsResponse + 37, // 44: bridge.v1.BridgeService.GetMonitoredTxsByStatus:output_type -> bridge.v1.CommonMonitoredTxsResponse + 40, // 45: bridge.v1.BridgeService.GetEstimateTime:output_type -> bridge.v1.CommonEstimateTimeResponse + 43, // 46: bridge.v1.BridgeService.ManualClaim:output_type -> bridge.v1.CommonManualClaimResponse + 29, // 47: bridge.v1.BridgeService.GetReadyPendingTransactions:output_type -> bridge.v1.CommonTransactionsResponse + 46, // 48: bridge.v1.BridgeService.GetFakePushMessages:output_type -> bridge.v1.GetFakePushMessagesResponse + 32, // [32:49] is the sub-list for method output_type + 15, // [15:32] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_query_proto_init() } @@ -4145,7 +4408,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MonitoredTx); i { + switch v := v.(*TokenLogoInfo); i { case 0: return &v.state case 1: @@ -4157,7 +4420,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCoinPriceRequest); i { + switch v := v.(*MonitoredTx); i { case 0: return &v.state case 1: @@ -4169,7 +4432,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonCoinPricesResponse); i { + switch v := v.(*GetCoinPriceRequest); i { case 0: return &v.state case 1: @@ -4181,7 +4444,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMainCoinsRequest); i { + switch v := v.(*CommonCoinPricesResponse); i { case 0: return &v.state case 1: @@ -4193,7 +4456,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonCoinsResponse); i { + switch v := v.(*GetMainCoinsRequest); i { case 0: return &v.state case 1: @@ -4205,7 +4468,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetPendingTransactionsRequest); i { + switch v := v.(*CommonCoinsResponse); i { case 0: return &v.state case 1: @@ -4217,7 +4480,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonTransactionsResponse); i { + switch v := v.(*GetPendingTransactionsRequest); i { case 0: return &v.state case 1: @@ -4229,7 +4492,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TransactionDetail); i { + switch v := v.(*CommonTransactionsResponse); i { case 0: return &v.state case 1: @@ -4241,7 +4504,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetAllTransactionsRequest); i { + switch v := v.(*TransactionDetail); i { case 0: return &v.state case 1: @@ -4253,7 +4516,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSmtProofRequest); i { + switch v := v.(*GetAllTransactionsRequest); i { case 0: return &v.state case 1: @@ -4265,7 +4528,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonProofResponse); i { + switch v := v.(*GetSmtProofRequest); i { case 0: return &v.state case 1: @@ -4277,7 +4540,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProofDetail); i { + switch v := v.(*CommonProofResponse); i { case 0: return &v.state case 1: @@ -4289,7 +4552,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetNotReadyTransactionsRequest); i { + switch v := v.(*ProofDetail); i { case 0: return &v.state case 1: @@ -4301,7 +4564,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMonitoredTxsByStatusRequest); i { + switch v := v.(*GetNotReadyTransactionsRequest); i { case 0: return &v.state case 1: @@ -4313,7 +4576,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonMonitoredTxsResponse); i { + switch v := v.(*GetMonitoredTxsByStatusRequest); i { case 0: return &v.state case 1: @@ -4325,7 +4588,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MonitoredTxsDetail); i { + switch v := v.(*CommonMonitoredTxsResponse); i { case 0: return &v.state case 1: @@ -4337,7 +4600,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetEstimateTimeRequest); i { + switch v := v.(*MonitoredTxsDetail); i { case 0: return &v.state case 1: @@ -4349,7 +4612,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonEstimateTimeResponse); i { + switch v := v.(*GetEstimateTimeRequest); i { case 0: return &v.state case 1: @@ -4361,7 +4624,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ManualClaimRequest); i { + switch v := v.(*CommonEstimateTimeResponse); i { case 0: return &v.state case 1: @@ -4373,7 +4636,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ManualClaimResponse); i { + switch v := v.(*ManualClaimRequest); i { case 0: return &v.state case 1: @@ -4385,7 +4648,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommonManualClaimResponse); i { + switch v := v.(*ManualClaimResponse); i { case 0: return &v.state case 1: @@ -4397,7 +4660,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetReadyPendingTransactionsRequest); i { + switch v := v.(*CommonManualClaimResponse); i { case 0: return &v.state case 1: @@ -4409,7 +4672,7 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFakePushMessagesRequest); i { + switch v := v.(*GetReadyPendingTransactionsRequest); i { case 0: return &v.state case 1: @@ -4421,6 +4684,18 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFakePushMessagesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetFakePushMessagesResponse); i { case 0: return &v.state @@ -4432,14 +4707,26 @@ func file_query_proto_init() { return nil } } + file_query_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommonResponse); 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{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_query_proto_rawDesc, - NumEnums: 1, - NumMessages: 44, + NumEnums: 2, + NumMessages: 46, NumExtensions: 0, NumServices: 1, }, diff --git a/bridgectrl/pb/query_grpc.pb.go b/bridgectrl/pb/query_grpc.pb.go index f1217902..7126aeb0 100644 --- a/bridgectrl/pb/query_grpc.pb.go +++ b/bridgectrl/pb/query_grpc.pb.go @@ -1,10 +1,7 @@ -//* -// Bridge service. - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc v3.21.5 +// - protoc-gen-go-grpc v1.2.0 +// - protoc v4.24.3 // source: query.proto package pb @@ -21,26 +18,6 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 -const ( - BridgeService_CheckAPI_FullMethodName = "/bridge.v1.BridgeService/CheckAPI" - BridgeService_GetBridges_FullMethodName = "/bridge.v1.BridgeService/GetBridges" - BridgeService_GetProof_FullMethodName = "/bridge.v1.BridgeService/GetProof" - BridgeService_GetBridge_FullMethodName = "/bridge.v1.BridgeService/GetBridge" - BridgeService_GetClaims_FullMethodName = "/bridge.v1.BridgeService/GetClaims" - BridgeService_GetTokenWrapped_FullMethodName = "/bridge.v1.BridgeService/GetTokenWrapped" - BridgeService_GetCoinPrice_FullMethodName = "/bridge.v1.BridgeService/GetCoinPrice" - BridgeService_GetMainCoins_FullMethodName = "/bridge.v1.BridgeService/GetMainCoins" - BridgeService_GetPendingTransactions_FullMethodName = "/bridge.v1.BridgeService/GetPendingTransactions" - BridgeService_GetAllTransactions_FullMethodName = "/bridge.v1.BridgeService/GetAllTransactions" - BridgeService_GetSmtProof_FullMethodName = "/bridge.v1.BridgeService/GetSmtProof" - BridgeService_GetNotReadyTransactions_FullMethodName = "/bridge.v1.BridgeService/GetNotReadyTransactions" - BridgeService_GetMonitoredTxsByStatus_FullMethodName = "/bridge.v1.BridgeService/GetMonitoredTxsByStatus" - BridgeService_GetEstimateTime_FullMethodName = "/bridge.v1.BridgeService/GetEstimateTime" - BridgeService_ManualClaim_FullMethodName = "/bridge.v1.BridgeService/ManualClaim" - BridgeService_GetReadyPendingTransactions_FullMethodName = "/bridge.v1.BridgeService/GetReadyPendingTransactions" - BridgeService_GetFakePushMessages_FullMethodName = "/bridge.v1.BridgeService/GetFakePushMessages" -) - // BridgeServiceClient is the client API for BridgeService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -91,7 +68,7 @@ func NewBridgeServiceClient(cc grpc.ClientConnInterface) BridgeServiceClient { func (c *bridgeServiceClient) CheckAPI(ctx context.Context, in *CheckAPIRequest, opts ...grpc.CallOption) (*CheckAPIResponse, error) { out := new(CheckAPIResponse) - err := c.cc.Invoke(ctx, BridgeService_CheckAPI_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/CheckAPI", in, out, opts...) if err != nil { return nil, err } @@ -100,7 +77,7 @@ func (c *bridgeServiceClient) CheckAPI(ctx context.Context, in *CheckAPIRequest, func (c *bridgeServiceClient) GetBridges(ctx context.Context, in *GetBridgesRequest, opts ...grpc.CallOption) (*GetBridgesResponse, error) { out := new(GetBridgesResponse) - err := c.cc.Invoke(ctx, BridgeService_GetBridges_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetBridges", in, out, opts...) if err != nil { return nil, err } @@ -109,7 +86,7 @@ func (c *bridgeServiceClient) GetBridges(ctx context.Context, in *GetBridgesRequ func (c *bridgeServiceClient) GetProof(ctx context.Context, in *GetProofRequest, opts ...grpc.CallOption) (*GetProofResponse, error) { out := new(GetProofResponse) - err := c.cc.Invoke(ctx, BridgeService_GetProof_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetProof", in, out, opts...) if err != nil { return nil, err } @@ -118,7 +95,7 @@ func (c *bridgeServiceClient) GetProof(ctx context.Context, in *GetProofRequest, func (c *bridgeServiceClient) GetBridge(ctx context.Context, in *GetBridgeRequest, opts ...grpc.CallOption) (*GetBridgeResponse, error) { out := new(GetBridgeResponse) - err := c.cc.Invoke(ctx, BridgeService_GetBridge_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetBridge", in, out, opts...) if err != nil { return nil, err } @@ -127,7 +104,7 @@ func (c *bridgeServiceClient) GetBridge(ctx context.Context, in *GetBridgeReques func (c *bridgeServiceClient) GetClaims(ctx context.Context, in *GetClaimsRequest, opts ...grpc.CallOption) (*GetClaimsResponse, error) { out := new(GetClaimsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetClaims_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetClaims", in, out, opts...) if err != nil { return nil, err } @@ -136,7 +113,7 @@ func (c *bridgeServiceClient) GetClaims(ctx context.Context, in *GetClaimsReques func (c *bridgeServiceClient) GetTokenWrapped(ctx context.Context, in *GetTokenWrappedRequest, opts ...grpc.CallOption) (*GetTokenWrappedResponse, error) { out := new(GetTokenWrappedResponse) - err := c.cc.Invoke(ctx, BridgeService_GetTokenWrapped_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetTokenWrapped", in, out, opts...) if err != nil { return nil, err } @@ -145,7 +122,7 @@ func (c *bridgeServiceClient) GetTokenWrapped(ctx context.Context, in *GetTokenW func (c *bridgeServiceClient) GetCoinPrice(ctx context.Context, in *GetCoinPriceRequest, opts ...grpc.CallOption) (*CommonCoinPricesResponse, error) { out := new(CommonCoinPricesResponse) - err := c.cc.Invoke(ctx, BridgeService_GetCoinPrice_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetCoinPrice", in, out, opts...) if err != nil { return nil, err } @@ -154,7 +131,7 @@ func (c *bridgeServiceClient) GetCoinPrice(ctx context.Context, in *GetCoinPrice func (c *bridgeServiceClient) GetMainCoins(ctx context.Context, in *GetMainCoinsRequest, opts ...grpc.CallOption) (*CommonCoinsResponse, error) { out := new(CommonCoinsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetMainCoins_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetMainCoins", in, out, opts...) if err != nil { return nil, err } @@ -163,7 +140,7 @@ func (c *bridgeServiceClient) GetMainCoins(ctx context.Context, in *GetMainCoins func (c *bridgeServiceClient) GetPendingTransactions(ctx context.Context, in *GetPendingTransactionsRequest, opts ...grpc.CallOption) (*CommonTransactionsResponse, error) { out := new(CommonTransactionsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetPendingTransactions_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetPendingTransactions", in, out, opts...) if err != nil { return nil, err } @@ -172,7 +149,7 @@ func (c *bridgeServiceClient) GetPendingTransactions(ctx context.Context, in *Ge func (c *bridgeServiceClient) GetAllTransactions(ctx context.Context, in *GetAllTransactionsRequest, opts ...grpc.CallOption) (*CommonTransactionsResponse, error) { out := new(CommonTransactionsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetAllTransactions_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetAllTransactions", in, out, opts...) if err != nil { return nil, err } @@ -181,7 +158,7 @@ func (c *bridgeServiceClient) GetAllTransactions(ctx context.Context, in *GetAll func (c *bridgeServiceClient) GetSmtProof(ctx context.Context, in *GetSmtProofRequest, opts ...grpc.CallOption) (*CommonProofResponse, error) { out := new(CommonProofResponse) - err := c.cc.Invoke(ctx, BridgeService_GetSmtProof_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetSmtProof", in, out, opts...) if err != nil { return nil, err } @@ -190,7 +167,7 @@ func (c *bridgeServiceClient) GetSmtProof(ctx context.Context, in *GetSmtProofRe func (c *bridgeServiceClient) GetNotReadyTransactions(ctx context.Context, in *GetNotReadyTransactionsRequest, opts ...grpc.CallOption) (*CommonTransactionsResponse, error) { out := new(CommonTransactionsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetNotReadyTransactions_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetNotReadyTransactions", in, out, opts...) if err != nil { return nil, err } @@ -199,7 +176,7 @@ func (c *bridgeServiceClient) GetNotReadyTransactions(ctx context.Context, in *G func (c *bridgeServiceClient) GetMonitoredTxsByStatus(ctx context.Context, in *GetMonitoredTxsByStatusRequest, opts ...grpc.CallOption) (*CommonMonitoredTxsResponse, error) { out := new(CommonMonitoredTxsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetMonitoredTxsByStatus_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetMonitoredTxsByStatus", in, out, opts...) if err != nil { return nil, err } @@ -208,7 +185,7 @@ func (c *bridgeServiceClient) GetMonitoredTxsByStatus(ctx context.Context, in *G func (c *bridgeServiceClient) GetEstimateTime(ctx context.Context, in *GetEstimateTimeRequest, opts ...grpc.CallOption) (*CommonEstimateTimeResponse, error) { out := new(CommonEstimateTimeResponse) - err := c.cc.Invoke(ctx, BridgeService_GetEstimateTime_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetEstimateTime", in, out, opts...) if err != nil { return nil, err } @@ -217,7 +194,7 @@ func (c *bridgeServiceClient) GetEstimateTime(ctx context.Context, in *GetEstima func (c *bridgeServiceClient) ManualClaim(ctx context.Context, in *ManualClaimRequest, opts ...grpc.CallOption) (*CommonManualClaimResponse, error) { out := new(CommonManualClaimResponse) - err := c.cc.Invoke(ctx, BridgeService_ManualClaim_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/ManualClaim", in, out, opts...) if err != nil { return nil, err } @@ -226,7 +203,7 @@ func (c *bridgeServiceClient) ManualClaim(ctx context.Context, in *ManualClaimRe func (c *bridgeServiceClient) GetReadyPendingTransactions(ctx context.Context, in *GetReadyPendingTransactionsRequest, opts ...grpc.CallOption) (*CommonTransactionsResponse, error) { out := new(CommonTransactionsResponse) - err := c.cc.Invoke(ctx, BridgeService_GetReadyPendingTransactions_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetReadyPendingTransactions", in, out, opts...) if err != nil { return nil, err } @@ -235,7 +212,7 @@ func (c *bridgeServiceClient) GetReadyPendingTransactions(ctx context.Context, i func (c *bridgeServiceClient) GetFakePushMessages(ctx context.Context, in *GetFakePushMessagesRequest, opts ...grpc.CallOption) (*GetFakePushMessagesResponse, error) { out := new(GetFakePushMessagesResponse) - err := c.cc.Invoke(ctx, BridgeService_GetFakePushMessages_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/bridge.v1.BridgeService/GetFakePushMessages", in, out, opts...) if err != nil { return nil, err } @@ -361,7 +338,7 @@ func _BridgeService_CheckAPI_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_CheckAPI_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/CheckAPI", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).CheckAPI(ctx, req.(*CheckAPIRequest)) @@ -379,7 +356,7 @@ func _BridgeService_GetBridges_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetBridges_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetBridges", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetBridges(ctx, req.(*GetBridgesRequest)) @@ -397,7 +374,7 @@ func _BridgeService_GetProof_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetProof_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetProof", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetProof(ctx, req.(*GetProofRequest)) @@ -415,7 +392,7 @@ func _BridgeService_GetBridge_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetBridge_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetBridge", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetBridge(ctx, req.(*GetBridgeRequest)) @@ -433,7 +410,7 @@ func _BridgeService_GetClaims_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetClaims_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetClaims", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetClaims(ctx, req.(*GetClaimsRequest)) @@ -451,7 +428,7 @@ func _BridgeService_GetTokenWrapped_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetTokenWrapped_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetTokenWrapped", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetTokenWrapped(ctx, req.(*GetTokenWrappedRequest)) @@ -469,7 +446,7 @@ func _BridgeService_GetCoinPrice_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetCoinPrice_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetCoinPrice", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetCoinPrice(ctx, req.(*GetCoinPriceRequest)) @@ -487,7 +464,7 @@ func _BridgeService_GetMainCoins_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetMainCoins_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetMainCoins", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetMainCoins(ctx, req.(*GetMainCoinsRequest)) @@ -505,7 +482,7 @@ func _BridgeService_GetPendingTransactions_Handler(srv interface{}, ctx context. } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetPendingTransactions_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetPendingTransactions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetPendingTransactions(ctx, req.(*GetPendingTransactionsRequest)) @@ -523,7 +500,7 @@ func _BridgeService_GetAllTransactions_Handler(srv interface{}, ctx context.Cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetAllTransactions_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetAllTransactions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetAllTransactions(ctx, req.(*GetAllTransactionsRequest)) @@ -541,7 +518,7 @@ func _BridgeService_GetSmtProof_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetSmtProof_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetSmtProof", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetSmtProof(ctx, req.(*GetSmtProofRequest)) @@ -559,7 +536,7 @@ func _BridgeService_GetNotReadyTransactions_Handler(srv interface{}, ctx context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetNotReadyTransactions_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetNotReadyTransactions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetNotReadyTransactions(ctx, req.(*GetNotReadyTransactionsRequest)) @@ -577,7 +554,7 @@ func _BridgeService_GetMonitoredTxsByStatus_Handler(srv interface{}, ctx context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetMonitoredTxsByStatus_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetMonitoredTxsByStatus", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetMonitoredTxsByStatus(ctx, req.(*GetMonitoredTxsByStatusRequest)) @@ -595,7 +572,7 @@ func _BridgeService_GetEstimateTime_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetEstimateTime_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetEstimateTime", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetEstimateTime(ctx, req.(*GetEstimateTimeRequest)) @@ -613,7 +590,7 @@ func _BridgeService_ManualClaim_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_ManualClaim_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/ManualClaim", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).ManualClaim(ctx, req.(*ManualClaimRequest)) @@ -631,7 +608,7 @@ func _BridgeService_GetReadyPendingTransactions_Handler(srv interface{}, ctx con } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetReadyPendingTransactions_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetReadyPendingTransactions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetReadyPendingTransactions(ctx, req.(*GetReadyPendingTransactionsRequest)) @@ -649,7 +626,7 @@ func _BridgeService_GetFakePushMessages_Handler(srv interface{}, ctx context.Con } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: BridgeService_GetFakePushMessages_FullMethodName, + FullMethod: "/bridge.v1.BridgeService/GetFakePushMessages", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServiceServer).GetFakePushMessages(ctx, req.(*GetFakePushMessagesRequest)) diff --git a/claimtxman/claimtxman.go b/claimtxman/claimtxman.go index 2c34e66e..1db3a67f 100644 --- a/claimtxman/claimtxman.go +++ b/claimtxman/claimtxman.go @@ -10,6 +10,7 @@ import ( "time" ctmtypes "github.com/0xPolygonHermez/zkevm-bridge-service/claimtxman/types" + "github.com/0xPolygonHermez/zkevm-bridge-service/config/apolloconfig" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/0xPolygonHermez/zkevm-bridge-service/messagepush" @@ -57,6 +58,7 @@ type ClaimTxManager struct { // Producer to push the transaction status change to front end messagePushProducer messagepush.KafkaProducer redisStorage redisstorage.RedisStorage + monitorTxsLimit apolloconfig.Entry[uint] } // NewClaimTxManager creates a new claim transaction manager. @@ -89,6 +91,7 @@ func NewClaimTxManager(cfg Config, chExitRootEvent chan *etherman.GlobalExitRoot nonceCache: cache, messagePushProducer: producer, redisStorage: redisStorage, + monitorTxsLimit: apolloconfig.NewIntEntry("claimtxman.monitorTxsLimit", uint(128)), //nolint:gomnd }, err } diff --git a/claimtxman/claimtxman_xlayer.go b/claimtxman/claimtxman_xlayer.go index 7a29cb73..9fe20bbb 100644 --- a/claimtxman/claimtxman_xlayer.go +++ b/claimtxman/claimtxman_xlayer.go @@ -10,6 +10,7 @@ import ( ctmtypes "github.com/0xPolygonHermez/zkevm-bridge-service/claimtxman/types" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/metrics" "github.com/0xPolygonHermez/zkevm-bridge-service/pushtask" "github.com/0xPolygonHermez/zkevm-bridge-service/utils" "github.com/0xPolygonHermez/zkevm-bridge-service/utils/gerror" @@ -118,7 +119,7 @@ func (tm *ClaimTxManager) processDepositStatusL2(ger *etherman.GlobalExitRoot) e return err } log.Infof("Rollup exitroot %v is updated", ger.ExitRoots[1]) - deposits, err := tm.storage.UpdateL2DepositsStatusXLayer(tm.ctx, ger.ExitRoots[1][:], ger.Time, tm.rollupID, tm.l2NetworkID, dbTx) + deposits, err := tm.storage.UpdateL2DepositsStatusXLayer(tm.ctx, ger.ExitRoots[1][:], tm.rollupID, tm.l2NetworkID, dbTx) if err != nil { log.Errorf("error getting and updating L2DepositsStatus. Error: %v", err) rollbackErr := tm.storage.Rollback(tm.ctx, dbTx) @@ -142,6 +143,8 @@ func (tm *ClaimTxManager) processDepositStatusL2(ger *etherman.GlobalExitRoot) e for _, deposit := range deposits { // Notify FE that tx is pending auto claim go tm.pushTransactionUpdate(deposit, uint32(pb.TransactionStatus_TX_PENDING_USER_CLAIM)) + // Record order waiting time metric + metrics.RecordOrderWaitTime(uint32(deposit.NetworkID), uint32(deposit.DestinationNetwork), time.Since(deposit.Time)) } return nil } @@ -168,7 +171,7 @@ func (tm *ClaimTxManager) processDepositStatusL1(newGer *etherman.GlobalExitRoot if err != nil { return err } - err = tm.storage.UpdateL1DepositStatus(tm.ctx, deposit.DepositCount, newGer.Time, dbTx) + err = tm.storage.UpdateL1DepositStatus(tm.ctx, deposit.DepositCount, dbTx) if err != nil { log.Errorf("error update deposit %d status. Error: %v", deposit.DepositCount, err) tm.rollbackStore(dbTx) @@ -222,7 +225,7 @@ func (tm *ClaimTxManager) processDepositStatusL1(newGer *etherman.GlobalExitRoot mtProof[i] = proof[i] mtRollupProof[i] = rollupProof[i] } - tx, err := tm.l2Node.BuildSendClaim(tm.ctx, deposit, mtProof, mtRollupProof, + tx, err := tm.l2Node.BuildSendClaimXLayer(tm.ctx, deposit, mtProof, mtRollupProof, ðerman.GlobalExitRoot{ ExitRoots: []common.Hash{ ger.ExitRoots[0], @@ -230,7 +233,7 @@ func (tm *ClaimTxManager) processDepositStatusL1(newGer *etherman.GlobalExitRoot }}, 1, 1, 1, tm.rollupID, tm.auth) if err != nil { - log.Errorf("error BuildSendClaim tx for deposit %d. Error: %v", deposit.DepositCount, err) + log.Errorf("error BuildSendClaimXLayer tx for deposit %d. Error: %v", deposit.DepositCount, err) tm.rollbackStore(dbTx) return err } @@ -266,6 +269,8 @@ func (tm *ClaimTxManager) processDepositStatusL1(newGer *etherman.GlobalExitRoot // Notify FE that tx is pending auto claim go tm.pushTransactionUpdate(deposit, uint32(pb.TransactionStatus_TX_PENDING_AUTO_CLAIM)) + // Record order waiting time metric + metrics.RecordOrderWaitTime(uint32(deposit.NetworkID), uint32(deposit.DestinationNetwork), time.Since(deposit.Time)) } return nil } @@ -280,7 +285,7 @@ func (tm *ClaimTxManager) rollbackStore(dbTx pgx.Tx) { func (tm *ClaimTxManager) processDepositStatusXLayer(ger *etherman.GlobalExitRoot, dbTx pgx.Tx) error { if ger.BlockID != 0 { // L2 exit root is updated log.Infof("Rollup exitroot %v is updated", ger.ExitRoots[1]) - deposits, err := tm.storage.UpdateL2DepositsStatusXLayer(tm.ctx, ger.ExitRoots[1][:], ger.Time, tm.rollupID, tm.l2NetworkID, dbTx) + deposits, err := tm.storage.UpdateL2DepositsStatusXLayer(tm.ctx, ger.ExitRoots[1][:], tm.rollupID, tm.l2NetworkID, dbTx) if err != nil { log.Errorf("error getting and updating L2DepositsStatus. Error: %v", err) return err @@ -290,10 +295,12 @@ func (tm *ClaimTxManager) processDepositStatusXLayer(ger *etherman.GlobalExitRoo for _, deposit := range deposits { // Notify FE that tx is pending auto claim go tm.pushTransactionUpdate(deposit, uint32(pb.TransactionStatus_TX_PENDING_USER_CLAIM)) + // Record order waiting time metric + metrics.RecordOrderWaitTime(uint32(deposit.NetworkID), uint32(deposit.DestinationNetwork), time.Since(deposit.Time)) } } else { // L1 exit root is updated in the trusted state log.Infof("Mainnet exitroot %v is updated", ger.ExitRoots[0]) - deposits, err := tm.storage.UpdateL1DepositsStatusXLayer(tm.ctx, ger.ExitRoots[0][:], ger.Time, dbTx) + deposits, err := tm.storage.UpdateL1DepositsStatusXLayer(tm.ctx, ger.ExitRoots[0][:], dbTx) if err != nil { log.Errorf("error getting and updating L1DepositsStatus. Error: %v", err) return err @@ -329,7 +336,7 @@ func (tm *ClaimTxManager) processDepositStatusXLayer(ger *etherman.GlobalExitRoo mtProof[i] = proof[i] mtRollupProof[i] = rollupProof[i] } - tx, err := tm.l2Node.BuildSendClaim(tm.ctx, deposit, mtProof, mtRollupProof, + tx, err := tm.l2Node.BuildSendClaimXLayer(tm.ctx, deposit, mtProof, mtRollupProof, ðerman.GlobalExitRoot{ ExitRoots: []common.Hash{ ger.ExitRoots[0], @@ -337,7 +344,7 @@ func (tm *ClaimTxManager) processDepositStatusXLayer(ger *etherman.GlobalExitRoo }}, 1, 1, 1, tm.rollupID, tm.auth) if err != nil { - log.Errorf("error BuildSendClaim tx for deposit %d. Error: %v", deposit.DepositCount, err) + log.Errorf("error BuildSendClaimXLayer tx for deposit %d. Error: %v", deposit.DepositCount, err) return err } log.Debugf("claimTx for deposit %d build successfully %d", deposit.DepositCount) @@ -359,6 +366,8 @@ func (tm *ClaimTxManager) processDepositStatusXLayer(ger *etherman.GlobalExitRoo // Notify FE that tx is pending auto claim go tm.pushTransactionUpdate(deposit, uint32(pb.TransactionStatus_TX_PENDING_AUTO_CLAIM)) + // Record order waiting time metric + metrics.RecordOrderWaitTime(uint32(deposit.NetworkID), uint32(deposit.DestinationNetwork), time.Since(deposit.Time)) } } return nil @@ -414,7 +423,7 @@ func (tm *ClaimTxManager) monitorTxsXLayer(ctx context.Context) error { mLog.Infof("monitorTxs begin") statusesFilter := []ctmtypes.MonitoredTxStatus{ctmtypes.MonitoredTxStatusCreated} - mTxs, err := tm.storage.GetClaimTxsByStatus(ctx, statusesFilter, dbTx) + mTxs, err := tm.storage.GetClaimTxsByStatusWithLimit(ctx, statusesFilter, tm.monitorTxsLimit.Get(), 0, dbTx) if err != nil { mLog.Errorf("failed to get created monitored txs: %v", err) rollbackErr := tm.storage.Rollback(tm.ctx, dbTx) @@ -425,6 +434,7 @@ func (tm *ClaimTxManager) monitorTxsXLayer(ctx context.Context) error { return fmt.Errorf("failed to get created monitored txs: %v", err) } mLog.Infof("found %v monitored tx to process", len(mTxs)) + metrics.RecordPendingMonitoredTxsCount(len(mTxs)) isResetNonce := false // it will reset the nonce in one cycle for _, mTx := range mTxs { @@ -445,6 +455,8 @@ func (tm *ClaimTxManager) monitorTxsXLayer(ctx context.Context) error { if err != nil { mTxLog.Errorf("failed to update tx status to confirmed: %v", err) } + metrics.RecordMonitoredTxsResult(string(mTx.Status)) + metrics.RecordAutoClaimDuration(time.Since(mTx.CreatedAt)) continue } @@ -500,6 +512,8 @@ func (tm *ClaimTxManager) monitorTxsXLayer(ctx context.Context) error { if err != nil { mTxLog.Errorf("failed to update monitored tx when confirmed: %v", err) } + metrics.RecordMonitoredTxsResult(string(mTx.Status)) + metrics.RecordAutoClaimDuration(time.Since(mTx.CreatedAt)) break } @@ -525,6 +539,7 @@ func (tm *ClaimTxManager) monitorTxsXLayer(ctx context.Context) error { if err != nil { mTxLog.Errorf("failed to update monitored tx when max history size limit reached: %v", err) } + metrics.RecordMonitoredTxsResult(string(mTx.Status)) // Notify FE that tx is pending user claim go func() { @@ -620,6 +635,7 @@ func (tm *ClaimTxManager) monitorTxsXLayer(ctx context.Context) error { mTxLog.Infof("nonce cache cleared for address %v", mTx.From.Hex()) } } + tm.decreaseNonceCache(mTx.From) mTx.RemoveHistory(signedTx) // we should rebuild the monitored tx to fix the nonce err := tm.ReviewMonitoredTxXLayer(ctx, &mTx) @@ -669,13 +685,29 @@ func (tm *ClaimTxManager) setTxNonce(mTx *ctmtypes.MonitoredTx) error { return nil } +// decreaseNonceCache decreases the nonce value stored in the local cache +func (tm *ClaimTxManager) decreaseNonceCache(from common.Address) { + nonce, err := tm.l2Node.NonceAt(tm.ctx, from, nil) + if err != nil { + return + } + if tempNonce, found := tm.nonceCache.Get(from.Hex()); found { + tempNonce-- + if tempNonce >= nonce { + tm.nonceCache.Add(from.Hex(), tempNonce) + } else { + tm.nonceCache.Remove(from.Hex()) + } + } +} + // Push message to FE to notify about tx status change func (tm *ClaimTxManager) pushTransactionUpdate(deposit *etherman.Deposit, status uint32) { if tm.messagePushProducer == nil { log.Errorf("kafka push producer is nil, so can't push tx status change msg!") return } - if deposit.LeafType != uint8(utils.LeafTypeAsset) { + if deposit.LeafType != uint8(utils.LeafTypeAsset) && !tm.isDepositMessageAllowed(deposit) { log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) return } diff --git a/claimtxman/interfaces.go b/claimtxman/interfaces.go index 5379d195..0963bda2 100644 --- a/claimtxman/interfaces.go +++ b/claimtxman/interfaces.go @@ -2,7 +2,6 @@ package claimtxman import ( "context" - "time" "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl" "github.com/0xPolygonHermez/zkevm-bridge-service/claimtxman/types" @@ -23,12 +22,13 @@ type storageInterface interface { Commit(ctx context.Context, dbTx pgx.Tx) error // XLayer - UpdateL1DepositsStatusXLayer(ctx context.Context, exitRoot []byte, eventTime time.Time, dbTx pgx.Tx) ([]*etherman.Deposit, error) - UpdateL2DepositsStatusXLayer(ctx context.Context, exitRoot []byte, eventTime time.Time, rollupID, networkID uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) + UpdateL1DepositsStatusXLayer(ctx context.Context, exitRoot []byte, dbTx pgx.Tx) ([]*etherman.Deposit, error) + UpdateL2DepositsStatusXLayer(ctx context.Context, exitRoot []byte, rollupID, networkID uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) GetL1Deposits(ctx context.Context, exitRoot []byte, dbTx pgx.Tx) ([]*etherman.Deposit, error) - UpdateL1DepositStatus(ctx context.Context, depositCount uint, eventTime time.Time, dbTx pgx.Tx) error + UpdateL1DepositStatus(ctx context.Context, depositCount uint, dbTx pgx.Tx) error GetDeposit(ctx context.Context, depositCounterUser uint, networkID uint, dbTx pgx.Tx) (*etherman.Deposit, error) GetClaim(ctx context.Context, depositCount, networkID uint, dbTx pgx.Tx) (*etherman.Claim, error) + GetClaimTxsByStatusWithLimit(ctx context.Context, statuses []types.MonitoredTxStatus, limit, offset uint, dbTx pgx.Tx) ([]types.MonitoredTx, error) } type bridgeServiceInterface interface { diff --git a/cmd/run_xlayer.go b/cmd/run_xlayer.go index e2d3a616..3afb0b48 100644 --- a/cmd/run_xlayer.go +++ b/cmd/run_xlayer.go @@ -15,10 +15,13 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/localcache" "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/0xPolygonHermez/zkevm-bridge-service/messagepush" + "github.com/0xPolygonHermez/zkevm-bridge-service/metrics" "github.com/0xPolygonHermez/zkevm-bridge-service/pushtask" "github.com/0xPolygonHermez/zkevm-bridge-service/redisstorage" "github.com/0xPolygonHermez/zkevm-bridge-service/sentinel" "github.com/0xPolygonHermez/zkevm-bridge-service/server" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/iprestriction" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/tokenlogoinfo" "github.com/0xPolygonHermez/zkevm-bridge-service/utils" "github.com/0xPolygonHermez/zkevm-bridge-service/utils/gerror" "github.com/0xPolygonHermez/zkevm-node/jsonrpc/client" @@ -87,6 +90,8 @@ func startServer(ctx *cli.Context, opts ...runOptionFunc) error { return err } + utils.InitUSDCLxLyMapping(c.BusinessConfig.USDCContractAddresses, c.BusinessConfig.USDCTokenAddresses) + l1ChainId := c.Etherman.L1ChainId l2ChainIds := c.Etherman.L2ChainIds var chainIDs = []uint{l1ChainId} @@ -164,7 +169,7 @@ func startServer(ctx *cli.Context, opts ...runOptionFunc) error { return err } - mainCoinsCache, err := localcache.NewMainCoinsCache(apiStorage) + err = localcache.InitDefaultCache(apiStorage) if err != nil { log.Error(err) return err @@ -192,12 +197,17 @@ func startServer(ctx *cli.Context, opts ...runOptionFunc) error { }() } + // Start metrics + if c.Metrics.Enabled { + go metrics.StartMetricsHttpServer(c.Metrics) + } + // Initialize chainId manager utils.InitChainIdManager(networkIDs, chainIDs) rollupID := l1Etherman.GetRollupID() bridgeService := server.NewBridgeService(c.BridgeServer, c.BridgeController.Height, networkIDs, l2NodeClients, l2Auths, apiStorage, rollupID). - WithRedisStorage(redisStorage).WithMainCoinsCache(mainCoinsCache).WithMessagePushProducer(messagePushProducer) + WithRedisStorage(redisStorage).WithMainCoinsCache(localcache.GetDefaultCache()).WithMessagePushProducer(messagePushProducer) // Initialize inner chain id conf utils.InnitOkInnerChainIdMapper(c.BusinessConfig) @@ -214,6 +224,8 @@ func startServer(ctx *cli.Context, opts ...runOptionFunc) error { log.Infof("init sentinel error[%v]; ignored and proceed with no sentinel config", err) } server.RegisterNacos(c.NacosConfig) + iprestriction.InitClient(c.IPRestriction) + tokenlogoinfo.InitClient(c.TokenLogoServiceConfig) err = server.RunServer(c.BridgeServer, bridgeService) if err != nil { @@ -287,21 +299,26 @@ func startServer(ctx *cli.Context, opts ...runOptionFunc) error { }() } - // Start the coin middleware kafka consumer - log.Debugf("start initializing kafka consumer...") - coinKafkaConsumer, err := coinmiddleware.NewKafkaConsumer(c.CoinKafkaConsumer, redisStorage) - if err != nil { - log.Error(err) - return err - } - log.Debugf("finish initializing kafka consumer") - go coinKafkaConsumer.Start(ctx.Context) - defer func() { - err := coinKafkaConsumer.Close() + // init token logo client + tokenlogoinfo.InitClient(c.TokenLogoServiceConfig) + + if len(c.CoinKafkaConsumer.Brokers) > 0 { + // Start the coin middleware kafka consumer + log.Debugf("start initializing kafka consumer...") + coinKafkaConsumer, err := coinmiddleware.NewKafkaConsumer(c.CoinKafkaConsumer, redisStorage) if err != nil { - log.Errorf("close kafka consumer error: %v", err) + log.Error(err) + return err } - }() + log.Debugf("finish initializing kafka consumer") + go coinKafkaConsumer.Start(ctx.Context) + defer func() { + err := coinKafkaConsumer.Close() + if err != nil { + log.Errorf("close kafka consumer error: %v", err) + } + }() + } } // Wait for an in interrupt. diff --git a/config/businessconfig/config.go b/config/businessconfig/config.go index 85b24f96..185ca079 100644 --- a/config/businessconfig/config.go +++ b/config/businessconfig/config.go @@ -1,6 +1,13 @@ package businessconfig +import ( + "github.com/ethereum/go-ethereum/common" +) + type Config struct { StandardChainIds []uint64 `mapstructure:"StandardChainIds"` InnerChainIds []uint64 `mapstructure:"InnerChainIds"` + + USDCContractAddresses []common.Address `mapstructure:"USDCContractAddresses"` + USDCTokenAddresses []common.Address `mapstructure:"USDCTokenAddresses"` } diff --git a/config/config.debug.toml b/config/config.debug.toml index 33f46ec4..cc6e9df2 100644 --- a/config/config.debug.toml +++ b/config/config.debug.toml @@ -68,7 +68,7 @@ BridgeVersion = "v1" MockPrice = true [CoinKafkaConsumer] -Brokers = ["localhost:9092"] +Brokers = [] Topics = ["explorer_chainAddressPrice_push"] ConsumerGroupID = "xlayer-bridge-service" InitialOffset = -1 @@ -96,3 +96,8 @@ ExternalListenAddr = "127.0.0.1:26659" [BusinessConfig] StandardChainIds = [195] InnerChainIds = [19500] + +[Metrics] +Enabled = true +Port = "9091" + diff --git a/config/config.go b/config/config.go index 5b3597a5..a3023d19 100644 --- a/config/config.go +++ b/config/config.go @@ -15,8 +15,11 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/0xPolygonHermez/zkevm-bridge-service/messagepush" + "github.com/0xPolygonHermez/zkevm-bridge-service/metrics" "github.com/0xPolygonHermez/zkevm-bridge-service/nacos" "github.com/0xPolygonHermez/zkevm-bridge-service/server" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/iprestriction" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/tokenlogoinfo" "github.com/0xPolygonHermez/zkevm-bridge-service/synchronizer" "github.com/mitchellh/mapstructure" "github.com/spf13/viper" @@ -24,19 +27,22 @@ import ( // Config struct type Config struct { - Log log.Config - Apollo apolloconfig.Config - SyncDB db.Config `apollo:"SyncDB"` - ClaimTxManager claimtxman.Config `apollo:"ClaimTxManager"` - Etherman etherman.Config `apollo:"Etherman"` - Synchronizer synchronizer.Config `apollo:"Synchronizer"` - BridgeController bridgectrl.Config `apollo:"BridgeController"` - BridgeServer server.Config `apollo:"BridgeServer"` - CoinKafkaConsumer coinmiddleware.Config `apollo:"CoinKafkaConsumer"` - MessagePushProducer messagepush.Config `apollo:"MessagePushProducer"` - NetworkConfig `apollo:"NetworkConfig"` - NacosConfig nacos.Config - BusinessConfig businessconfig.Config `apollo:"BusinessConfig"` + Log log.Config + Apollo apolloconfig.Config + SyncDB db.Config `apollo:"SyncDB"` + ClaimTxManager claimtxman.Config `apollo:"ClaimTxManager"` + Etherman etherman.Config `apollo:"Etherman"` + Synchronizer synchronizer.Config `apollo:"Synchronizer"` + BridgeController bridgectrl.Config `apollo:"BridgeController"` + BridgeServer server.Config `apollo:"BridgeServer"` + CoinKafkaConsumer coinmiddleware.Config `apollo:"CoinKafkaConsumer"` + MessagePushProducer messagepush.Config `apollo:"MessagePushProducer"` + NetworkConfig `apollo:"NetworkConfig"` + NacosConfig nacos.Config + BusinessConfig businessconfig.Config `apollo:"BusinessConfig"` + Metrics metrics.Config `apollo:"Metrics"` + IPRestriction iprestriction.Config `apollo:"IPRestriction"` + TokenLogoServiceConfig tokenlogoinfo.Config `apollo:"TokenLogoServiceConfig"` } // Load loads the configuration diff --git a/config/config.local.toml b/config/config.local.toml index 94556a20..ae484531 100644 --- a/config/config.local.toml +++ b/config/config.local.toml @@ -69,7 +69,7 @@ SentinelConfigFilePath = "/app/sentinel_config.json" MockPrice = true [CoinKafkaConsumer] -Brokers = ["xlayer-bridge-coin-kafka:9092"] +Brokers = [] Topics = ["explorer_chainAddressPrice_push"] ConsumerGroupID = "xlayer-bridge-service" InitialOffset = -1 @@ -97,3 +97,7 @@ ExternalListenAddr = "127.0.0.1:26659" [BusinessConfig] StandardChainIds = [195] InnerChainIds = [19500] + +[Metrics] +Enabled = true +Port = "9091" diff --git a/db/pgstorage/migrations/1003.sql b/db/pgstorage/migrations/1003.sql new file mode 100644 index 00000000..faf3ee2d --- /dev/null +++ b/db/pgstorage/migrations/1003.sql @@ -0,0 +1,7 @@ +-- +migrate Down + +ALTER TABLE sync.deposit DROP COLUMN IF EXISTS dest_contract_addr; + +-- +migrate Up + +ALTER TABLE sync.deposit ADD COLUMN IF NOT EXISTS dest_contract_addr BYTEA NOT NULL DEFAULT '\x0000000000000000000000000000000000000000'; diff --git a/db/pgstorage/pgstorage.go b/db/pgstorage/pgstorage.go index a70bdf43..9fe66863 100644 --- a/db/pgstorage/pgstorage.go +++ b/db/pgstorage/pgstorage.go @@ -521,7 +521,7 @@ func (p *PostgresStorage) GetClaims(ctx context.Context, destAddr string, limit // GetDeposits gets the deposit list which be smaller than depositCount. func (p *PostgresStorage) GetDeposits(ctx context.Context, destAddr string, limit uint, offset uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { const getDepositsSQL = ` - SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id WHERE dest_addr = $1 AND (d.network_id = $4 OR dest_net = $4) ORDER BY d.block_id DESC, d.deposit_cnt DESC LIMIT $2 OFFSET $3` diff --git a/db/pgstorage/pgstorage_xlayer.go b/db/pgstorage/pgstorage_xlayer.go index e85e8975..f9ac154c 100644 --- a/db/pgstorage/pgstorage_xlayer.go +++ b/db/pgstorage/pgstorage_xlayer.go @@ -17,39 +17,27 @@ import ( "github.com/pkg/errors" ) -// GetDepositsWithLeafType gets the deposit list which be smaller than depositCount. -func (p *PostgresStorage) GetDepositsWithLeafType(ctx context.Context, destAddr string, limit uint, offset uint, leafType uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { +// AddDeposit adds new deposit to the storage. +func (p *PostgresStorage) AddDepositXLayer(ctx context.Context, deposit *etherman.Deposit, dbTx pgx.Tx) (uint64, error) { + const addDepositSQL = "INSERT INTO sync.deposit (leaf_type, network_id, orig_net, orig_addr, amount, dest_net, dest_addr, block_id, deposit_cnt, tx_hash, metadata, dest_contract_addr) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING id" + e := p.getExecQuerier(dbTx) + var depositID uint64 + err := e.QueryRow(ctx, addDepositSQL, deposit.LeafType, deposit.NetworkID, deposit.OriginalNetwork, deposit.OriginalAddress, deposit.Amount.String(), deposit.DestinationNetwork, deposit.DestinationAddress, deposit.BlockID, deposit.DepositCount, deposit.TxHash, deposit.Metadata, deposit.DestContractAddress).Scan(&depositID) + return depositID, err +} + +// GetDepositsXLayer gets the deposit list which be smaller than depositCount. +func (p *PostgresStorage) GetDepositsXLayer(ctx context.Context, destAddr string, limit uint, offset uint, messageAllowlist []common.Address, dbTx pgx.Tx) ([]*etherman.Deposit, error) { const getDepositsSQL = ` - SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id - WHERE dest_addr = $1 AND leaf_type = $4 AND (d.network_id = $5 OR dest_net = $5) + WHERE dest_addr = $1 AND (leaf_type = 0 OR (leaf_type = 1 AND orig_addr = ANY($4))) AND (d.network_id = $5 OR dest_net = $5) ORDER BY d.block_id DESC, d.deposit_cnt DESC LIMIT $2 OFFSET $3` - rows, err := p.getExecQuerier(dbTx).Query(ctx, getDepositsSQL, common.FromHex(destAddr), limit, offset, leafType, utils.GetRollupNetworkId()) - return p.convertDepositBase(rows, err) -} - -func (p *PostgresStorage) convertDepositBase(rows pgx.Rows, err error) ([]*etherman.Deposit, error) { - if err != nil { - return nil, err - } - - deposits := make([]*etherman.Deposit, 0, len(rows.RawValues())) - - for rows.Next() { - var ( - deposit etherman.Deposit - amount string - ) - err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time) - if err != nil { - return nil, err - } - deposit.Amount, _ = new(big.Int).SetString(amount, 10) //nolint:gomnd - deposits = append(deposits, &deposit) + allowListBytes := make([][]byte, 0) + for _, addr := range messageAllowlist { + allowListBytes = append(allowListBytes, addr.Bytes()) } - - return deposits, nil + return p.getDepositList(ctx, getDepositsSQL, dbTx, common.FromHex(destAddr), limit, offset, pq.Array(allowListBytes), utils.GetRollupNetworkId()) } // GetDepositByHash returns a deposit from a specific account and tx hash @@ -59,12 +47,12 @@ func (p *PostgresStorage) GetDepositByHash(ctx context.Context, destAddr string, amount string ) const getDepositSQL = ` - SELECT leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim + SELECT leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id WHERE d.dest_addr = $1 AND d.network_id = $2 AND d.tx_hash = $3` err := p.getExecQuerier(dbTx).QueryRow(ctx, getDepositSQL, common.HexToAddress(destAddr), networkID, common.HexToHash(txHash)).Scan( &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim) + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.DestContractAddress) if errors.Is(err, pgx.ErrNoRows) { return nil, gerror.ErrStorageNotFound } @@ -74,14 +62,18 @@ func (p *PostgresStorage) GetDepositByHash(ctx context.Context, destAddr string, } // GetPendingTransactions gets all the deposit transactions of a user that have not been claimed -func (p *PostgresStorage) GetPendingTransactions(ctx context.Context, destAddr string, limit uint, offset uint, leafType uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { - const getDepositsSQL = `SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at +func (p *PostgresStorage) GetPendingTransactions(ctx context.Context, destAddr string, limit uint, offset uint, messageAllowlist []common.Address, dbTx pgx.Tx) ([]*etherman.Deposit, error) { + const getDepositsSQL = `SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id - WHERE dest_addr = $1 AND leaf_type = $4 AND (d.network_id = $5 OR dest_net = $5) AND NOT EXISTS + WHERE dest_addr = $1 AND (leaf_type = 0 OR (leaf_type = 1 AND orig_addr = ANY($4))) AND (d.network_id = $5 OR dest_net = $5) AND NOT EXISTS (SELECT 1 FROM sync.claim as c WHERE c.index = d.deposit_cnt AND c.network_id = d.dest_net) ORDER BY d.block_id DESC, d.deposit_cnt DESC LIMIT $2 OFFSET $3` - return p.getDepositList(ctx, getDepositsSQL, dbTx, common.FromHex(destAddr), limit, offset, leafType, utils.GetRollupNetworkId()) + allowListBytes := make([][]byte, 0) + for _, addr := range messageAllowlist { + allowListBytes = append(allowListBytes, addr.Bytes()) + } + return p.getDepositList(ctx, getDepositsSQL, dbTx, common.FromHex(destAddr), limit, offset, pq.Array(allowListBytes), utils.GetRollupNetworkId()) } // GetNotReadyTransactions returns all the deposit transactions with ready_for_claim = false @@ -94,14 +86,14 @@ func (p *PostgresStorage) GetNotReadyTransactions(ctx context.Context, limit uin return p.getDepositList(ctx, getDepositsSQL, dbTx, limit, offset, utils.GetRollupNetworkId()) } -func (p *PostgresStorage) GetReadyPendingTransactions(ctx context.Context, networkID uint, leafType uint, limit uint, offset uint, minReadyTime time.Time, dbTx pgx.Tx) ([]*etherman.Deposit, error) { - const getDepositsSQL = `SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at +func (p *PostgresStorage) GetReadyPendingTransactions(ctx context.Context, networkID uint, limit uint, offset uint, minReadyTime time.Time, dbTx pgx.Tx) ([]*etherman.Deposit, error) { + const getDepositsSQL = `SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id - WHERE d.network_id = $1 AND ready_for_claim = true AND leaf_type = $4 AND ready_time >= $5 AND (d.network_id = $6 OR dest_net = $6) AND NOT EXISTS + WHERE d.network_id = $1 AND ready_for_claim = true AND ready_time >= $4 AND (d.network_id = $5 OR dest_net = $5) AND NOT EXISTS (SELECT 1 FROM sync.claim as c WHERE c.index = d.deposit_cnt AND c.network_id = d.dest_net) ORDER BY d.block_id DESC, d.deposit_cnt DESC LIMIT $2 OFFSET $3` - return p.getDepositList(ctx, getDepositsSQL, dbTx, networkID, limit, offset, leafType, minReadyTime, utils.GetRollupNetworkId()) + return p.getDepositList(ctx, getDepositsSQL, dbTx, networkID, limit, offset, minReadyTime, utils.GetRollupNetworkId()) } func (p *PostgresStorage) getDepositList(ctx context.Context, sql string, dbTx pgx.Tx, args ...interface{}) ([]*etherman.Deposit, error) { @@ -118,7 +110,7 @@ func (p *PostgresStorage) getDepositList(ctx context.Context, sql string, dbTx p amount string ) err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time) + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time, &deposit.DestContractAddress) if err != nil { return nil, err } @@ -130,7 +122,7 @@ func (p *PostgresStorage) getDepositList(ctx context.Context, sql string, dbTx p } func (p *PostgresStorage) GetNotReadyTransactionsWithBlockRange(ctx context.Context, networkID uint, minBlockNum, maxBlockNum uint64, limit, offset uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { - const getDepositsSQL = `SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + const getDepositsSQL = `SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id WHERE b.network_id = $1 AND ready_for_claim = false AND b.block_num >= $2 AND b.block_num <= $3 ORDER BY d.block_id DESC, d.deposit_cnt DESC LIMIT $4 OFFSET $5` @@ -148,7 +140,7 @@ func (p *PostgresStorage) GetNotReadyTransactionsWithBlockRange(ctx context.Cont amount string ) err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time) + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time, &deposit.DestContractAddress) if err != nil { return nil, err } @@ -161,7 +153,7 @@ func (p *PostgresStorage) GetNotReadyTransactionsWithBlockRange(ctx context.Cont // GetL1Deposits get the L1 deposits remain to be ready_for_claim func (p *PostgresStorage) GetL1Deposits(ctx context.Context, exitRoot []byte, dbTx pgx.Tx) ([]*etherman.Deposit, error) { - const updateDepositsStatusSQL = `Select d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + const updateDepositsStatusSQL = `Select d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id WHERE deposit_cnt <= (SELECT d.deposit_cnt FROM mt.root as r INNER JOIN sync.deposit as d ON d.id = r.deposit_id WHERE r.root = $1 AND r.network = 0) AND d.network_id = 0 AND ready_for_claim = false` @@ -177,7 +169,7 @@ func (p *PostgresStorage) GetL1Deposits(ctx context.Context, exitRoot []byte, db amount string ) err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time) + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time, &deposit.DestContractAddress) if err != nil { return nil, err } @@ -187,21 +179,23 @@ func (p *PostgresStorage) GetL1Deposits(ctx context.Context, exitRoot []byte, db return deposits, nil } -func (p *PostgresStorage) UpdateL1DepositStatus(ctx context.Context, depositCount uint, eventTime time.Time, dbTx pgx.Tx) error { +func (p *PostgresStorage) UpdateL1DepositStatus(ctx context.Context, depositCount uint, dbTx pgx.Tx) error { const updateDepositStatusSQL = `UPDATE sync.deposit SET ready_for_claim = true, ready_time = $1 WHERE deposit_cnt = $2 And network_id = 0` - _, err := p.getExecQuerier(dbTx).Exec(ctx, updateDepositStatusSQL, eventTime, depositCount) + _, err := p.getExecQuerier(dbTx).Exec(ctx, updateDepositStatusSQL, time.Now(), depositCount) return err } -// UpdateL2DepositsStatus updates the ready_for_claim status of L2 deposits. and return deposit list -func (p *PostgresStorage) UpdateL2DepositsStatusXLayer(ctx context.Context, exitRoot []byte, eventTime time.Time, rollupID, networkID uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { - const updateDepositsStatusSQL = `UPDATE sync.deposit SET ready_for_claim = true, ready_time = $4 +// UpdateL2DepositsStatusXLayer updates the ready_for_claim status of L2 deposits. and return deposit list +func (p *PostgresStorage) UpdateL2DepositsStatusXLayer(ctx context.Context, exitRoot []byte, rollupID, networkID uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { + const updateDepositsStatusSQL = `WITH d AS (UPDATE sync.deposit SET ready_for_claim = true, ready_time = $4 WHERE deposit_cnt <= (SELECT d.deposit_cnt FROM mt.root as r INNER JOIN sync.deposit as d ON d.id = r.deposit_id WHERE r.root = (select leaf from mt.rollup_exit where root = $1 and rollup_id = $2) AND r.network = $3) AND network_id = $3 AND ready_for_claim = false - RETURNING leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, network_id, tx_hash, metadata, ready_for_claim;` - rows, err := p.getExecQuerier(dbTx).Query(ctx, updateDepositsStatusSQL, exitRoot, rollupID, networkID, eventTime) + RETURNING *) + SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + FROM d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id` + rows, err := p.getExecQuerier(dbTx).Query(ctx, updateDepositsStatusSQL, exitRoot, rollupID, networkID, time.Now()) if err != nil { return nil, err } @@ -211,8 +205,8 @@ func (p *PostgresStorage) UpdateL2DepositsStatusXLayer(ctx context.Context, exit deposit etherman.Deposit amount string ) - err = rows.Scan(&deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim) + err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time) if err != nil { return nil, err } @@ -306,7 +300,7 @@ func (p *PostgresStorage) GetAllMainCoins(ctx context.Context, limit uint, offse // GetLatestReadyDeposits returns the latest deposit transactions with ready_for_claim = true func (p *PostgresStorage) GetLatestReadyDeposits(ctx context.Context, networkID uint, limit uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { const getDepositsSQL = ` - SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, ready_time + SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, ready_time, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id WHERE d.network_id = $1 AND ready_for_claim = true AND ready_time IS NOT NULL ORDER BY d.deposit_cnt DESC LIMIT $2` @@ -324,7 +318,7 @@ func (p *PostgresStorage) GetLatestReadyDeposits(ctx context.Context, networkID amount string ) err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time, &deposit.ReadyTime) + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time, &deposit.ReadyTime, &deposit.DestContractAddress) if err != nil { return nil, err } @@ -336,15 +330,15 @@ func (p *PostgresStorage) GetLatestReadyDeposits(ctx context.Context, networkID } // UpdateL1DepositsStatusXLayer updates the ready_for_claim status of L1 deposits. -func (p *PostgresStorage) UpdateL1DepositsStatusXLayer(ctx context.Context, exitRoot []byte, eventTime time.Time, dbTx pgx.Tx) ([]*etherman.Deposit, error) { +func (p *PostgresStorage) UpdateL1DepositsStatusXLayer(ctx context.Context, exitRoot []byte, dbTx pgx.Tx) ([]*etherman.Deposit, error) { const updateDepositsStatusSQL = `WITH d AS (UPDATE sync.deposit SET ready_for_claim = true, ready_time = $1 WHERE deposit_cnt <= (SELECT d.deposit_cnt FROM mt.root as r INNER JOIN sync.deposit as d ON d.id = r.deposit_id WHERE r.root = $2 AND r.network = 0) AND network_id = 0 AND ready_for_claim = false RETURNING *) - SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id` - rows, err := p.getExecQuerier(dbTx).Query(ctx, updateDepositsStatusSQL, eventTime, exitRoot) + rows, err := p.getExecQuerier(dbTx).Query(ctx, updateDepositsStatusSQL, time.Now(), exitRoot) if err != nil { return nil, err } @@ -356,7 +350,7 @@ func (p *PostgresStorage) UpdateL1DepositsStatusXLayer(ctx context.Context, exit amount string ) err = rows.Scan(&deposit.Id, &deposit.LeafType, &deposit.OriginalNetwork, &deposit.OriginalAddress, &amount, &deposit.DestinationNetwork, &deposit.DestinationAddress, - &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time) + &deposit.DepositCount, &deposit.BlockID, &deposit.BlockNumber, &deposit.NetworkID, &deposit.TxHash, &deposit.Metadata, &deposit.ReadyForClaim, &deposit.Time, &deposit.DestContractAddress) if err != nil { return nil, err } @@ -369,7 +363,7 @@ func (p *PostgresStorage) UpdateL1DepositsStatusXLayer(ctx context.Context, exit // GetDepositsForUnitTest gets the deposit list which be smaller than depositCount. func (p *PostgresStorage) GetDepositsForUnitTest(ctx context.Context, destAddr string, limit uint, offset uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) { const getDepositsSQL = ` - SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at + SELECT d.id, leaf_type, orig_net, orig_addr, amount, dest_net, dest_addr, deposit_cnt, block_id, b.block_num, d.network_id, tx_hash, metadata, ready_for_claim, b.received_at, dest_contract_addr FROM sync.deposit as d INNER JOIN sync.block as b ON d.network_id = b.network_id AND d.block_id = b.id WHERE dest_addr = $1 ORDER BY d.block_id DESC, d.deposit_cnt DESC LIMIT $2 OFFSET $3` diff --git a/db/pgstorage/pgstorage_xlayer_test.go b/db/pgstorage/pgstorage_xlayer_test.go new file mode 100644 index 00000000..e6d6be37 --- /dev/null +++ b/db/pgstorage/pgstorage_xlayer_test.go @@ -0,0 +1,48 @@ +package pgstorage + +import ( + "context" + "testing" + + "github.com/0xPolygonHermez/zkevm-bridge-service/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestGetDepositsXLayer(t *testing.T) { + data := `INSERT INTO sync.block + (id, block_num, block_hash, parent_hash, network_id, received_at) + VALUES(1, 1, decode('5C7831','hex'), decode('5C7830','hex'), 0, '1970-01-01 01:00:00.000'); + INSERT INTO sync.block + (id, block_num, block_hash, parent_hash, network_id, received_at) + VALUES(2, 2, decode('5C7832','hex'), decode('5C7831','hex'), 0, '1970-01-01 01:00:00.000'); + + INSERT INTO sync.deposit (leaf_type, network_id, orig_net, orig_addr, amount, dest_net, dest_addr, block_id, deposit_cnt, tx_hash, metadata, dest_contract_addr) + VALUES (1, 0, 0, '\xca3faf8a0e99b136394286569f95f04127cb2087', 0, 1, '\x23335657622dcc27bb1914e51cdc30871d6d04d3', 1, 1, '\xf6ff1541a10bb49be5a38da488690f9fc8a97021e245ec1bc5190fec8a64909a', + '\x00000000000000000000000023335657622dcc27bb1914e51cdc30871d6d04d300000000000000000000000000000000000000000000000000000000000f4240', + '\x74b7f16337b8972027f6196a17a631ac6de26d22'); + INSERT INTO sync.deposit (leaf_type, network_id, orig_net, orig_addr, amount, dest_net, dest_addr, block_id, deposit_cnt, tx_hash, metadata) + VALUES (0, 0, 0, '\x0000000000000000000000000000000000000000', 100000000, 1, '\x23335657622dcc27bb1914e51cdc30871d6d04d3', 1, 2, '\xf6ff1541a10bb49be5a38da488690f9fc8a97021e245ec1bc5190fec8a64909a', + '\x00000000000000000000000023335657622dcc27bb1914e51cdc30871d6d04d300000000000000000000000000000000000000000000000000000000000f4240');` + + dbCfg := NewConfigFromEnv() + ctx := context.Background() + err := InitOrReset(dbCfg) + require.NoError(t, err) + + store, err := NewPostgresStorage(dbCfg) + require.NoError(t, err) + _, err = store.Exec(ctx, data) + require.NoError(t, err) + + utils.InitRollupNetworkId(1) + addr := "0x23335657622dcc27bb1914e51cdc30871d6d04d3" + + deposits, err := store.GetDepositsXLayer(ctx, addr, 25, 0, []common.Address{common.HexToAddress("0xca3faf8a0e99b136394286569f95f04127cb2087"), common.HexToAddress("0x74b7f16337b8972027f6196a17a631ac6de26d22")}, nil) + require.NoError(t, err) + require.Len(t, deposits, 2) + + deposits, err = store.GetPendingTransactions(ctx, addr, 25, 0, []common.Address{common.HexToAddress("0xca3faf8a0e99b136394286569f95f04127cb2087"), common.HexToAddress("0x74b7f16337b8972027f6196a17a631ac6de26d22")}, nil) + require.NoError(t, err) + require.Len(t, deposits, 2) +} diff --git a/docker-compose.yml b/docker-compose.yml index eea1f2e0..cb202e15 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -77,26 +77,26 @@ services: - REDIS_PORT=6379 - REDIS_DATABASES=8 - kafka-zookeeper: - image: wurstmeister/zookeeper - container_name: kafka-zookeeper - ports: - - "2181:2181" - expose: - - 2181 +# kafka-zookeeper: +# image: wurstmeister/zookeeper +# container_name: kafka-zookeeper +# ports: +# - "2181:2181" +# expose: +# - 2181 - xlayer-bridge-coin-kafka: - image: wurstmeister/kafka - container_name: xlayer-bridge-coin-kafka - expose: - - 9092 - environment: - KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://localhost:9123 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT - KAFKA_LISTENERS: INSIDE://0.0.0.0:9092,OUTSIDE://0.0.0.0:9123 - KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE - KAFKA_ZOOKEEPER_CONNECT: kafka-zookeeper:2181 - KAFKA_CREATE_TOPICS: "explorer_chainAddressPrice_push:1:1" +# xlayer-bridge-coin-kafka: +# image: wurstmeister/kafka +# container_name: xlayer-bridge-coin-kafka +# expose: +# - 9092 +# environment: +# KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://localhost:9123 +# KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT +# KAFKA_LISTENERS: INSIDE://0.0.0.0:9092,OUTSIDE://0.0.0.0:9123 +# KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE +# KAFKA_ZOOKEEPER_CONNECT: kafka-zookeeper:2181 +# KAFKA_CREATE_TOPICS: "explorer_chainAddressPrice_push:1:1" xlayer-bridge-service-api: container_name: xlayer-bridge-service-api @@ -104,6 +104,7 @@ services: ports: - 8080:8080 - 9090:9090 + - 9300:9091 environment: - ZKEVM_BRIDGE_DATABASE_USER=test_user - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password @@ -123,6 +124,8 @@ services: xlayer-bridge-service-task: container_name: xlayer-bridge-service-task image: xlayer-bridge-service + ports: + - 9302:9091 environment: - ZKEVM_BRIDGE_DATABASE_USER=test_user - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password @@ -141,6 +144,8 @@ services: xlayer-bridge-service-push: container_name: xlayer-bridge-service-push image: xlayer-bridge-service + ports: + - 9301:9091 environment: - ZKEVM_BRIDGE_DATABASE_USER=test_user - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password @@ -296,6 +301,7 @@ services: ports: - 8080:8080 - 9090:9090 + - 9300:9091 environment: - ZKEVM_BRIDGE_DATABASE_USER=test_user - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password @@ -318,6 +324,7 @@ services: ports: - 8080:8080 - 9090:9090 + - 9300:9091 environment: - ZKEVM_BRIDGE_DATABASE_USER=test_user - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password @@ -337,4 +344,4 @@ services: command: - "/bin/sh" - "-c" - - "/app/xlayer-bridge run --cfg /app/config.toml" \ No newline at end of file + - "/app/xlayer-bridge run --cfg /app/config.toml" diff --git a/etherman/types.go b/etherman/types.go index 696a3725..e4147680 100644 --- a/etherman/types.go +++ b/etherman/types.go @@ -52,9 +52,10 @@ type Deposit struct { ReadyForClaim bool // XLayer - Time time.Time - Id uint64 - ReadyTime time.Time + Time time.Time + Id uint64 + ReadyTime time.Time + DestContractAddress common.Address } // Claim struct diff --git a/go.mod b/go.mod index 53fd7ae1..e7663da7 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/apolloconfig/agollo/v4 v4.0.9 github.com/ethereum/go-ethereum v1.13.2 github.com/gobuffalo/packr/v2 v2.8.3 - github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 github.com/hashicorp/golang-lru/v2 v2.0.7 + github.com/hermeznetwork/tracerr v0.3.2 github.com/iden3/go-iden3-crypto v0.0.15 github.com/jackc/pgconn v1.14.1 github.com/jackc/pgx/v4 v4.18.1 @@ -21,11 +21,13 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/nacos-group/nacos-sdk-go v1.1.4 github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.17.0 github.com/redis/go-redis/v9 v9.1.0 github.com/rubenv/sql-migrate v1.6.1 github.com/spf13/viper v1.17.0 github.com/stretchr/testify v1.8.4 github.com/urfave/cli/v2 v2.26.0 + go.uber.org/zap v1.26.0 golang.org/x/crypto v0.18.0 golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 @@ -41,7 +43,7 @@ require ( github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.6.0 // indirect - github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 // indirect github.com/allegro/bigcache v1.2.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -98,7 +100,6 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 // indirect - github.com/hermeznetwork/tracerr v0.3.2 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/huin/goupnp v1.3.0 // indirect @@ -140,7 +141,6 @@ require ( github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect @@ -173,7 +173,6 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sync v0.6.0 // indirect diff --git a/go.sum b/go.sum index c665e4e7..785d433f 100644 --- a/go.sum +++ b/go.sum @@ -99,8 +99,9 @@ github.com/alibaba/sentinel-golang/pkg/adapters/grpc v0.0.0-20230626085943-08071 github.com/alibaba/sentinel-golang/pkg/adapters/grpc v0.0.0-20230626085943-08071855bc67/go.mod h1:wOJbMtkzLxlDKDB0LnJKXLfGNqd3/GGBk4x2LNWmjRs= github.com/alibaba/sentinel-golang/pkg/datasource/apollo v0.0.0-20230626085943-08071855bc67 h1:6ggvGpGxj/DcWO8Z6zWdtESQ7M0s0XF5K9c51ib2I9A= github.com/alibaba/sentinel-golang/pkg/datasource/apollo v0.0.0-20230626085943-08071855bc67/go.mod h1:tXrCRKugizvHUk/k0W78rovVyPvyB/7VNId6i5HTIik= -github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 h1:ie/8RxBOfKZWcrbYSJi2Z8uX8TcOlSMwPlEJh83OeOw= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= @@ -125,7 +126,6 @@ github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZw github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -472,8 +472,6 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -1071,7 +1069,6 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1086,7 +1083,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1329,7 +1325,6 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1403,7 +1398,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1517,7 +1511,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1622,6 +1615,7 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= diff --git a/localcache/maincoinscache.go b/localcache/maincoinscache.go index 9278652d..a202237d 100644 --- a/localcache/maincoinscache.go +++ b/localcache/maincoinscache.go @@ -7,6 +7,8 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl/pb" "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/utils/gerror" + "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" "github.com/pkg/errors" ) @@ -17,8 +19,13 @@ const ( maxRetries = 5 ) +var ( + defaultCache MainCoinsCache +) + type MainCoinsCache interface { GetMainCoinsByNetwork(ctx context.Context, networkID uint32) ([]*pb.CoinInfo, error) + GetCoinInfoByAddress(ctx context.Context, networkID uint32, address common.Address) (*pb.CoinInfo, error) } type MainCoinsDBStorage interface { @@ -32,6 +39,19 @@ type mainCoinsCacheImpl struct { storage MainCoinsDBStorage } +func InitDefaultCache(storage interface{}) error { + cache, err := NewMainCoinsCache(storage) + if err != nil { + return nil + } + defaultCache = cache + return nil +} + +func GetDefaultCache() MainCoinsCache { + return defaultCache +} + func NewMainCoinsCache(storage interface{}) (MainCoinsCache, error) { if storage == nil { return nil, errors.New("NewMainCoinsCache storage is nil") @@ -106,3 +126,19 @@ func (c *mainCoinsCacheImpl) GetMainCoinsByNetwork(ctx context.Context, networkI return c.data[networkID], nil } + +func (c *mainCoinsCacheImpl) GetCoinInfoByAddress(ctx context.Context, networkID uint32, address common.Address) (*pb.CoinInfo, error) { + coins, err := c.GetMainCoinsByNetwork(ctx, networkID) + if err != nil { + return nil, err + } + + for _, coin := range coins { + coinAddr := common.HexToAddress(coin.Address) + if coinAddr == address { + return coin, nil + } + } + + return nil, gerror.ErrStorageNotFound +} diff --git a/metrics/config.go b/metrics/config.go new file mode 100644 index 00000000..f5953285 --- /dev/null +++ b/metrics/config.go @@ -0,0 +1,12 @@ +package metrics + +type Config struct { + Enabled bool `mapstructure:"Enabled"` + Port string `mapstructure:"Port"` + + // Endpoint is the metrics endpoint for prometheus to query the metrics + Endpoint string `mapstructure:"Endpoint"` + + // Env is the environment label for the metrics, to separate mainnet and testnet metrics + Env string `mapstructure:"Env"` +} diff --git a/metrics/consts.go b/metrics/consts.go new file mode 100644 index 00000000..4684346d --- /dev/null +++ b/metrics/consts.go @@ -0,0 +1,48 @@ +package metrics + +const ( + defaultMetricsEndpoint = "/metrics" +) + +// Metric types +const ( + typeGauge = "gauge" + typeCounter = "counter" + typeHistogram = "histogram" +) + +// Metric names and labels +const ( + prefix = "xlayer_bridge_" + labelEnv = "env" + + prefixRequest = prefix + "request_" + metricRequestCount = prefixRequest + "count" + metricRequestLatency = prefixRequest + "latency_ms" + labelMethod = "method" + labelCode = "code" + labelErrMessage = "msg" + + prefixOrder = prefix + "order_" + metricOrderCount = prefixOrder + "count" + metricOrderTotalAmount = prefixOrder + "total_amount" + metricOrderWaitTime = prefixOrder + "wait_time_sec" + labelNetworkID = "network_id" + labelLeafType = "leaf_type" + labelToken = "token" + labelTokenAddress = "token_address" + labelTokenOriginNetwork = "token_origin_network" + labelDestNet = "dest_net" + + prefixMonitoredTxs = prefix + "monitored_txs_" + metricMonitoredTxsPendingCount = prefixMonitoredTxs + "pending_count" + metricMonitoredTxsResultCount = prefixMonitoredTxs + "result_count" + metricMonitoredTxsDuration = prefixMonitoredTxs + "duration_sec" + labelStatus = "status" + + prefixSynchronizer = prefix + "synchronizer_" + metricSynchronizerEventCount = prefixSynchronizer + "event_count" + metricLastSyncedBlockNum = prefixSynchronizer + "last_synced_block_num" + metricLatestBlockNum = prefixSynchronizer + "latest_block_num" + labelEventType = "type" +) diff --git a/metrics/metrics.go b/metrics/metrics.go new file mode 100644 index 00000000..d0551edf --- /dev/null +++ b/metrics/metrics.go @@ -0,0 +1,132 @@ +package metrics + +import ( + "context" + "math" + "math/big" + "strconv" + "time" + + "github.com/0xPolygonHermez/zkevm-bridge-service/localcache" + "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/ethereum/go-ethereum/common" + "github.com/prometheus/client_golang/prometheus" +) + +func initMetrics(c Config) { + if !initialized { + registerer = prometheus.DefaultRegisterer + gauges = make(map[string]*prometheus.GaugeVec) + counters = make(map[string]*prometheus.CounterVec) + histograms = make(map[string]*prometheus.HistogramVec) + initialized = true + } + + constLabels := map[string]string{labelEnv: c.Env} + + registerCounter(prometheus.CounterOpts{Name: metricRequestCount, ConstLabels: constLabels}, labelMethod, labelCode, labelErrMessage) + registerHistogram(prometheus.HistogramOpts{ + Name: metricRequestLatency, + ConstLabels: constLabels, + Buckets: []float64{1, 10, 25, 50, 100, 250, 500, 750, 1000, 2500, 5000, 10000}, + }, labelMethod, labelCode) + registerCounter(prometheus.CounterOpts{Name: metricOrderCount, ConstLabels: constLabels}, labelNetworkID, labelLeafType, labelToken, labelTokenAddress, labelTokenOriginNetwork, labelDestNet) + registerCounter(prometheus.CounterOpts{Name: metricOrderTotalAmount, ConstLabels: constLabels}, labelNetworkID, labelLeafType, labelToken, labelTokenAddress, labelTokenOriginNetwork, labelDestNet) + registerHistogram(prometheus.HistogramOpts{ + Name: metricOrderWaitTime, + ConstLabels: constLabels, + Buckets: []float64{300, 700, 900, 1000, 1200, 1800, 3000, 3300, 3600, 3900, 5000, 7000}, + }, labelNetworkID, labelDestNet) + registerGauge(prometheus.GaugeOpts{Name: metricMonitoredTxsPendingCount, ConstLabels: constLabels}) + registerCounter(prometheus.CounterOpts{Name: metricMonitoredTxsResultCount, ConstLabels: constLabels}, labelStatus) + registerHistogram(prometheus.HistogramOpts{ + Name: metricMonitoredTxsDuration, + ConstLabels: constLabels, + Buckets: []float64{0.5, 1, 2.5, 5, 10, 20, 30, 60, 100, 500, 1000}, + }) + registerCounter(prometheus.CounterOpts{Name: metricSynchronizerEventCount, ConstLabels: constLabels}, labelNetworkID, labelEventType) + registerGauge(prometheus.GaugeOpts{Name: metricLastSyncedBlockNum, ConstLabels: constLabels}, labelNetworkID) + registerGauge(prometheus.GaugeOpts{Name: metricLatestBlockNum, ConstLabels: constLabels}, labelNetworkID) +} + +// RecordRequest increments the request count for the method +func RecordRequest(method string, code int64, msg string) { + counterInc(metricRequestCount, map[string]string{labelMethod: method, labelCode: strconv.FormatInt(code, 10), labelErrMessage: msg}) //nolint:gomnd +} + +// RecordRequestLatency records the latency histogram in nanoseconds +func RecordRequestLatency(method string, latency time.Duration, code int64) { + latencyMs := float64(latency) / float64(time.Millisecond) + histogramObserve(metricRequestLatency, latencyMs, map[string]string{labelMethod: method, labelCode: strconv.FormatInt(code, 10)}) //nolint:gomnd +} + +// RecordOrder records one bridge order, increase the order count and add the amount to the total order amount +// networkID is the "from" network of the transaction +func RecordOrder(networkID, destNet, leafType, tokenOriginNetwork uint32, tokenAddress common.Address, amount *big.Int) { + tokenSymbol := "unknown" + decimals := uint64(0) + if coinsCache := localcache.GetDefaultCache(); coinsCache != nil { + coinInfo, err := coinsCache.GetCoinInfoByAddress(context.Background(), tokenOriginNetwork, tokenAddress) + if err == nil { + tokenSymbol = coinInfo.Symbol + decimals = coinInfo.Decimals + } + } + + // This is inflated amount, e.g.: 1 ETH is stored as 1000000000000000000 + floatAmount, err := strconv.ParseFloat(amount.String(), 64) //nolint:gomnd + if err != nil { + log.Warnf("cannot convert [%v] to float", amount.String()) + } + // Deflate the amount + if decimals != 0 { + floatAmount = floatAmount / math.Pow(10, float64(decimals)) //nolint:gomnd + } + + labels := map[string]string{ + labelNetworkID: strconv.Itoa(int(networkID)), + labelDestNet: strconv.Itoa(int(destNet)), + labelLeafType: strconv.Itoa(int(leafType)), + labelToken: tokenSymbol, + labelTokenAddress: tokenAddress.String(), + labelTokenOriginNetwork: strconv.Itoa(int(tokenOriginNetwork)), + } + + counterInc(metricOrderCount, labels) + counterAdd(metricOrderTotalAmount, floatAmount, labels) +} + +// RecordOrderWaitTime records the waiting time (seconds) of a bridge order, from order creation (deposit time) to ready_for_claim time +func RecordOrderWaitTime(networkID, destNet uint32, dur time.Duration) { + histogramObserve(metricOrderWaitTime, float64(dur)/float64(time.Second), map[string]string{labelNetworkID: strconv.Itoa(int(networkID)), labelDestNet: strconv.Itoa(int(destNet))}) +} + +// RecordPendingMonitoredTxsCount records the current number of pending monitored txs (status == "created") +func RecordPendingMonitoredTxsCount(count int) { + gaugeSet(metricMonitoredTxsPendingCount, float64(count), map[string]string{}) +} + +// RecordMonitoredTxsResult records the final result of a monitored tx (confirmed or failed) +func RecordMonitoredTxsResult(status string) { + counterInc(metricMonitoredTxsResultCount, map[string]string{labelStatus: status}) +} + +// RecordAutoClaimDuration records the duration (seconds) of a confirmed monitored tx (from creation time to confirm time) +func RecordAutoClaimDuration(dur time.Duration) { + histogramObserve(metricMonitoredTxsDuration, float64(dur)/float64(time.Second), map[string]string{}) +} + +// RecordSynchronizerEvent records an event log consumed by the synchronizer +func RecordSynchronizerEvent(networkID uint32, eventType string) { + counterInc(metricSynchronizerEventCount, map[string]string{labelNetworkID: strconv.Itoa(int(networkID)), labelEventType: eventType}) +} + +// RecordLastSyncedBlockNum records the latest block number that has been synced by the synchronizer, per network +func RecordLastSyncedBlockNum(networkID uint32, blockNum uint64) { + gaugeSet(metricLastSyncedBlockNum, float64(blockNum), map[string]string{labelNetworkID: strconv.Itoa(int(networkID))}) +} + +// RecordLatestBlockNum records the latest known block number on chain +func RecordLatestBlockNum(networkID uint32, blockNum uint64) { + gaugeSet(metricLatestBlockNum, float64(blockNum), map[string]string{labelNetworkID: strconv.Itoa(int(networkID))}) +} diff --git a/metrics/prometheus.go b/metrics/prometheus.go new file mode 100644 index 00000000..37c00bc8 --- /dev/null +++ b/metrics/prometheus.go @@ -0,0 +1,259 @@ +package metrics + +import ( + "context" + "net/http" + "os" + "os/signal" + "sync" + "time" + + "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +var ( + mutex sync.RWMutex + registerer prometheus.Registerer + initialized bool + + gauges map[string]*prometheus.GaugeVec + counters map[string]*prometheus.CounterVec + histograms map[string]*prometheus.HistogramVec +) + +func getLogger(metricName, metricType string) *log.Logger { + return log.WithFields("metricName", metricName, "metricType", metricType) +} + +// StartMetricsHttpServer initializes the metrics registry and starts the prometheus metrics HTTP server +func StartMetricsHttpServer(c Config) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + if !c.Enabled { + return + } + + // Init metrics registry + initMetrics(c) + + // Start metrics HTTP server + mux := http.NewServeMux() + addr := ":" + c.Port + + endpoint := c.Endpoint + if endpoint == "" { + endpoint = defaultMetricsEndpoint + } + + mux.Handle(endpoint, promhttp.Handler()) + srv := &http.Server{ + Addr: addr, + Handler: mux, + ReadTimeout: 5 * time.Second, //nolint:gomnd + } + + ch := make(chan os.Signal, 1) + signal.Notify(ch, os.Interrupt) + go func() { + // gracefully shutdown the server + for range ch { + _ = srv.Shutdown(ctx) + <-ctx.Done() + } + + _, cancel := context.WithTimeout(ctx, 5*time.Second) //nolint:gomnd + defer cancel() + + _ = srv.Shutdown(ctx) + }() + + err := srv.ListenAndServe() + if err != nil { + log.Errorf("serve metrics http server error: %v", err) + } +} + +/* + * -------------------- Gauge functions -------------------- + */ + +func registerGauge(opt prometheus.GaugeOpts, labelNames ...string) { + logger := getLogger(opt.Name, typeGauge) + if !initialized { + return + } + mutex.Lock() + defer mutex.Unlock() + + if _, ok := gauges[opt.Name]; ok { + return + } + + collector := prometheus.NewGaugeVec(opt, labelNames) + if err := registerer.Register(collector); err != nil { + logger.Errorf("metrics register error: %v", err) + return + } + gauges[opt.Name] = collector + + logger.Debugf("metrics register successfully") +} + +func gaugeSet(name string, value float64, labelValues map[string]string) { + if !initialized { + return + } + + c, ok := gauges[name] + if !ok { + getLogger(name, typeGauge).Errorf("collector not found") + return + } + c.With(labelValues).Set(value) +} + +//func gaugeInc(name string, labelValues map[string]string) { +// if !initialized { +// return +// } +// +// c, ok := gauges[name] +// if !ok { +// getLogger(name, typeGauge).Errorf("collector not found") +// return +// } +// c.With(labelValues).Inc() +//} +// +//func gaugeDec(name string, labelValues map[string]string) { +// if !initialized { +// return +// } +// +// c, ok := gauges[name] +// if !ok { +// getLogger(name, typeGauge).Errorf("collector not found") +// return +// } +// c.With(labelValues).Dec() +//} +// +//func gaugeAdd(name string, value float64, labelValues map[string]string) { +// if !initialized { +// return +// } +// +// c, ok := gauges[name] +// if !ok { +// getLogger(name, typeGauge).Errorf("collector not found") +// return +// } +// c.With(labelValues).Add(value) +//} +// +//func gaugeSub(name string, value float64, labelValues map[string]string) { +// if !initialized { +// return +// } +// +// c, ok := gauges[name] +// if !ok { +// getLogger(name, typeGauge).Errorf("collector not found") +// return +// } +// c.With(labelValues).Sub(value) +//} + +/* + * -------------------- Counter functions -------------------- + */ + +func registerCounter(opt prometheus.CounterOpts, labelNames ...string) { + logger := getLogger(opt.Name, typeCounter) + if !initialized { + return + } + mutex.Lock() + defer mutex.Unlock() + + if _, ok := gauges[opt.Name]; ok { + return + } + + collector := prometheus.NewCounterVec(opt, labelNames) + if err := registerer.Register(collector); err != nil { + logger.Errorf("metrics register error: %v", err) + return + } + counters[opt.Name] = collector + + logger.Debugf("metrics register successfully") +} + +func counterInc(name string, labelValues map[string]string) { + if !initialized { + return + } + + c, ok := counters[name] + if !ok { + getLogger(name, typeCounter).Errorf("collector not found") + return + } + c.With(labelValues).Inc() +} + +func counterAdd(name string, value float64, labelValues map[string]string) { + if !initialized { + return + } + + c, ok := counters[name] + if !ok { + getLogger(name, typeCounter).Errorf("collector not found") + return + } + c.With(labelValues).Add(value) +} + +/* + * -------------------- Histogram functions -------------------- + */ + +func registerHistogram(opt prometheus.HistogramOpts, labelNames ...string) { + logger := getLogger(opt.Name, typeHistogram) + if !initialized { + return + } + mutex.Lock() + defer mutex.Unlock() + + if _, ok := gauges[opt.Name]; ok { + return + } + + collector := prometheus.NewHistogramVec(opt, labelNames) + if err := registerer.Register(collector); err != nil { + logger.Errorf("metrics register error: %v", err) + return + } + histograms[opt.Name] = collector + + logger.Debugf("metrics register successfully") +} + +func histogramObserve(name string, value float64, labelValues map[string]string) { + if !initialized { + return + } + + c, ok := histograms[name] + if !ok { + getLogger(name, typeHistogram).Errorf("collector not found") + return + } + c.With(labelValues).Observe(value) +} diff --git a/models/tokenlogo/logotypes.go b/models/tokenlogo/logotypes.go new file mode 100644 index 00000000..2f5161c2 --- /dev/null +++ b/models/tokenlogo/logotypes.go @@ -0,0 +1,25 @@ +package tokenlogo + +type QueryLogoParam struct { + ChainId uint32 `json:"chainId"` + TokenContractAddress string `json:"tokenContractAddress"` +} + +type LogoInfo struct { + LogoUrl string `json:"logoUrl"` + LogoOssUrl string `json:"logoOssUrl"` + ChainIdStr string `json:"chainId"` + TokenContractAddress string `json:"tokenContractAddress"` + TokenSymbol string `json:"tokenSymbol"` + Unit uint32 `json:"unit"` + TokenName string `json:"tokenName"` +} + +type GetTokenLogosResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + ErrorCode string `json:"error_code"` + ErrorMessage string `json:"error_message"` + DetailMsg string `json:"detailMsg"` + Data []LogoInfo `json:"data"` +} diff --git a/nacos/start.go b/nacos/nacos.go similarity index 57% rename from nacos/start.go rename to nacos/nacos.go index 803c3ed5..2e8448e7 100644 --- a/nacos/start.go +++ b/nacos/nacos.go @@ -2,37 +2,40 @@ package nacos import ( "fmt" - "net" "strconv" - "strings" "time" "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/nacos-group/nacos-sdk-go/clients" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" "github.com/nacos-group/nacos-sdk-go/common/constant" + "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/vo" + "github.com/pkg/errors" ) -// StartNacosClient start nacos client and register rest service in nacos -func StartNacosClient(urls string, namespace string, name string, externalAddr string) { - ip, port, err := ResolveIPAndPort(externalAddr) +var ( + client naming_client.INamingClient +) + +// InitNacosClient start nacos client and register rest service in nacos +func InitNacosClient(urls string, namespace string, name string, externalAddr string) error { + ip, port, err := resolveIPAndPort(externalAddr) if err != nil { log.Error(fmt.Sprintf("failed to resolve %s error: %s", externalAddr, err.Error())) - return + return err } serverConfigs, err := getServerConfigs(urls) if err != nil { log.Error(fmt.Sprintf("failed to resolve nacos server url %s: %s", urls, err.Error())) - return + return err } const timeoutMs = 5000 - const listenInterval = 10000 - client, err := clients.CreateNamingClient(map[string]interface{}{ + client, err = clients.CreateNamingClient(map[string]interface{}{ "serverConfigs": serverConfigs, "clientConfig": constant.ClientConfig{ TimeoutMs: timeoutMs, - ListenInterval: listenInterval, NotLoadCacheAtStart: true, NamespaceId: namespace, LogDir: "/dev/null", @@ -41,7 +44,7 @@ func StartNacosClient(urls string, namespace string, name string, externalAddr s }) if err != nil { log.Error(fmt.Sprintf("failed to create nacos client. error: %s", err.Error())) - return + return err } const weight = 10 @@ -61,37 +64,28 @@ func StartNacosClient(urls string, namespace string, name string, externalAddr s }) if err != nil { log.Error(fmt.Sprintf("failed to register instance in nacos server. error: %s", err.Error())) - return + return err } log.Info("register application instance in nacos successfully") + return nil } -func ResolveIPAndPort(addr string) (string, int, error) { - laddr := strings.Split(addr, ":") - ip := laddr[0] - if ip == "127.0.0.1" { - const port = 26659 - return GetLocalIP(), port, nil - } - port, err := strconv.Atoi(laddr[1]) - if err != nil { - return "", 0, err +// GetOneInstance returns the info of one healthy instance of the service +func GetOneInstance(serviceName string) (*model.Instance, error) { + if client == nil { + return nil, errors.New("nacos client is not initialized") } - return ip, port, nil + params := vo.SelectOneHealthInstanceParam{ServiceName: serviceName} + return client.SelectOneHealthyInstance(params) } -// GetLocalIP get local ip -func GetLocalIP() string { - addrs, err := net.InterfaceAddrs() +// GetOneURL returns the URL address of one healthy instance of the service +func GetOneURL(serviceName string) (string, error) { + instance, err := GetOneInstance(serviceName) if err != nil { - return "" - } - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { - return ipnet.IP.String() - } - } + return "", err } - return "" + + url := fmt.Sprintf("%v:%v", instance.Ip, instance.Port) + return url, nil } diff --git a/nacos/util.go b/nacos/util.go index bb42b897..4312b68e 100644 --- a/nacos/util.go +++ b/nacos/util.go @@ -1,41 +1,41 @@ package nacos import ( - "fmt" + "net" "strconv" "strings" - "github.com/nacos-group/nacos-sdk-go/clients" "github.com/nacos-group/nacos-sdk-go/common/constant" - "github.com/nacos-group/nacos-sdk-go/model" - "github.com/nacos-group/nacos-sdk-go/vo" ) -func GetOneInstance(urls string, nameSpace string, param vo.SelectOneHealthInstanceParam) (instance *model.Instance, err error) { - serverConfigs, err := getServerConfigs(urls) - if err != nil { - return nil, fmt.Errorf("failed to resolve nacos server url %s: %s", urls, err.Error()) +func resolveIPAndPort(addr string) (string, int, error) { + laddr := strings.Split(addr, ":") + ip := laddr[0] + if ip == "127.0.0.1" { + const port = 26659 + return getLocalIP(), port, nil } - - const timeoutMs = 5000 - namingClient, err := clients.CreateNamingClient(map[string]interface{}{ - "serverConfigs": serverConfigs, - "clientConfig": constant.ClientConfig{ - NamespaceId: nameSpace, - TimeoutMs: timeoutMs, - NotLoadCacheAtStart: true, - LogDir: "/dev/null", - }, - }) + port, err := strconv.Atoi(laddr[1]) if err != nil { - return nil, fmt.Errorf("failed to create nacos client when getting one service. error: %s", err.Error()) + return "", 0, err } + return ip, port, nil +} - instance, err = namingClient.SelectOneHealthyInstance(param) +// getLocalIP get local ip +func getLocalIP() string { + addrs, err := net.InterfaceAddrs() if err != nil { - return nil, fmt.Errorf("failed to get %s service in [%s, %s]. error: %s", param, urls, nameSpace, err.Error()) + return "" + } + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return ipnet.IP.String() + } + } } - return instance, nil + return "" } func getServerConfigs(urls string) ([]constant.ServerConfig, error) { diff --git a/proto/src/proto/bridge/v1/query.proto b/proto/src/proto/bridge/v1/query.proto index 9d6e37bc..8bce82d2 100644 --- a/proto/src/proto/bridge/v1/query.proto +++ b/proto/src/proto/bridge/v1/query.proto @@ -258,6 +258,14 @@ enum TransactionStatus { TX_PENDING_VERIFICATION = 4; // Only for L2->L1 } +enum ErrorCode { + ERROR_OK = 0; + // Start from 1000 so that it will not conflict with gRPC error code range + ERROR_DEFAULT = 1000; + ERROR_BUSINESS = 1001; // General business error + ERROR_IP_RESTRICTED = 1009; +} + // Symbol info message message SymbolInfo { uint64 chainId = 1; @@ -304,6 +312,16 @@ message Transaction { uint32 leafType = 17; uint64 blockNumber = 18; string globalIndex = 19; + string destContractAddr = 20; + TokenLogoInfo logoInfo = 21; + uint32 originalNetwork = 22; +} + +message TokenLogoInfo { + string symbol = 1; + string tokenName = 2; + string logoOssUrl = 3; + uint32 decimal = 4; } // Monitored tx @@ -468,3 +486,11 @@ message GetFakePushMessagesResponse { string detailMsg = 5; repeated string data = 6; } + +message CommonResponse { + uint32 code = 1; + string msg = 2; + string error_code = 3; + string error_message = 4; + string detailMsg = 5; +} \ No newline at end of file diff --git a/pushtask/committedbatchtask.go b/pushtask/committedbatchtask.go index 50486e1e..ddf3a15d 100644 --- a/pushtask/committedbatchtask.go +++ b/pushtask/committedbatchtask.go @@ -274,7 +274,7 @@ func (ins *CommittedBatchHandler) pushMsgForDeposit(deposit *etherman.Deposit, l log.Errorf("kafka push producer is nil, so can't push tx status change msg!") return } - if deposit.LeafType != uint8(utils.LeafTypeAsset) { + if deposit.LeafType != uint8(utils.LeafTypeAsset) && !utils.IsUSDCContractAddress(deposit.OriginalAddress) { log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) return } diff --git a/pushtask/l1blocknumtask.go b/pushtask/l1blocknumtask.go index 0cab9312..9a2e8a07 100644 --- a/pushtask/l1blocknumtask.go +++ b/pushtask/l1blocknumtask.go @@ -129,7 +129,7 @@ func (t *L1BlockNumTask) doTask(ctx context.Context) { if t.messagePushProducer == nil { return } - if deposit.LeafType != uint8(utils.LeafTypeAsset) { + if deposit.LeafType != uint8(utils.LeafTypeAsset) && !utils.IsUSDCContractAddress(deposit.OriginalAddress) { log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) return } diff --git a/redisstorage/interfaces.go b/redisstorage/interfaces.go index c1b56144..51568b1e 100644 --- a/redisstorage/interfaces.go +++ b/redisstorage/interfaces.go @@ -6,6 +6,7 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl/pb" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" + "github.com/0xPolygonHermez/zkevm-bridge-service/models/tokenlogo" "github.com/redis/go-redis/v9" ) @@ -44,6 +45,10 @@ type RedisStorage interface { LPushVerifyTime(ctx context.Context, commitTimeTimestamp int64) error LLenVerifyTimeList(ctx context.Context) (int64, error) RPopVerifyTime(ctx context.Context) (int64, error) + + // token logo storage + SetTokenLogoInfo(ctx context.Context, keySuffix string, logoInfo tokenlogo.LogoInfo) error + GetTokenLogoInfo(ctx context.Context, keySuffix string) (*tokenlogo.LogoInfo, error) } type RedisClient interface { diff --git a/redisstorage/redisstorage.go b/redisstorage/redisstorage.go index 48fc32b4..d9851cfc 100644 --- a/redisstorage/redisstorage.go +++ b/redisstorage/redisstorage.go @@ -12,6 +12,7 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/config/apolloconfig" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/models/tokenlogo" "github.com/pkg/errors" "github.com/redis/go-redis/v9" "google.golang.org/protobuf/encoding/protojson" @@ -34,6 +35,9 @@ const ( verifyBatchTimeListKey = "bridge_verify_batch_simple_info" l2BlockCommitTimeKey = "bridge_l2_block_commit_time_key_" + // token logo info key + tokenLogoInfoKey = "bridge_token_logo_info_" + // Set a default expiration for locks to prevent a process from keeping the lock for too long lockExpire = 1 * time.Minute @@ -424,6 +428,35 @@ func (s *redisStorageImpl) rPopIntCacheFoundation(ctx context.Context, key strin return num, nil } +func (s *redisStorageImpl) SetTokenLogoInfo(ctx context.Context, keySuffix string, logoInfo tokenlogo.LogoInfo) error { + value, err := json.Marshal(logoInfo) + if err != nil { + return errors.Wrap(err, "failed to convert logoInfo to string") + } + return s.setFoundation(ctx, s.getTokenInfoCacheKey(keySuffix), value, durationFor48h) +} + +func (s *redisStorageImpl) GetTokenLogoInfo(ctx context.Context, keySuffix string) (*tokenlogo.LogoInfo, error) { + if s == nil || s.client == nil { + return nil, errors.New("redis client is nil") + } + fullKey := s.addKeyPrefix(s.getTokenInfoCacheKey(keySuffix)) + res, err := s.client.Get(ctx, fullKey).Result() + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("get redis cache for key: %v failed", fullKey)) + } + logoStruct := &tokenlogo.LogoInfo{} + err = json.Unmarshal([]byte(res), logoStruct) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("failed convert logo info cache to struct, cache: %v", res)) + } + return logoStruct, nil +} + +func (s *redisStorageImpl) getTokenInfoCacheKey(keySuffix string) string { + return tokenLogoInfoKey + keySuffix +} + func getCoinPriceKey(chainID uint64, tokenAddr string) string { if tokenAddr == "" { tokenAddr = "null" diff --git a/sentinel/sentinel.go b/sentinel/sentinel.go index 454993f3..991ead5f 100644 --- a/sentinel/sentinel.go +++ b/sentinel/sentinel.go @@ -6,7 +6,7 @@ import ( "sync" "github.com/0xPolygonHermez/zkevm-bridge-service/config/apolloconfig" - "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/alibaba/sentinel-golang/api" "github.com/alibaba/sentinel-golang/core/config" "github.com/alibaba/sentinel-golang/core/flow" diff --git a/server/interceptors.go b/server/interceptors.go index f59420d9..682feae2 100644 --- a/server/interceptors.go +++ b/server/interceptors.go @@ -2,14 +2,24 @@ package server import ( "context" + "reflect" + "strings" "time" + "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl/pb" "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/metrics" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/iprestriction" "google.golang.org/grpc" + "google.golang.org/grpc/metadata" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) +const ( + ipRestrictionErrorMsg = "XLayer product isn't available in your region" +) + func NewRequestLogInterceptor() grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { startTime := time.Now() @@ -19,9 +29,113 @@ func NewRequestLogInterceptor() grpc.UnaryServerInterceptor { resp, err := handler(ctx, req) duration := time.Since(startTime) - reqJson, _ := protojson.Marshal(req.(proto.Message)) - respJson, _ := protojson.Marshal(resp.(proto.Message)) + var reqJson, respJson []byte + if req != nil { + reqJson, _ = protojson.Marshal(req.(proto.Message)) + } else { + reqJson = []byte("") + } + if resp != nil { + respJson, _ = protojson.Marshal(resp.(proto.Message)) + } else { + respJson = []byte("") + } + log.Infof("method[%v] req[%v] resp[%v] err[%v] processTime[%v]", methodName, string(reqJson), string(respJson), err, duration.String()) return resp, err } } + +// NewRequestMetricsInterceptor returns a GRPC interceptor to record the request metrics to prometheus +func NewRequestMetricsInterceptor() grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + startTime := time.Now() + methodName := info.FullMethod + + // Actual process of the request + resp, err := handler(ctx, req) + + duration := time.Since(startTime) + code, msg := getRespErrorInfo(resp, err) + + metrics.RecordRequest(methodName, code, msg) + metrics.RecordRequestLatency(methodName, duration, code) + + return resp, err + } +} + +// getRespErrorInfo returns the error code and msg from the resp +func getRespErrorInfo(resp any, err error) (code int64, msg string) { + if err != nil { + return int64(pb.ErrorCode_ERROR_DEFAULT), err.Error() + } + + if resp == nil { + // This should not happen + return int64(pb.ErrorCode_ERROR_OK), "" + } + + // Check `Msg" field in the resp body + v := reflect.Indirect(reflect.ValueOf(resp)) + codeField := v.FieldByName("Code") + msgField := v.FieldByName("Msg") + + if codeField.CanInt() { + code = codeField.Int() + } + if codeField.CanUint() { + code = int64(codeField.Uint()) + } + if msgField.Kind() == reflect.String { + msg = msgField.String() + } + + return +} + +func NewIPCheckInterceptor() grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + headers, ok := metadata.FromIncomingContext(ctx) + if !ok { + log.Warnf("cannot get headers from incoming context, skipped checking IP") + return handler(ctx, req) + } + ip := getIPAddrFromHeaders(headers) + log.Debugf("method[%v] client IP: %v", info.FullMethod, ip) + if ip != "" && iprestriction.GetClient().CheckIPRestricted(ip) { + // IP is restricted, need to block the request + return &pb.CommonResponse{ + Code: uint32(pb.ErrorCode_ERROR_IP_RESTRICTED), + Msg: ipRestrictionErrorMsg, + }, nil + } + + // Not restricted, continue the flow + return handler(ctx, req) + } +} + +func getIPAddrFromHeaders(headers metadata.MD) string { + ipHeaders := []string{"x-real-ip", "x-forwarded-for", "Proxy-Client-IP", "WL-Proxy-Client-IP"} + + // Check each header in order + for _, h := range ipHeaders { + // Find the first valid IP address from the headers + vals := headers.Get(h) + if len(vals) == 0 { + continue + } + ipArray := strings.Split(vals[0], ",") + if len(ipArray) == 0 { + continue + } + ip := strings.TrimSpace(ipArray[0]) + // Return the first valid IP address found + if ip != "" && strings.ToLower(ip) != "unknown" { + return ip + } + } + + return "" +} diff --git a/server/interceptors_test.go b/server/interceptors_test.go new file mode 100644 index 00000000..a66e3333 --- /dev/null +++ b/server/interceptors_test.go @@ -0,0 +1,54 @@ +package server + +import ( + "testing" + + "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl/pb" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +func TestGetRespErrorInfo(t *testing.T) { + cases := []struct { + name string + inputResp any + inputErr error + outputCode int64 + outputMsg string + }{ + { + "err is not nil", + pb.CommonCoinsResponse{Code: 2, Msg: "this will not be returned"}, + errors.New("this is an error"), + int64(pb.ErrorCode_ERROR_DEFAULT), + "this is an error", + }, + { + "no error and resp is nil", + nil, + nil, + int64(pb.ErrorCode_ERROR_OK), + "", + }, + { + "return msg from the resp body", + pb.CommonCoinsResponse{Code: 2, Msg: "this is an error"}, + nil, + 2, + "this is an error", + }, + { + "no code and msg field", + struct{}{}, + nil, + int64(pb.ErrorCode_ERROR_OK), + "", + }, + } + + for _, c := range cases { + code, msg := getRespErrorInfo(c.inputResp, c.inputErr) + assert.Equal(t, c.outputCode, code, c.name) + assert.Equal(t, c.outputMsg, msg, c.name) + } +} diff --git a/server/interfaces.go b/server/interfaces.go index baa3d1de..78d5c573 100644 --- a/server/interfaces.go +++ b/server/interfaces.go @@ -26,10 +26,10 @@ type bridgeServiceStorage interface { // XLayer GetDepositByHash(ctx context.Context, destAddr string, networkID uint, txHash string, dbTx pgx.Tx) (*etherman.Deposit, error) - GetDepositsWithLeafType(ctx context.Context, destAddr string, limit uint, offset uint, leafType uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) - GetPendingTransactions(ctx context.Context, destAddr string, limit uint, offset uint, leafType uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) + GetDepositsXLayer(ctx context.Context, destAddr string, limit uint, offset uint, messageAllowlist []common.Address, dbTx pgx.Tx) ([]*etherman.Deposit, error) + GetPendingTransactions(ctx context.Context, destAddr string, limit uint, offset uint, messageAllowlist []common.Address, dbTx pgx.Tx) ([]*etherman.Deposit, error) GetNotReadyTransactions(ctx context.Context, limit uint, offset uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) - GetReadyPendingTransactions(ctx context.Context, networkID uint, leafType uint, limit uint, offset uint, minReadyTime time.Time, dbTx pgx.Tx) ([]*etherman.Deposit, error) + GetReadyPendingTransactions(ctx context.Context, networkID uint, limit uint, offset uint, minReadyTime time.Time, dbTx pgx.Tx) ([]*etherman.Deposit, error) GetClaimTxById(ctx context.Context, id uint, dbTx pgx.Tx) (*ctmtypes.MonitoredTx, error) GetClaimTxsByStatusWithLimit(ctx context.Context, statuses []ctmtypes.MonitoredTxStatus, limit uint, offset uint, dbTx pgx.Tx) ([]ctmtypes.MonitoredTx, error) GetDepositsForUnitTest(ctx context.Context, destAddr string, limit uint, offset uint, dbTx pgx.Tx) ([]*etherman.Deposit, error) diff --git a/server/iprestriction/client.go b/server/iprestriction/client.go new file mode 100644 index 00000000..aee82759 --- /dev/null +++ b/server/iprestriction/client.go @@ -0,0 +1,116 @@ +package iprestriction + +import ( + "encoding/json" + "io" + "net/http" + "net/url" + + "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/nacos" +) + +type Client struct { + cfg Config + httpClient *http.Client +} + +var ( + client *Client +) + +func InitClient(c Config) { + if !c.Enabled { + return + } + if c.Host == "" { + log.Errorf("host is empty") + return + } + if c.Scheme == "" { + c.Scheme = "http" + } + client = &Client{ + cfg: c, + httpClient: &http.Client{ + Timeout: c.Timeout.Duration, + }, + } +} + +func GetClient() *Client { + return client +} + +func (c *Client) CheckIPRestricted(ip string) bool { + if c == nil || !c.cfg.Enabled { + log.Debugf("IP restriction is disabled, skipped") + return false + } + for _, blockedIP := range c.cfg.IPBlocklist { + if ip == blockedIP { + return true + } + } + host := c.cfg.Host + if c.cfg.UseNacos { + // Resolve nacos service name to URL + nacosUrl, err := nacos.GetOneURL(c.cfg.Host) + if err != nil { + log.Errorf("[CheckIPRestricted] cannot get URL from nacos service, name[%v] err[%v]", c.cfg.Host, err) + return false + } + host = c.cfg.Scheme + "://" + nacosUrl + } + + fullPath, err := url.JoinPath(host, endpointCheckCountryLimit) + if err != nil { + log.Errorf("[CheckIPRestricted] JoinPath err[%v] host[%v] endpoint[%v]", err, host, endpointCheckCountryLimit) + return false + } + req, err := http.NewRequest("GET", fullPath, nil) + if err != nil { + log.Errorf("[CheckIPRestricted] create new GET request err[%v] path[%v]", err, fullPath) + return false + } + // Add request params + q := req.URL.Query() + q.Add("ip", ip) + q.Add("type", queryTypeXLayerBridge) + q.Add("siteCode", siteCodeOKXGLobal) + req.URL.RawQuery = q.Encode() + + // Call the API + resp, err := c.httpClient.Do(req) + if err != nil { + log.Errorf("[CheckIPRestricted] call GET API err[%v] url[%v] ip[%v]", err, fullPath, ip) + return false + } + defer func() { + _ = resp.Body.Close() + }() + + if resp.StatusCode != http.StatusOK { + log.Errorf("[CheckIPRestricted] GET API status code %v url[%v] ip[%v]", resp.StatusCode, fullPath, ip) + return false + } + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Errorf("[CheckIPRestricted] failed to read resp body err[%v]") + return false + } + + respStruct := new(CheckCountryLimitResponse) + err = json.Unmarshal(respBody, respStruct) + if err != nil { + log.Errorf("[CheckIPRestricted] failed to unmarshal response, err[%v] body[%v]", err, respBody) + return false + } + log.Debugf("[CheckIPRestricted] URL[%v] IP[%v] Result[%+v]", fullPath, ip, respStruct) + if respStruct.Data.XLayerBridge != nil && (respStruct.Data.XLayerBridge.Hidden || respStruct.Data.XLayerBridge.Limit) { + return true + } + + return false +} diff --git a/server/iprestriction/config.go b/server/iprestriction/config.go new file mode 100644 index 00000000..144e6647 --- /dev/null +++ b/server/iprestriction/config.go @@ -0,0 +1,16 @@ +package iprestriction + +import ( + "github.com/0xPolygonHermez/zkevm-node/config/types" +) + +type Config struct { + Enabled bool `mapstructure:"Enabled"` + UseNacos bool `mapstructure:"UseNacos"` + Scheme string `mapstructure:"Scheme"` + Host string `mapstructure:"Host"` // If UseNacos, Host is the nacos service name + Timeout types.Duration `mapstructure:"TimeoutSeconds"` + + // Additional restricted IP list, this should be used for testing only + IPBlocklist []string `mapstructure:"IPBlockList"` +} diff --git a/server/iprestriction/consts.go b/server/iprestriction/consts.go new file mode 100644 index 00000000..86238f7b --- /dev/null +++ b/server/iprestriction/consts.go @@ -0,0 +1,7 @@ +package iprestriction + +const ( + queryTypeXLayerBridge = "64" + endpointCheckCountryLimit = "/inner/v3/users/support/common/check-country-limit" + siteCodeOKXGLobal = "OKX_GLOBAL" +) diff --git a/server/iprestriction/types.go b/server/iprestriction/types.go new file mode 100644 index 00000000..f5b197c8 --- /dev/null +++ b/server/iprestriction/types.go @@ -0,0 +1,19 @@ +package iprestriction + +type CheckResult struct { + Hidden bool `json:"hidden"` + Limit bool `json:"limit"` +} + +type CheckCountryLimitResponseData struct { + XLayerBridge *CheckResult `json:"xLayerBridge"` +} + +type CheckCountryLimitResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + ErrorCode string `json:"error_code"` + ErrorMessage string `json:"error_message"` + DetailMsg string `json:"detailMsg"` + Data CheckCountryLimitResponseData `json:"data"` +} diff --git a/server/server.go b/server/server.go index 90011fa6..97bee4e1 100644 --- a/server/server.go +++ b/server/server.go @@ -14,7 +14,6 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/nacos" "github.com/alibaba/sentinel-golang/core/base" sentinelGrpc "github.com/alibaba/sentinel-golang/pkg/adapters/grpc" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -29,10 +28,11 @@ const ( ) func RegisterNacos(cfg nacos.Config) { - log.Info(fmt.Sprintf("nacos config NacosUrls %s NamespaceId %s ApplicationName %s ExternalListenAddr %s", cfg.NacosUrls, cfg.NamespaceId, cfg.ApplicationName, cfg.ExternalListenAddr)) + var err error if cfg.NacosUrls != "" { - nacos.StartNacosClient(cfg.NacosUrls, cfg.NamespaceId, cfg.ApplicationName, cfg.ExternalListenAddr) + err = nacos.InitNacosClient(cfg.NacosUrls, cfg.NamespaceId, cfg.ApplicationName, cfg.ExternalListenAddr) } + log.Debugf("Init nacos NacosUrls[%s] NamespaceId[%s] ApplicationName[%s] ExternalListenAddr[%s] Error[%v]", cfg.NacosUrls, cfg.NamespaceId, cfg.ApplicationName, cfg.ExternalListenAddr, err) } // RunServer runs gRPC server and HTTP gateway @@ -98,9 +98,12 @@ func runGRPCServer(ctx context.Context, bridgeServer pb.BridgeServiceServer, por return nil, status.Error(codes.ResourceExhausted, blockErr.Error()) } - server := grpc.NewServer(grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( + server := grpc.NewServer(grpc.ChainUnaryInterceptor( + NewRequestMetricsInterceptor(), sentinelGrpc.NewUnaryServerInterceptor(sentinelGrpc.WithUnaryServerBlockFallback(blockErrFallbackFn)), - NewRequestLogInterceptor()))) + NewRequestLogInterceptor(), + NewIPCheckInterceptor(), + )) pb.RegisterBridgeServiceServer(server, bridgeServer) healthService := newHealthChecker() diff --git a/server/service.go b/server/service.go index 12a445a6..44eca1bb 100644 --- a/server/service.go +++ b/server/service.go @@ -414,6 +414,7 @@ func (s *bridgeService) GetBridge(ctx context.Context, req *pb.GetBridgeRequest) ClaimTxHash: claimTxHash, Metadata: "0x" + hex.EncodeToString(deposit.Metadata), ReadyForClaim: deposit.ReadyForClaim, + GlobalIndex: s.getGlobalIndex(deposit).String(), }, }, nil } diff --git a/server/service_xlayer.go b/server/service_xlayer.go index 07d16ca8..97e3d522 100644 --- a/server/service_xlayer.go +++ b/server/service_xlayer.go @@ -17,14 +17,13 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/messagepush" "github.com/0xPolygonHermez/zkevm-bridge-service/pushtask" "github.com/0xPolygonHermez/zkevm-bridge-service/redisstorage" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/tokenlogoinfo" "github.com/0xPolygonHermez/zkevm-bridge-service/utils" "github.com/0xPolygonHermez/zkevm-bridge-service/utils/gerror" "github.com/pkg/errors" ) const ( - defaultErrorCode = 1 - defaultSuccessCode = 0 mtHeight = 32 // For sending mtProof to bridge contract, it requires constant-sized array... defaultMinDuration = 1 ) @@ -53,8 +52,7 @@ func (s *bridgeService) GetSmtProof(ctx context.Context, req *pb.GetSmtProofRequ if err != nil || len(merkleProof) != len(rollupMerkleProof) { log.Errorf("GetSmtProof err[%v] merkleProofLen[%v] rollupMerkleProofLen[%v]", err, len(merkleProof), len(rollupMerkleProof)) return &pb.CommonProofResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: err.Error(), }, nil } @@ -68,7 +66,7 @@ func (s *bridgeService) GetSmtProof(ctx context.Context, req *pb.GetSmtProofRequ } return &pb.CommonProofResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.ProofDetail{ SmtProof: proof, RollupSmtProof: rollupProof, @@ -89,8 +87,7 @@ func (s *bridgeService) GetCoinPrice(ctx context.Context, req *pb.GetCoinPriceRe if err != nil { log.Errorf("get coin price from redis failed for symbol: %v, error: %v", req.SymbolInfos, err) return &pb.CommonCoinPricesResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: gerror.ErrInternalErrorForRpcCall.Error(), }, nil } @@ -99,7 +96,7 @@ func (s *bridgeService) GetCoinPrice(ctx context.Context, req *pb.GetCoinPriceRe priceInfo.ChainId = utils.GetInnerChainIdByStandardId(priceInfo.ChainId) } return &pb.CommonCoinPricesResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: priceList, }, nil } @@ -111,8 +108,7 @@ func (s *bridgeService) GetMainCoins(ctx context.Context, req *pb.GetMainCoinsRe if err != nil { log.Errorf("get main coins from cache failed for net: %v, error: %v", req.NetworkId, err) return &pb.CommonCoinsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: gerror.ErrInternalErrorForRpcCall.Error(), }, nil } @@ -121,7 +117,7 @@ func (s *bridgeService) GetMainCoins(ctx context.Context, req *pb.GetMainCoinsRe coinInfo.ChainId = utils.GetInnerChainIdByStandardId(coinInfo.ChainId) } return &pb.CommonCoinsResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: coins, }, nil } @@ -137,12 +133,11 @@ func (s *bridgeService) GetPendingTransactions(ctx context.Context, req *pb.GetP limit = s.maxPageLimit.Get() } - deposits, err := s.storage.GetPendingTransactions(ctx, req.DestAddr, uint(limit+1), uint(req.Offset), uint(utils.LeafTypeAsset), nil) + deposits, err := s.storage.GetPendingTransactions(ctx, req.DestAddr, uint(limit+1), uint(req.Offset), utils.GetUSDCContractAddressList(), nil) if err != nil { log.Errorf("get pending tx failed for address: %v, limit: %v, offset: %v, error: %v", req.DestAddr, limit, req.Offset, err) return &pb.CommonTransactionsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: gerror.ErrInternalErrorForRpcCall.Error(), }, nil } @@ -159,7 +154,10 @@ func (s *bridgeService) GetPendingTransactions(ctx context.Context, req *pb.GetP currTime := time.Now() var pbTransactions []*pb.Transaction + transactionMap := make(map[string][]*pb.Transaction) for _, deposit := range deposits { + // replace contract address to real token address + utils.ReplaceUSDCDepositInfo(deposit, false) transaction := utils.EthermanDepositToPbTransaction(deposit) transaction.EstimateTime = estimatetime.GetDefaultCalculator().Get(deposit.NetworkID) transaction.Status = uint32(pb.TransactionStatus_TX_CREATED) @@ -196,9 +194,13 @@ func (s *bridgeService) GetPendingTransactions(ctx context.Context, req *pb.GetP transaction.ToChainId = uint32(utils.GetInnerChainIdByStandardId(uint64(transaction.ToChainId))) } pbTransactions = append(pbTransactions, transaction) + chainId := utils.GetChainIdByNetworkId(deposit.OriginalNetwork) + logoCacheKey := tokenlogoinfo.GetTokenLogoMapKey(transaction.GetBridgeToken(), chainId) + transactionMap[logoCacheKey] = append(transactionMap[logoCacheKey], transaction) } + tokenlogoinfo.FillLogoInfos(ctx, s.redisStorage, transactionMap) return &pb.CommonTransactionsResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.TransactionDetail{HasNext: hasNext, Transactions: pbTransactions}, }, nil } @@ -230,12 +232,11 @@ func (s *bridgeService) GetAllTransactions(ctx context.Context, req *pb.GetAllTr limit = s.maxPageLimit.Get() } - deposits, err := s.storage.GetDepositsWithLeafType(ctx, req.DestAddr, uint(limit+1), uint(req.Offset), uint(utils.LeafTypeAsset), nil) + deposits, err := s.storage.GetDepositsXLayer(ctx, req.DestAddr, uint(limit+1), uint(req.Offset), utils.GetUSDCContractAddressList(), nil) if err != nil { log.Errorf("get deposits from db failed for address: %v, limit: %v, offset: %v, error: %v", req.DestAddr, limit, req.Offset, err) return &pb.CommonTransactionsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: gerror.ErrInternalErrorForRpcCall.Error(), }, nil } @@ -252,7 +253,10 @@ func (s *bridgeService) GetAllTransactions(ctx context.Context, req *pb.GetAllTr currTime := time.Now() var pbTransactions []*pb.Transaction + transactionMap := make(map[string][]*pb.Transaction) for _, deposit := range deposits { + // replace contract address to real token address + utils.ReplaceUSDCDepositInfo(deposit, false) transaction := utils.EthermanDepositToPbTransaction(deposit) transaction.EstimateTime = estimatetime.GetDefaultCalculator().Get(deposit.NetworkID) transaction.Status = uint32(pb.TransactionStatus_TX_CREATED) // Not ready for claim @@ -264,8 +268,7 @@ func (s *bridgeService) GetAllTransactions(ctx context.Context, req *pb.GetAllTr if err != nil { if !errors.Is(err, gerror.ErrStorageNotFound) { return &pb.CommonTransactionsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: errors.Wrap(err, "load claim error").Error(), }, nil } @@ -304,10 +307,14 @@ func (s *bridgeService) GetAllTransactions(ctx context.Context, req *pb.GetAllTr transaction.ToChainId = uint32(utils.GetInnerChainIdByStandardId(uint64(transaction.ToChainId))) } pbTransactions = append(pbTransactions, transaction) + chainId := utils.GetChainIdByNetworkId(deposit.OriginalNetwork) + logoCacheKey := tokenlogoinfo.GetTokenLogoMapKey(transaction.GetBridgeToken(), chainId) + transactionMap[logoCacheKey] = append(transactionMap[logoCacheKey], transaction) } + tokenlogoinfo.FillLogoInfos(ctx, s.redisStorage, transactionMap) return &pb.CommonTransactionsResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.TransactionDetail{HasNext: hasNext, Transactions: pbTransactions}, }, nil } @@ -325,8 +332,7 @@ func (s *bridgeService) GetNotReadyTransactions(ctx context.Context, req *pb.Get deposits, err := s.storage.GetNotReadyTransactions(ctx, uint(limit+1), uint(req.Offset), nil) if err != nil { return &pb.CommonTransactionsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: err.Error(), }, nil } @@ -346,7 +352,7 @@ func (s *bridgeService) GetNotReadyTransactions(ctx context.Context, req *pb.Get } return &pb.CommonTransactionsResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.TransactionDetail{HasNext: hasNext, Transactions: pbTransactions}, }, nil } @@ -364,8 +370,7 @@ func (s *bridgeService) GetMonitoredTxsByStatus(ctx context.Context, req *pb.Get mTxs, err := s.storage.GetClaimTxsByStatusWithLimit(ctx, []ctmtypes.MonitoredTxStatus{ctmtypes.MonitoredTxStatus(req.Status)}, uint(limit+1), uint(req.Offset), nil) if err != nil { return &pb.CommonMonitoredTxsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: err.Error(), }, nil } @@ -397,7 +402,7 @@ func (s *bridgeService) GetMonitoredTxsByStatus(ctx context.Context, req *pb.Get } return &pb.CommonMonitoredTxsResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.MonitoredTxsDetail{HasNext: hasNext, Transactions: pbTransactions}, }, nil } @@ -405,7 +410,7 @@ func (s *bridgeService) GetMonitoredTxsByStatus(ctx context.Context, req *pb.Get // GetEstimateTime returns the estimated deposit waiting time for L1 and L2 func (s *bridgeService) GetEstimateTime(ctx context.Context, req *pb.GetEstimateTimeRequest) (*pb.CommonEstimateTimeResponse, error) { return &pb.CommonEstimateTimeResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: []uint32{estimatetime.GetDefaultCalculator().Get(0), estimatetime.GetDefaultCalculator().Get(1)}, }, nil } @@ -415,7 +420,7 @@ func (s *bridgeService) ManualClaim(ctx context.Context, req *pb.ManualClaimRequ // Only allow L1->L2 if req.FromChain != 0 { return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: "only allow L1->L2 claim", }, nil } @@ -425,7 +430,7 @@ func (s *bridgeService) ManualClaim(ctx context.Context, req *pb.ManualClaimRequ if err != nil { log.Errorf("Failed to get deposit: %v", err) return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: "failed to get deposit info", }, nil } @@ -433,7 +438,7 @@ func (s *bridgeService) ManualClaim(ctx context.Context, req *pb.ManualClaimRequ // Only allow to claim ready transactions if !deposit.ReadyForClaim { return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: "transaction is not ready for claim", }, nil } @@ -442,13 +447,13 @@ func (s *bridgeService) ManualClaim(ctx context.Context, req *pb.ManualClaimRequ _, err = s.storage.GetClaim(ctx, deposit.DepositCount, deposit.DestinationNetwork, nil) if err == nil { return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: "transaction has already been claimed", }, nil } if !errors.Is(err, gerror.ErrStorageNotFound) { return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), }, nil } @@ -457,7 +462,7 @@ func (s *bridgeService) ManualClaim(ctx context.Context, req *pb.ManualClaimRequ if !ok || client == nil { log.Errorf("node client for networkID %v not found", destNet) return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), }, nil } // Get the claim proof @@ -478,13 +483,13 @@ func (s *bridgeService) ManualClaim(ctx context.Context, req *pb.ManualClaimRequ if err != nil { log.Errorf("failed to send claim transaction: %v", err) return &pb.CommonManualClaimResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: "failed to send claim transaction", }, nil } return &pb.CommonManualClaimResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.ManualClaimResponse{ ClaimTxHash: tx.Hash().String(), }, @@ -503,11 +508,10 @@ func (s *bridgeService) GetReadyPendingTransactions(ctx context.Context, req *pb minReadyTime := time.Now().Add(time.Duration(-minReadyTimeLimitForWaitClaimSeconds.Get()) * time.Second) - deposits, err := s.storage.GetReadyPendingTransactions(ctx, uint(req.NetworkId), uint(utils.LeafTypeAsset), uint(limit+1), uint(req.Offset), minReadyTime, nil) + deposits, err := s.storage.GetReadyPendingTransactions(ctx, uint(req.NetworkId), uint(limit+1), uint(req.Offset), minReadyTime, nil) if err != nil { return &pb.CommonTransactionsResponse{ - Code: defaultErrorCode, - Data: nil, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), }, nil } @@ -526,7 +530,7 @@ func (s *bridgeService) GetReadyPendingTransactions(ctx context.Context, req *pb } return &pb.CommonTransactionsResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: &pb.TransactionDetail{HasNext: hasNext, Transactions: pbTransactions}, }, nil } @@ -541,13 +545,13 @@ func (s *bridgeService) getGlobalIndex(deposit *etherman.Deposit) *big.Int { func (s *bridgeService) GetFakePushMessages(ctx context.Context, req *pb.GetFakePushMessagesRequest) (*pb.GetFakePushMessagesResponse, error) { if s.messagePushProducer == nil { return &pb.GetFakePushMessagesResponse{ - Code: defaultErrorCode, + Code: uint32(pb.ErrorCode_ERROR_DEFAULT), Msg: "producer is nil", }, nil } return &pb.GetFakePushMessagesResponse{ - Code: defaultSuccessCode, + Code: uint32(pb.ErrorCode_ERROR_OK), Data: s.messagePushProducer.GetFakeMessages(req.Topic), }, nil } diff --git a/server/tokenlogoinfo/Client.go b/server/tokenlogoinfo/Client.go new file mode 100644 index 00000000..7e0367d5 --- /dev/null +++ b/server/tokenlogoinfo/Client.go @@ -0,0 +1,126 @@ +package tokenlogoinfo + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/0xPolygonHermez/zkevm-bridge-service/models/tokenlogo" + "github.com/0xPolygonHermez/zkevm-bridge-service/nacos" + "github.com/0xPolygonHermez/zkevm-node/log" +) + +const ( + endpointGetLogoInfos = "/priapi/v1/oc/web-common/coin/getLogoInfoBatch" + ChainNativeTokenAddr = "0x0000000000000000000000000000000000000000" + EmptyStr = "" +) + +type Client struct { + cfg Config + httpClient *http.Client +} + +var ( + client *Client +) + +func GetClient() *Client { + return client +} + +func InitClient(c Config) { + if !c.Enabled { + return + } + if c.LogoServiceNacosName == "" { + log.Errorf("token logo service name is empty") + return + } + client = &Client{ + cfg: c, + httpClient: &http.Client{ + Timeout: c.Timeout.Duration, + }, + } +} + +func (c *Client) GetTokenLogoInfos(tokenAddArr []*tokenlogo.QueryLogoParam) (map[string]tokenlogo.LogoInfo, error) { + if c == nil { + log.Infof("init logo info client failed, so skip") + return nil, nil + } + if !c.cfg.Enabled { + log.Infof("get token logo enable is false, so skip") + return nil, nil + } + host, err := nacos.GetOneURL(c.cfg.LogoServiceNacosName) + if err != nil { + log.Errorf("[getTokenLogoInfos] cannot get URL from nacos service, name[%v] err[%v]", c.cfg.LogoServiceNacosName, err) + return nil, err + } + host = c.cfg.Scheme + "://" + host + fullPath, err := url.JoinPath(host, endpointGetLogoInfos) + if err != nil { + log.Errorf("[getTokenLogoInfos] JoinPath err[%v] host[%v] endpoint[%v]", err, host, endpointGetLogoInfos) + return nil, err + } + postBody, _ := json.Marshal(tokenAddArr) + requestBody := bytes.NewBuffer(postBody) + req, err := http.NewRequest("POST", fullPath, requestBody) + if err != nil { + log.Errorf("[getTokenLogoInfos] create request failed err[%v] full path[%v]", err, fullPath) + return nil, err + } + req.Header.Set("Content-Type", "application/json") + resp, err := c.httpClient.Do(req) + if err != nil { + log.Errorf("[getTokenLogoInfos] call logo service failed err[%v] full path[%v]", err, fullPath) + return nil, err + } + if resp.StatusCode != http.StatusOK { + log.Errorf("[getTokenLogoInfos] http status code [%v] url[%v]", resp.StatusCode, fullPath) + return nil, nil + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + log.Errorf("[getTokenLogoInfos] close response body failed, err [%v]", err) + } + }(resp.Body) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Errorf("[getTokenLogoInfos] failed to read resp body err[%v]", err) + return nil, err + } + respStruct := &tokenlogo.GetTokenLogosResponse{} + err = json.Unmarshal(respBody, respStruct) + if err != nil { + log.Errorf("[getTokenLogoInfos] failed to convert resp to struct, resp [%v] err[%v]", string(respBody), err) + return nil, err + } + logoMap := make(map[string]tokenlogo.LogoInfo, len(respStruct.Data)) + for _, v := range respStruct.Data { + chainId, errConvert := strconv.ParseInt(v.ChainIdStr, 10, 64) + if errConvert != nil { + log.Errorf("token: %v convert chain id to uint failed, chain str: %v, err: %v", v.TokenContractAddress, v.ChainIdStr, errConvert) + continue + } + logoMap[GetTokenLogoMapKey(v.TokenContractAddress, uint32(chainId))] = v + } + convertRet, _ := json.Marshal(logoMap) + log.Debugf("request token info by rpc, final ret: %v", convertRet) + return logoMap, nil +} + +func GetTokenLogoMapKey(tokenAddr string, chainId uint32) string { + if tokenAddr == ChainNativeTokenAddr { + tokenAddr = EmptyStr + } + return fmt.Sprintf("%s_%d", strings.ToLower(tokenAddr), chainId) +} diff --git a/server/tokenlogoinfo/Config.go b/server/tokenlogoinfo/Config.go new file mode 100644 index 00000000..09d24f6c --- /dev/null +++ b/server/tokenlogoinfo/Config.go @@ -0,0 +1,12 @@ +package tokenlogoinfo + +import ( + "github.com/0xPolygonHermez/zkevm-node/config/types" +) + +type Config struct { + Enabled bool `mapstructure:"Enabled"` + LogoServiceNacosName string `mapstructure:"LogoServiceNacosName"` + Timeout types.Duration `mapstructure:"TimeoutSeconds"` + Scheme string `mapstructure:"Scheme"` +} diff --git a/server/tokenlogoinfo/logohelper.go b/server/tokenlogoinfo/logohelper.go new file mode 100644 index 00000000..eb31ad4a --- /dev/null +++ b/server/tokenlogoinfo/logohelper.go @@ -0,0 +1,80 @@ +package tokenlogoinfo + +import ( + "context" + + "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl/pb" + "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/models/tokenlogo" + "github.com/0xPolygonHermez/zkevm-bridge-service/redisstorage" + "github.com/0xPolygonHermez/zkevm-bridge-service/utils" + "github.com/pkg/errors" + "github.com/redis/go-redis/v9" +) + +func FillLogoInfos(ctx context.Context, redisStorage redisstorage.RedisStorage, transactionMap map[string][]*pb.Transaction) { + noCacheTokenMap := make(map[uint32][]string) + for k, v := range transactionMap { + chainId := utils.GetChainIdByNetworkId(uint(v[0].OriginalNetwork)) + logoInfo, err := redisStorage.GetTokenLogoInfo(ctx, k) + if err != nil { + if !errors.Is(err, redis.Nil) { + log.Errorf("get token logo info failed, so use rpc to fetch, chainId: %v, token: %v, error: %v", chainId, v[0].BridgeToken, err) + } + log.Infof("token need to use rpc to get logo, token: %v, chainId: %v", v[0].BridgeToken, chainId) + noCacheTokenMap[chainId] = append(noCacheTokenMap[chainId], v[0].BridgeToken) + continue + } + for _, tx := range v { + fillOneTxLogoInfo(tx, *logoInfo) + } + } + if len(noCacheTokenMap) == 0 { + return + } + logoParams := buildQueryLogoParams(noCacheTokenMap) + tokenLogoMap, err := GetClient().GetTokenLogoInfos(logoParams) + if err != nil { + log.Errorf("get token logo infos by rpc failed, so skip these tokens") + return + } + if len(tokenLogoMap) == 0 { + log.Infof("get token logo infos, but result is empty, so skip these tokens") + return + } + for k, v := range tokenLogoMap { + for _, tx := range transactionMap[k] { + fillOneTxLogoInfo(tx, v) + } + err = redisStorage.SetTokenLogoInfo(ctx, k, v) + if err != nil { + log.Errorf("failed to set logo info cache for token: %v", v.TokenContractAddress) + } + } +} + +func buildQueryLogoParams(noCacheTokenMap map[uint32][]string) []*tokenlogo.QueryLogoParam { + var logoParams []*tokenlogo.QueryLogoParam + for k, v := range noCacheTokenMap { + for _, addr := range v { + finalAddr := addr + if addr == ChainNativeTokenAddr { + finalAddr = EmptyStr + } + logoParams = append(logoParams, &tokenlogo.QueryLogoParam{ + ChainId: k, + TokenContractAddress: finalAddr, + }) + } + } + return logoParams +} + +func fillOneTxLogoInfo(tx *pb.Transaction, logoInfo tokenlogo.LogoInfo) { + tx.LogoInfo = &pb.TokenLogoInfo{ + Symbol: logoInfo.TokenSymbol, + TokenName: logoInfo.TokenName, + LogoOssUrl: logoInfo.LogoOssUrl, + Decimal: logoInfo.Unit, + } +} diff --git a/synchronizer/interfaces.go b/synchronizer/interfaces.go index a7748e2e..37f6fa6b 100644 --- a/synchronizer/interfaces.go +++ b/synchronizer/interfaces.go @@ -40,6 +40,7 @@ type storageInterface interface { // XLayer GetDeposit(ctx context.Context, depositCounterUser uint, networkID uint, dbTx pgx.Tx) (*etherman.Deposit, error) + AddDepositXLayer(ctx context.Context, deposit *etherman.Deposit, dbTx pgx.Tx) (uint64, error) } type bridgectrlInterface interface { diff --git a/synchronizer/mock_bridgectrl.go b/synchronizer/mock_bridgectrl.go index f7c1e9d1..5df28ee1 100644 --- a/synchronizer/mock_bridgectrl.go +++ b/synchronizer/mock_bridgectrl.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.39.0. DO NOT EDIT. +// Code generated by mockery v2.28.1. DO NOT EDIT. package synchronizer @@ -20,10 +20,6 @@ type bridgectrlMock struct { func (_m *bridgectrlMock) AddDeposit(ctx context.Context, deposit *etherman.Deposit, depositID uint64, dbTx pgx.Tx) error { ret := _m.Called(ctx, deposit, depositID, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddDeposit") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.Deposit, uint64, pgx.Tx) error); ok { r0 = rf(ctx, deposit, depositID, dbTx) @@ -38,10 +34,6 @@ func (_m *bridgectrlMock) AddDeposit(ctx context.Context, deposit *etherman.Depo func (_m *bridgectrlMock) AddRollupExitLeaf(ctx context.Context, rollupLeaf etherman.RollupExitLeaf, dbTx pgx.Tx) error { ret := _m.Called(ctx, rollupLeaf, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddRollupExitLeaf") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, etherman.RollupExitLeaf, pgx.Tx) error); ok { r0 = rf(ctx, rollupLeaf, dbTx) @@ -56,10 +48,6 @@ func (_m *bridgectrlMock) AddRollupExitLeaf(ctx context.Context, rollupLeaf ethe func (_m *bridgectrlMock) GetNetworkID(networkID uint) (uint8, error) { ret := _m.Called(networkID) - if len(ret) == 0 { - panic("no return value specified for GetNetworkID") - } - var r0 uint8 var r1 error if rf, ok := ret.Get(0).(func(uint) (uint8, error)); ok { @@ -84,10 +72,6 @@ func (_m *bridgectrlMock) GetNetworkID(networkID uint) (uint8, error) { func (_m *bridgectrlMock) ReorgMT(ctx context.Context, depositCount uint, networkID uint, dbTx pgx.Tx) error { ret := _m.Called(ctx, depositCount, networkID, dbTx) - if len(ret) == 0 { - panic("no return value specified for ReorgMT") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, uint, uint, pgx.Tx) error); ok { r0 = rf(ctx, depositCount, networkID, dbTx) @@ -98,12 +82,13 @@ func (_m *bridgectrlMock) ReorgMT(ctx context.Context, depositCount uint, networ return r0 } -// newBridgectrlMock creates a new instance of bridgectrlMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func newBridgectrlMock(t interface { +type mockConstructorTestingTnewBridgectrlMock interface { mock.TestingT Cleanup(func()) -}) *bridgectrlMock { +} + +// newBridgectrlMock creates a new instance of bridgectrlMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func newBridgectrlMock(t mockConstructorTestingTnewBridgectrlMock) *bridgectrlMock { mock := &bridgectrlMock{} mock.Mock.Test(t) diff --git a/synchronizer/mock_dbtx.go b/synchronizer/mock_dbtx.go index e3a48a61..fd8ed224 100644 --- a/synchronizer/mock_dbtx.go +++ b/synchronizer/mock_dbtx.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.39.0. DO NOT EDIT. +// Code generated by mockery v2.28.1. DO NOT EDIT. package synchronizer @@ -20,10 +20,6 @@ type dbTxMock struct { func (_m *dbTxMock) Begin(ctx context.Context) (pgx.Tx, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for Begin") - } - var r0 pgx.Tx var r1 error if rf, ok := ret.Get(0).(func(context.Context) (pgx.Tx, error)); ok { @@ -50,10 +46,6 @@ func (_m *dbTxMock) Begin(ctx context.Context) (pgx.Tx, error) { func (_m *dbTxMock) BeginFunc(ctx context.Context, f func(pgx.Tx) error) error { ret := _m.Called(ctx, f) - if len(ret) == 0 { - panic("no return value specified for BeginFunc") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, func(pgx.Tx) error) error); ok { r0 = rf(ctx, f) @@ -68,10 +60,6 @@ func (_m *dbTxMock) BeginFunc(ctx context.Context, f func(pgx.Tx) error) error { func (_m *dbTxMock) Commit(ctx context.Context) error { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for Commit") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) @@ -86,10 +74,6 @@ func (_m *dbTxMock) Commit(ctx context.Context) error { func (_m *dbTxMock) Conn() *pgx.Conn { ret := _m.Called() - if len(ret) == 0 { - panic("no return value specified for Conn") - } - var r0 *pgx.Conn if rf, ok := ret.Get(0).(func() *pgx.Conn); ok { r0 = rf() @@ -106,10 +90,6 @@ func (_m *dbTxMock) Conn() *pgx.Conn { func (_m *dbTxMock) CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) { ret := _m.Called(ctx, tableName, columnNames, rowSrc) - if len(ret) == 0 { - panic("no return value specified for CopyFrom") - } - var r0 int64 var r1 error if rf, ok := ret.Get(0).(func(context.Context, pgx.Identifier, []string, pgx.CopyFromSource) (int64, error)); ok { @@ -137,10 +117,6 @@ func (_m *dbTxMock) Exec(ctx context.Context, sql string, arguments ...interface _ca = append(_ca, arguments...) ret := _m.Called(_ca...) - if len(ret) == 0 { - panic("no return value specified for Exec") - } - var r0 pgconn.CommandTag var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, ...interface{}) (pgconn.CommandTag, error)); ok { @@ -167,10 +143,6 @@ func (_m *dbTxMock) Exec(ctx context.Context, sql string, arguments ...interface func (_m *dbTxMock) LargeObjects() pgx.LargeObjects { ret := _m.Called() - if len(ret) == 0 { - panic("no return value specified for LargeObjects") - } - var r0 pgx.LargeObjects if rf, ok := ret.Get(0).(func() pgx.LargeObjects); ok { r0 = rf() @@ -185,10 +157,6 @@ func (_m *dbTxMock) LargeObjects() pgx.LargeObjects { func (_m *dbTxMock) Prepare(ctx context.Context, name string, sql string) (*pgconn.StatementDescription, error) { ret := _m.Called(ctx, name, sql) - if len(ret) == 0 { - panic("no return value specified for Prepare") - } - var r0 *pgconn.StatementDescription var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string) (*pgconn.StatementDescription, error)); ok { @@ -218,10 +186,6 @@ func (_m *dbTxMock) Query(ctx context.Context, sql string, args ...interface{}) _ca = append(_ca, args...) ret := _m.Called(_ca...) - if len(ret) == 0 { - panic("no return value specified for Query") - } - var r0 pgx.Rows var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, ...interface{}) (pgx.Rows, error)); ok { @@ -248,10 +212,6 @@ func (_m *dbTxMock) Query(ctx context.Context, sql string, args ...interface{}) func (_m *dbTxMock) QueryFunc(ctx context.Context, sql string, args []interface{}, scans []interface{}, f func(pgx.QueryFuncRow) error) (pgconn.CommandTag, error) { ret := _m.Called(ctx, sql, args, scans, f) - if len(ret) == 0 { - panic("no return value specified for QueryFunc") - } - var r0 pgconn.CommandTag var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, []interface{}, []interface{}, func(pgx.QueryFuncRow) error) (pgconn.CommandTag, error)); ok { @@ -281,10 +241,6 @@ func (_m *dbTxMock) QueryRow(ctx context.Context, sql string, args ...interface{ _ca = append(_ca, args...) ret := _m.Called(_ca...) - if len(ret) == 0 { - panic("no return value specified for QueryRow") - } - var r0 pgx.Row if rf, ok := ret.Get(0).(func(context.Context, string, ...interface{}) pgx.Row); ok { r0 = rf(ctx, sql, args...) @@ -301,10 +257,6 @@ func (_m *dbTxMock) QueryRow(ctx context.Context, sql string, args ...interface{ func (_m *dbTxMock) Rollback(ctx context.Context) error { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for Rollback") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) @@ -319,10 +271,6 @@ func (_m *dbTxMock) Rollback(ctx context.Context) error { func (_m *dbTxMock) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults { ret := _m.Called(ctx, b) - if len(ret) == 0 { - panic("no return value specified for SendBatch") - } - var r0 pgx.BatchResults if rf, ok := ret.Get(0).(func(context.Context, *pgx.Batch) pgx.BatchResults); ok { r0 = rf(ctx, b) @@ -335,12 +283,13 @@ func (_m *dbTxMock) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResult return r0 } -// newDbTxMock creates a new instance of dbTxMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func newDbTxMock(t interface { +type mockConstructorTestingTnewDbTxMock interface { mock.TestingT Cleanup(func()) -}) *dbTxMock { +} + +// newDbTxMock creates a new instance of dbTxMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func newDbTxMock(t mockConstructorTestingTnewDbTxMock) *dbTxMock { mock := &dbTxMock{} mock.Mock.Test(t) diff --git a/synchronizer/mock_etherman.go b/synchronizer/mock_etherman.go index 74ced374..8930dadb 100644 --- a/synchronizer/mock_etherman.go +++ b/synchronizer/mock_etherman.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.39.0. DO NOT EDIT. +// Code generated by mockery v2.28.1. DO NOT EDIT. package synchronizer @@ -24,10 +24,6 @@ type ethermanMock struct { func (_m *ethermanMock) EthBlockByNumber(ctx context.Context, blockNumber uint64) (*types.Block, error) { ret := _m.Called(ctx, blockNumber) - if len(ret) == 0 { - panic("no return value specified for EthBlockByNumber") - } - var r0 *types.Block var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint64) (*types.Block, error)); ok { @@ -54,10 +50,6 @@ func (_m *ethermanMock) EthBlockByNumber(ctx context.Context, blockNumber uint64 func (_m *ethermanMock) GetNetworkID(ctx context.Context) (uint, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for GetNetworkID") - } - var r0 uint var r1 error if rf, ok := ret.Get(0).(func(context.Context) (uint, error)); ok { @@ -82,10 +74,6 @@ func (_m *ethermanMock) GetNetworkID(ctx context.Context) (uint, error) { func (_m *ethermanMock) GetRollupID() uint { ret := _m.Called() - if len(ret) == 0 { - panic("no return value specified for GetRollupID") - } - var r0 uint if rf, ok := ret.Get(0).(func() uint); ok { r0 = rf() @@ -100,10 +88,6 @@ func (_m *ethermanMock) GetRollupID() uint { func (_m *ethermanMock) GetRollupInfoByBlockRange(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]etherman.Block, map[common.Hash][]etherman.Order, error) { ret := _m.Called(ctx, fromBlock, toBlock) - if len(ret) == 0 { - panic("no return value specified for GetRollupInfoByBlockRange") - } - var r0 []etherman.Block var r1 map[common.Hash][]etherman.Order var r2 error @@ -139,10 +123,6 @@ func (_m *ethermanMock) GetRollupInfoByBlockRange(ctx context.Context, fromBlock func (_m *ethermanMock) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { ret := _m.Called(ctx, number) - if len(ret) == 0 { - panic("no return value specified for HeaderByNumber") - } - var r0 *types.Header var r1 error if rf, ok := ret.Get(0).(func(context.Context, *big.Int) (*types.Header, error)); ok { @@ -165,12 +145,13 @@ func (_m *ethermanMock) HeaderByNumber(ctx context.Context, number *big.Int) (*t return r0, r1 } -// newEthermanMock creates a new instance of ethermanMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func newEthermanMock(t interface { +type mockConstructorTestingTnewEthermanMock interface { mock.TestingT Cleanup(func()) -}) *ethermanMock { +} + +// newEthermanMock creates a new instance of ethermanMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func newEthermanMock(t mockConstructorTestingTnewEthermanMock) *ethermanMock { mock := ðermanMock{} mock.Mock.Test(t) diff --git a/synchronizer/mock_storage.go b/synchronizer/mock_storage.go index f7e7697d..ac974019 100644 --- a/synchronizer/mock_storage.go +++ b/synchronizer/mock_storage.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.39.0. DO NOT EDIT. +// Code generated by mockery v2.28.1. DO NOT EDIT. package synchronizer @@ -20,10 +20,6 @@ type storageMock struct { func (_m *storageMock) AddBlock(ctx context.Context, block *etherman.Block, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, block, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddBlock") - } - var r0 uint64 var r1 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.Block, pgx.Tx) (uint64, error)); ok { @@ -48,10 +44,6 @@ func (_m *storageMock) AddBlock(ctx context.Context, block *etherman.Block, dbTx func (_m *storageMock) AddClaim(ctx context.Context, claim *etherman.Claim, dbTx pgx.Tx) error { ret := _m.Called(ctx, claim, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddClaim") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.Claim, pgx.Tx) error); ok { r0 = rf(ctx, claim, dbTx) @@ -66,10 +58,30 @@ func (_m *storageMock) AddClaim(ctx context.Context, claim *etherman.Claim, dbTx func (_m *storageMock) AddDeposit(ctx context.Context, deposit *etherman.Deposit, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, deposit, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddDeposit") + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *etherman.Deposit, pgx.Tx) (uint64, error)); ok { + return rf(ctx, deposit, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, *etherman.Deposit, pgx.Tx) uint64); ok { + r0 = rf(ctx, deposit, dbTx) + } else { + r0 = ret.Get(0).(uint64) } + if rf, ok := ret.Get(1).(func(context.Context, *etherman.Deposit, pgx.Tx) error); ok { + r1 = rf(ctx, deposit, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// AddDepositXLayer provides a mock function with given fields: ctx, deposit, dbTx +func (_m *storageMock) AddDepositXLayer(ctx context.Context, deposit *etherman.Deposit, dbTx pgx.Tx) (uint64, error) { + ret := _m.Called(ctx, deposit, dbTx) + var r0 uint64 var r1 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.Deposit, pgx.Tx) (uint64, error)); ok { @@ -94,10 +106,6 @@ func (_m *storageMock) AddDeposit(ctx context.Context, deposit *etherman.Deposit func (_m *storageMock) AddGlobalExitRoot(ctx context.Context, exitRoot *etherman.GlobalExitRoot, dbTx pgx.Tx) error { ret := _m.Called(ctx, exitRoot, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddGlobalExitRoot") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.GlobalExitRoot, pgx.Tx) error); ok { r0 = rf(ctx, exitRoot, dbTx) @@ -112,10 +120,6 @@ func (_m *storageMock) AddGlobalExitRoot(ctx context.Context, exitRoot *etherman func (_m *storageMock) AddTokenWrapped(ctx context.Context, tokenWrapped *etherman.TokenWrapped, dbTx pgx.Tx) error { ret := _m.Called(ctx, tokenWrapped, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddTokenWrapped") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.TokenWrapped, pgx.Tx) error); ok { r0 = rf(ctx, tokenWrapped, dbTx) @@ -130,10 +134,6 @@ func (_m *storageMock) AddTokenWrapped(ctx context.Context, tokenWrapped *etherm func (_m *storageMock) AddTrustedGlobalExitRoot(ctx context.Context, trustedExitRoot *etherman.GlobalExitRoot, dbTx pgx.Tx) (bool, error) { ret := _m.Called(ctx, trustedExitRoot, dbTx) - if len(ret) == 0 { - panic("no return value specified for AddTrustedGlobalExitRoot") - } - var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context, *etherman.GlobalExitRoot, pgx.Tx) (bool, error)); ok { @@ -158,10 +158,6 @@ func (_m *storageMock) AddTrustedGlobalExitRoot(ctx context.Context, trustedExit func (_m *storageMock) BeginDBTransaction(ctx context.Context) (pgx.Tx, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for BeginDBTransaction") - } - var r0 pgx.Tx var r1 error if rf, ok := ret.Get(0).(func(context.Context) (pgx.Tx, error)); ok { @@ -188,10 +184,6 @@ func (_m *storageMock) BeginDBTransaction(ctx context.Context) (pgx.Tx, error) { func (_m *storageMock) CheckIfRootExists(ctx context.Context, root []byte, network uint8, dbTx pgx.Tx) (bool, error) { ret := _m.Called(ctx, root, network, dbTx) - if len(ret) == 0 { - panic("no return value specified for CheckIfRootExists") - } - var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context, []byte, uint8, pgx.Tx) (bool, error)); ok { @@ -216,10 +208,6 @@ func (_m *storageMock) CheckIfRootExists(ctx context.Context, root []byte, netwo func (_m *storageMock) Commit(ctx context.Context, dbTx pgx.Tx) error { ret := _m.Called(ctx, dbTx) - if len(ret) == 0 { - panic("no return value specified for Commit") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) error); ok { r0 = rf(ctx, dbTx) @@ -260,10 +248,6 @@ func (_m *storageMock) GetDeposit(ctx context.Context, depositCounterUser uint, func (_m *storageMock) GetLastBlock(ctx context.Context, networkID uint, dbTx pgx.Tx) (*etherman.Block, error) { ret := _m.Called(ctx, networkID, dbTx) - if len(ret) == 0 { - panic("no return value specified for GetLastBlock") - } - var r0 *etherman.Block var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint, pgx.Tx) (*etherman.Block, error)); ok { @@ -290,10 +274,6 @@ func (_m *storageMock) GetLastBlock(ctx context.Context, networkID uint, dbTx pg func (_m *storageMock) GetLatestL1SyncedExitRoot(ctx context.Context, dbTx pgx.Tx) (*etherman.GlobalExitRoot, error) { ret := _m.Called(ctx, dbTx) - if len(ret) == 0 { - panic("no return value specified for GetLatestL1SyncedExitRoot") - } - var r0 *etherman.GlobalExitRoot var r1 error if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) (*etherman.GlobalExitRoot, error)); ok { @@ -320,10 +300,6 @@ func (_m *storageMock) GetLatestL1SyncedExitRoot(ctx context.Context, dbTx pgx.T func (_m *storageMock) GetNumberDeposits(ctx context.Context, origNetworkID uint, blockNumber uint64, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, origNetworkID, blockNumber, dbTx) - if len(ret) == 0 { - panic("no return value specified for GetNumberDeposits") - } - var r0 uint64 var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint, uint64, pgx.Tx) (uint64, error)); ok { @@ -348,10 +324,6 @@ func (_m *storageMock) GetNumberDeposits(ctx context.Context, origNetworkID uint func (_m *storageMock) GetPreviousBlock(ctx context.Context, networkID uint, offset uint64, dbTx pgx.Tx) (*etherman.Block, error) { ret := _m.Called(ctx, networkID, offset, dbTx) - if len(ret) == 0 { - panic("no return value specified for GetPreviousBlock") - } - var r0 *etherman.Block var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint, uint64, pgx.Tx) (*etherman.Block, error)); ok { @@ -378,10 +350,6 @@ func (_m *storageMock) GetPreviousBlock(ctx context.Context, networkID uint, off func (_m *storageMock) IsLxLyActivated(ctx context.Context, dbTx pgx.Tx) (bool, error) { ret := _m.Called(ctx, dbTx) - if len(ret) == 0 { - panic("no return value specified for IsLxLyActivated") - } - var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) (bool, error)); ok { @@ -406,10 +374,6 @@ func (_m *storageMock) IsLxLyActivated(ctx context.Context, dbTx pgx.Tx) (bool, func (_m *storageMock) Reset(ctx context.Context, blockNumber uint64, networkID uint, dbTx pgx.Tx) error { ret := _m.Called(ctx, blockNumber, networkID, dbTx) - if len(ret) == 0 { - panic("no return value specified for Reset") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, uint64, uint, pgx.Tx) error); ok { r0 = rf(ctx, blockNumber, networkID, dbTx) @@ -424,10 +388,6 @@ func (_m *storageMock) Reset(ctx context.Context, blockNumber uint64, networkID func (_m *storageMock) Rollback(ctx context.Context, dbTx pgx.Tx) error { ret := _m.Called(ctx, dbTx) - if len(ret) == 0 { - panic("no return value specified for Rollback") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) error); ok { r0 = rf(ctx, dbTx) @@ -438,12 +398,13 @@ func (_m *storageMock) Rollback(ctx context.Context, dbTx pgx.Tx) error { return r0 } -// newStorageMock creates a new instance of storageMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func newStorageMock(t interface { +type mockConstructorTestingTnewStorageMock interface { mock.TestingT Cleanup(func()) -}) *storageMock { +} + +// newStorageMock creates a new instance of storageMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func newStorageMock(t mockConstructorTestingTnewStorageMock) *storageMock { mock := &storageMock{} mock.Mock.Test(t) diff --git a/synchronizer/mock_zkevmclient.go b/synchronizer/mock_zkevmclient.go index fb943353..79fc0626 100644 --- a/synchronizer/mock_zkevmclient.go +++ b/synchronizer/mock_zkevmclient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.39.0. DO NOT EDIT. +// Code generated by mockery v2.28.1. DO NOT EDIT. package synchronizer @@ -21,10 +21,6 @@ type zkEVMClientMock struct { func (_m *zkEVMClientMock) ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) { ret := _m.Called(ctx, globalExitRoot) - if len(ret) == 0 { - panic("no return value specified for ExitRootsByGER") - } - var r0 *types.ExitRoots var r1 error if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*types.ExitRoots, error)); ok { @@ -51,10 +47,6 @@ func (_m *zkEVMClientMock) ExitRootsByGER(ctx context.Context, globalExitRoot co func (_m *zkEVMClientMock) GetLatestGlobalExitRoot(ctx context.Context) (common.Hash, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for GetLatestGlobalExitRoot") - } - var r0 common.Hash var r1 error if rf, ok := ret.Get(0).(func(context.Context) (common.Hash, error)); ok { @@ -77,12 +69,13 @@ func (_m *zkEVMClientMock) GetLatestGlobalExitRoot(ctx context.Context) (common. return r0, r1 } -// newZkEVMClientMock creates a new instance of zkEVMClientMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func newZkEVMClientMock(t interface { +type mockConstructorTestingTnewZkEVMClientMock interface { mock.TestingT Cleanup(func()) -}) *zkEVMClientMock { +} + +// newZkEVMClientMock creates a new instance of zkEVMClientMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func newZkEVMClientMock(t mockConstructorTestingTnewZkEVMClientMock) *zkEVMClientMock { mock := &zkEVMClientMock{} mock.Mock.Test(t) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 43702b1b..8e84b313 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -10,6 +10,7 @@ import ( "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/0xPolygonHermez/zkevm-bridge-service/messagepush" + "github.com/0xPolygonHermez/zkevm-bridge-service/metrics" "github.com/0xPolygonHermez/zkevm-bridge-service/redisstorage" "github.com/0xPolygonHermez/zkevm-bridge-service/utils/gerror" "github.com/ethereum/go-ethereum/common" @@ -121,6 +122,7 @@ var waitDuration = time.Duration(0) // Sync function will read the last state synced and will continue from that point. // Sync() will read blockchain events to detect rollup updates func (s *ClientSynchronizer) Sync() error { + go s.recordLatestBlockNum() // If there is no lastEthereumBlock means that sync from the beginning is necessary. If not, it continues from the retrieved ethereum block // Get the latest synced block. If there is no block on db, use genesis block log.Infof("NetworkID: %d, Synchronization started", s.networkID) @@ -300,6 +302,7 @@ func (s *ClientSynchronizer) syncBlocks(lastBlockSynced *etherman.Block) (*ether s.synced = true s.chSynced <- s.networkID } + metrics.RecordLastSyncedBlockNum(uint32(s.networkID), lastKnownBlock.Uint64()) break } if len(blocks) == 0 { // If there is no events in the checked blocks range and lastKnownBlock > fromBlock. @@ -323,6 +326,7 @@ func (s *ClientSynchronizer) syncBlocks(lastBlockSynced *etherman.Block) (*ether log.Debugf("NetworkID: %d, Storing empty block. BlockNumber: %d. BlockHash: %s", s.networkID, b.BlockNumber, b.BlockHash.String()) } + metrics.RecordLastSyncedBlockNum(uint32(s.networkID), lastBlockSynced.BlockNumber) } return lastBlockSynced, nil @@ -394,6 +398,8 @@ func (s *ClientSynchronizer) processBlockRange(blocks []etherman.Block, order ma // this is activated when the bridge detects the CreateNewRollup or the AddExistingRollup event from the rollupManager log.Info("Event received. Activating LxLyEtrog...") } + + metrics.RecordSynchronizerEvent(uint32(s.networkID), string(element.Name)) } log.Infof("NetworkID: %d. block %d element number %d", s.networkID, blocks[i].BlockNumber, counter) err = s.storage.Commit(s.ctx, dbTx) @@ -594,9 +600,10 @@ func (s *ClientSynchronizer) processGlobalExitRoot(globalExitRoot etherman.Globa } func (s *ClientSynchronizer) processDeposit(deposit etherman.Deposit, blockID uint64, dbTx pgx.Tx) error { + s.beforeProcessDeposit(&deposit) deposit.BlockID = blockID deposit.NetworkID = s.networkID - depositID, err := s.storage.AddDeposit(s.ctx, &deposit, dbTx) + depositID, err := s.storage.AddDepositXLayer(s.ctx, &deposit, dbTx) if err != nil { log.Errorf("networkID: %d, failed to store new deposit locally, BlockNumber: %d, Deposit: %+v err: %v", s.networkID, deposit.BlockNumber, deposit, err) rollbackErr := s.storage.Rollback(s.ctx, dbTx) diff --git a/synchronizer/synchronizer_xlayer.go b/synchronizer/synchronizer_xlayer.go index f6d2878b..36022fa1 100644 --- a/synchronizer/synchronizer_xlayer.go +++ b/synchronizer/synchronizer_xlayer.go @@ -3,16 +3,27 @@ package synchronizer import ( "context" "math/big" + "time" "github.com/0xPolygonHermez/zkevm-bridge-service/bridgectrl/pb" "github.com/0xPolygonHermez/zkevm-bridge-service/estimatetime" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/metrics" "github.com/0xPolygonHermez/zkevm-bridge-service/pushtask" + "github.com/0xPolygonHermez/zkevm-bridge-service/server/tokenlogoinfo" "github.com/0xPolygonHermez/zkevm-bridge-service/utils" "github.com/jackc/pgx/v4" ) +func (s *ClientSynchronizer) beforeProcessDeposit(deposit *etherman.Deposit) { + // If the deposit is USDC LxLy message, extract the user address from the metadata + if deposit.LeafType == uint8(utils.LeafTypeMessage) && utils.IsUSDCContractAddress(deposit.OriginalAddress) { + deposit.DestContractAddress = deposit.DestinationAddress + deposit.DestinationAddress, _ = utils.DecodeUSDCBridgeMetadata(deposit.Metadata) + } +} + func (s *ClientSynchronizer) afterProcessDeposit(deposit *etherman.Deposit, depositID uint64, dbTx pgx.Tx) error { // Add the deposit to Redis for L1 if deposit.NetworkID == 0 { @@ -29,6 +40,11 @@ func (s *ClientSynchronizer) afterProcessDeposit(deposit *etherman.Deposit, depo } } + // Original address is needed for message allow list check, but it may be changed when we replace USDC info + origAddress := deposit.OriginalAddress + // Replace the USDC info here so that the metrics can report the correct token info + utils.ReplaceUSDCDepositInfo(deposit, true) + // Notify FE about a new deposit go func() { if s.messagePushProducer == nil { @@ -36,30 +52,42 @@ func (s *ClientSynchronizer) afterProcessDeposit(deposit *etherman.Deposit, depo return } if deposit.LeafType != uint8(utils.LeafTypeAsset) { - log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) - return + if !utils.IsUSDCContractAddress(origAddress) { + log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) + return + } } - err := s.messagePushProducer.PushTransactionUpdate(&pb.Transaction{ - FromChain: uint32(deposit.NetworkID), - ToChain: uint32(deposit.DestinationNetwork), - BridgeToken: deposit.OriginalAddress.Hex(), - TokenAmount: deposit.Amount.String(), - EstimateTime: s.getEstimateTimeForDepositCreated(deposit.NetworkID), - Time: uint64(deposit.Time.UnixMilli()), - TxHash: deposit.TxHash.String(), - Id: depositID, - Index: uint64(deposit.DepositCount), - Status: uint32(pb.TransactionStatus_TX_CREATED), - BlockNumber: deposit.BlockNumber, - DestAddr: deposit.DestinationAddress.Hex(), - FromChainId: utils.GetChainIdByNetworkId(deposit.NetworkID), - ToChainId: utils.GetChainIdByNetworkId(deposit.DestinationNetwork), - GlobalIndex: s.getGlobalIndex(deposit).String(), - }) + transaction := &pb.Transaction{ + FromChain: uint32(deposit.NetworkID), + ToChain: uint32(deposit.DestinationNetwork), + BridgeToken: deposit.OriginalAddress.Hex(), + TokenAmount: deposit.Amount.String(), + EstimateTime: s.getEstimateTimeForDepositCreated(deposit.NetworkID), + Time: uint64(deposit.Time.UnixMilli()), + TxHash: deposit.TxHash.String(), + Id: depositID, + Index: uint64(deposit.DepositCount), + Status: uint32(pb.TransactionStatus_TX_CREATED), + BlockNumber: deposit.BlockNumber, + DestAddr: deposit.DestinationAddress.Hex(), + FromChainId: utils.GetChainIdByNetworkId(deposit.NetworkID), + ToChainId: utils.GetChainIdByNetworkId(deposit.DestinationNetwork), + GlobalIndex: s.getGlobalIndex(deposit).String(), + LeafType: uint32(deposit.LeafType), + OriginalNetwork: uint32(deposit.OriginalNetwork), + } + transactionMap := make(map[string][]*pb.Transaction) + chainId := utils.GetChainIdByNetworkId(deposit.OriginalNetwork) + logoCacheKey := tokenlogoinfo.GetTokenLogoMapKey(transaction.GetBridgeToken(), chainId) + transactionMap[logoCacheKey] = append(transactionMap[logoCacheKey], transaction) + tokenlogoinfo.FillLogoInfos(s.ctx, s.redisStorage, transactionMap) + err := s.messagePushProducer.PushTransactionUpdate(transaction) if err != nil { log.Errorf("PushTransactionUpdate error: %v", err) } }() + + metrics.RecordOrder(uint32(deposit.NetworkID), uint32(deposit.DestinationNetwork), uint32(deposit.LeafType), uint32(deposit.OriginalNetwork), deposit.OriginalAddress, deposit.Amount) return nil } @@ -90,8 +118,10 @@ func (s *ClientSynchronizer) afterProcessClaim(claim *etherman.Claim) error { return } if deposit.LeafType != uint8(utils.LeafTypeAsset) { - log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) - return + if !utils.IsUSDCContractAddress(deposit.OriginalAddress) { + log.Infof("transaction is not asset, so skip push update change, hash: %v", deposit.TxHash) + return + } } err = s.messagePushProducer.PushTransactionUpdate(&pb.Transaction{ FromChain: uint32(deposit.NetworkID), @@ -116,3 +146,19 @@ func (s *ClientSynchronizer) getGlobalIndex(deposit *etherman.Deposit) *big.Int rollupIndex := s.rollupID - 1 return etherman.GenerateGlobalIndex(isMainnet, rollupIndex, deposit.DepositCount) } + +// recordLatestBlockNum continuously records the latest block number to prometheus metrics +func (s *ClientSynchronizer) recordLatestBlockNum() { + log.Debugf("Start recordLatestBlockNum") + ticker := time.NewTicker(2 * time.Second) //nolint:gomnd + + for range ticker.C { + // Get the latest block header + header, err := s.etherMan.HeaderByNumber(s.ctx, nil) + if err != nil { + log.Errorf("HeaderByNumber err: %v", err) + continue + } + metrics.RecordLatestBlockNum(uint32(s.networkID), header.Number.Uint64()) + } +} diff --git a/utils/client_xlayer.go b/utils/client_xlayer.go index 075a1ed5..be83b036 100644 --- a/utils/client_xlayer.go +++ b/utils/client_xlayer.go @@ -2,13 +2,55 @@ package utils import ( "context" + "fmt" + "math/big" "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" "github.com/0xPolygonHermez/zkevm-bridge-service/log" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) +// BuildSendClaimXLayer builds a tx data to be sent to the bridge method SendClaim. +func (c *Client) BuildSendClaimXLayer(ctx context.Context, deposit *etherman.Deposit, smtProof [mtHeight][keyLen]byte, smtRollupProof [mtHeight][keyLen]byte, globalExitRoot *etherman.GlobalExitRoot, nonce, gasPrice int64, gasLimit uint64, rollupID uint, auth *bind.TransactOpts) (*types.Transaction, error) { + opts := *auth + opts.NoSend = true + // force nonce, gas limit and gas price to avoid querying it from the chain + opts.Nonce = big.NewInt(nonce) + opts.GasPrice = big.NewInt(gasPrice) + opts.GasLimit = gasLimit + + var ( + tx *types.Transaction + err error + ) + mainnetFlag := deposit.NetworkID == 0 + rollupIndex := rollupID - 1 + localExitRootIndex := deposit.DepositCount + globalIndex := etherman.GenerateGlobalIndex(mainnetFlag, rollupIndex, localExitRootIndex) + if deposit.LeafType == uint8(LeafTypeAsset) { + tx, err = c.bridge.ClaimAsset(&opts, smtProof, smtRollupProof, globalIndex, globalExitRoot.ExitRoots[0], globalExitRoot.ExitRoots[1], uint32(deposit.OriginalNetwork), deposit.OriginalAddress, uint32(deposit.DestinationNetwork), deposit.DestinationAddress, deposit.Amount, deposit.Metadata) + } else if deposit.LeafType == uint8(LeafTypeMessage) { + destAddr := deposit.DestinationAddress + emptyAddress := common.Address{} + if deposit.DestContractAddress != emptyAddress { + destAddr = deposit.DestContractAddress + } + tx, err = c.bridge.ClaimMessage(&opts, smtProof, smtRollupProof, globalIndex, globalExitRoot.ExitRoots[0], globalExitRoot.ExitRoots[1], uint32(deposit.OriginalNetwork), deposit.OriginalAddress, uint32(deposit.DestinationNetwork), destAddr, deposit.Amount, deposit.Metadata) + } + if err != nil { + txHash := "" + if tx != nil { + txHash = tx.Hash().String() + } + log.Error("Error: ", err, ". Tx Hash: ", txHash) + return nil, fmt.Errorf("failed to build SendClaim tx, err: %v", err) + } + + return tx, nil +} + // SendClaimXLayer sends a claim transaction func (c *Client) SendClaimXLayer(ctx context.Context, deposit *etherman.Deposit, smtProof, rollupSmtProof [mtHeight][keyLen]byte, globalExitRoot *etherman.GlobalExitRoot, rollupID uint, auth *bind.TransactOpts) (*types.Transaction, error) { var ( @@ -22,7 +64,12 @@ func (c *Client) SendClaimXLayer(ctx context.Context, deposit *etherman.Deposit, if deposit.LeafType == uint8(LeafTypeAsset) { tx, err = c.bridge.ClaimAsset(auth, smtProof, rollupSmtProof, globalIndex, globalExitRoot.ExitRoots[0], globalExitRoot.ExitRoots[1], uint32(deposit.OriginalNetwork), deposit.OriginalAddress, uint32(deposit.DestinationNetwork), deposit.DestinationAddress, deposit.Amount, deposit.Metadata) } else if deposit.LeafType == uint8(LeafTypeMessage) { - tx, err = c.bridge.ClaimMessage(auth, smtProof, rollupSmtProof, globalIndex, globalExitRoot.ExitRoots[0], globalExitRoot.ExitRoots[1], uint32(deposit.OriginalNetwork), deposit.OriginalAddress, uint32(deposit.DestinationNetwork), deposit.DestinationAddress, deposit.Amount, deposit.Metadata) + destAddr := deposit.DestinationAddress + emptyAddress := common.Address{} + if deposit.DestContractAddress != emptyAddress { + destAddr = deposit.DestContractAddress + } + tx, err = c.bridge.ClaimMessage(auth, smtProof, rollupSmtProof, globalIndex, globalExitRoot.ExitRoots[0], globalExitRoot.ExitRoots[1], uint32(deposit.OriginalNetwork), deposit.OriginalAddress, uint32(deposit.DestinationNetwork), destAddr, deposit.Amount, deposit.Metadata) } if err != nil { txHash := "" diff --git a/utils/helpers_xlayer.go b/utils/helpers_xlayer.go index 37914874..9cc71f62 100644 --- a/utils/helpers_xlayer.go +++ b/utils/helpers_xlayer.go @@ -38,20 +38,22 @@ func EthermanDepositToPbTransaction(deposit *etherman.Deposit) *pb.Transaction { } return &pb.Transaction{ - FromChain: uint32(deposit.NetworkID), - ToChain: uint32(deposit.DestinationNetwork), - BridgeToken: deposit.OriginalAddress.Hex(), - TokenAmount: deposit.Amount.String(), - Time: uint64(deposit.Time.UnixMilli()), - TxHash: deposit.TxHash.String(), - FromChainId: GetChainIdByNetworkId(deposit.NetworkID), - ToChainId: GetChainIdByNetworkId(deposit.DestinationNetwork), - Id: deposit.Id, - Index: uint64(deposit.DepositCount), - Metadata: "0x" + hex.EncodeToString(deposit.Metadata), - DestAddr: deposit.DestinationAddress.Hex(), - LeafType: uint32(deposit.LeafType), - BlockNumber: deposit.BlockNumber, + FromChain: uint32(deposit.NetworkID), + ToChain: uint32(deposit.DestinationNetwork), + BridgeToken: deposit.OriginalAddress.Hex(), + TokenAmount: deposit.Amount.String(), + Time: uint64(deposit.Time.UnixMilli()), + TxHash: deposit.TxHash.String(), + FromChainId: GetChainIdByNetworkId(deposit.NetworkID), + ToChainId: GetChainIdByNetworkId(deposit.DestinationNetwork), + Id: deposit.Id, + Index: uint64(deposit.DepositCount), + Metadata: "0x" + hex.EncodeToString(deposit.Metadata), + DestAddr: deposit.DestinationAddress.Hex(), + LeafType: uint32(deposit.LeafType), + BlockNumber: deposit.BlockNumber, + DestContractAddr: deposit.DestContractAddress.Hex(), + OriginalNetwork: uint32(deposit.OriginalNetwork), } } diff --git a/utils/usdclxly.go b/utils/usdclxly.go new file mode 100644 index 00000000..c05e4919 --- /dev/null +++ b/utils/usdclxly.go @@ -0,0 +1,74 @@ +package utils + +import ( + "math/big" + + "github.com/0xPolygonHermez/zkevm-bridge-service/etherman" + "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/ethereum/go-ethereum/common" +) + +var ( + usdcContractToTokenMapping map[common.Address]common.Address + emptyAddress = common.Address{} +) + +func InitUSDCLxLyMapping(usdcContractAddresses, usdcTokenAddresses []common.Address) { + log.Debugf("USDCLxLyMapping: contracts[%v] tokens[%v]", usdcContractAddresses, usdcTokenAddresses) + if len(usdcContractAddresses) != len(usdcTokenAddresses) { + log.Errorf("InitUSDCLxLyMapping: contract addresses (%v) and token addresses (%v) have different length", len(usdcContractAddresses), len(usdcTokenAddresses)) + } + + usdcContractToTokenMapping = make(map[common.Address]common.Address) + l := min(len(usdcContractAddresses), len(usdcTokenAddresses)) + for i := 0; i < l; i++ { + if usdcTokenAddresses[i] == emptyAddress { + continue + } + usdcContractToTokenMapping[usdcContractAddresses[i]] = usdcTokenAddresses[i] + } +} + +func GetUSDCContractAddressList() []common.Address { + result := make([]common.Address, 0) + for addr := range usdcContractToTokenMapping { + result = append(result, addr) + } + return result +} + +func IsUSDCContractAddress(address common.Address) bool { + if _, ok := usdcContractToTokenMapping[address]; ok { + return true + } + return false +} + +func GetUSDCTokenFromContract(contractAddress common.Address) (common.Address, bool) { + if token, ok := usdcContractToTokenMapping[contractAddress]; ok { + return token, true + } + return common.Address{}, false +} + +// DecodeUSDCBridgeMetadata extracts the user's account address from the metadata of USDC bridge +// Metadata structure: +// - Destination address: 32 bytes +// - Bridging amount: 32 bytes +func DecodeUSDCBridgeMetadata(metadata []byte) (common.Address, *big.Int) { + // Convert the first 32 bytes to address, and last 32 bytes to big int + // Maybe there's a more elegant way? + return common.BytesToAddress(metadata[:32]), new(big.Int).SetBytes(metadata[32:]) //nolint:gomnd +} + +func ReplaceUSDCDepositInfo(deposit *etherman.Deposit, overwriteOrigNetworkID bool) { + token, ok := GetUSDCTokenFromContract(deposit.OriginalAddress) + if !ok { + return + } + deposit.OriginalAddress = token + if overwriteOrigNetworkID { + deposit.OriginalNetwork = 0 // Always use 0 for this case when reporting metrics + } + _, deposit.Amount = DecodeUSDCBridgeMetadata(deposit.Metadata) +} diff --git a/utils/usdclxly_test.go b/utils/usdclxly_test.go new file mode 100644 index 00000000..494909ae --- /dev/null +++ b/utils/usdclxly_test.go @@ -0,0 +1,45 @@ +package utils + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestUSDCLxLyMapping(t *testing.T) { + contractAddr1 := common.HexToAddress("0xfe3240995c771f10D2583e8fa95F92ee40E15150") + contractAddr2 := common.HexToAddress("0x1A8C4999D32F05B63A227517Be0824AeD47e4728") + contractAddr3 := common.HexToAddress("0xfe3240995c771f10D2583e8fa95F92ee40E15151") + tokenAddr1 := common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48") + tokenAddr2 := common.HexToAddress("0x00d69D72a429d4985b34A8E1A6C9e47997F0aFA3") + + InitUSDCLxLyMapping([]common.Address{contractAddr1, contractAddr2}, []common.Address{tokenAddr1, tokenAddr2}) + + list := GetUSDCContractAddressList() + require.Len(t, list, 2) + require.Contains(t, list, contractAddr1) + require.Contains(t, list, contractAddr2) + + require.True(t, IsUSDCContractAddress(contractAddr1)) + require.True(t, IsUSDCContractAddress(contractAddr2)) + require.False(t, IsUSDCContractAddress(contractAddr3)) + + token, ok := GetUSDCTokenFromContract(contractAddr2) + require.True(t, ok) + require.Equal(t, tokenAddr2, token) + + _, ok = GetUSDCTokenFromContract(contractAddr3) + require.False(t, ok) +} + +func TestDecodeUSDCBridgeMetadata(t *testing.T) { + metadata := common.Hex2Bytes("00000000000000000000000023335657622dcc27bb1914e51cdc30871d6d04d300000000000000000000000000000000000000000000000000000000000f4240") + addr := common.HexToAddress("0x23335657622dcc27bb1914e51cdc30871d6d04d3") + amount := new(big.Int).SetUint64(1000000) + + addr1, amount1 := DecodeUSDCBridgeMetadata(metadata) + require.Equal(t, addr, addr1) + require.Equal(t, amount, amount1) +}